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)
180 ;; -------------------------------------------------------------------------
182 ;; -------------------------------------------------------------------------
187 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188 (const (symbol_ref "sh_cpu_attr")))
190 (define_attr "endian" "big,little"
191 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192 (const_string "little") (const_string "big"))))
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197 (const_string "yes") (const_string "no"))))
199 (define_attr "fmovd" "yes,no"
200 (const (if_then_else (symbol_ref "TARGET_FMOVD")
201 (const_string "yes") (const_string "no"))))
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
205 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207 (const_string "sh1"))))
209 ;; cbranch conditional branch instructions
210 ;; jump unconditional jumps
211 ;; arith ordinary arithmetic
212 ;; arith3 a compound insn that behaves similarly to a sequence of
213 ;; three insns of type arith
214 ;; arith3b like above, but might end with a redirected branch
216 ;; load_si Likewise, SImode variant for general register.
217 ;; fload Likewise, but load to fp register.
219 ;; fstore floating point register to memory
220 ;; move general purpose register to register
221 ;; movi8 8-bit immediate to general purpose register
222 ;; mt_group other sh4 mt instructions
223 ;; fmove register to register, floating point
224 ;; smpy word precision integer multiply
225 ;; dmpy longword or doublelongword precision integer multiply
227 ;; pload load of pr reg, which can't be put into delay slot of rts
228 ;; prset copy register to pr reg, ditto
229 ;; pstore store of pr reg, which can't be put into delay slot of jsr
230 ;; prget copy pr to register, ditto
231 ;; pcload pc relative load of constant value
232 ;; pcfload Likewise, but load to fp register.
233 ;; pcload_si Likewise, SImode variant for general register.
234 ;; rte return from exception
235 ;; sfunc special function call with known used registers
236 ;; call function call
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv floating point divide (or square root)
240 ;; gp_fpul move from general purpose register to fpul
241 ;; fpul_gp move from fpul to general purpose register
242 ;; mac_gp move from mac[lh] to general purpose register
243 ;; gp_mac move from general purpose register to mac[lh]
244 ;; mac_mem move from mac[lh] to memory
245 ;; mem_mac move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s fix_truncsfsi2_i4
248 ;; dfdiv double precision floating point divide (or square root)
249 ;; cwb ic_invalidate_line_i
250 ;; movua SH4a unaligned load
251 ;; fsrra square root reciprocal approximate
252 ;; fsca sine and cosine approximate
253 ;; tls_load load TLS related address
254 ;; arith_media SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media SHmedia compare instructions
257 ;; dfdiv_media SHmedia double precision divide and square root
258 ;; dfmul_media SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media SHmedia longword multiply
262 ;; fcmp_media SHmedia floating point compare instructions
263 ;; fdiv_media SHmedia single precision divide and square root
264 ;; fload_media SHmedia floating point register load instructions
265 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media SHmedia unconditional branch instructions
272 ;; load_media SHmedia general register load instructions
273 ;; pt_media SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media SHmedia ptabs instruction
275 ;; store_media SHmedia general register store instructions
276 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media SHmedia mac-style fixed point operations
278 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil no-op move, will be deleted.
284 "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"
285 (const_string "other"))
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
290 ;; mt_group SH4 "mt" group instructions.
292 ;; ex_group SH4 "ex" group instructions.
294 ;; ls_group SH4 "ls" group instructions.
297 (define_attr "insn_class"
298 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302 (eq_attr "type" "cbranch,jump") (const_string "br_group")
303 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304 (const_string "fe_group")
305 (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")]
306 (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long. Something in the
325 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
330 ;; The maximum range used for SImode constant pool entries is 1018. A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table. That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
348 (define_attr "short_cbranch_p" "no,yes"
349 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
351 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
353 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
357 ] (const_string "no")))
359 (define_attr "med_branch_p" "no,yes"
360 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
363 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
368 ] (const_string "no")))
370 (define_attr "med_cbranch_p" "no,yes"
371 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
374 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
379 ] (const_string "no")))
381 (define_attr "braf_branch_p" "no,yes"
382 (cond [(match_test "! TARGET_SH2")
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
387 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
392 ] (const_string "no")))
394 (define_attr "braf_cbranch_p" "no,yes"
395 (cond [(match_test "! TARGET_SH2")
397 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
400 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
402 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
405 ] (const_string "no")))
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
414 ; All other instructions are two bytes long by default.
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419 (cond [(eq_attr "type" "cbranch")
420 (cond [(eq_attr "short_cbranch_p" "yes")
422 (eq_attr "med_cbranch_p" "yes")
424 (eq_attr "braf_cbranch_p" "yes")
426 ;; ??? using pc is not computed transitively.
427 (ne (match_dup 0) (match_dup 0))
429 (match_test "flag_pic")
432 (eq_attr "type" "jump")
433 (cond [(eq_attr "med_branch_p" "yes")
435 (and (match_test "prev_nonnote_insn (insn)")
436 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") (symbol_ref "INSN"))
437 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") (symbol_ref "code_for_indirect_jump_scratch"))))
438 (cond [(eq_attr "braf_branch_p" "yes")
440 (not (match_test "flag_pic"))
442 (match_test "TARGET_SH2")
443 (const_int 10)] (const_int 18))
444 (eq_attr "braf_branch_p" "yes")
446 ;; ??? using pc is not computed transitively.
447 (ne (match_dup 0) (match_dup 0))
449 (match_test "flag_pic")
452 (eq_attr "type" "pt_media")
453 (if_then_else (match_test "TARGET_SHMEDIA64")
454 (const_int 20) (const_int 12))
455 (and (eq_attr "type" "jump_media")
456 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
458 ] (if_then_else (match_test "TARGET_SHMEDIA")
462 ;; DFA descriptions for the pipelines
465 (include "shmedia.md")
468 (include "predicates.md")
469 (include "constraints.md")
471 ;; Definitions for filling delay slots
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475 (define_attr "banked" "yes,no"
476 (cond [(match_test "sh_loads_bankedreg_p (insn)")
477 (const_string "yes")]
478 (const_string "no")))
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
484 (const_string "yes")))
486 (define_attr "interrupt_function" "no,yes"
487 (const (symbol_ref "current_function_interrupt")))
489 (define_attr "in_delay_slot" "yes,no"
490 (cond [(eq_attr "type" "cbranch") (const_string "no")
491 (eq_attr "type" "pcload,pcload_si") (const_string "no")
492 (eq_attr "needs_delay_slot" "yes") (const_string "no")
493 (eq_attr "length" "2") (const_string "yes")
494 ] (const_string "no")))
496 (define_attr "cond_delay_slot" "yes,no"
497 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498 ] (const_string "no")))
500 (define_attr "is_sfunc" ""
501 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
503 (define_attr "is_mac_media" ""
504 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
506 (define_attr "branch_zero" "yes,no"
507 (cond [(eq_attr "type" "!cbranch") (const_string "no")
508 (ne (symbol_ref "(next_active_insn (insn)\
509 == (prev_active_insn\
510 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511 && get_attr_length (next_active_insn (insn)) == 2")
513 (const_string "yes")]
514 (const_string "no")))
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520 (const_string "no")))
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527 (const_string "yes")]
528 (const_string "no")))
530 (define_attr "any_int_load" "yes,no"
531 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532 (const_string "yes")]
533 (const_string "no")))
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536 (const_string "user"))
539 (eq_attr "needs_delay_slot" "yes")
540 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
551 (eq_attr "type" "return")
552 [(and (eq_attr "in_delay_slot" "yes")
553 (ior (and (eq_attr "interrupt_function" "no")
554 (eq_attr "type" "!pload,prset"))
555 (and (eq_attr "interrupt_function" "yes")
557 (not (match_test "TARGET_SH3"))
558 (eq_attr "hit_stack" "no")
559 (eq_attr "banked" "no"))))) (nil) (nil)])
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 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
746 ;; That would still allow reload to create cmpi instructions, but would
747 ;; perhaps allow forcing the constant into a register when that is better.
748 ;; Probably should use r0 for mem/imm compares, but force constant into a
749 ;; register for pseudo/imm compares.
751 (define_insn "cmpeqsi_t"
753 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
754 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
760 [(set_attr "type" "mt_group")])
762 (define_insn "cmpgtsi_t"
764 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
765 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
770 [(set_attr "type" "mt_group")])
772 (define_insn "cmpgesi_t"
774 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
775 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
780 [(set_attr "type" "mt_group")])
782 ;; -------------------------------------------------------------------------
783 ;; SImode compare and branch
784 ;; -------------------------------------------------------------------------
786 (define_expand "cbranchsi4"
788 (if_then_else (match_operator 0 "comparison_operator"
789 [(match_operand:SI 1 "arith_operand" "")
790 (match_operand:SI 2 "arith_operand" "")])
791 (label_ref (match_operand 3 "" ""))
793 (clobber (reg:SI T_REG))]
797 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
798 operands[2], operands[3]));
799 else if (TARGET_CBRANCHDI4)
800 expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
802 sh_emit_compare_and_branch (operands, SImode);
806 ;; -------------------------------------------------------------------------
807 ;; SImode unsigned integer comparisons
808 ;; -------------------------------------------------------------------------
810 (define_insn_and_split "cmpgeusi_t"
812 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
813 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
816 "&& operands[1] == CONST0_RTX (SImode)"
819 emit_insn (gen_sett ());
822 [(set_attr "type" "mt_group")])
824 (define_insn "cmpgtusi_t"
826 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
827 (match_operand:SI 1 "arith_reg_operand" "r")))]
830 [(set_attr "type" "mt_group")])
833 ;; -------------------------------------------------------------------------
834 ;; DImode compare and branch
835 ;; -------------------------------------------------------------------------
838 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
839 ;; Therefore, we aim to have a set of three branches that go straight to the
840 ;; destination, i.e. only one of them is taken at any one time.
841 ;; This mechanism should also be slightly better for the sh4-200.
843 (define_expand "cbranchdi4"
845 (if_then_else (match_operator 0 "comparison_operator"
846 [(match_operand:DI 1 "arith_operand" "")
847 (match_operand:DI 2 "arith_operand" "")])
848 (label_ref (match_operand 3 "" ""))
850 (clobber (match_dup 4))
851 (clobber (reg:SI T_REG))]
852 "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
854 enum rtx_code comparison;
858 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
859 operands[2], operands[3]));
863 else if (!TARGET_CBRANCHDI4)
865 sh_emit_compare_and_branch (operands, DImode);
871 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
874 comparison = prepare_cbranch_operands (operands, DImode,
875 LAST_AND_UNUSED_RTX_CODE);
876 if (comparison != GET_CODE (operands[0]))
878 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
879 operands[4] = gen_rtx_SCRATCH (SImode);
883 (define_insn_and_split "cbranchdi4_i"
885 (if_then_else (match_operator 0 "comparison_operator"
886 [(match_operand:DI 1 "arith_operand" "r,r")
887 (match_operand:DI 2 "arith_operand" "rN,I08")])
888 (label_ref (match_operand 3 "" ""))
890 (clobber (match_scratch:SI 4 "=X,&r"))
891 (clobber (reg:SI T_REG))]
894 "&& reload_completed"
897 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
902 ;; -------------------------------------------------------------------------
903 ;; DImode signed integer comparisons
904 ;; -------------------------------------------------------------------------
908 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
909 (match_operand:DI 1 "arith_operand" "r"))
913 return output_branchy_insn (EQ, "tst\t%S1,%S0;bf\t%l9;tst\t%R1,%R0",
916 [(set_attr "length" "6")
917 (set_attr "type" "arith3b")])
919 (define_insn "cmpeqdi_t"
921 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
922 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
925 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
926 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
927 [(set_attr "length" "6")
928 (set_attr "type" "arith3b")])
932 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
933 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
934 ;; If we applied this split when not optimizing, it would only be
935 ;; applied during the machine-dependent reorg, when no new basic blocks
937 "TARGET_SH1 && reload_completed && optimize"
938 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
939 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
940 (label_ref (match_dup 6))
942 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
945 operands[2] = gen_highpart (SImode, operands[0]);
946 operands[3] = operands[1] == const0_rtx
948 : gen_highpart (SImode, operands[1]);
949 operands[4] = gen_lowpart (SImode, operands[0]);
950 operands[5] = gen_lowpart (SImode, operands[1]);
951 operands[6] = gen_label_rtx ();
954 (define_insn "cmpgtdi_t"
956 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
957 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
960 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
961 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
962 [(set_attr "length" "8")
963 (set_attr "type" "arith3")])
965 (define_insn "cmpgedi_t"
967 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
968 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
971 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
973 [(set_attr "length" "8,2")
974 (set_attr "type" "arith3,mt_group")])
976 ;; -------------------------------------------------------------------------
977 ;; DImode unsigned integer comparisons
978 ;; -------------------------------------------------------------------------
980 (define_insn "cmpgeudi_t"
982 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
983 (match_operand:DI 1 "arith_reg_operand" "r")))]
985 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
986 [(set_attr "length" "8")
987 (set_attr "type" "arith3")])
989 (define_insn "cmpgtudi_t"
991 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
992 (match_operand:DI 1 "arith_reg_operand" "r")))]
994 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
995 [(set_attr "length" "8")
996 (set_attr "type" "arith3")])
998 (define_insn "cmpeqsi_media"
999 [(set (match_operand:SI 0 "register_operand" "=r")
1000 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1001 (match_operand:SI 2 "cmp_operand" "Nr")))]
1004 [(set_attr "type" "cmp_media")])
1006 (define_insn "cmpeqdi_media"
1007 [(set (match_operand:SI 0 "register_operand" "=r")
1008 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1009 (match_operand:DI 2 "cmp_operand" "Nr")))]
1012 [(set_attr "type" "cmp_media")])
1014 (define_insn "cmpgtsi_media"
1015 [(set (match_operand:SI 0 "register_operand" "=r")
1016 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1017 (match_operand:SI 2 "cmp_operand" "rN")))]
1019 "cmpgt %N1, %N2, %0"
1020 [(set_attr "type" "cmp_media")])
1022 (define_insn "cmpgtdi_media"
1023 [(set (match_operand:SI 0 "register_operand" "=r")
1024 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1025 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1027 "cmpgt %N1, %N2, %0"
1028 [(set_attr "type" "cmp_media")])
1030 (define_insn "cmpgtusi_media"
1031 [(set (match_operand:SI 0 "register_operand" "=r")
1032 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1033 (match_operand:SI 2 "cmp_operand" "rN")))]
1035 "cmpgtu %N1, %N2, %0"
1036 [(set_attr "type" "cmp_media")])
1038 (define_insn "cmpgtudi_media"
1039 [(set (match_operand:SI 0 "register_operand" "=r")
1040 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1041 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1043 "cmpgtu %N1, %N2, %0"
1044 [(set_attr "type" "cmp_media")])
1046 ; These two patterns are for combine.
1047 (define_insn "*cmpne0sisi_media"
1048 [(set (match_operand:SI 0 "register_operand" "=r")
1049 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1052 [(set_attr "type" "cmp_media")])
1054 ;; -------------------------------------------------------------------------
1055 ;; Conditional move instructions
1056 ;; -------------------------------------------------------------------------
1058 ;; The insn names may seem reversed, but note that cmveq performs the move
1059 ;; if op1 == 0, and cmvne does it if op1 != 0.
1061 (define_insn "movdicc_false"
1062 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1063 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1065 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1066 (match_operand:DI 3 "arith_reg_operand" "0")))]
1069 [(set_attr "type" "arith_media")])
1071 (define_insn "movdicc_true"
1072 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1073 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1075 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1076 (match_operand:DI 3 "arith_reg_operand" "0")))]
1079 [(set_attr "type" "arith_media")])
1082 [(set (match_operand:DI 0 "arith_reg_dest" "")
1083 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1084 [(match_operand:DI 1 "arith_reg_operand" "")
1086 (match_operand:DI 2 "arith_reg_dest" "")
1088 (set (match_dup 2) (match_dup 0))]
1089 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1091 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1093 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1094 VOIDmode, operands[1], CONST0_RTX (DImode));
1098 [(set (match_operand:DI 0 "general_movdst_operand" "")
1099 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1100 (set (match_operand:DI 2 "arith_reg_dest" "")
1101 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1102 [(match_operand:DI 3 "arith_reg_operand" "")
1106 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1108 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1111 (define_expand "movdicc"
1112 [(set (match_operand:DI 0 "register_operand" "")
1113 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1114 (match_operand:DI 2 "register_operand" "")
1115 (match_operand:DI 3 "register_operand" "")))]
1118 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1119 && GET_MODE (XEXP (operands[1], 0)) == DImode
1120 && XEXP (operands[1], 1) == const0_rtx)
1124 if (!can_create_pseudo_p ())
1127 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1128 GET_CODE (operands[1]),
1129 XEXP (operands[1], 0),
1130 XEXP (operands[1], 1));
1136 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1137 ;; SImode to DImode.
1138 (define_insn "movsicc_false"
1139 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1140 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1142 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1143 (match_operand:SI 3 "arith_reg_operand" "0")))]
1146 [(set_attr "type" "arith_media")])
1148 (define_insn "movsicc_true"
1149 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1150 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1152 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1153 (match_operand:SI 3 "arith_reg_operand" "0")))]
1156 [(set_attr "type" "arith_media")])
1159 [(set (match_operand:SI 0 "arith_reg_dest" "")
1160 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1161 [(match_operand:SI 1 "arith_reg_operand" "")
1163 (match_operand:SI 2 "arith_reg_dest" "")
1165 (set (match_dup 2) (match_dup 0))]
1166 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1168 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1170 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1171 VOIDmode, operands[1], CONST0_RTX (SImode));
1175 [(set (match_operand:SI 0 "general_movdst_operand" "")
1176 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1177 (set (match_operand:SI 2 "arith_reg_dest" "")
1178 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1179 [(match_operand:SI 3 "arith_reg_operand" "")
1183 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1184 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1186 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1188 replace_rtx (operands[4], operands[0], operands[1]);
1192 [(set (match_operand 0 "any_register_operand" "")
1193 (match_operand 1 "any_register_operand" ""))
1194 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1195 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1196 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1197 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1198 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1199 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1200 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1201 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1202 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1203 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1204 && (REGNO_REG_CLASS (REGNO (operands[0]))
1205 == REGNO_REG_CLASS (REGNO (operands[2])))
1206 && (REGNO_REG_CLASS (REGNO (operands[1]))
1207 == REGNO_REG_CLASS (REGNO (operands[0])))"
1208 [(set (match_dup 0) (match_dup 3))
1209 (set (match_dup 4) (match_dup 5))]
1211 rtx set1, set2, insn2;
1212 rtx replacements[4];
1214 /* We want to replace occurrences of operands[0] with operands[1] and
1215 operands[2] with operands[0] in operands[4]/operands[5].
1216 Doing just two replace_rtx calls naively would result in the second
1217 replacement undoing all that the first did if operands[1] and operands[2]
1218 are identical, so we must do this simultaneously. */
1219 replacements[0] = operands[0];
1220 replacements[1] = operands[1];
1221 replacements[2] = operands[2];
1222 replacements[3] = operands[0];
1223 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1224 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1225 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1228 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1229 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1230 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1231 /* The operands array is aliased to recog_data.operand, which gets
1232 clobbered by extract_insn, so finish with it now. */
1233 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1234 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1235 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1236 always uses emit_insn. */
1237 /* Check that we don't violate matching constraints or earlyclobbers. */
1238 extract_insn (emit_insn (set1));
1239 if (! constrain_operands (1))
1241 insn2 = emit (set2);
1242 if (GET_CODE (insn2) == BARRIER)
1244 extract_insn (insn2);
1245 if (! constrain_operands (1))
1249 tmp = replacements[0];
1250 replacements[0] = replacements[1];
1251 replacements[1] = tmp;
1252 tmp = replacements[2];
1253 replacements[2] = replacements[3];
1254 replacements[3] = tmp;
1255 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1256 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1257 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1263 ;; The register allocator is rather clumsy in handling multi-way conditional
1264 ;; moves, so allow the combiner to make them, and we split them up after
1266 (define_insn_and_split "*movsicc_umin"
1267 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1268 (umin:SI (if_then_else:SI
1269 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1271 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1272 (match_operand:SI 3 "register_operand" "0"))
1273 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1274 (clobber (match_scratch:SI 5 "=&r"))]
1275 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1277 "TARGET_SHMEDIA && reload_completed"
1280 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1282 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1283 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1288 (define_insn "*movsicc_t_false"
1289 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1290 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1291 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1292 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1293 "TARGET_PRETEND_CMOVE
1294 && (arith_reg_operand (operands[1], SImode)
1295 || (immediate_operand (operands[1], SImode)
1296 && satisfies_constraint_I08 (operands[1])))"
1297 "bt 0f\;mov %1,%0\\n0:"
1298 [(set_attr "type" "mt_group,arith") ;; poor approximation
1299 (set_attr "length" "4")])
1301 (define_insn "*movsicc_t_true"
1302 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1303 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1304 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1305 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1306 "TARGET_PRETEND_CMOVE
1307 && (arith_reg_operand (operands[1], SImode)
1308 || (immediate_operand (operands[1], SImode)
1309 && satisfies_constraint_I08 (operands[1])))"
1310 "bf 0f\;mov %1,%0\\n0:"
1311 [(set_attr "type" "mt_group,arith") ;; poor approximation
1312 (set_attr "length" "4")])
1314 (define_expand "movsicc"
1315 [(set (match_operand:SI 0 "arith_reg_dest" "")
1316 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1317 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1318 (match_operand:SI 3 "arith_reg_operand" "")))]
1319 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1321 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1322 && GET_MODE (XEXP (operands[1], 0)) == SImode
1324 || (REG_P (XEXP (operands[1], 0))
1325 && REGNO (XEXP (operands[1], 0)) == T_REG))
1326 && XEXP (operands[1], 1) == const0_rtx)
1329 else if (TARGET_PRETEND_CMOVE)
1331 enum rtx_code code = GET_CODE (operands[1]);
1332 enum rtx_code new_code = code;
1333 rtx op0 = XEXP (operands[1], 0);
1334 rtx op1 = XEXP (operands[1], 1);
1336 if (! currently_expanding_to_rtl)
1340 case LT: case LE: case LEU: case LTU:
1341 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1344 new_code = reverse_condition (code);
1346 case EQ: case GT: case GE: case GEU: case GTU:
1351 sh_emit_scc_to_t (new_code, op0, op1);
1352 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1353 gen_rtx_REG (SImode, T_REG), const0_rtx);
1357 if (!can_create_pseudo_p ())
1360 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1361 GET_CODE (operands[1]),
1362 XEXP (operands[1], 0),
1363 XEXP (operands[1], 1));
1369 (define_expand "movqicc"
1370 [(set (match_operand:QI 0 "register_operand" "")
1371 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1372 (match_operand:QI 2 "register_operand" "")
1373 (match_operand:QI 3 "register_operand" "")))]
1376 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1377 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1378 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1379 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1383 ;; -------------------------------------------------------------------------
1384 ;; Addition instructions
1385 ;; -------------------------------------------------------------------------
1387 (define_expand "adddi3"
1388 [(set (match_operand:DI 0 "arith_reg_operand" "")
1389 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1390 (match_operand:DI 2 "arith_operand" "")))]
1395 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1397 operands[2] = force_reg (DImode, operands[2]);
1398 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1403 (define_insn "*adddi3_media"
1404 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1405 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1406 (match_operand:DI 2 "arith_operand" "r,I10")))]
1411 [(set_attr "type" "arith_media")])
1413 (define_insn "*adddisi3_media"
1414 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1415 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1416 (match_operand:DI 2 "arith_operand" "r,I10")))]
1421 [(set_attr "type" "arith_media")
1422 (set_attr "highpart" "ignore")])
1424 (define_insn "adddi3z_media"
1425 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1427 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1428 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1430 "addz.l %1, %N2, %0"
1431 [(set_attr "type" "arith_media")
1432 (set_attr "highpart" "ignore")])
1434 (define_insn "adddi3_compact"
1435 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1436 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1437 (match_operand:DI 2 "arith_reg_operand" "r")))
1438 (clobber (reg:SI T_REG))]
1441 [(set_attr "length" "6")])
1444 [(set (match_operand:DI 0 "arith_reg_dest" "")
1445 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1446 (match_operand:DI 2 "arith_reg_operand" "")))
1447 (clobber (reg:SI T_REG))]
1448 "TARGET_SH1 && reload_completed"
1451 rtx high0 = gen_highpart (SImode, operands[0]);
1452 rtx high2 = gen_highpart (SImode, operands[2]);
1453 rtx low0 = gen_lowpart (SImode, operands[0]);
1455 emit_insn (gen_clrt ());
1456 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1457 emit_insn (gen_addc1 (high0, high0, high2));
1462 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1463 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1464 (match_operand:SI 2 "arith_reg_operand" "r"))
1467 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1470 [(set_attr "type" "arith")])
1472 (define_insn "addc1"
1473 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1474 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1475 (match_operand:SI 2 "arith_reg_operand" "r"))
1477 (clobber (reg:SI T_REG))]
1480 [(set_attr "type" "arith")])
1482 (define_expand "addsi3"
1483 [(set (match_operand:SI 0 "arith_reg_operand" "")
1484 (plus:SI (match_operand:SI 1 "arith_operand" "")
1485 (match_operand:SI 2 "arith_operand" "")))]
1489 operands[1] = force_reg (SImode, operands[1]);
1492 (define_insn "addsi3_media"
1493 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1494 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1495 (match_operand:SI 2 "arith_operand" "r,I10")))]
1500 [(set_attr "type" "arith_media")
1501 (set_attr "highpart" "ignore")])
1503 (define_insn "addsidi3_media"
1504 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1505 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1507 (match_operand:SI 2 "arith_operand"
1513 [(set_attr "type" "arith_media")
1514 (set_attr "highpart" "ignore")])
1516 (define_insn "*addsi3_compact"
1517 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1518 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1519 (match_operand:SI 2 "arith_operand" "rI08")))]
1522 [(set_attr "type" "arith")])
1524 ;; -------------------------------------------------------------------------
1525 ;; Subtraction instructions
1526 ;; -------------------------------------------------------------------------
1528 (define_expand "subdi3"
1529 [(set (match_operand:DI 0 "arith_reg_operand" "")
1530 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1531 (match_operand:DI 2 "arith_reg_operand" "")))]
1536 operands[1] = force_reg (DImode, operands[1]);
1537 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1542 (define_insn "*subdi3_media"
1543 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1544 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1545 (match_operand:DI 2 "arith_reg_operand" "r")))]
1548 [(set_attr "type" "arith_media")])
1550 (define_insn "subdisi3_media"
1551 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1552 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1553 (match_operand:DI 2 "arith_reg_operand" "r")))]
1556 [(set_attr "type" "arith_media")
1557 (set_attr "highpart" "ignore")])
1559 (define_insn "subdi3_compact"
1560 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1561 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1562 (match_operand:DI 2 "arith_reg_operand" "r")))
1563 (clobber (reg:SI T_REG))]
1566 [(set_attr "length" "6")])
1569 [(set (match_operand:DI 0 "arith_reg_dest" "")
1570 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1571 (match_operand:DI 2 "arith_reg_operand" "")))
1572 (clobber (reg:SI T_REG))]
1573 "TARGET_SH1 && reload_completed"
1576 rtx high0 = gen_highpart (SImode, operands[0]);
1577 rtx high2 = gen_highpart (SImode, operands[2]);
1578 rtx low0 = gen_lowpart (SImode, operands[0]);
1580 emit_insn (gen_clrt ());
1581 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1582 emit_insn (gen_subc1 (high0, high0, high2));
1587 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1588 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1589 (match_operand:SI 2 "arith_reg_operand" "r"))
1592 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1597 [(set_attr "type" "arith")])
1599 (define_insn "subc1"
1600 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1601 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1602 (match_operand:SI 2 "arith_reg_operand" "r"))
1604 (clobber (reg:SI T_REG))]
1607 [(set_attr "type" "arith")])
1609 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1610 ;; pattern for this case. This helps multimedia applications that compute
1611 ;; the sum of absolute differences.
1612 (define_insn "mov_neg_si_t"
1613 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1616 [(set_attr "type" "arith")])
1618 (define_insn "*subsi3_internal"
1619 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1620 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1621 (match_operand:SI 2 "arith_reg_operand" "r")))]
1624 [(set_attr "type" "arith")])
1626 (define_insn_and_split "*subsi3_media"
1627 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1628 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1629 (match_operand:SI 2 "extend_reg_operand" "r")))]
1631 && (operands[1] != constm1_rtx
1632 || (GET_CODE (operands[2]) != TRUNCATE
1633 && GET_CODE (operands[2]) != SUBREG))"
1635 "operands[1] == constm1_rtx"
1636 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1638 [(set_attr "type" "arith_media")
1639 (set_attr "highpart" "ignore")])
1642 [(set (match_operand:SI 0 "arith_reg_dest" "")
1643 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1644 "general_extend_operand"
1646 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1647 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1648 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1652 [(set (match_operand:SI 0 "arith_reg_dest" "")
1653 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1654 "general_extend_operand"
1656 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1657 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1658 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1660 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1661 ;; will sometimes save one instruction. Otherwise we might get
1662 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1665 (define_expand "subsi3"
1666 [(set (match_operand:SI 0 "arith_reg_operand" "")
1667 (minus:SI (match_operand:SI 1 "arith_operand" "")
1668 (match_operand:SI 2 "arith_reg_operand" "")))]
1671 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1673 emit_insn (gen_negsi2 (operands[0], operands[2]));
1674 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1679 if (!can_create_pseudo_p ()
1680 && ! arith_reg_or_0_operand (operands[1], SImode))
1682 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1683 operands[1] = force_reg (SImode, operands[1]);
1687 ;; -------------------------------------------------------------------------
1688 ;; Division instructions
1689 ;; -------------------------------------------------------------------------
1691 ;; We take advantage of the library routines which don't clobber as many
1692 ;; registers as a normal function call would.
1694 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1695 ;; also has an effect on the register that holds the address of the sfunc.
1696 ;; To make this work, we have an extra dummy insn that shows the use
1697 ;; of this register for reorg.
1699 (define_insn "use_sfunc_addr"
1700 [(set (reg:SI PR_REG)
1701 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1702 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1704 [(set_attr "length" "0")])
1706 (define_insn "udivsi3_sh2a"
1707 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1708 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1709 (match_operand:SI 2 "arith_reg_operand" "z")))]
1712 [(set_attr "type" "arith")
1713 (set_attr "in_delay_slot" "no")])
1715 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1716 ;; hard register 0. If we used hard register 0, then the next instruction
1717 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1718 ;; gets allocated to a stack slot that needs its address reloaded, then
1719 ;; there is nothing to prevent reload from using r0 to reload the address.
1720 ;; This reload would clobber the value in r0 we are trying to store.
1721 ;; If we let reload allocate r0, then this problem can never happen.
1723 (define_insn "udivsi3_i1"
1724 [(set (match_operand:SI 0 "register_operand" "=z")
1725 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1726 (clobber (reg:SI T_REG))
1727 (clobber (reg:SI PR_REG))
1728 (clobber (reg:SI R4_REG))
1729 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1730 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1732 [(set_attr "type" "sfunc")
1733 (set_attr "needs_delay_slot" "yes")])
1735 ; Since shmedia-nofpu code could be linked against shcompact code, and
1736 ; the udivsi3 libcall has the same name, we must consider all registers
1737 ; clobbered that are in the union of the registers clobbered by the
1738 ; shmedia and the shcompact implementation. Note, if the shcompact
1739 ; implementation actually used shcompact code, we'd need to clobber
1740 ; also r23 and fr23.
1741 (define_insn "udivsi3_i1_media"
1742 [(set (match_operand:SI 0 "register_operand" "=z")
1743 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1744 (clobber (reg:SI T_MEDIA_REG))
1745 (clobber (reg:SI PR_MEDIA_REG))
1746 (clobber (reg:SI R20_REG))
1747 (clobber (reg:SI R21_REG))
1748 (clobber (reg:SI R22_REG))
1749 (clobber (reg:DI TR0_REG))
1750 (clobber (reg:DI TR1_REG))
1751 (clobber (reg:DI TR2_REG))
1752 (use (match_operand 1 "target_reg_operand" "b"))]
1753 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1755 [(set_attr "type" "sfunc")
1756 (set_attr "needs_delay_slot" "yes")])
1758 (define_expand "udivsi3_i4_media"
1760 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1762 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1763 (set (match_dup 5) (float:DF (match_dup 3)))
1764 (set (match_dup 6) (float:DF (match_dup 4)))
1765 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1766 (set (match_dup 8) (fix:DI (match_dup 7)))
1767 (set (match_operand:SI 0 "register_operand" "")
1768 (truncate:SI (match_dup 8)))]
1769 "TARGET_SHMEDIA_FPU"
1771 operands[3] = gen_reg_rtx (DImode);
1772 operands[4] = gen_reg_rtx (DImode);
1773 operands[5] = gen_reg_rtx (DFmode);
1774 operands[6] = gen_reg_rtx (DFmode);
1775 operands[7] = gen_reg_rtx (DFmode);
1776 operands[8] = gen_reg_rtx (DImode);
1779 (define_insn "udivsi3_i4"
1780 [(set (match_operand:SI 0 "register_operand" "=y")
1781 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1782 (clobber (reg:SI T_REG))
1783 (clobber (reg:SI PR_REG))
1784 (clobber (reg:DF DR0_REG))
1785 (clobber (reg:DF DR2_REG))
1786 (clobber (reg:DF DR4_REG))
1787 (clobber (reg:SI R0_REG))
1788 (clobber (reg:SI R1_REG))
1789 (clobber (reg:SI R4_REG))
1790 (clobber (reg:SI R5_REG))
1791 (use (reg:PSI FPSCR_REG))
1792 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1793 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1795 [(set_attr "type" "sfunc")
1796 (set_attr "fp_mode" "double")
1797 (set_attr "needs_delay_slot" "yes")])
1799 (define_insn "udivsi3_i4_single"
1800 [(set (match_operand:SI 0 "register_operand" "=y")
1801 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1802 (clobber (reg:SI T_REG))
1803 (clobber (reg:SI PR_REG))
1804 (clobber (reg:DF DR0_REG))
1805 (clobber (reg:DF DR2_REG))
1806 (clobber (reg:DF DR4_REG))
1807 (clobber (reg:SI R0_REG))
1808 (clobber (reg:SI R1_REG))
1809 (clobber (reg:SI R4_REG))
1810 (clobber (reg:SI R5_REG))
1811 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1812 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1814 [(set_attr "type" "sfunc")
1815 (set_attr "needs_delay_slot" "yes")])
1817 (define_insn "udivsi3_i4_int"
1818 [(set (match_operand:SI 0 "register_operand" "=z")
1819 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1820 (clobber (reg:SI T_REG))
1821 (clobber (reg:SI R1_REG))
1822 (clobber (reg:SI PR_REG))
1823 (clobber (reg:SI MACH_REG))
1824 (clobber (reg:SI MACL_REG))
1825 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1828 [(set_attr "type" "sfunc")
1829 (set_attr "needs_delay_slot" "yes")])
1832 (define_expand "udivsi3"
1833 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1834 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1835 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1836 (parallel [(set (match_operand:SI 0 "register_operand" "")
1837 (udiv:SI (reg:SI R4_REG)
1839 (clobber (reg:SI T_REG))
1840 (clobber (reg:SI PR_REG))
1841 (clobber (reg:SI R4_REG))
1842 (use (match_dup 3))])]
1847 operands[3] = gen_reg_rtx (Pmode);
1848 /* Emit the move of the address to a pseudo outside of the libcall. */
1849 if (TARGET_DIVIDE_CALL_TABLE)
1851 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1852 that causes problems when the divide code is supposed to come from a
1853 separate library. Division by zero is undefined, so dividing 1 can be
1854 implemented by comparing with the divisor. */
1855 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1857 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1858 emit_insn (gen_cstoresi4 (operands[0], test,
1859 operands[1], operands[2]));
1862 else if (operands[2] == const0_rtx)
1864 emit_move_insn (operands[0], operands[2]);
1867 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
1868 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1870 else if (TARGET_DIVIDE_CALL_FP)
1872 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
1873 if (TARGET_FPU_SINGLE)
1874 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1876 last = gen_udivsi3_i4 (operands[0], operands[3]);
1878 else if (TARGET_SHMEDIA_FPU)
1880 operands[1] = force_reg (SImode, operands[1]);
1881 operands[2] = force_reg (SImode, operands[2]);
1882 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1885 else if (TARGET_SH2A)
1887 operands[1] = force_reg (SImode, operands[1]);
1888 operands[2] = force_reg (SImode, operands[2]);
1889 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1892 else if (TARGET_SH5)
1894 function_symbol (operands[3],
1895 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
1899 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1900 else if (TARGET_FPU_ANY)
1901 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1903 last = gen_udivsi3_i1 (operands[0], operands[3]);
1907 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
1908 last = gen_udivsi3_i1 (operands[0], operands[3]);
1910 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1911 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1916 (define_insn "divsi3_sh2a"
1917 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1918 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1919 (match_operand:SI 2 "arith_reg_operand" "z")))]
1922 [(set_attr "type" "arith")
1923 (set_attr "in_delay_slot" "no")])
1925 (define_insn "divsi3_i1"
1926 [(set (match_operand:SI 0 "register_operand" "=z")
1927 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1928 (clobber (reg:SI T_REG))
1929 (clobber (reg:SI PR_REG))
1930 (clobber (reg:SI R1_REG))
1931 (clobber (reg:SI R2_REG))
1932 (clobber (reg:SI R3_REG))
1933 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1934 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1936 [(set_attr "type" "sfunc")
1937 (set_attr "needs_delay_slot" "yes")])
1939 (define_insn "divsi3_i1_media"
1940 [(set (match_operand:SI 0 "register_operand" "=z")
1941 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942 (clobber (reg:SI T_MEDIA_REG))
1943 (clobber (reg:SI PR_MEDIA_REG))
1944 (clobber (reg:SI R1_REG))
1945 (clobber (reg:SI R20_REG))
1946 (clobber (reg:SI R21_REG))
1947 (clobber (reg:SI TR0_REG))
1948 (use (match_operand 1 "target_reg_operand" "b"))]
1949 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1951 [(set_attr "type" "sfunc")])
1953 (define_insn "divsi3_media_2"
1954 [(set (match_operand:SI 0 "register_operand" "=z")
1955 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956 (clobber (reg:SI T_MEDIA_REG))
1957 (clobber (reg:SI PR_MEDIA_REG))
1958 (clobber (reg:SI R1_REG))
1959 (clobber (reg:SI R21_REG))
1960 (clobber (reg:SI TR0_REG))
1961 (use (reg:SI R20_REG))
1962 (use (match_operand 1 "target_reg_operand" "b"))]
1963 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1965 [(set_attr "type" "sfunc")])
1967 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1968 ;; hard reg clobbers and data dependencies that we need when we want
1969 ;; to rematerialize the division into a call.
1970 (define_insn_and_split "divsi_inv_call"
1971 [(set (match_operand:SI 0 "register_operand" "=r")
1972 (div:SI (match_operand:SI 1 "register_operand" "r")
1973 (match_operand:SI 2 "register_operand" "r")))
1974 (clobber (reg:SI R4_REG))
1975 (clobber (reg:SI R5_REG))
1976 (clobber (reg:SI T_MEDIA_REG))
1977 (clobber (reg:SI PR_MEDIA_REG))
1978 (clobber (reg:SI R1_REG))
1979 (clobber (reg:SI R21_REG))
1980 (clobber (reg:SI TR0_REG))
1981 (clobber (reg:SI R20_REG))
1982 (use (match_operand:SI 3 "register_operand" "r"))]
1985 "&& (reload_in_progress || reload_completed)"
1986 [(set (match_dup 0) (match_dup 3))]
1988 [(set_attr "highpart" "must_split")])
1990 ;; This is the combiner pattern for -mdiv=inv:call .
1991 (define_insn_and_split "*divsi_inv_call_combine"
1992 [(set (match_operand:SI 0 "register_operand" "=z")
1993 (div:SI (match_operand:SI 1 "register_operand" "r")
1994 (match_operand:SI 2 "register_operand" "r")))
1995 (clobber (reg:SI R4_REG))
1996 (clobber (reg:SI R5_REG))
1997 (clobber (reg:SI T_MEDIA_REG))
1998 (clobber (reg:SI PR_MEDIA_REG))
1999 (clobber (reg:SI R1_REG))
2000 (clobber (reg:SI R21_REG))
2001 (clobber (reg:SI TR0_REG))
2002 (clobber (reg:SI R20_REG))
2003 (use (unspec:SI [(match_dup 1)
2004 (match_operand:SI 3 "" "")
2005 (unspec:SI [(match_operand:SI 4 "" "")
2007 (match_operand:DI 5 "" "")]
2009 (match_operand:DI 6 "" "")
2012 UNSPEC_DIV_INV_M3))]
2015 "&& (reload_in_progress || reload_completed)"
2018 const char *name = sh_divsi3_libfunc;
2019 enum sh_function_kind kind = SFUNC_GOT;
2022 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2023 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2024 while (TARGET_DIVIDE_INV_CALL2)
2026 rtx x = operands[3];
2028 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2030 x = XVECEXP (x, 0, 0);
2031 name = "__sdivsi3_2";
2032 kind = SFUNC_STATIC;
2033 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2036 sym = function_symbol (NULL, name, kind);
2037 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2040 [(set_attr "highpart" "must_split")])
2042 (define_expand "divsi3_i4_media"
2043 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2044 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2045 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2046 (set (match_operand:SI 0 "register_operand" "=r")
2047 (fix:SI (match_dup 5)))]
2048 "TARGET_SHMEDIA_FPU"
2050 operands[3] = gen_reg_rtx (DFmode);
2051 operands[4] = gen_reg_rtx (DFmode);
2052 operands[5] = gen_reg_rtx (DFmode);
2055 (define_insn "divsi3_i4"
2056 [(set (match_operand:SI 0 "register_operand" "=y")
2057 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2058 (clobber (reg:SI PR_REG))
2059 (clobber (reg:DF DR0_REG))
2060 (clobber (reg:DF DR2_REG))
2061 (use (reg:PSI FPSCR_REG))
2062 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2063 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2065 [(set_attr "type" "sfunc")
2066 (set_attr "fp_mode" "double")
2067 (set_attr "needs_delay_slot" "yes")])
2069 (define_insn "divsi3_i4_single"
2070 [(set (match_operand:SI 0 "register_operand" "=y")
2071 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2072 (clobber (reg:SI PR_REG))
2073 (clobber (reg:DF DR0_REG))
2074 (clobber (reg:DF DR2_REG))
2075 (clobber (reg:SI R2_REG))
2076 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2077 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2079 [(set_attr "type" "sfunc")
2080 (set_attr "needs_delay_slot" "yes")])
2082 (define_insn "divsi3_i4_int"
2083 [(set (match_operand:SI 0 "register_operand" "=z")
2084 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2085 (clobber (reg:SI T_REG))
2086 (clobber (reg:SI PR_REG))
2087 (clobber (reg:SI R1_REG))
2088 (clobber (reg:SI MACH_REG))
2089 (clobber (reg:SI MACL_REG))
2090 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093 [(set_attr "type" "sfunc")
2094 (set_attr "needs_delay_slot" "yes")])
2096 (define_expand "divsi3"
2097 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2098 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2099 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2100 (parallel [(set (match_operand:SI 0 "register_operand" "")
2101 (div:SI (reg:SI R4_REG)
2103 (clobber (reg:SI T_REG))
2104 (clobber (reg:SI PR_REG))
2105 (clobber (reg:SI R1_REG))
2106 (clobber (reg:SI R2_REG))
2107 (clobber (reg:SI R3_REG))
2108 (use (match_dup 3))])]
2113 operands[3] = gen_reg_rtx (Pmode);
2114 /* Emit the move of the address to a pseudo outside of the libcall. */
2115 if (TARGET_DIVIDE_CALL_TABLE)
2117 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2118 last = gen_divsi3_i4_int (operands[0], operands[3]);
2120 else if (TARGET_DIVIDE_CALL_FP)
2122 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2123 if (TARGET_FPU_SINGLE)
2124 last = gen_divsi3_i4_single (operands[0], operands[3]);
2126 last = gen_divsi3_i4 (operands[0], operands[3]);
2128 else if (TARGET_SH2A)
2130 operands[1] = force_reg (SImode, operands[1]);
2131 operands[2] = force_reg (SImode, operands[2]);
2132 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2135 else if (TARGET_DIVIDE_INV)
2137 rtx dividend = operands[1];
2138 rtx divisor = operands[2];
2140 rtx nsb_res = gen_reg_rtx (DImode);
2141 rtx norm64 = gen_reg_rtx (DImode);
2142 rtx tab_ix = gen_reg_rtx (DImode);
2143 rtx norm32 = gen_reg_rtx (SImode);
2144 rtx i92 = force_reg (DImode, GEN_INT (92));
2145 rtx scratch0a = gen_reg_rtx (DImode);
2146 rtx scratch0b = gen_reg_rtx (DImode);
2147 rtx inv0 = gen_reg_rtx (SImode);
2148 rtx scratch1a = gen_reg_rtx (DImode);
2149 rtx scratch1b = gen_reg_rtx (DImode);
2150 rtx shift = gen_reg_rtx (DImode);
2152 rtx inv1 = gen_reg_rtx (SImode);
2153 rtx scratch2a = gen_reg_rtx (DImode);
2154 rtx scratch2b = gen_reg_rtx (SImode);
2155 rtx inv2 = gen_reg_rtx (SImode);
2156 rtx scratch3a = gen_reg_rtx (DImode);
2157 rtx scratch3b = gen_reg_rtx (DImode);
2158 rtx scratch3c = gen_reg_rtx (DImode);
2159 rtx scratch3d = gen_reg_rtx (SImode);
2160 rtx scratch3e = gen_reg_rtx (DImode);
2161 rtx result = gen_reg_rtx (SImode);
2163 if (! arith_reg_or_0_operand (dividend, SImode))
2164 dividend = force_reg (SImode, dividend);
2165 if (! arith_reg_operand (divisor, SImode))
2166 divisor = force_reg (SImode, divisor);
2167 if (flag_pic && Pmode != DImode)
2169 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2170 tab_base = gen_datalabel_ref (tab_base);
2171 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2175 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2176 tab_base = gen_datalabel_ref (tab_base);
2177 tab_base = force_reg (DImode, tab_base);
2179 if (TARGET_DIVIDE_INV20U)
2180 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2182 i2p27 = GEN_INT (0);
2183 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2184 i43 = force_reg (DImode, GEN_INT (43));
2187 emit_insn (gen_nsbdi (nsb_res,
2188 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2189 emit_insn (gen_ashldi3_media (norm64,
2190 gen_rtx_SUBREG (DImode, divisor, 0),
2192 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2193 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2194 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2195 inv0, scratch0a, scratch0b,
2196 scratch1a, scratch1b));
2197 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2198 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2200 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2202 scratch3a, scratch3b, scratch3c,
2203 scratch2a, scratch2b, scratch3d, scratch3e));
2204 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2205 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2206 else if (TARGET_DIVIDE_INV_FP)
2207 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2208 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2209 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2210 gen_reg_rtx (DFmode)));
2212 emit_move_insn (operands[0], result);
2215 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2217 operands[1] = force_reg (SImode, operands[1]);
2218 operands[2] = force_reg (SImode, operands[2]);
2219 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2222 else if (TARGET_SH5)
2224 if (TARGET_DIVIDE_CALL2)
2226 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2227 tab_base = gen_datalabel_ref (tab_base);
2228 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2230 if (TARGET_FPU_ANY && TARGET_SH1)
2231 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2232 else if (TARGET_DIVIDE_CALL2)
2233 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2235 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2238 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2239 (operands[0], operands[3]));
2240 else if (TARGET_FPU_ANY)
2241 last = gen_divsi3_i4_single (operands[0], operands[3]);
2243 last = gen_divsi3_i1 (operands[0], operands[3]);
2247 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2248 last = gen_divsi3_i1 (operands[0], operands[3]);
2250 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2251 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2256 ;; operands: scratch, tab_base, tab_ix
2257 ;; These are unspecs because we could generate an indexed addressing mode
2258 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2259 ;; confuse reload. See PR27117.
2261 (define_insn "divsi_inv_qitable"
2262 [(set (match_operand:DI 0 "register_operand" "=r")
2263 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2264 (match_operand:DI 2 "register_operand" "r")]
2265 UNSPEC_DIV_INV_TABLE)))]
2269 [(set_attr "type" "load_media")
2270 (set_attr "highpart" "user")])
2272 ;; operands: scratch, tab_base, tab_ix
2273 (define_insn "divsi_inv_hitable"
2274 [(set (match_operand:DI 0 "register_operand" "=r")
2275 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2276 (match_operand:DI 2 "register_operand" "r")]
2277 UNSPEC_DIV_INV_TABLE)))]
2281 [(set_attr "type" "load_media")
2282 (set_attr "highpart" "user")])
2284 ;; operands: inv0, tab_base, tab_ix, norm32
2285 ;; scratch equiv in sdivsi3_2: r19, r21
2286 (define_expand "divsi_inv_m0"
2287 [(set (match_operand:SI 0 "register_operand" "=r")
2288 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2289 (match_operand:DI 2 "register_operand" "r")
2290 (match_operand:SI 3 "register_operand" "r")]
2292 (clobber (match_operand:DI 4 "register_operand" "=r"))
2293 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2300 ldx.ub r20, r21, r19 // u0.8
2302 muls.l r25, r19, r19 // s2.38
2303 ldx.w r20, r21, r21 // s2.14
2304 shari r19, 24, r19 // truncate to s2.14
2305 sub r21, r19, r19 // some 11 bit inverse in s1.14
2308 rtx inv0 = operands[0];
2309 rtx tab_base = operands[1];
2310 rtx tab_ix = operands[2];
2311 rtx norm32 = operands[3];
2312 rtx scratch0 = operands[4];
2313 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2314 rtx scratch1 = operands[5];
2316 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2317 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2318 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2319 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2320 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2321 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2325 ;; operands: inv1, tab_base, tab_ix, norm32
2326 (define_insn_and_split "divsi_inv_m1"
2327 [(set (match_operand:SI 0 "register_operand" "=r")
2328 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2329 (match_operand:DI 2 "register_operand" "r")
2330 (match_operand:SI 3 "register_operand" "r")]
2332 (clobber (match_operand:SI 4 "register_operand" "=r"))
2333 (clobber (match_operand:DI 5 "register_operand" "=r"))
2334 (clobber (match_operand:DI 6 "register_operand" "=r"))
2335 (clobber (match_operand:DI 7 "register_operand" "=r"))
2336 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2339 "&& !can_create_pseudo_p ()"
2343 muls.l r19, r19, r18 // u0.28
2344 muls.l r25, r18, r18 // s2.58
2345 shlli r19, 45, r0 // multiply by two and convert to s2.58
2347 shari r18, 28, r18 // some 18 bit inverse in s1.30
2350 rtx inv1 = operands[0];
2351 rtx tab_base = operands[1];
2352 rtx tab_ix = operands[2];
2353 rtx norm32 = operands[3];
2354 rtx inv0 = operands[4];
2355 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2356 rtx scratch0a = operands[5];
2357 rtx scratch0b = operands[6];
2358 rtx scratch0 = operands[7];
2359 rtx scratch1 = operands[8];
2360 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2362 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2363 scratch0a, scratch0b));
2364 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2365 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2366 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2367 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2368 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2372 ;; operands: inv2, norm32, inv1, i92
2373 (define_insn_and_split "divsi_inv_m2"
2374 [(set (match_operand:SI 0 "register_operand" "=r")
2375 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2376 (match_operand:SI 2 "register_operand" "r")
2377 (match_operand:DI 3 "register_operand" "r")]
2379 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2382 "&& !can_create_pseudo_p ()"
2386 muls.l r18, r25, r0 // s2.60
2387 shari r0, 16, r0 // s-16.44
2389 muls.l r0, r18, r19 // s-16.74
2390 shari r19, 30, r19 // s-16.44
2392 rtx inv2 = operands[0];
2393 rtx norm32 = operands[1];
2394 rtx inv1 = operands[2];
2395 rtx i92 = operands[3];
2396 rtx scratch0 = operands[4];
2397 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2399 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2400 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2401 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2402 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2403 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2407 (define_insn_and_split "divsi_inv_m3"
2408 [(set (match_operand:SI 0 "register_operand" "=r")
2409 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2410 (match_operand:SI 2 "register_operand" "r")
2411 (match_operand:SI 3 "register_operand" "r")
2412 (match_operand:DI 4 "register_operand" "r")
2413 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2414 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2416 (clobber (match_operand:DI 7 "register_operand" "=r"))
2417 (clobber (match_operand:DI 8 "register_operand" "=r"))
2418 (clobber (match_operand:DI 9 "register_operand" "=r"))
2419 (clobber (match_operand:DI 10 "register_operand" "=r"))
2420 (clobber (match_operand:SI 11 "register_operand" "=r"))
2421 (clobber (match_operand:SI 12 "register_operand" "=r"))
2422 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2425 "&& !can_create_pseudo_p ()"
2429 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2430 r0: scratch0 r19: scratch1 r21: scratch2
2432 muls.l r18, r4, r25 // s32.30
2433 muls.l r19, r4, r19 // s15.30
2435 shari r19, 14, r19 // s18.-14
2441 rtx result = operands[0];
2442 rtx dividend = operands[1];
2443 rtx inv1 = operands[2];
2444 rtx inv2 = operands[3];
2445 rtx shift = operands[4];
2446 rtx scratch0 = operands[7];
2447 rtx scratch1 = operands[8];
2448 rtx scratch2 = operands[9];
2450 if (satisfies_constraint_N (dividend))
2452 emit_move_insn (result, dividend);
2456 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2457 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2458 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2459 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2460 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2461 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2462 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2466 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2467 ;; inv1: tab_base, tab_ix, norm32
2468 ;; inv2: norm32, inv1, i92
2469 (define_insn_and_split "divsi_inv_m1_3"
2470 [(set (match_operand:SI 0 "register_operand" "=r")
2471 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2472 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2473 (match_operand:DI 3 "register_operand" "r")
2474 (match_operand:SI 4 "register_operand" "r")]
2476 (unspec:SI [(match_dup 4)
2477 (unspec:SI [(match_dup 2)
2479 (match_dup 4)] UNSPEC_DIV_INV_M1)
2480 (match_operand:SI 5 "" "")]
2482 (match_operand:DI 6 "register_operand" "r")
2483 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2484 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2486 (clobber (match_operand:DI 9 "register_operand" "=r"))
2487 (clobber (match_operand:DI 10 "register_operand" "=r"))
2488 (clobber (match_operand:DI 11 "register_operand" "=r"))
2489 (clobber (match_operand:DI 12 "register_operand" "=r"))
2490 (clobber (match_operand:SI 13 "register_operand" "=r"))
2491 (clobber (match_operand:SI 14 "register_operand" "=r"))
2492 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2494 && (TARGET_DIVIDE_INV_MINLAT
2495 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2497 "&& !can_create_pseudo_p ()"
2500 rtx result = operands[0];
2501 rtx dividend = operands[1];
2502 rtx tab_base = operands[2];
2503 rtx tab_ix = operands[3];
2504 rtx norm32 = operands[4];
2505 /* rtx i92 = operands[5]; */
2506 rtx shift = operands[6];
2507 rtx i2p27 = operands[7];
2508 rtx i43 = operands[8];
2509 rtx scratch0 = operands[9];
2510 rtx scratch0_si = gen_lowpart (SImode, scratch0);
2511 rtx scratch1 = operands[10];
2512 rtx scratch1_si = gen_lowpart (SImode, scratch1);
2513 rtx scratch2 = operands[11];
2514 rtx scratch3 = operands[12];
2515 rtx scratch4 = operands[13];
2516 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2517 rtx scratch5 = operands[14];
2518 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2519 rtx scratch6 = operands[15];
2521 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2522 scratch0, scratch1));
2523 /* inv0 == scratch4 */
2524 if (! TARGET_DIVIDE_INV20U)
2526 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2528 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2532 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2533 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2535 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2536 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2537 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2538 /* inv1 == scratch4 */
2540 if (TARGET_DIVIDE_INV_MINLAT)
2542 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2543 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2544 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2545 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2546 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2547 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2548 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2549 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2550 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2551 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2552 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2556 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2557 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2558 emit_insn (gen_nsbdi (scratch6,
2559 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2560 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2561 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2562 emit_insn (gen_divsi_inv20 (scratch2,
2563 norm32, scratch4, dividend,
2564 scratch6, scratch3, i43,
2565 /* scratch0 may be shared with i2p27. */
2566 scratch0, scratch1, scratch5,
2567 label, label, i2p27));
2569 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2570 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2574 (define_insn "divsi_inv20"
2575 [(set (match_operand:DI 0 "register_operand" "=&r")
2576 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2577 (match_operand:SI 2 "register_operand" "r")
2578 (match_operand:SI 3 "register_operand" "r")
2579 (match_operand:DI 4 "register_operand" "r")
2580 (match_operand:DI 5 "register_operand" "r")
2581 (match_operand:DI 6 "register_operand" "r")
2582 (match_operand:DI 12 "register_operand" "r")
2583 (match_operand 10 "target_operand" "b")
2584 (match_operand 11 "immediate_operand" "i")]
2586 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2587 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2588 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2590 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2592 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2593 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2594 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2595 %10 label (tr), %11 label (imm)
2597 muls.l inv1, norm32, scratch0 // s2.60
2598 muls.l inv1, dividend, result // s32.30
2599 xor i2p27, result_sign, round_scratch
2600 bge/u dividend_nsb, i43, tr.. (label)
2601 shari scratch0, 16, scratch0 // s-16.44
2602 muls.l sratch0_si, inv1, scratch0 // s-16.74
2603 sub result, round_scratch, result
2604 shari dividend, 14, scratch1 // s19.-14
2605 shari scratch0, 30, scratch0 // s-16.44
2606 muls.l scratch0, scratch1, round_scratch // s15.30
2608 sub result, round_scratch, result */
2610 int likely = TARGET_DIVIDE_INV20L;
2612 if (! likely) output_asm_insn ("muls.l\t%2, %1 , %8", operands);
2613 output_asm_insn ("muls.l\t%2, %3, %0\;xor\t%12, %5, %7", operands);
2614 output_asm_insn (likely
2615 ? "bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8"
2616 : "bge/u\t%4, %6, %10", operands);
2617 output_asm_insn ("shari\t%8, 16, %8\;muls.l\t%8, %2, %8", operands);
2618 if (! likely) output_asm_insn ("sub\t%0, %7, %0", operands);
2619 output_asm_insn ("shari\t%3, 14, %9\;shari\t%8, 30, %8", operands);
2621 ? "muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0"
2622 : "muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0");
2625 (define_insn_and_split "divsi_inv_fp"
2626 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2627 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2628 (match_operand:SI 2 "register_operand" "rf")))
2629 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2630 (clobber (match_operand:SI 4 "register_operand" "=r"))
2631 (clobber (match_operand:SI 5 "register_operand" "=r"))
2632 (clobber (match_operand:DF 6 "register_operand" "=r"))
2633 (clobber (match_operand:DF 7 "register_operand" "=r"))
2634 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2635 "TARGET_SHMEDIA_FPU"
2637 "&& (reload_in_progress || reload_completed)"
2638 [(set (match_dup 0) (match_dup 3))]
2640 [(set_attr "highpart" "must_split")])
2642 ;; If a matching group of divide-by-inverse instructions is in the same
2643 ;; basic block after gcse & loop optimizations, we want to transform them
2644 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2645 (define_insn_and_split "*divsi_inv_fp_combine"
2646 [(set (match_operand:SI 0 "register_operand" "=f")
2647 (div:SI (match_operand:SI 1 "register_operand" "f")
2648 (match_operand:SI 2 "register_operand" "f")))
2649 (use (unspec:SI [(match_dup 1)
2650 (match_operand:SI 3 "" "")
2651 (unspec:SI [(match_operand:SI 4 "" "")
2653 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2654 (match_operand:DI 6 "" "")
2656 (const_int 0)] UNSPEC_DIV_INV_M3))
2657 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2658 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2659 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2660 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2661 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2662 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2665 [(set (match_dup 9) (float:DF (match_dup 1)))
2666 (set (match_dup 10) (float:DF (match_dup 2)))
2667 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2669 (fix:SI (match_dup 11)))
2670 (set (match_dup 0) (match_dup 8))]
2672 if (! fp_arith_reg_operand (operands[1], SImode))
2674 emit_move_insn (operands[7], operands[1]);
2675 operands[1] = operands[7];
2677 if (! fp_arith_reg_operand (operands[2], SImode))
2679 emit_move_insn (operands[8], operands[2]);
2680 operands[2] = operands[8];
2683 [(set_attr "highpart" "must_split")])
2685 ;; -------------------------------------------------------------------------
2686 ;; Multiplication instructions
2687 ;; -------------------------------------------------------------------------
2689 (define_insn "umulhisi3_i"
2690 [(set (reg:SI MACL_REG)
2691 (mult:SI (zero_extend:SI
2692 (match_operand:HI 0 "arith_reg_operand" "r"))
2694 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2697 [(set_attr "type" "smpy")])
2699 (define_insn "mulhisi3_i"
2700 [(set (reg:SI MACL_REG)
2701 (mult:SI (sign_extend:SI
2702 (match_operand:HI 0 "arith_reg_operand" "r"))
2704 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2707 [(set_attr "type" "smpy")])
2709 (define_expand "mulhisi3"
2710 [(set (reg:SI MACL_REG)
2711 (mult:SI (sign_extend:SI
2712 (match_operand:HI 1 "arith_reg_operand" ""))
2714 (match_operand:HI 2 "arith_reg_operand" ""))))
2715 (set (match_operand:SI 0 "arith_reg_operand" "")
2721 macl = gen_rtx_REG (SImode, MACL_REG);
2723 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2724 insn = get_insns ();
2726 /* expand_binop can't find a suitable code in umul_widen_optab to
2727 make a REG_EQUAL note from, so make one here.
2728 See also smulsi3_highpart.
2729 ??? Alternatively, we could put this at the calling site of expand_binop,
2730 i.e. expand_expr. */
2731 /* Use emit_libcall_block for loop invariant code motion and to make
2732 a REG_EQUAL note. */
2733 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2738 (define_expand "umulhisi3"
2739 [(set (reg:SI MACL_REG)
2740 (mult:SI (zero_extend:SI
2741 (match_operand:HI 1 "arith_reg_operand" ""))
2743 (match_operand:HI 2 "arith_reg_operand" ""))))
2744 (set (match_operand:SI 0 "arith_reg_operand" "")
2750 macl = gen_rtx_REG (SImode, MACL_REG);
2752 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2753 insn = get_insns ();
2755 /* expand_binop can't find a suitable code in umul_widen_optab to
2756 make a REG_EQUAL note from, so make one here.
2757 See also smulsi3_highpart.
2758 ??? Alternatively, we could put this at the calling site of expand_binop,
2759 i.e. expand_expr. */
2760 /* Use emit_libcall_block for loop invariant code motion and to make
2761 a REG_EQUAL note. */
2762 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2767 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2768 ;; a call to a routine which clobbers known registers.
2771 [(set (match_operand:SI 1 "register_operand" "=z")
2772 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2773 (clobber (reg:SI MACL_REG))
2774 (clobber (reg:SI T_REG))
2775 (clobber (reg:SI PR_REG))
2776 (clobber (reg:SI R3_REG))
2777 (clobber (reg:SI R2_REG))
2778 (clobber (reg:SI R1_REG))
2779 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2782 [(set_attr "type" "sfunc")
2783 (set_attr "needs_delay_slot" "yes")])
2785 (define_expand "mulsi3_call"
2786 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2787 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2788 (parallel[(set (match_operand:SI 0 "register_operand" "")
2789 (mult:SI (reg:SI R4_REG)
2791 (clobber (reg:SI MACL_REG))
2792 (clobber (reg:SI T_REG))
2793 (clobber (reg:SI PR_REG))
2794 (clobber (reg:SI R3_REG))
2795 (clobber (reg:SI R2_REG))
2796 (clobber (reg:SI R1_REG))
2797 (use (match_operand:SI 3 "register_operand" ""))])]
2801 (define_insn "mul_r"
2802 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2803 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2804 (match_operand:SI 2 "arith_reg_operand" "z")))]
2807 [(set_attr "type" "dmpy")])
2809 (define_insn "mul_l"
2810 [(set (reg:SI MACL_REG)
2811 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2812 (match_operand:SI 1 "arith_reg_operand" "r")))]
2815 [(set_attr "type" "dmpy")])
2817 (define_expand "mulsi3"
2818 [(set (reg:SI MACL_REG)
2819 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2820 (match_operand:SI 2 "arith_reg_operand" "")))
2821 (set (match_operand:SI 0 "arith_reg_operand" "")
2827 /* The address must be set outside the libcall,
2828 since it goes into a pseudo. */
2829 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
2830 rtx addr = force_reg (SImode, sym);
2831 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2837 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2839 emit_insn (gen_mul_l (operands[1], operands[2]));
2840 /* consec_sets_giv can only recognize the first insn that sets a
2841 giv as the giv insn. So we must tag this also with a REG_EQUAL
2843 emit_insn (gen_movsi_i ((operands[0]), macl));
2848 (define_insn "mulsidi3_i"
2849 [(set (reg:SI MACH_REG)
2853 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2854 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2856 (set (reg:SI MACL_REG)
2857 (mult:SI (match_dup 0)
2861 [(set_attr "type" "dmpy")])
2863 (define_expand "mulsidi3"
2864 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2865 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2866 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2867 "TARGET_SH2 || TARGET_SHMEDIA"
2871 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
2876 (define_insn "mulsidi3_media"
2877 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2878 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2879 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2882 [(set_attr "type" "dmpy_media")
2883 (set_attr "highpart" "ignore")])
2885 (define_insn "mulsidi3_compact"
2886 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2888 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2889 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2890 (clobber (reg:SI MACH_REG))
2891 (clobber (reg:SI MACL_REG))]
2896 [(set (match_operand:DI 0 "arith_reg_dest" "")
2898 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2899 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2900 (clobber (reg:SI MACH_REG))
2901 (clobber (reg:SI MACL_REG))]
2905 rtx low_dst = gen_lowpart (SImode, operands[0]);
2906 rtx high_dst = gen_highpart (SImode, operands[0]);
2908 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2910 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2911 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2912 /* We need something to tag the possible REG_EQUAL notes on to. */
2913 emit_move_insn (operands[0], operands[0]);
2917 (define_insn "umulsidi3_i"
2918 [(set (reg:SI MACH_REG)
2922 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2923 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2925 (set (reg:SI MACL_REG)
2926 (mult:SI (match_dup 0)
2930 [(set_attr "type" "dmpy")])
2932 (define_expand "umulsidi3"
2933 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2934 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2935 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2936 "TARGET_SH2 || TARGET_SHMEDIA"
2940 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
2945 (define_insn "umulsidi3_media"
2946 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2947 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2948 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2951 [(set_attr "type" "dmpy_media")
2952 (set_attr "highpart" "ignore")])
2954 (define_insn "umulsidi3_compact"
2955 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2957 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2958 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2959 (clobber (reg:SI MACH_REG))
2960 (clobber (reg:SI MACL_REG))]
2965 [(set (match_operand:DI 0 "arith_reg_dest" "")
2966 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2967 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2968 (clobber (reg:SI MACH_REG))
2969 (clobber (reg:SI MACL_REG))]
2973 rtx low_dst = gen_lowpart (SImode, operands[0]);
2974 rtx high_dst = gen_highpart (SImode, operands[0]);
2976 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2978 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2979 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2980 /* We need something to tag the possible REG_EQUAL notes on to. */
2981 emit_move_insn (operands[0], operands[0]);
2985 (define_insn "smulsi3_highpart_i"
2986 [(set (reg:SI MACH_REG)
2990 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2991 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2993 (clobber (reg:SI MACL_REG))]
2996 [(set_attr "type" "dmpy")])
2998 (define_expand "smulsi3_highpart"
3000 [(set (reg:SI MACH_REG)
3004 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3005 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3007 (clobber (reg:SI MACL_REG))])
3008 (set (match_operand:SI 0 "arith_reg_operand" "")
3014 mach = gen_rtx_REG (SImode, MACH_REG);
3016 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3017 insn = get_insns ();
3019 /* expand_binop can't find a suitable code in mul_highpart_optab to
3020 make a REG_EQUAL note from, so make one here.
3021 See also {,u}mulhisi.
3022 ??? Alternatively, we could put this at the calling site of expand_binop,
3023 i.e. expand_mult_highpart. */
3024 /* Use emit_libcall_block for loop invariant code motion and to make
3025 a REG_EQUAL note. */
3026 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3031 (define_insn "umulsi3_highpart_i"
3032 [(set (reg:SI MACH_REG)
3036 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3037 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3039 (clobber (reg:SI MACL_REG))]
3042 [(set_attr "type" "dmpy")])
3044 (define_expand "umulsi3_highpart"
3046 [(set (reg:SI MACH_REG)
3050 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3051 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3053 (clobber (reg:SI MACL_REG))])
3054 (set (match_operand:SI 0 "arith_reg_operand" "")
3060 mach = gen_rtx_REG (SImode, MACH_REG);
3062 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3063 insn = get_insns ();
3065 /* Use emit_libcall_block for loop invariant code motion and to make
3066 a REG_EQUAL note. */
3067 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3072 (define_insn_and_split "muldi3"
3073 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3074 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3075 (match_operand:DI 2 "arith_reg_operand" "r")))
3076 (clobber (match_scratch:DI 3 "=&r"))
3077 (clobber (match_scratch:DI 4 "=r"))]
3083 rtx op3_v2si, op2_v2si;
3085 op3_v2si = operands[3];
3086 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3088 op3_v2si = XEXP (op3_v2si, 0);
3089 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3091 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3092 op2_v2si = operands[2];
3093 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3095 op2_v2si = XEXP (op2_v2si, 0);
3096 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3098 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3099 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3100 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3101 emit_insn (gen_umulsidi3_media (operands[4],
3102 sh_gen_truncate (SImode, operands[1], 0),
3103 sh_gen_truncate (SImode, operands[2], 0)));
3104 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3105 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3106 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3107 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3112 ;; -------------------------------------------------------------------------
3113 ;; Logical operations
3114 ;; -------------------------------------------------------------------------
3116 (define_expand "andsi3"
3117 [(set (match_operand:SI 0 "arith_reg_operand" "")
3118 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3119 (match_operand:SI 2 "logical_and_operand" "")))]
3122 /* If it is possible to turn the and insn into a zero extension
3123 already, redundant zero extensions will be folded, which results
3125 Ideally the splitter of *andsi_compact would be enough, if reundant
3126 zero extensions were detected after the combine pass, which does not
3127 happen at the moment. */
3130 if (satisfies_constraint_Jmb (operands[2]))
3132 emit_insn (gen_zero_extendqisi2 (operands[0],
3133 gen_lowpart (QImode, operands[1])));
3136 else if (satisfies_constraint_Jmw (operands[2]))
3138 emit_insn (gen_zero_extendhisi2 (operands[0],
3139 gen_lowpart (HImode, operands[1])));
3145 (define_insn_and_split "*andsi_compact"
3146 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,z,r")
3147 (and:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,0,0")
3148 (match_operand:SI 2 "logical_and_operand" "Jmb,Jmw,K08,r")))]
3156 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
3158 if (satisfies_constraint_Jmb (operands[2]))
3159 operands[1] = gen_lowpart (QImode, operands[1]);
3160 else if (satisfies_constraint_Jmw (operands[2]))
3161 operands[1] = gen_lowpart (HImode, operands[1]);
3165 [(set_attr "type" "arith")])
3167 (define_insn "*andsi3_media"
3168 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3169 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3170 (match_operand:SI 2 "logical_operand" "r,I10")))]
3175 [(set_attr "type" "arith_media")])
3177 (define_insn "*andsi3_bclr"
3178 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3179 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3180 (match_operand:SI 2 "const_int_operand" "Psz")))]
3181 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3183 [(set_attr "type" "arith")])
3185 (define_insn_and_split "anddi3"
3186 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3187 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3188 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3195 && ! logical_operand (operands[2], DImode)"
3198 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3199 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3201 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3204 [(set_attr "type" "arith_media")])
3206 (define_insn "andcsi3"
3207 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3208 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3209 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3212 [(set_attr "type" "arith_media")])
3214 (define_insn "andcdi3"
3215 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3216 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3217 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3220 [(set_attr "type" "arith_media")])
3222 (define_expand "iorsi3"
3223 [(set (match_operand:SI 0 "arith_reg_operand" "")
3224 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3225 (match_operand:SI 2 "logical_operand" "")))]
3229 (define_insn "*iorsi3_compact"
3230 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3231 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3232 (match_operand:SI 2 "logical_operand" "r,K08")))]
3234 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3236 [(set_attr "type" "arith")])
3238 (define_insn "*iorsi3_media"
3239 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3240 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3241 (match_operand:SI 2 "logical_operand" "r,I10")))]
3246 [(set_attr "type" "arith_media")])
3248 (define_insn "*iorsi3_bset"
3249 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3250 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3251 (match_operand:SI 2 "const_int_operand" "Pso")))]
3252 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3254 [(set_attr "type" "arith")])
3256 (define_insn "iordi3"
3257 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3258 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3259 (match_operand:DI 2 "logical_operand" "r,I10")))]
3264 [(set_attr "type" "arith_media")])
3266 (define_insn_and_split "*logical_sidi3"
3267 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3268 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3269 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3270 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3273 "&& reload_completed"
3274 [(set (match_dup 0) (match_dup 3))]
3277 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3278 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3279 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3282 (define_insn_and_split "*logical_sidisi3"
3283 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3284 (truncate:SI (sign_extend:DI
3285 (match_operator:SI 3 "logical_operator"
3286 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3287 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3291 [(set (match_dup 0) (match_dup 3))])
3293 (define_insn_and_split "*logical_sidi3_2"
3294 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295 (sign_extend:DI (truncate:SI (sign_extend:DI
3296 (match_operator:SI 3 "logical_operator"
3297 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3298 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3302 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3304 (define_expand "xorsi3"
3305 [(set (match_operand:SI 0 "arith_reg_operand" "")
3306 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3307 (match_operand:SI 2 "xor_operand" "")))]
3311 (define_insn "*xorsi3_compact"
3312 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3313 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3314 (match_operand:SI 2 "logical_operand" "K08,r")))]
3317 [(set_attr "type" "arith")])
3319 (define_insn "*xorsi3_media"
3320 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3321 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3322 (match_operand:SI 2 "xor_operand" "r,I06")))]
3327 [(set_attr "type" "arith_media")])
3329 (define_insn "xordi3"
3330 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3331 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3332 (match_operand:DI 2 "xor_operand" "r,I06")))]
3337 [(set_attr "type" "arith_media")])
3339 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3340 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3342 [(set (match_operand:DI 0 "arith_reg_dest" "")
3343 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3344 [(match_operand 1 "any_register_operand" "")
3345 (match_operand 2 "any_register_operand" "")])))]
3347 [(set (match_dup 5) (match_dup 4))
3348 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3350 enum machine_mode inmode = GET_MODE (operands[1]);
3353 if (GET_CODE (operands[0]) == SUBREG)
3355 offset = SUBREG_BYTE (operands[0]);
3356 operands[0] = SUBREG_REG (operands[0]);
3358 gcc_assert (REG_P (operands[0]));
3359 if (! TARGET_LITTLE_ENDIAN)
3360 offset += 8 - GET_MODE_SIZE (inmode);
3361 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3364 ;; -------------------------------------------------------------------------
3365 ;; Shifts and rotates
3366 ;; -------------------------------------------------------------------------
3368 (define_expand "rotldi3"
3369 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3370 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3371 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3373 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3375 (define_insn "rotldi3_mextr"
3376 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3377 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3378 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3381 static char templ[16];
3383 sprintf (templ, "mextr%d\\t%%1,%%1,%%0",
3384 8 - (int) (INTVAL (operands[2]) >> 3));
3387 [(set_attr "type" "arith_media")])
3389 (define_expand "rotrdi3"
3390 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3391 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3392 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3395 if (! mextr_bit_offset (operands[2], HImode))
3399 (define_insn "rotrdi3_mextr"
3400 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3401 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3402 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3405 static char templ[16];
3407 sprintf (templ, "mextr%d\\t%%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3410 [(set_attr "type" "arith_media")])
3413 [(set (match_operand:DI 0 "arith_reg_dest" "")
3414 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3415 "ua_address_operand" "")))
3416 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3418 (clobber (match_operand:DI 3 "register_operand" ""))]
3420 [(match_dup 4) (match_dup 5)]
3422 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3423 (operands[3], operands[1]));
3424 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3425 GEN_INT (56), GEN_INT (8));
3428 (define_insn "rotlsi3_1"
3429 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3430 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3433 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3436 [(set_attr "type" "arith")])
3438 (define_insn "rotlsi3_31"
3439 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3440 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3442 (clobber (reg:SI T_REG))]
3445 [(set_attr "type" "arith")])
3447 (define_insn "rotlsi3_16"
3448 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3449 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3453 [(set_attr "type" "arith")])
3455 (define_expand "rotlsi3"
3456 [(set (match_operand:SI 0 "arith_reg_dest" "")
3457 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3458 (match_operand:SI 2 "immediate_operand" "")))]
3461 static const char rot_tab[] = {
3462 000, 000, 000, 000, 000, 000, 010, 001,
3463 001, 001, 011, 013, 003, 003, 003, 003,
3464 003, 003, 003, 003, 003, 013, 012, 002,
3465 002, 002, 010, 000, 000, 000, 000, 000,
3470 if (!CONST_INT_P (operands[2]))
3472 count = INTVAL (operands[2]);
3473 choice = rot_tab[count];
3474 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3480 emit_move_insn (operands[0], operands[1]);
3481 count -= (count & 16) * 2;
3484 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3491 parts[0] = gen_reg_rtx (SImode);
3492 parts[1] = gen_reg_rtx (SImode);
3493 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3494 emit_move_insn (parts[choice-1], operands[1]);
3495 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3496 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3497 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3498 count = (count & ~16) - 8;
3502 for (; count > 0; count--)
3503 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3504 for (; count < 0; count++)
3505 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3510 (define_insn "*rotlhi3_8"
3511 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3512 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3516 [(set_attr "type" "arith")])
3518 (define_expand "rotlhi3"
3519 [(set (match_operand:HI 0 "arith_reg_operand" "")
3520 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3521 (match_operand:HI 2 "immediate_operand" "")))]
3524 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3531 ;; This pattern is used by init_expmed for computing the costs of shift
3534 (define_insn_and_split "ashlsi3_std"
3535 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3536 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3537 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3538 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3539 "(TARGET_SH3 || TARGET_SH2A)
3540 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3546 "(TARGET_SH3 || TARGET_SH2A)
3548 && CONST_INT_P (operands[2])
3549 && ! satisfies_constraint_P27 (operands[2])"
3550 [(set (match_dup 3) (match_dup 2))
3552 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3553 (clobber (match_dup 4))])]
3555 operands[4] = gen_rtx_SCRATCH (SImode);
3557 [(set_attr "length" "*,*,*,4")
3558 (set_attr "type" "dyn_shift,arith,arith,arith")])
3560 (define_insn "ashlhi3_k"
3561 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3562 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3563 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3564 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3568 [(set_attr "type" "arith")])
3570 (define_insn "ashlsi3_n"
3571 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3572 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3573 (match_operand:SI 2 "const_int_operand" "n")))
3574 (clobber (reg:SI T_REG))]
3575 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3577 [(set (attr "length")
3578 (cond [(match_test "shift_insns_rtx (insn)")
3580 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3582 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3584 (const_string "8")))
3585 (set_attr "type" "arith")])
3588 [(set (match_operand:SI 0 "arith_reg_dest" "")
3589 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3590 (match_operand:SI 2 "const_int_operand" "")))
3591 (clobber (reg:SI T_REG))]
3592 "TARGET_SH1 && reload_completed"
3593 [(use (reg:SI R0_REG))]
3595 gen_shifty_op (ASHIFT, operands);
3599 (define_insn "ashlsi3_media"
3600 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3601 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3602 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3607 [(set_attr "type" "arith_media")
3608 (set_attr "highpart" "ignore")])
3610 (define_expand "ashlsi3"
3611 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3612 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3613 (match_operand:SI 2 "nonmemory_operand" "")))
3614 (clobber (reg:SI T_REG))])]
3619 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3622 if (CONST_INT_P (operands[2])
3623 && sh_dynamicalize_shift_p (operands[2]))
3624 operands[2] = force_reg (SImode, operands[2]);
3625 if (TARGET_SH3 || TARGET_SH2A)
3627 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3630 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3634 (define_insn "*ashlhi3_n"
3635 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3636 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3637 (match_operand:HI 2 "const_int_operand" "n")))
3638 (clobber (reg:SI T_REG))]
3641 [(set (attr "length")
3642 (cond [(match_test "shift_insns_rtx (insn)")
3644 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3646 (const_string "6")))
3647 (set_attr "type" "arith")])
3649 (define_expand "ashlhi3"
3650 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3651 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3652 (match_operand:SI 2 "nonmemory_operand" "")))
3653 (clobber (reg:SI T_REG))])]
3656 if (!CONST_INT_P (operands[2]))
3658 /* It may be possible to call gen_ashlhi3 directly with more generic
3659 operands. Make sure operands[1] is a HImode register here. */
3660 if (!arith_reg_operand (operands[1], HImode))
3661 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3665 [(set (match_operand:HI 0 "arith_reg_dest" "")
3666 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3667 (match_operand:HI 2 "const_int_operand" "")))
3668 (clobber (reg:SI T_REG))]
3669 "TARGET_SH1 && reload_completed"
3670 [(use (reg:SI R0_REG))]
3672 gen_shifty_hi_op (ASHIFT, operands);
3677 ;; arithmetic shift right
3680 (define_insn "ashrsi3_k"
3681 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3682 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3683 (match_operand:SI 2 "const_int_operand" "M")))
3684 (clobber (reg:SI T_REG))]
3685 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3687 [(set_attr "type" "arith")])
3689 ;; We can't do HImode right shifts correctly unless we start out with an
3690 ;; explicit zero / sign extension; doing that would result in worse overall
3691 ;; code, so just let the machine independent code widen the mode.
3692 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3695 ;; ??? This should be a define expand.
3697 (define_insn "ashrsi2_16"
3698 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3699 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3703 [(set_attr "length" "4")])
3706 [(set (match_operand:SI 0 "arith_reg_dest" "")
3707 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3710 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3711 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3713 operands[2] = gen_lowpart (HImode, operands[0]);
3716 ;; ??? This should be a define expand.
3718 (define_insn "ashrsi2_31"
3719 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3720 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3722 (clobber (reg:SI T_REG))]
3725 [(set_attr "length" "4")])
3728 [(set (match_operand:SI 0 "arith_reg_dest" "")
3729 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3731 (clobber (reg:SI T_REG))]
3735 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3736 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3741 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3743 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3745 && peep2_reg_dead_p (2, operands[0])
3746 && peep2_reg_dead_p (2, operands[1])"
3749 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3753 (define_insn "ashlsi_c"
3754 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3755 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3757 (lt:SI (match_dup 1) (const_int 0)))]
3760 [(set_attr "type" "arith")])
3762 (define_insn "*ashlsi_c_void"
3763 [(set (reg:SI T_REG)
3764 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3765 (clobber (match_scratch:SI 1 "=0"))]
3766 "TARGET_SH1 && cse_not_expected"
3768 [(set_attr "type" "arith")])
3770 (define_insn "ashrsi3_d"
3771 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3772 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3773 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3774 "TARGET_SH3 || TARGET_SH2A"
3776 [(set_attr "type" "dyn_shift")])
3778 (define_insn "ashrsi3_n"
3779 [(set (reg:SI R4_REG)
3780 (ashiftrt:SI (reg:SI R4_REG)
3781 (match_operand:SI 0 "const_int_operand" "i")))
3782 (clobber (reg:SI T_REG))
3783 (clobber (reg:SI PR_REG))
3784 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3787 [(set_attr "type" "sfunc")
3788 (set_attr "needs_delay_slot" "yes")])
3790 (define_insn "ashrsi3_media"
3791 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3792 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3793 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3798 [(set_attr "type" "arith_media")
3799 (set_attr "highpart" "ignore")])
3801 (define_expand "ashrsi3"
3802 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3803 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3804 (match_operand:SI 2 "nonmemory_operand" "")))
3805 (clobber (reg:SI T_REG))])]
3810 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3813 if (expand_ashiftrt (operands))
3819 ;; logical shift right
3821 (define_insn "lshrsi3_d"
3822 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3823 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3824 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3825 "TARGET_SH3 || TARGET_SH2A"
3827 [(set_attr "type" "dyn_shift")])
3829 ;; Only the single bit shift clobbers the T bit.
3831 (define_insn "lshrsi3_m"
3832 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3833 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3834 (match_operand:SI 2 "const_int_operand" "M")))
3835 (clobber (reg:SI T_REG))]
3836 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3838 [(set_attr "type" "arith")])
3840 (define_insn "lshrsi3_k"
3841 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3842 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3843 (match_operand:SI 2 "const_int_operand" "P27")))]
3844 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3845 && ! satisfies_constraint_M (operands[2])"
3847 [(set_attr "type" "arith")])
3849 (define_insn "lshrsi3_n"
3850 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3851 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3852 (match_operand:SI 2 "const_int_operand" "n")))
3853 (clobber (reg:SI T_REG))]
3854 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3856 [(set (attr "length")
3857 (cond [(match_test "shift_insns_rtx (insn)")
3859 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3861 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3863 (const_string "8")))
3864 (set_attr "type" "arith")])
3867 [(set (match_operand:SI 0 "arith_reg_dest" "")
3868 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3869 (match_operand:SI 2 "const_int_operand" "")))
3870 (clobber (reg:SI T_REG))]
3871 "TARGET_SH1 && reload_completed"
3872 [(use (reg:SI R0_REG))]
3874 gen_shifty_op (LSHIFTRT, operands);
3878 (define_insn "lshrsi3_media"
3879 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3880 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3881 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3886 [(set_attr "type" "arith_media")
3887 (set_attr "highpart" "ignore")])
3889 (define_expand "lshrsi3"
3890 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3891 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3892 (match_operand:SI 2 "nonmemory_operand" "")))
3893 (clobber (reg:SI T_REG))])]
3898 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3901 if (CONST_INT_P (operands[2])
3902 && sh_dynamicalize_shift_p (operands[2]))
3903 operands[2] = force_reg (SImode, operands[2]);
3904 if ((TARGET_SH3 || TARGET_SH2A)
3905 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3907 rtx count = copy_to_mode_reg (SImode, operands[2]);
3908 emit_insn (gen_negsi2 (count, count));
3909 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3912 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3916 ;; ??? This should be a define expand.
3918 (define_insn "ashldi3_k"
3919 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3920 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3922 (clobber (reg:SI T_REG))]
3924 "shll %R0\;rotcl %S0"
3925 [(set_attr "length" "4")
3926 (set_attr "type" "arith")])
3928 ;; Expander for DImode shift left with SImode operations.
3930 (define_expand "ashldi3_std"
3931 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3932 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3933 (match_operand:DI 2 "const_int_operand" "n")))]
3934 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3936 rtx low_src = gen_lowpart (SImode, operands[1]);
3937 rtx high_src = gen_highpart (SImode, operands[1]);
3938 rtx dst = gen_reg_rtx (DImode);
3939 rtx low_dst = gen_lowpart (SImode, dst);
3940 rtx high_dst = gen_highpart (SImode, dst);
3941 rtx tmp0 = gen_reg_rtx (SImode);
3942 rtx tmp1 = gen_reg_rtx (SImode);
3944 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3945 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3946 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3947 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3948 emit_move_insn (operands[0], dst);
3952 (define_insn "ashldi3_media"
3953 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3954 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3955 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3960 [(set_attr "type" "arith_media")])
3962 (define_insn "*ashldisi3_media"
3963 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3964 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3965 (match_operand:DI 2 "const_int_operand" "n")))]
3966 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3967 "shlli.l %1, %2, %0"
3968 [(set_attr "type" "arith_media")
3969 (set_attr "highpart" "ignore")])
3971 (define_expand "ashldi3"
3972 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3973 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3974 (match_operand:DI 2 "immediate_operand" "")))
3975 (clobber (reg:SI T_REG))])]
3980 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3983 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
3985 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3988 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
3990 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3997 ;; ??? This should be a define expand.
3999 (define_insn "lshrdi3_k"
4000 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4001 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4003 (clobber (reg:SI T_REG))]
4005 "shlr %S0\;rotcr %R0"
4006 [(set_attr "length" "4")
4007 (set_attr "type" "arith")])
4009 (define_insn "lshrdi3_media"
4010 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4011 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4012 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4014 && (arith_reg_dest (operands[0], DImode)
4015 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4019 [(set_attr "type" "arith_media")])
4021 (define_insn "*lshrdisi3_media"
4022 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4023 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4024 (match_operand:DI 2 "const_int_operand" "n")))]
4025 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4026 "shlri.l %1, %2, %0"
4027 [(set_attr "type" "arith_media")
4028 (set_attr "highpart" "ignore")])
4030 (define_expand "lshrdi3"
4031 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4032 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4033 (match_operand:DI 2 "immediate_operand" "")))
4034 (clobber (reg:SI T_REG))])]
4039 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4042 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4046 ;; ??? This should be a define expand.
4048 (define_insn "ashrdi3_k"
4049 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4050 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4052 (clobber (reg:SI T_REG))]
4054 "shar %S0\;rotcr %R0"
4055 [(set_attr "length" "4")
4056 (set_attr "type" "arith")])
4058 (define_insn "ashrdi3_media"
4059 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4060 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4061 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4063 && (arith_reg_dest (operands[0], DImode)
4064 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4068 [(set_attr "type" "arith_media")])
4070 (define_insn "*ashrdisi3_media"
4071 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4072 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4073 (match_operand:DI 2 "const_int_operand" "n")))]
4074 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4075 "shari.l %1, %2, %0"
4076 [(set_attr "type" "arith_media")
4077 (set_attr "highpart" "ignore")])
4079 (define_insn "ashrdisi3_media_high"
4080 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4082 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4083 (match_operand:DI 2 "const_int_operand" "n"))))]
4084 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4086 [(set_attr "type" "arith_media")])
4088 (define_insn "ashrdisi3_media_opaque"
4089 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4090 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4091 (match_operand:DI 2 "const_int_operand" "n")]
4095 [(set_attr "type" "arith_media")])
4097 (define_expand "ashrdi3"
4098 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4099 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4100 (match_operand:DI 2 "immediate_operand" "")))
4101 (clobber (reg:SI T_REG))])]
4106 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4109 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4113 ;; combined left/right shift
4116 [(set (match_operand:SI 0 "register_operand" "")
4117 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4118 (match_operand:SI 2 "const_int_operand" ""))
4119 (match_operand:SI 3 "const_int_operand" "")))]
4120 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4121 [(use (reg:SI R0_REG))]
4123 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4129 [(set (match_operand:SI 0 "register_operand" "")
4130 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4131 (match_operand:SI 2 "const_int_operand" ""))
4132 (match_operand:SI 3 "const_int_operand" "")))
4133 (clobber (reg:SI T_REG))]
4134 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4135 [(use (reg:SI R0_REG))]
4137 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4143 [(set (match_operand:SI 0 "register_operand" "=r")
4144 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4145 (match_operand:SI 2 "const_int_operand" "n"))
4146 (match_operand:SI 3 "const_int_operand" "n")))
4147 (clobber (reg:SI T_REG))]
4148 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4150 [(set (attr "length")
4151 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4153 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4155 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4157 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4159 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4161 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4163 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4164 (const_string "16")]
4165 (const_string "18")))
4166 (set_attr "type" "arith")])
4169 [(set (match_operand:SI 0 "register_operand" "=z")
4170 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4171 (match_operand:SI 2 "const_int_operand" "n"))
4172 (match_operand:SI 3 "const_int_operand" "n")))
4173 (clobber (reg:SI T_REG))]
4174 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4176 [(set (attr "length")
4177 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4179 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4181 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4183 (const_string "10")))
4184 (set_attr "type" "arith")])
4186 ;; shift left / and combination with a scratch register: The combine pass
4187 ;; does not accept the individual instructions, even though they are
4188 ;; cheap. But it needs a precise description so that it is usable after
4190 (define_insn "and_shl_scratch"
4191 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4195 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4196 (match_operand:SI 2 "const_int_operand" "N,n"))
4197 (match_operand:SI 3 "" "0,r"))
4198 (match_operand:SI 4 "const_int_operand" "n,n"))
4199 (match_operand:SI 5 "const_int_operand" "n,n")))
4200 (clobber (reg:SI T_REG))]
4203 [(set (attr "length")
4204 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4206 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4208 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4210 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4211 (const_string "10")]
4212 (const_string "12")))
4213 (set_attr "type" "arith")])
4216 [(set (match_operand:SI 0 "register_operand" "")
4220 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4221 (match_operand:SI 2 "const_int_operand" ""))
4222 (match_operand:SI 3 "register_operand" ""))
4223 (match_operand:SI 4 "const_int_operand" ""))
4224 (match_operand:SI 5 "const_int_operand" "")))
4225 (clobber (reg:SI T_REG))]
4227 [(use (reg:SI R0_REG))]
4229 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4231 if (INTVAL (operands[2]))
4233 gen_shifty_op (LSHIFTRT, operands);
4235 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4236 operands[2] = operands[4];
4237 gen_shifty_op (ASHIFT, operands);
4238 if (INTVAL (operands[5]))
4240 operands[2] = operands[5];
4241 gen_shifty_op (LSHIFTRT, operands);
4246 ;; signed left/right shift combination.
4248 [(set (match_operand:SI 0 "register_operand" "")
4250 (ashift:SI (match_operand:SI 1 "register_operand" "")
4251 (match_operand:SI 2 "const_int_operand" ""))
4252 (match_operand:SI 3 "const_int_operand" "")
4254 (clobber (reg:SI T_REG))]
4256 [(use (reg:SI R0_REG))]
4258 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
4263 (define_insn "shl_sext_ext"
4264 [(set (match_operand:SI 0 "register_operand" "=r")
4266 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4267 (match_operand:SI 2 "const_int_operand" "n"))
4268 (match_operand:SI 3 "const_int_operand" "n")
4270 (clobber (reg:SI T_REG))]
4271 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4273 [(set (attr "length")
4274 (cond [(match_test "shl_sext_length (insn)")
4276 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4278 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4280 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4282 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4284 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4286 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4288 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4289 (const_string "16")]
4290 (const_string "18")))
4291 (set_attr "type" "arith")])
4293 (define_insn "shl_sext_sub"
4294 [(set (match_operand:SI 0 "register_operand" "=z")
4296 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4297 (match_operand:SI 2 "const_int_operand" "n"))
4298 (match_operand:SI 3 "const_int_operand" "n")
4300 (clobber (reg:SI T_REG))]
4301 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4303 [(set (attr "length")
4304 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4306 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4308 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4310 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4311 (const_string "12")]
4312 (const_string "14")))
4313 (set_attr "type" "arith")])
4315 ;; These patterns are found in expansions of DImode shifts by 16, and
4316 ;; allow the xtrct instruction to be generated from C source.
4318 (define_insn "xtrct_left"
4319 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4320 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4322 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4326 [(set_attr "type" "arith")])
4328 (define_insn "xtrct_right"
4329 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4330 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4332 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4336 [(set_attr "type" "arith")])
4338 ;; -------------------------------------------------------------------------
4340 ;; -------------------------------------------------------------------------
4342 (define_expand "negc"
4343 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4344 (neg:SI (plus:SI (reg:SI T_REG)
4345 (match_operand:SI 1 "arith_reg_operand" ""))))
4347 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4352 (define_insn "*negc"
4353 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4354 (neg:SI (plus:SI (reg:SI T_REG)
4355 (match_operand:SI 1 "arith_reg_operand" "r"))))
4357 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4361 [(set_attr "type" "arith")])
4363 (define_insn "*negdi_media"
4364 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4365 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4368 [(set_attr "type" "arith_media")])
4370 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4372 (define_expand "negdi2"
4373 [(set (match_operand:DI 0 "arith_reg_dest" "")
4374 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4375 (clobber (reg:SI T_REG))]
4379 (define_insn_and_split "*negdi2"
4380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4381 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4387 rtx low_src = gen_lowpart (SImode, operands[1]);
4388 rtx high_src = gen_highpart (SImode, operands[1]);
4389 rtx low_dst = gen_lowpart (SImode, operands[0]);
4390 rtx high_dst = gen_highpart (SImode, operands[0]);
4392 emit_insn (gen_clrt ());
4393 emit_insn (gen_negc (low_dst, low_src));
4394 emit_insn (gen_negc (high_dst, high_src));
4398 (define_insn "negsi2"
4399 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4400 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4403 [(set_attr "type" "arith")])
4405 (define_insn "one_cmplsi2"
4406 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4407 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4410 [(set_attr "type" "arith")])
4412 (define_expand "one_cmpldi2"
4413 [(set (match_operand:DI 0 "arith_reg_dest" "")
4414 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4416 "TARGET_SHMEDIA" "")
4418 (define_expand "abssi2"
4419 [(set (match_operand:SI 0 "arith_reg_dest" "")
4420 (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4421 (clobber (reg:SI T_REG))]
4425 (define_insn_and_split "*abssi2"
4426 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4427 (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4433 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4434 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4439 (define_insn_and_split "*negabssi2"
4440 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4441 (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4447 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4448 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4453 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4454 ;; This can be used as some kind of conditional execution, which is useful
4456 ;; Actually the instruction scheduling should decide whether to use a
4457 ;; zero-offset branch or not for any generic case involving a single
4458 ;; instruction on SH4 202.
4460 (define_insn_and_split "negsi_cond"
4461 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4462 (if_then_else:SI (eq:SI (reg:SI T_REG)
4463 (match_operand:SI 3 "const_int_operand" "M,N"))
4464 (match_operand:SI 1 "arith_reg_operand" "0,0")
4465 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4468 bt\\t0f\;neg\\t%2,%0\\n0:
4469 bf\\t0f\;neg\\t%2,%0\\n0:"
4473 rtx skip_neg_label = gen_label_rtx ();
4475 emit_insn (gen_movsi (operands[0], operands[1]));
4477 emit_jump_insn (INTVAL (operands[3])
4478 ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
4479 : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
4481 emit_label_after (skip_neg_label,
4482 emit_insn (gen_negsi2 (operands[0], operands[1])));
4485 [(set_attr "type" "arith") ;; poor approximation
4486 (set_attr "length" "4")])
4488 (define_expand "absdi2"
4489 [(set (match_operand:DI 0 "arith_reg_dest" "")
4490 (abs:DI (match_operand:DI 1 "arith_reg_operand" "")))
4491 (clobber (reg:SI T_REG))]
4495 (define_insn_and_split "*absdi2"
4496 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4497 (abs:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4500 "&& reload_completed"
4503 rtx high_src = gen_highpart (SImode, operands[1]);
4504 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4505 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4510 (define_insn_and_split "*negabsdi2"
4511 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4512 (neg:DI (abs:DI (match_operand:DI 1 "arith_reg_operand" "r"))))]
4515 "&& reload_completed"
4518 rtx high_src = gen_highpart (SImode, operands[1]);
4519 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4520 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4525 (define_insn_and_split "negdi_cond"
4526 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4527 (if_then_else:DI (eq:SI (reg:SI T_REG)
4528 (match_operand:SI 3 "const_int_operand" "M,N"))
4529 (match_operand:DI 1 "arith_reg_operand" "r,r")
4530 (neg:DI (match_operand:DI 2 "arith_reg_operand" "1,1"))))]
4536 rtx low_src = gen_lowpart (SImode, operands[1]);
4537 rtx high_src = gen_highpart (SImode, operands[1]);
4538 rtx low_dst = gen_lowpart (SImode, operands[0]);
4539 rtx high_dst = gen_highpart (SImode, operands[0]);
4541 rtx skip_neg_label = gen_label_rtx ();
4543 emit_insn (gen_movsi (low_dst, low_src));
4544 emit_insn (gen_movsi (high_dst, high_src));
4546 emit_jump_insn (INTVAL (operands[3])
4547 ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
4548 : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
4550 if (!INTVAL (operands[3]))
4551 emit_insn (gen_clrt ());
4553 emit_insn (gen_negc (low_dst, low_src));
4554 emit_label_after (skip_neg_label, emit_insn (gen_negc (high_dst, high_src)));
4558 (define_expand "bswapsi2"
4559 [(set (match_operand:SI 0 "arith_reg_dest" "")
4560 (bswap:SI (match_operand:SI 1 "arith_reg_operand" "")))]
4563 if (! can_create_pseudo_p ())
4567 rtx tmp0 = gen_reg_rtx (SImode);
4568 rtx tmp1 = gen_reg_rtx (SImode);
4570 emit_insn (gen_swapbsi2 (tmp0, operands[1]));
4571 emit_insn (gen_rotlsi3_16 (tmp1, tmp0));
4572 emit_insn (gen_swapbsi2 (operands[0], tmp1));
4577 (define_insn "swapbsi2"
4578 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4579 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
4580 (const_int 4294901760))
4581 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
4583 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
4584 (const_int 255)))))]
4587 [(set_attr "type" "arith")])
4589 ;; The *swapbisi2_and_shl8 pattern helps the combine pass simplifying
4590 ;; partial byte swap expressions such as...
4591 ;; ((x & 0xFF) << 8) | ((x >> 8) & 0xFF).
4592 ;; ...which are currently not handled by the tree optimizers.
4593 ;; The combine pass will not initially try to combine the full expression,
4594 ;; but only some sub-expressions. In such a case the *swapbisi2_and_shl8
4595 ;; pattern acts as an intermediate pattern that will eventually lead combine
4596 ;; to the swapbsi2 pattern above.
4597 ;; As a side effect this also improves code that does (x & 0xFF) << 8
4598 ;; or (x << 8) & 0xFF00.
4599 (define_insn_and_split "*swapbisi2_and_shl8"
4600 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4601 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4604 (match_operand:SI 2 "arith_reg_operand" "r")))]
4605 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4607 "&& can_create_pseudo_p ()"
4610 rtx tmp0 = gen_reg_rtx (SImode);
4611 rtx tmp1 = gen_reg_rtx (SImode);
4613 emit_insn (gen_zero_extendqisi2 (tmp0, gen_lowpart (QImode, operands[1])));
4614 emit_insn (gen_swapbsi2 (tmp1, tmp0));
4615 emit_insn (gen_iorsi3 (operands[0], tmp1, operands[2]));
4619 ;; The *swapbhisi2 pattern is, like the *swapbisi2_and_shl8 pattern, another
4620 ;; intermediate pattern that will help the combine pass arriving at swapbsi2.
4621 (define_insn_and_split "*swapbhisi2"
4622 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4623 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4626 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))))]
4627 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4629 "&& can_create_pseudo_p ()"
4632 rtx tmp = gen_reg_rtx (SImode);
4634 emit_insn (gen_zero_extendhisi2 (tmp, gen_lowpart (HImode, operands[1])));
4635 emit_insn (gen_swapbsi2 (operands[0], tmp));
4639 ;; In some cases the swapbsi2 pattern might leave a sequence such as...
4643 ;; which can be simplified to...
4646 [(set (match_operand:SI 0 "arith_reg_dest" "")
4647 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
4648 (const_int 4294901760))
4649 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
4651 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
4653 (set (match_operand:SI 2 "arith_reg_dest" "")
4655 "TARGET_SH1 && peep2_reg_dead_p (2, operands[0])"
4657 (ior:SI (and:SI (match_operand:SI 1 "arith_reg_operand" "")
4658 (const_int 4294901760))
4659 (ior:SI (and:SI (ashift:SI (match_dup 1) (const_int 8))
4661 (and:SI (ashiftrt:SI (match_dup 1) (const_int 8))
4662 (const_int 255)))))])
4665 ;; -------------------------------------------------------------------------
4666 ;; Zero extension instructions
4667 ;; -------------------------------------------------------------------------
4669 (define_insn "zero_extendsidi2"
4670 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4671 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4673 "addz.l %1, r63, %0"
4674 [(set_attr "type" "arith_media")
4675 (set_attr "highpart" "extend")])
4677 (define_insn "zero_extendhidi2"
4678 [(set (match_operand:DI 0 "register_operand" "=r,r")
4679 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4684 [(set_attr "type" "*,load_media")
4685 (set (attr "highpart")
4686 (cond [(match_test "sh_contains_memref_p (insn)")
4687 (const_string "user")]
4688 (const_string "ignore")))])
4691 [(set (match_operand:DI 0 "register_operand" "")
4692 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4693 "TARGET_SHMEDIA && reload_completed"
4694 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4695 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4697 if (GET_CODE (operands[1]) == TRUNCATE)
4698 operands[1] = XEXP (operands[1], 0);
4701 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4702 ;; reload the entire truncate expression.
4703 (define_insn_and_split "*loaddi_trunc"
4704 [(set (match_operand 0 "any_register_operand" "=r")
4705 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4706 "TARGET_SHMEDIA && reload_completed"
4708 "TARGET_SHMEDIA && reload_completed"
4709 [(set (match_dup 0) (match_dup 1))]
4711 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4714 (define_insn "zero_extendqidi2"
4715 [(set (match_operand:DI 0 "register_operand" "=r,r")
4716 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4721 [(set_attr "type" "arith_media,load_media")
4722 (set (attr "highpart")
4723 (cond [(match_test "sh_contains_memref_p (insn)")
4724 (const_string "user")]
4725 (const_string "ignore")))])
4727 (define_expand "zero_extendhisi2"
4728 [(set (match_operand:SI 0 "arith_reg_dest" "")
4729 (zero_extend:SI (match_operand:HI 1 "zero_extend_operand" "")))])
4731 (define_insn "*zero_extendhisi2_compact"
4732 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4733 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4736 [(set_attr "type" "arith")])
4738 (define_insn "*zero_extendhisi2_media"
4739 [(set (match_operand:SI 0 "register_operand" "=r,r")
4740 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4745 [(set_attr "type" "arith_media,load_media")
4746 (set (attr "highpart")
4747 (cond [(match_test "sh_contains_memref_p (insn)")
4748 (const_string "user")]
4749 (const_string "ignore")))])
4752 [(set (match_operand:SI 0 "register_operand" "")
4753 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4754 "TARGET_SHMEDIA && reload_completed"
4755 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4756 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4758 rtx op1 = operands[1];
4760 if (GET_CODE (op1) == TRUNCATE)
4761 op1 = XEXP (op1, 0);
4763 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4764 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4767 (define_expand "zero_extendqisi2"
4768 [(set (match_operand:SI 0 "arith_reg_dest" "")
4769 (zero_extend:SI (match_operand:QI 1 "zero_extend_operand" "")))])
4771 (define_insn "*zero_extendqisi2_compact"
4772 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4773 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4776 [(set_attr "type" "arith")])
4778 (define_insn "*zero_extendqisi2_media"
4779 [(set (match_operand:SI 0 "register_operand" "=r,r")
4780 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4785 [(set_attr "type" "arith_media,load_media")
4786 (set (attr "highpart")
4787 (cond [(match_test "sh_contains_memref_p (insn)")
4788 (const_string "user")]
4789 (const_string "ignore")))])
4791 (define_insn "zero_extendqihi2"
4792 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4793 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4796 [(set_attr "type" "arith")])
4798 ;; -------------------------------------------------------------------------
4799 ;; Sign extension instructions
4800 ;; -------------------------------------------------------------------------
4802 ;; ??? This should be a define expand.
4803 ;; ??? Or perhaps it should be dropped?
4805 ;; convert_move generates good code for SH[1-4].
4806 (define_insn "extendsidi2"
4807 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4808 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4814 [(set_attr "type" "arith_media,load_media,fpconv_media")
4815 (set (attr "highpart")
4816 (cond [(match_test "sh_contains_memref_p (insn)")
4817 (const_string "user")]
4818 (const_string "extend")))])
4820 (define_insn "extendhidi2"
4821 [(set (match_operand:DI 0 "register_operand" "=r,r")
4822 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4827 [(set_attr "type" "*,load_media")
4828 (set (attr "highpart")
4829 (cond [(match_test "sh_contains_memref_p (insn)")
4830 (const_string "user")]
4831 (const_string "ignore")))])
4834 [(set (match_operand:DI 0 "register_operand" "")
4835 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4836 "TARGET_SHMEDIA && reload_completed"
4837 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4838 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4840 if (GET_CODE (operands[1]) == TRUNCATE)
4841 operands[1] = XEXP (operands[1], 0);
4844 (define_insn "extendqidi2"
4845 [(set (match_operand:DI 0 "register_operand" "=r,r")
4846 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4851 [(set_attr "type" "*,load_media")
4852 (set (attr "highpart")
4853 (cond [(match_test "sh_contains_memref_p (insn)")
4854 (const_string "user")]
4855 (const_string "ignore")))])
4858 [(set (match_operand:DI 0 "register_operand" "")
4859 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4860 "TARGET_SHMEDIA && reload_completed"
4861 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4862 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4864 if (GET_CODE (operands[1]) == TRUNCATE)
4865 operands[1] = XEXP (operands[1], 0);
4868 ;; FIXME: Maybe fold HImode and QImode stuff with mode iterator?
4869 (define_expand "extendhisi2"
4870 [(set (match_operand:SI 0 "arith_reg_dest" "")
4871 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4875 (define_expand "extendqisi2"
4876 [(set (match_operand:SI 0 "arith_reg_dest" "")
4877 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4881 (define_insn "*extendhisi2_media"
4882 [(set (match_operand:SI 0 "register_operand" "=r,r")
4883 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4888 [(set_attr "type" "arith_media,load_media")
4889 (set (attr "highpart")
4890 (cond [(match_test "sh_contains_memref_p (insn)")
4891 (const_string "user")]
4892 (const_string "ignore")))])
4895 [(set (match_operand:SI 0 "register_operand" "")
4896 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4897 "TARGET_SHMEDIA && reload_completed"
4898 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4899 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4901 rtx op1 = operands[1];
4902 if (GET_CODE (op1) == TRUNCATE)
4903 op1 = XEXP (op1, 0);
4905 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4906 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4909 (define_insn "*extendqisi2_compact_reg"
4910 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4911 (sign_extend:SI (match_operand:QI 1 "register_operand" "r,t")))]
4916 [(set_attr "type" "arith,arith")])
4918 (define_insn "*extendhisi2_compact_reg"
4919 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4920 (sign_extend:SI (match_operand:HI 1 "register_operand" "r,t")))]
4925 [(set_attr "type" "arith,arith")])
4927 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
4929 (define_insn "*extendqisi2_compact_mem_disp"
4930 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
4932 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
4933 (match_operand:SI 2 "const_int_operand" "K04,N")))))]
4934 "TARGET_SH1 && ! TARGET_SH2A
4935 && sh_legitimate_index_p (QImode, operands[2], false, true)"
4939 [(set_attr "type" "load")])
4941 (define_insn "*extendhisi2_compact_mem_disp"
4942 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
4944 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
4945 (match_operand:SI 2 "const_int_operand" "K05,N")))))]
4946 "TARGET_SH1 && ! TARGET_SH2A
4947 && sh_legitimate_index_p (HImode, operands[2], false, true)"
4951 [(set_attr "type" "load")])
4953 (define_insn "*extendqisi2_compact_mem_disp"
4954 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
4956 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
4957 (match_operand:SI 2 "const_int_operand" "K04,N,K12")))))]
4958 "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[2], true, true)"
4963 [(set_attr "type" "load")
4964 (set_attr "length" "2,2,4")])
4966 (define_insn "*extendhisi2_compact_mem_disp"
4967 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
4969 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
4970 (match_operand:SI 2 "const_int_operand" "K05,N,K13")))))]
4971 "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[2], true, true)"
4976 [(set_attr "type" "load")
4977 (set_attr "length" "2,2,4")])
4979 ;; The *_snd patterns will take care of other QImode/HImode addressing
4980 ;; modes than displacement addressing. They must be defined _after_ the
4981 ;; displacement addressing patterns. Otherwise the displacement addressing
4982 ;; patterns will not be picked.
4983 (define_insn "*extendqisi2_compact_snd"
4984 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4985 (sign_extend:SI (match_operand:QI 1 "movsrc_no_disp_mem_operand" "Snd")))]
4988 [(set_attr "type" "load")])
4990 (define_insn "*extendhisi2_compact_snd"
4991 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4992 (sign_extend:SI (match_operand:HI 1 "movsrc_no_disp_mem_operand" "Snd")))]
4995 [(set_attr "type" "load")])
4997 (define_insn "*extendqisi2_media"
4998 [(set (match_operand:SI 0 "register_operand" "=r,r")
4999 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
5004 [(set_attr "type" "arith_media,load_media")
5005 (set (attr "highpart")
5006 (cond [(match_test "sh_contains_memref_p (insn)")
5007 (const_string "user")]
5008 (const_string "ignore")))])
5011 [(set (match_operand:SI 0 "register_operand" "")
5012 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
5013 "TARGET_SHMEDIA && reload_completed"
5014 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5015 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5017 rtx op1 = operands[1];
5018 if (GET_CODE (op1) == TRUNCATE)
5019 op1 = XEXP (op1, 0);
5021 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
5022 subreg_lowpart_offset (SImode, GET_MODE (op1)));
5025 (define_expand "extendqihi2"
5026 [(set (match_operand:HI 0 "arith_reg_dest" "")
5027 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
5031 (define_insn "*extendqihi2_compact_reg"
5032 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
5033 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
5036 [(set_attr "type" "arith")])
5038 ;; It would seem useful to combine the truncXi patterns into the movXi
5039 ;; patterns, but unary operators are ignored when matching constraints,
5040 ;; so we need separate patterns.
5041 (define_insn "truncdisi2"
5042 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
5043 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
5052 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
5053 (set (attr "highpart")
5054 (cond [(match_test "sh_contains_memref_p (insn)")
5055 (const_string "user")]
5056 (const_string "extend")))])
5058 (define_insn "truncdihi2"
5059 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
5060 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
5063 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
5065 [(set_attr "type" "arith_media,store_media")
5066 (set_attr "length" "8,4")
5067 (set (attr "highpart")
5068 (cond [(match_test "sh_contains_memref_p (insn)")
5069 (const_string "user")]
5070 (const_string "extend")))])
5072 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
5073 ; Because we use zero extension, we can't provide signed QImode compares
5074 ; using a simple compare or conditional branch insn.
5075 (define_insn "truncdiqi2"
5076 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
5077 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
5082 [(set_attr "type" "arith_media,store")
5083 (set (attr "highpart")
5084 (cond [(match_test "sh_contains_memref_p (insn)")
5085 (const_string "user")]
5086 (const_string "extend")))])
5087 ;; -------------------------------------------------------------------------
5088 ;; Move instructions
5089 ;; -------------------------------------------------------------------------
5091 ;; define push and pop so it is easy for sh.c
5092 ;; We can't use push and pop on SHcompact because the stack must always
5093 ;; be 8-byte aligned.
5095 (define_expand "push"
5096 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
5097 (match_operand:SI 0 "register_operand" "r,l,x"))]
5098 "TARGET_SH1 && ! TARGET_SH5"
5101 (define_expand "pop"
5102 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
5103 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
5104 "TARGET_SH1 && ! TARGET_SH5"
5107 (define_expand "push_e"
5108 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
5109 (match_operand:SF 0 "" ""))
5110 (use (reg:PSI FPSCR_REG))
5111 (clobber (scratch:SI))])]
5112 "TARGET_SH1 && ! TARGET_SH5"
5115 (define_insn "push_fpul"
5116 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
5117 "TARGET_SH2E && ! TARGET_SH5"
5119 [(set_attr "type" "fstore")
5120 (set_attr "late_fp_use" "yes")
5121 (set_attr "hit_stack" "yes")])
5123 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
5125 (define_expand "push_4"
5126 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
5127 (match_operand:DF 0 "" ""))
5128 (use (reg:PSI FPSCR_REG))
5129 (clobber (scratch:SI))])]
5130 "TARGET_SH1 && ! TARGET_SH5"
5133 (define_expand "pop_e"
5134 [(parallel [(set (match_operand:SF 0 "" "")
5135 (mem:SF (post_inc:SI (reg:SI SP_REG))))
5136 (use (reg:PSI FPSCR_REG))
5137 (clobber (scratch:SI))])]
5138 "TARGET_SH1 && ! TARGET_SH5"
5141 (define_insn "pop_fpul"
5142 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
5143 "TARGET_SH2E && ! TARGET_SH5"
5145 [(set_attr "type" "load")
5146 (set_attr "hit_stack" "yes")])
5148 (define_expand "pop_4"
5149 [(parallel [(set (match_operand:DF 0 "" "")
5150 (mem:DF (post_inc:SI (reg:SI SP_REG))))
5151 (use (reg:PSI FPSCR_REG))
5152 (clobber (scratch:SI))])]
5153 "TARGET_SH1 && ! TARGET_SH5"
5156 (define_expand "push_fpscr"
5160 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
5161 gen_rtx_PRE_DEC (Pmode,
5162 stack_pointer_rtx)),
5164 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5168 (define_expand "pop_fpscr"
5172 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
5173 gen_frame_mem (PSImode,
5174 gen_rtx_POST_INC (Pmode,
5175 stack_pointer_rtx))));
5176 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5180 ;; These two patterns can happen as the result of optimization, when
5181 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5182 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5185 [(set (reg:SI T_REG) (const_int 0))]
5190 [(set (reg:SI T_REG) (const_int 1))]
5194 ;; Define additional pop for SH1 and SH2 so it does not get
5195 ;; placed in the delay slot.
5196 (define_insn "*movsi_pop"
5197 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5198 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5199 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5205 [(set_attr "type" "load_si,mem_mac,pload")
5206 (set_attr "length" "2,2,2")
5207 (set_attr "in_delay_slot" "no,no,no")])
5209 ;; t/r must come after r/r, lest reload will try to reload stuff like
5210 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5211 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5212 (define_insn "movsi_i"
5213 [(set (match_operand:SI 0 "general_movdst_operand"
5214 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5215 (match_operand:SI 1 "general_movsrc_operand"
5216 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5220 && (register_operand (operands[0], SImode)
5221 || register_operand (operands[1], SImode))"
5239 [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
5240 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5242 ;; t/r must come after r/r, lest reload will try to reload stuff like
5243 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5244 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5245 ;; will require a reload.
5246 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5247 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5248 (define_insn "movsi_ie"
5249 [(set (match_operand:SI 0 "general_movdst_operand"
5250 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5251 (match_operand:SI 1 "general_movsrc_operand"
5252 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5253 "(TARGET_SH2E || TARGET_SH2A)
5254 && (register_operand (operands[0], SImode)
5255 || register_operand (operands[1], SImode))"
5282 ! move optimized away"
5283 [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
5284 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5285 (set_attr_alternative "length"
5293 (match_test "TARGET_SH2A")
5294 (const_int 4) (const_int 2))
5299 (match_test "TARGET_SH2A")
5300 (const_int 4) (const_int 2))
5317 (define_insn "movsi_i_lowpart"
5318 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5319 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5321 && (register_operand (operands[0], SImode)
5322 || register_operand (operands[1], SImode))"
5333 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5335 (define_insn_and_split "load_ra"
5336 [(set (match_operand:SI 0 "general_movdst_operand" "")
5337 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5340 "&& ! currently_expanding_to_rtl"
5341 [(set (match_dup 0) (match_dup 1))]
5343 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5344 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5347 ;; The '?'s in the following constraints may not reflect the time taken
5348 ;; to perform the move. They are there to discourage the use of floating-
5349 ;; point registers for storing integer values.
5350 (define_insn "*movsi_media"
5351 [(set (match_operand:SI 0 "general_movdst_operand"
5352 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5353 (match_operand:SI 1 "general_movsrc_operand"
5354 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5356 && (register_operand (operands[0], SImode)
5357 || sh_register_operand (operands[1], SImode)
5358 || GET_CODE (operands[1]) == TRUNCATE)"
5373 [(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")
5374 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5375 (set (attr "highpart")
5376 (cond [(match_test "sh_contains_memref_p (insn)")
5377 (const_string "user")]
5378 (const_string "ignore")))])
5380 (define_insn "*movsi_media_nofpu"
5381 [(set (match_operand:SI 0 "general_movdst_operand"
5382 "=r,r,r,r,m,*b,r,*b")
5383 (match_operand:SI 1 "general_movsrc_operand"
5384 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5386 && (register_operand (operands[0], SImode)
5387 || sh_register_operand (operands[1], SImode)
5388 || GET_CODE (operands[1]) == TRUNCATE)"
5398 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5399 (set_attr "length" "4,4,8,4,4,4,4,12")
5400 (set (attr "highpart")
5401 (cond [(match_test "sh_contains_memref_p (insn)")
5402 (const_string "user")]
5403 (const_string "ignore")))])
5405 (define_expand "movsi_const"
5406 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5407 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5408 (const_int 16)] UNSPEC_EXTRACT_S16)))
5410 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5411 (const:SI (unspec:SI [(match_dup 1)
5412 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5413 "TARGET_SHMEDIA && reload_completed
5414 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5416 if (GET_CODE (operands[1]) == LABEL_REF
5417 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5418 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5419 else if (GOTOFF_P (operands[1]))
5421 rtx unspec = XEXP (operands[1], 0);
5423 if (! UNSPEC_GOTOFF_P (unspec))
5425 unspec = XEXP (unspec, 0);
5426 if (! UNSPEC_GOTOFF_P (unspec))
5429 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5430 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5431 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5435 (define_expand "movsi_const_16bit"
5436 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5437 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5438 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5439 "TARGET_SHMEDIA && flag_pic && reload_completed
5440 && GET_CODE (operands[1]) == SYMBOL_REF"
5444 [(set (match_operand:SI 0 "arith_reg_dest" "")
5445 (match_operand:SI 1 "immediate_operand" ""))]
5446 "TARGET_SHMEDIA && reload_completed
5447 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5450 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5452 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5458 [(set (match_operand:SI 0 "register_operand" "")
5459 (match_operand:SI 1 "immediate_operand" ""))]
5460 "TARGET_SHMEDIA && reload_completed
5461 && ((CONST_INT_P (operands[1])
5462 && ! satisfies_constraint_I16 (operands[1]))
5463 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5464 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5466 (define_expand "movsi"
5467 [(set (match_operand:SI 0 "general_movdst_operand" "")
5468 (match_operand:SI 1 "general_movsrc_operand" ""))]
5471 prepare_move_operands (operands, SImode);
5474 (define_expand "ic_invalidate_line"
5475 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5476 (match_dup 1)] UNSPEC_ICACHE)
5477 (clobber (scratch:SI))])]
5478 "TARGET_HARD_SH4 || TARGET_SH5"
5482 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5485 else if (TARGET_SHCOMPACT)
5487 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
5488 operands[1] = force_reg (Pmode, operands[1]);
5489 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5492 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5494 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5497 operands[0] = force_reg (Pmode, operands[0]);
5498 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5502 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5503 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5504 ;; the requirement *1*00 for associative address writes. The alignment of
5505 ;; %0 implies that its least significant bit is cleared,
5506 ;; thus we clear the V bit of a matching entry if there is one.
5507 (define_insn "ic_invalidate_line_i"
5508 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5509 (match_operand:SI 1 "register_operand" "r")]
5511 (clobber (match_scratch:SI 2 "=&r"))]
5513 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5514 [(set_attr "length" "8")
5515 (set_attr "type" "cwb")])
5517 (define_insn "ic_invalidate_line_sh4a"
5518 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5520 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5521 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5522 [(set_attr "length" "16")
5523 (set_attr "type" "cwb")])
5525 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5526 ;; an add in the code that calculates the address.
5527 (define_insn "ic_invalidate_line_media"
5528 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5531 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5532 [(set_attr "length" "16")
5533 (set_attr "type" "invalidate_line_media")])
5535 (define_insn "ic_invalidate_line_compact"
5536 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5537 (match_operand:SI 1 "register_operand" "r")]
5539 (clobber (reg:SI PR_REG))]
5542 [(set_attr "type" "sfunc")
5543 (set_attr "needs_delay_slot" "yes")])
5545 (define_expand "initialize_trampoline"
5546 [(match_operand:SI 0 "" "")
5547 (match_operand:SI 1 "" "")
5548 (match_operand:SI 2 "" "")]
5553 tramp = force_reg (Pmode, operands[0]);
5554 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
5556 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5557 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5559 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5563 (define_insn "initialize_trampoline_compact"
5564 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5565 (match_operand:SI 1 "register_operand" "r")
5566 (reg:SI R2_REG) (reg:SI R3_REG)]
5569 (clobber (reg:SI PR_REG))]
5572 [(set_attr "type" "sfunc")
5573 (set_attr "needs_delay_slot" "yes")])
5575 (define_expand "movhi"
5576 [(set (match_operand:HI 0 "general_movdst_operand" "")
5577 (match_operand:HI 1 "general_movsrc_operand" ""))]
5580 prepare_move_operands (operands, HImode);
5583 (define_expand "movqi"
5584 [(set (match_operand:QI 0 "general_operand" "")
5585 (match_operand:QI 1 "general_operand" ""))]
5588 prepare_move_operands (operands, QImode);
5591 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
5592 ;; selected to copy QImode regs. If one of them happens to be allocated
5593 ;; on the stack, reload will stick to movqi insn and generate wrong
5594 ;; displacement addressing because of the generic m alternatives.
5595 ;; With the movqi_reg_reg being specified before movqi it will be initially
5596 ;; picked to load/store regs. If the regs regs are on the stack reload will
5597 ;; try other insns and not stick to movqi_reg_reg.
5598 ;; The same applies to the movhi variants.
5599 (define_insn "*movqi_reg_reg"
5600 [(set (match_operand:QI 0 "arith_reg_dest" "=r,r")
5601 (match_operand:QI 1 "register_operand" "r,t"))]
5606 [(set_attr "type" "move,arith")])
5608 (define_insn "*movhi_reg_reg"
5609 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
5610 (match_operand:HI 1 "register_operand" "r,t"))]
5615 [(set_attr "type" "move,arith")])
5617 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
5618 ;; "enabled" attribute as it is done in other targets.
5619 (define_insn "*movqi_store_mem_disp04"
5620 [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
5621 (match_operand:SI 1 "const_int_operand" "K04,N")))
5622 (match_operand:QI 2 "arith_reg_operand" "z,r"))]
5623 "TARGET_SH1 && sh_legitimate_index_p (QImode, operands[1], false, true)"
5627 [(set_attr "type" "store")])
5629 (define_insn "*movhi_store_mem_disp05"
5630 [(set (mem:HI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
5631 (match_operand:SI 1 "const_int_operand" "K05,N")))
5632 (match_operand:HI 2 "arith_reg_operand" "z,r"))]
5633 "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[1], false, true)"
5637 [(set_attr "type" "store")])
5639 (define_insn "*movqi_store_mem_disp12"
5640 [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
5641 (match_operand:SI 1 "const_int_operand" "K12")))
5642 (match_operand:QI 2 "arith_reg_operand" "r"))]
5643 "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[1], true, true)"
5644 "mov.b %2,@(%O1,%0)"
5645 [(set_attr "type" "store")
5646 (set_attr "length" "4")])
5648 (define_insn "*movhi_store_mem_disp13"
5649 [(set (mem:HI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
5650 (match_operand:SI 1 "const_int_operand" "K13")))
5651 (match_operand:HI 2 "arith_reg_operand" "r"))]
5652 "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[1], true, true)"
5653 "mov.w %2,@(%O1,%0)"
5654 [(set_attr "type" "store")
5655 (set_attr "length" "4")])
5657 (define_insn "*movqi_load_mem_disp"
5658 [(set (match_operand:QI 0 "arith_reg_dest" "=z,r")
5659 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
5660 (match_operand:SI 2 "const_int_operand" "K04,N"))))]
5661 "TARGET_SH1 && ! TARGET_SH2A
5662 && sh_legitimate_index_p (QImode, operands[2], false, true)"
5666 [(set_attr "type" "load")])
5668 (define_insn "*movhi_load_mem_disp"
5669 [(set (match_operand:HI 0 "arith_reg_dest" "=z,r")
5670 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
5671 (match_operand:SI 2 "const_int_operand" "K05,N"))))]
5672 "TARGET_SH1 && ! TARGET_SH2A
5673 && sh_legitimate_index_p (HImode, operands[2], false, true)"
5677 [(set_attr "type" "load")])
5679 (define_insn "*movqi_load_mem_disp"
5680 [(set (match_operand:QI 0 "arith_reg_dest" "=z,r,r")
5681 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
5682 (match_operand:SI 2 "const_int_operand" "K04,N,K12"))))]
5683 "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[2], true, true)"
5688 [(set_attr "type" "load")
5689 (set_attr "length" "2,2,4")])
5691 (define_insn "*movhi_load_mem_disp"
5692 [(set (match_operand:HI 0 "arith_reg_dest" "=z,r,r")
5693 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
5694 (match_operand:SI 2 "const_int_operand" "K05,N,K13"))))]
5695 "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[2], true, true)"
5700 [(set_attr "type" "load")
5701 (set_attr "length" "2,2,4")])
5703 ;; The m constraints basically allow any kind of addresses to be used with any
5704 ;; source/target register as the other operand. This is not true for
5705 ;; displacement addressing modes on anything but SH2A. That's why the
5706 ;; specialized load/store insns are specified above.
5707 (define_insn "*movqi"
5708 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
5709 (match_operand:QI 1 "general_movsrc_operand" "i,m,r,l,r"))]
5711 && (arith_reg_operand (operands[0], QImode)
5712 || arith_reg_operand (operands[1], QImode))"
5719 [(set_attr "type" "movi8,load,store,prget,prset")])
5721 (define_insn "*movhi"
5722 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l")
5723 (match_operand:HI 1 "general_movsrc_operand" "Q,i,m,r,l,r"))]
5725 && (arith_reg_operand (operands[0], HImode)
5726 || arith_reg_operand (operands[1], HImode))"
5734 [(set_attr "type" "pcload,movi8,load,store,prget,prset")])
5736 (define_insn "*movqi_media"
5737 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5738 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5740 && (arith_reg_operand (operands[0], QImode)
5741 || extend_reg_or_0_operand (operands[1], QImode))"
5747 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5748 (set (attr "highpart")
5749 (cond [(match_test "sh_contains_memref_p (insn)")
5750 (const_string "user")]
5751 (const_string "ignore")))])
5753 (define_expand "reload_inqi"
5754 [(set (match_operand:SI 2 "" "=&r")
5755 (match_operand:QI 1 "inqhi_operand" ""))
5756 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5757 (truncate:QI (match_dup 3)))]
5760 rtx inner = XEXP (operands[1], 0);
5761 int regno = REGNO (inner);
5763 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5764 operands[1] = gen_rtx_REG (SImode, regno);
5765 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5768 (define_insn "*movhi_media"
5769 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5770 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5772 && (arith_reg_operand (operands[0], HImode)
5773 || arith_reg_or_0_operand (operands[1], HImode))"
5780 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5781 (set (attr "highpart")
5782 (cond [(match_test "sh_contains_memref_p (insn)")
5783 (const_string "user")]
5784 (const_string "ignore")))])
5787 [(set (match_operand:HI 0 "register_operand" "")
5788 (match_operand:HI 1 "immediate_operand" ""))]
5789 "TARGET_SHMEDIA && reload_completed
5790 && ! satisfies_constraint_I16 (operands[1])"
5791 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5793 (define_expand "reload_inhi"
5794 [(set (match_operand:SI 2 "" "=&r")
5795 (match_operand:HI 1 "inqhi_operand" ""))
5796 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5797 (truncate:HI (match_dup 3)))]
5800 rtx inner = XEXP (operands[1], 0);
5801 int regno = REGNO (inner);
5803 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5804 operands[1] = gen_rtx_REG (SImode, regno);
5805 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5808 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5809 ;; compiled with -m2 -ml -O3 -funroll-loops
5810 (define_insn "*movdi_i"
5811 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5812 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5814 && (arith_reg_operand (operands[0], DImode)
5815 || arith_reg_operand (operands[1], DImode))"
5817 return output_movedouble (insn, operands, DImode);
5819 [(set_attr "length" "4")
5820 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5822 ;; If the output is a register and the input is memory or a register, we have
5823 ;; to be careful and see which word needs to be loaded first.
5826 [(set (match_operand:DI 0 "general_movdst_operand" "")
5827 (match_operand:DI 1 "general_movsrc_operand" ""))]
5828 "TARGET_SH1 && reload_completed"
5829 [(set (match_dup 2) (match_dup 3))
5830 (set (match_dup 4) (match_dup 5))]
5834 if ((MEM_P (operands[0])
5835 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5836 || (MEM_P (operands[1])
5837 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5840 switch (GET_CODE (operands[0]))
5843 regno = REGNO (operands[0]);
5846 regno = subreg_regno (operands[0]);
5856 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5858 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5859 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5860 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5861 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5865 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5866 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5867 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5868 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5871 if (operands[2] == 0 || operands[3] == 0
5872 || operands[4] == 0 || operands[5] == 0)
5876 ;; The '?'s in the following constraints may not reflect the time taken
5877 ;; to perform the move. They are there to discourage the use of floating-
5878 ;; point registers for storing integer values.
5879 (define_insn "*movdi_media"
5880 [(set (match_operand:DI 0 "general_movdst_operand"
5881 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5882 (match_operand:DI 1 "general_movsrc_operand"
5883 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5885 && (register_operand (operands[0], DImode)
5886 || sh_register_operand (operands[1], DImode))"
5901 [(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")
5902 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5904 (define_insn "*movdi_media_nofpu"
5905 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5906 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5908 && (register_operand (operands[0], DImode)
5909 || sh_register_operand (operands[1], DImode))"
5919 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5920 (set_attr "length" "4,4,16,4,4,4,4,*")])
5922 (define_insn "*movdi_media_I16"
5923 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5924 (match_operand:DI 1 "const_int_operand" "I16"))]
5925 "TARGET_SHMEDIA && reload_completed"
5927 [(set_attr "type" "arith_media")
5928 (set_attr "length" "4")])
5931 [(set (match_operand:DI 0 "arith_reg_dest" "")
5932 (match_operand:DI 1 "immediate_operand" ""))]
5933 "TARGET_SHMEDIA && reload_completed
5934 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5935 [(set (match_dup 0) (match_dup 1))]
5939 if (TARGET_SHMEDIA64)
5940 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5942 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5944 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5949 (define_expand "movdi_const"
5950 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5951 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5952 (const_int 48)] UNSPEC_EXTRACT_S16)))
5954 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5955 (const:DI (unspec:DI [(match_dup 1)
5956 (const_int 32)] UNSPEC_EXTRACT_U16))))
5958 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5959 (const:DI (unspec:DI [(match_dup 1)
5960 (const_int 16)] UNSPEC_EXTRACT_U16))))
5962 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5963 (const:DI (unspec:DI [(match_dup 1)
5964 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5965 "TARGET_SHMEDIA64 && reload_completed
5966 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5968 sh_mark_label (operands[1], 4);
5971 (define_expand "movdi_const_32bit"
5972 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5973 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5974 (const_int 16)] UNSPEC_EXTRACT_S16)))
5976 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5977 (const:DI (unspec:DI [(match_dup 1)
5978 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5979 "TARGET_SHMEDIA32 && reload_completed
5980 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5982 sh_mark_label (operands[1], 2);
5985 (define_expand "movdi_const_16bit"
5986 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5987 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5988 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5989 "TARGET_SHMEDIA && flag_pic && reload_completed
5990 && GET_CODE (operands[1]) == SYMBOL_REF"
5994 [(set (match_operand:DI 0 "ext_dest_operand" "")
5995 (match_operand:DI 1 "immediate_operand" ""))]
5996 "TARGET_SHMEDIA && reload_completed
5997 && CONST_INT_P (operands[1])
5998 && ! satisfies_constraint_I16 (operands[1])"
5999 [(set (match_dup 0) (match_dup 2))
6002 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
6003 unsigned HOST_WIDE_INT low = val;
6004 unsigned HOST_WIDE_INT high = val;
6005 unsigned HOST_WIDE_INT sign;
6006 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
6008 /* Zero-extend the 16 least-significant bits. */
6011 /* Arithmetic shift right the word by 16 bits. */
6013 if (GET_CODE (operands[0]) == SUBREG
6014 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
6023 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
6029 /* If we can't generate the constant with a two-insn movi / shori
6030 sequence, try some other strategies. */
6031 if (! CONST_OK_FOR_I16 (high))
6033 /* Try constant load / left shift. We know VAL != 0. */
6034 val2 = val ^ (val-1);
6037 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
6039 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
6040 || (! CONST_OK_FOR_I16 (high >> 16)
6041 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
6043 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
6044 operands[1] = gen_ashldi3_media (operands[0], operands[0],
6045 GEN_INT (trailing_zeroes));
6049 /* Try constant load / right shift. */
6050 val2 = (val >> 15) + 1;
6051 if (val2 == (val2 & -val2))
6053 int shift = 49 - exact_log2 (val2);
6055 val2 = trunc_int_for_mode (val << shift, DImode);
6056 if (CONST_OK_FOR_I16 (val2))
6058 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
6064 val2 = val & 0xffff;
6065 if ((val >> 16 & 0xffff) == val2
6066 && (val >> 32 & 0xffff) == val2
6067 && (val >> 48 & 0xffff) == val2)
6069 val2 = (HOST_WIDE_INT) val >> 48;
6070 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
6071 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
6074 /* Try movi / mshflo.l */
6075 val2 = (HOST_WIDE_INT) val >> 32;
6076 if (val2 == ((unsigned HOST_WIDE_INT)
6077 trunc_int_for_mode (val, SImode)))
6079 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
6083 /* Try movi / mshflo.l w/ r63. */
6084 val2 = val + ((HOST_WIDE_INT) -1 << 32);
6085 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
6087 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
6093 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
6096 operands[2] = GEN_INT (val2);
6100 [(set (match_operand:DI 0 "ext_dest_operand" "")
6101 (match_operand:DI 1 "immediate_operand" ""))]
6102 "TARGET_SHMEDIA && reload_completed
6103 && GET_CODE (operands[1]) == CONST_DOUBLE"
6104 [(set (match_dup 0) (match_dup 2))
6106 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
6108 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
6109 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
6110 unsigned HOST_WIDE_INT val = low;
6111 unsigned HOST_WIDE_INT sign;
6113 /* Zero-extend the 16 least-significant bits. */
6115 operands[1] = GEN_INT (val);
6117 /* Arithmetic shift right the double-word by 16 bits. */
6119 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
6122 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
6126 /* This will only be true if high is a sign-extension of low, i.e.,
6127 it must be either 0 or (unsigned)-1, and be zero iff the
6128 most-significant bit of low is set. */
6129 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
6130 operands[2] = GEN_INT (low);
6132 operands[2] = immed_double_const (low, high, DImode);
6135 (define_insn "shori_media"
6136 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
6137 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
6139 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
6140 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
6144 [(set_attr "type" "arith_media,*")])
6146 (define_insn "*shori_media_si"
6147 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
6148 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
6150 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
6154 (define_expand "movdi"
6155 [(set (match_operand:DI 0 "general_movdst_operand" "")
6156 (match_operand:DI 1 "general_movsrc_operand" ""))]
6159 prepare_move_operands (operands, DImode);
6162 (define_insn "movdf_media"
6163 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6164 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6166 && (register_operand (operands[0], DFmode)
6167 || sh_register_operand (operands[1], DFmode))"
6178 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
6180 (define_insn "movdf_media_nofpu"
6181 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6182 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6184 && (register_operand (operands[0], DFmode)
6185 || sh_register_operand (operands[1], DFmode))"
6191 [(set_attr "type" "arith_media,*,load_media,store_media")])
6194 [(set (match_operand:DF 0 "arith_reg_dest" "")
6195 (match_operand:DF 1 "immediate_operand" ""))]
6196 "TARGET_SHMEDIA && reload_completed"
6197 [(set (match_dup 3) (match_dup 2))]
6199 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
6201 REAL_VALUE_TYPE value;
6203 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6204 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
6206 if (HOST_BITS_PER_WIDE_INT >= 64)
6207 operands[2] = immed_double_const ((unsigned long) values[endian]
6208 | ((HOST_WIDE_INT) values[1 - endian]
6212 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
6213 operands[2] = immed_double_const (values[endian], values[1 - endian],
6217 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6220 ;; ??? This should be a define expand.
6222 (define_insn "movdf_k"
6223 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6224 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
6226 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
6227 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
6228 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6229 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6230 && (arith_reg_operand (operands[0], DFmode)
6231 || arith_reg_operand (operands[1], DFmode))"
6233 return output_movedouble (insn, operands, DFmode);
6235 [(set_attr "length" "4")
6236 (set_attr "type" "move,pcload,load,store")])
6238 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
6239 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
6240 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
6241 ;; the d/m/c/X alternative, which is split later into single-precision
6242 ;; instructions. And when not optimizing, no splits are done before fixing
6243 ;; up pcloads, so we need usable length information for that.
6244 (define_insn "movdf_i4"
6245 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
6246 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
6247 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
6248 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
6249 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6250 && (arith_reg_operand (operands[0], DFmode)
6251 || arith_reg_operand (operands[1], DFmode))"
6253 switch (which_alternative)
6257 return "fmov %1,%0";
6258 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
6259 return "fmov %R1,%R0\n\tfmov %S1,%S0";
6261 return "fmov %S1,%S0\n\tfmov %R1,%R0";
6264 return "fmov.d %1,%0";
6269 [(set_attr_alternative "length"
6270 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6272 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6273 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6274 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6276 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6277 ;; We can't use 4-byte push/pop on SHcompact, so we have to
6278 ;; increment or decrement r15 explicitly.
6280 (match_test "TARGET_SHCOMPACT")
6281 (const_int 10) (const_int 8))
6283 (match_test "TARGET_SHCOMPACT")
6284 (const_int 10) (const_int 8))])
6285 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6286 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6287 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6288 (const_string "double")
6289 (const_string "none")))])
6291 ;; Moving DFmode between fp/general registers through memory
6292 ;; (the top of the stack) is faster than moving through fpul even for
6293 ;; little endian. Because the type of an instruction is important for its
6294 ;; scheduling, it is beneficial to split these operations, rather than
6295 ;; emitting them in one single chunk, even if this will expose a stack
6296 ;; use that will prevent scheduling of other stack accesses beyond this
6299 [(set (match_operand:DF 0 "register_operand" "")
6300 (match_operand:DF 1 "register_operand" ""))
6301 (use (match_operand:PSI 2 "fpscr_operand" ""))
6302 (clobber (match_scratch:SI 3 "=X"))]
6303 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6304 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6309 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6311 emit_move_insn (stack_pointer_rtx,
6312 plus_constant (Pmode, stack_pointer_rtx, -8));
6313 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6316 tos = gen_tmp_stack_mem (DFmode,
6317 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6318 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6319 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6320 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6321 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6322 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6324 tos = gen_tmp_stack_mem (DFmode,
6325 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6326 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6327 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6328 emit_move_insn (stack_pointer_rtx,
6329 plus_constant (Pmode, stack_pointer_rtx, 8));
6331 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6335 ;; local-alloc sometimes allocates scratch registers even when not required,
6336 ;; so we must be prepared to handle these.
6338 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6340 [(set (match_operand:DF 0 "general_movdst_operand" "")
6341 (match_operand:DF 1 "general_movsrc_operand" ""))
6342 (use (match_operand:PSI 2 "fpscr_operand" ""))
6343 (clobber (match_scratch:SI 3 ""))]
6344 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6346 && true_regnum (operands[0]) < 16
6347 && true_regnum (operands[1]) < 16"
6348 [(set (match_dup 0) (match_dup 1))]
6350 /* If this was a reg <-> mem operation with base + index reg addressing,
6351 we have to handle this in a special way. */
6352 rtx mem = operands[0];
6354 if (! memory_operand (mem, DFmode))
6359 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6360 mem = SUBREG_REG (mem);
6363 rtx addr = XEXP (mem, 0);
6364 if (GET_CODE (addr) == PLUS
6365 && REG_P (XEXP (addr, 0))
6366 && REG_P (XEXP (addr, 1)))
6369 rtx reg0 = gen_rtx_REG (Pmode, 0);
6370 rtx regop = operands[store_p], word0 ,word1;
6372 if (GET_CODE (regop) == SUBREG)
6373 alter_subreg (®op);
6374 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6378 mem = copy_rtx (mem);
6379 PUT_MODE (mem, SImode);
6380 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6381 alter_subreg (&word0);
6382 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6383 alter_subreg (&word1);
6384 if (store_p || ! refers_to_regno_p (REGNO (word0),
6385 REGNO (word0) + 1, addr, 0))
6388 ? gen_movsi_ie (mem, word0)
6389 : gen_movsi_ie (word0, mem));
6390 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6391 mem = copy_rtx (mem);
6393 ? gen_movsi_ie (mem, word1)
6394 : gen_movsi_ie (word1, mem));
6395 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6399 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6400 emit_insn (gen_movsi_ie (word1, mem));
6401 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6402 mem = copy_rtx (mem);
6403 emit_insn (gen_movsi_ie (word0, mem));
6410 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6412 [(set (match_operand:DF 0 "register_operand" "")
6413 (match_operand:DF 1 "memory_operand" ""))
6414 (use (match_operand:PSI 2 "fpscr_operand" ""))
6415 (clobber (reg:SI R0_REG))]
6416 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6417 [(parallel [(set (match_dup 0) (match_dup 1))
6419 (clobber (scratch:SI))])]
6422 (define_expand "reload_indf__frn"
6423 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6424 (match_operand:DF 1 "immediate_operand" "FQ"))
6425 (use (reg:PSI FPSCR_REG))
6426 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6430 (define_expand "reload_outdf__RnFRm"
6431 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6432 (match_operand:DF 1 "register_operand" "af,r"))
6433 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6437 ;; Simplify no-op moves.
6439 [(set (match_operand:SF 0 "register_operand" "")
6440 (match_operand:SF 1 "register_operand" ""))
6441 (use (match_operand:PSI 2 "fpscr_operand" ""))
6442 (clobber (match_scratch:SI 3 ""))]
6443 "TARGET_SH2E && reload_completed
6444 && true_regnum (operands[0]) == true_regnum (operands[1])"
6445 [(set (match_dup 0) (match_dup 0))]
6448 ;; fmovd substitute post-reload splits
6450 [(set (match_operand:DF 0 "register_operand" "")
6451 (match_operand:DF 1 "register_operand" ""))
6452 (use (match_operand:PSI 2 "fpscr_operand" ""))
6453 (clobber (match_scratch:SI 3 ""))]
6454 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6455 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6456 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6459 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6460 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6461 gen_rtx_REG (SFmode, src), operands[2]));
6462 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6463 gen_rtx_REG (SFmode, src + 1), operands[2]));
6468 [(set (match_operand:DF 0 "register_operand" "")
6469 (mem:DF (match_operand:SI 1 "register_operand" "")))
6470 (use (match_operand:PSI 2 "fpscr_operand" ""))
6471 (clobber (match_scratch:SI 3 ""))]
6472 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6473 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6474 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6477 int regno = true_regnum (operands[0]);
6479 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6481 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6482 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6483 regno + !! TARGET_LITTLE_ENDIAN),
6484 mem2, operands[2]));
6485 add_reg_note (insn, REG_INC, operands[1]);
6486 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6487 regno + ! TARGET_LITTLE_ENDIAN),
6488 change_address (mem, SFmode, NULL_RTX),
6494 [(set (match_operand:DF 0 "register_operand" "")
6495 (match_operand:DF 1 "memory_operand" ""))
6496 (use (match_operand:PSI 2 "fpscr_operand" ""))
6497 (clobber (match_scratch:SI 3 ""))]
6498 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6499 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6502 int regno = true_regnum (operands[0]);
6504 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6505 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6506 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6508 operands[1] = copy_rtx (mem2);
6509 addr = XEXP (mem2, 0);
6511 switch (GET_CODE (addr))
6514 /* This is complicated. If the register is an arithmetic register
6515 we can just fall through to the REG+DISP case below. Otherwise
6516 we have to use a combination of POST_INC and REG addressing... */
6517 if (! arith_reg_operand (operands[1], SFmode))
6519 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6520 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6521 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6523 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6525 /* If we have modified the stack pointer, the value that we have
6526 read with post-increment might be modified by an interrupt,
6527 so write it back. */
6528 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6529 emit_insn (gen_push_e (reg0));
6531 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6537 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6538 operands[1] = copy_rtx (operands[1]);
6539 XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4);
6540 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6544 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6545 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6547 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6548 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6560 [(set (match_operand:DF 0 "memory_operand" "")
6561 (match_operand:DF 1 "register_operand" ""))
6562 (use (match_operand:PSI 2 "fpscr_operand" ""))
6563 (clobber (match_scratch:SI 3 ""))]
6564 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6565 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6568 int regno = true_regnum (operands[1]);
6570 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6571 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6573 operands[0] = copy_rtx (operands[0]);
6574 PUT_MODE (operands[0], SFmode);
6575 addr = XEXP (operands[0], 0);
6577 switch (GET_CODE (addr))
6580 /* This is complicated. If the register is an arithmetic register
6581 we can just fall through to the REG+DISP case below. Otherwise
6582 we have to use a combination of REG and PRE_DEC addressing... */
6583 if (! arith_reg_operand (operands[0], SFmode))
6585 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6586 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6588 operands[0] = copy_rtx (operands[0]);
6589 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6591 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6592 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6598 /* Since REG+DISP addressing has already been decided upon by gcc
6599 we can rely upon it having chosen an arithmetic register as the
6600 register component of the address. Just emit the lower numbered
6601 register first, to the lower address, then the higher numbered
6602 register to the higher address. */
6603 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6605 operands[0] = copy_rtx (operands[0]);
6606 XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4);
6608 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6612 /* This is easy. Output the word to go to the higher address
6613 first (ie the word in the higher numbered register) then the
6614 word to go to the lower address. */
6616 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6617 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6619 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6620 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6632 ;; If the output is a register and the input is memory or a register, we have
6633 ;; to be careful and see which word needs to be loaded first.
6636 [(set (match_operand:DF 0 "general_movdst_operand" "")
6637 (match_operand:DF 1 "general_movsrc_operand" ""))]
6638 "TARGET_SH1 && reload_completed"
6639 [(set (match_dup 2) (match_dup 3))
6640 (set (match_dup 4) (match_dup 5))]
6644 if ((MEM_P (operands[0])
6645 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6646 || (MEM_P (operands[1])
6647 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6650 switch (GET_CODE (operands[0]))
6653 regno = REGNO (operands[0]);
6656 regno = subreg_regno (operands[0]);
6666 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6668 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6669 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6670 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6671 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6675 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6676 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6677 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6678 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6681 if (operands[2] == 0 || operands[3] == 0
6682 || operands[4] == 0 || operands[5] == 0)
6686 (define_expand "movdf"
6687 [(set (match_operand:DF 0 "general_movdst_operand" "")
6688 (match_operand:DF 1 "general_movsrc_operand" ""))]
6691 prepare_move_operands (operands, DFmode);
6694 if (TARGET_SHMEDIA_FPU)
6695 emit_insn (gen_movdf_media (operands[0], operands[1]));
6697 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6700 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6702 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6707 ;;This is incompatible with the way gcc uses subregs.
6708 ;;(define_insn "movv2sf_i"
6709 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6710 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6711 ;; "TARGET_SHMEDIA_FPU
6712 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6713 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6717 ;; fst%M0.p %m0, %1"
6718 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6720 (define_insn_and_split "movv2sf_i"
6721 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6722 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6723 "TARGET_SHMEDIA_FPU"
6725 "TARGET_SHMEDIA_FPU && reload_completed"
6726 [(set (match_dup 0) (match_dup 1))]
6728 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6729 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6732 (define_expand "movv2sf"
6733 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6734 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6735 "TARGET_SHMEDIA_FPU"
6737 prepare_move_operands (operands, V2SFmode);
6740 (define_expand "addv2sf3"
6741 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6742 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6743 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6744 "TARGET_SHMEDIA_FPU"
6746 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6750 (define_expand "subv2sf3"
6751 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6752 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6753 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6754 "TARGET_SHMEDIA_FPU"
6756 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6760 (define_expand "mulv2sf3"
6761 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6762 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6763 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6764 "TARGET_SHMEDIA_FPU"
6766 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6770 (define_expand "divv2sf3"
6771 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6772 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6773 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6774 "TARGET_SHMEDIA_FPU"
6776 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6780 (define_insn_and_split "*movv4sf_i"
6781 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6782 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6783 "TARGET_SHMEDIA_FPU"
6785 "&& reload_completed"
6790 for (i = 0; i < 4/2; i++)
6794 if (MEM_P (operands[0]))
6795 x = adjust_address (operands[0], V2SFmode,
6796 i * GET_MODE_SIZE (V2SFmode));
6798 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6800 if (MEM_P (operands[1]))
6801 y = adjust_address (operands[1], V2SFmode,
6802 i * GET_MODE_SIZE (V2SFmode));
6804 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6806 emit_insn (gen_movv2sf_i (x, y));
6811 [(set_attr "length" "8")])
6813 (define_expand "movv4sf"
6814 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6815 (match_operand:V4SF 1 "general_operand" ""))]
6816 "TARGET_SHMEDIA_FPU"
6818 prepare_move_operands (operands, V4SFmode);
6821 (define_insn_and_split "*movv16sf_i"
6822 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6823 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6824 "TARGET_SHMEDIA_FPU"
6826 "&& reload_completed"
6831 for (i = 0; i < 16/2; i++)
6835 if (MEM_P (operands[0]))
6836 x = adjust_address (operands[0], V2SFmode,
6837 i * GET_MODE_SIZE (V2SFmode));
6840 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6844 if (MEM_P (operands[1]))
6845 y = adjust_address (operands[1], V2SFmode,
6846 i * GET_MODE_SIZE (V2SFmode));
6849 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6853 emit_insn (gen_movv2sf_i (x, y));
6858 [(set_attr "length" "32")])
6860 (define_expand "movv16sf"
6861 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6862 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6863 "TARGET_SHMEDIA_FPU"
6865 prepare_move_operands (operands, V16SFmode);
6868 (define_insn "movsf_media"
6869 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6870 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6872 && (register_operand (operands[0], SFmode)
6873 || sh_register_operand (operands[1], SFmode))"
6884 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6885 (set (attr "highpart")
6886 (cond [(match_test "sh_contains_memref_p (insn)")
6887 (const_string "user")]
6888 (const_string "ignore")))])
6890 (define_insn "movsf_media_nofpu"
6891 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6892 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6894 && (register_operand (operands[0], SFmode)
6895 || sh_register_operand (operands[1], SFmode))"
6901 [(set_attr "type" "arith_media,*,load_media,store_media")
6902 (set (attr "highpart")
6903 (cond [(match_test "sh_contains_memref_p (insn)")
6904 (const_string "user")]
6905 (const_string "ignore")))])
6908 [(set (match_operand:SF 0 "arith_reg_dest" "")
6909 (match_operand:SF 1 "immediate_operand" ""))]
6910 "TARGET_SHMEDIA && reload_completed
6911 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6912 [(set (match_dup 3) (match_dup 2))]
6915 REAL_VALUE_TYPE value;
6917 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6918 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6919 operands[2] = GEN_INT (values);
6921 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6924 (define_insn "movsf_i"
6925 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6926 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6929 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6930 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6931 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6932 && (arith_reg_operand (operands[0], SFmode)
6933 || arith_reg_operand (operands[1], SFmode))"
6942 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6944 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6945 ;; update_flow_info would not know where to put REG_EQUAL notes
6946 ;; when the destination changes mode.
6947 (define_insn "movsf_ie"
6948 [(set (match_operand:SF 0 "general_movdst_operand"
6949 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6950 (match_operand:SF 1 "general_movsrc_operand"
6951 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6952 (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"))
6953 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6955 && (arith_reg_operand (operands[0], SFmode)
6956 || arith_reg_operand (operands[1], SFmode)
6957 || arith_reg_operand (operands[3], SImode)
6958 || (fpul_operand (operands[0], SFmode)
6959 && memory_operand (operands[1], SFmode)
6960 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6961 || (fpul_operand (operands[1], SFmode)
6962 && memory_operand (operands[0], SFmode)
6963 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6983 ! move optimized away"
6984 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6985 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6986 (set_attr_alternative "length"
6993 (match_test "TARGET_SH2A")
6994 (const_int 4) (const_int 2))
6996 (match_test "TARGET_SH2A")
6997 (const_int 4) (const_int 2))
7000 (match_test "TARGET_SH2A")
7001 (const_int 4) (const_int 2))
7003 (match_test "TARGET_SH2A")
7004 (const_int 4) (const_int 2))
7014 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
7015 (const_string "single")
7016 (const_string "single")))])
7019 [(set (match_operand:SF 0 "register_operand" "")
7020 (match_operand:SF 1 "register_operand" ""))
7021 (use (match_operand:PSI 2 "fpscr_operand" ""))
7022 (clobber (reg:SI FPUL_REG))]
7024 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
7026 (clobber (scratch:SI))])
7027 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
7029 (clobber (scratch:SI))])]
7032 (define_expand "movsf"
7033 [(set (match_operand:SF 0 "general_movdst_operand" "")
7034 (match_operand:SF 1 "general_movsrc_operand" ""))]
7037 prepare_move_operands (operands, SFmode);
7040 if (TARGET_SHMEDIA_FPU)
7041 emit_insn (gen_movsf_media (operands[0], operands[1]));
7043 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
7048 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
7053 (define_insn "mov_nop"
7054 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
7057 [(set_attr "length" "0")
7058 (set_attr "type" "nil")])
7060 (define_expand "reload_insf__frn"
7061 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
7062 (match_operand:SF 1 "immediate_operand" "FQ"))
7063 (use (reg:PSI FPSCR_REG))
7064 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7068 (define_expand "reload_insi__i_fpul"
7069 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
7070 (match_operand:SI 1 "immediate_operand" "i"))
7071 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
7075 (define_expand "ptabs"
7076 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
7079 if (!TARGET_PT_FIXED)
7081 rtx eq = operands[1];
7083 /* ??? For canonical RTL we really should remove any CONST from EQ
7084 before wrapping it in the AND, and finally wrap the EQ into a
7085 const if is constant. However, for reload we must expose the
7086 input register or symbolic constant, and we can't have
7087 different insn structures outside of the operands for different
7088 alternatives of the same pattern. */
7089 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
7092 = (gen_rtx_IF_THEN_ELSE
7095 gen_rtx_MEM (PDImode, operands[1]),
7096 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
7097 PDImode, operands[1])));
7101 ;; expanded by ptabs expander.
7102 (define_insn "*extendsipdi_media"
7103 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
7104 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
7108 (mem:PDI (match_dup 1))
7109 (sign_extend:PDI (match_dup 1))))]
7110 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
7114 [(set_attr "type" "ptabs_media,pt_media")
7115 (set_attr "length" "4,*")])
7117 (define_insn "*truncdipdi_media"
7118 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
7119 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
7123 (mem:PDI (match_dup 1))
7124 (truncate:PDI (match_dup 1))))]
7125 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
7129 [(set_attr "type" "ptabs_media,pt_media")
7130 (set_attr "length" "4,*")])
7132 (define_insn "*movsi_y"
7133 [(set (match_operand:SI 0 "register_operand" "=y,y")
7134 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
7135 (clobber (match_scratch:SI 2 "=&z,r"))]
7137 && (reload_in_progress || reload_completed)"
7139 [(set_attr "length" "4")
7140 (set_attr "type" "pcload,move")])
7143 [(set (match_operand:SI 0 "register_operand" "")
7144 (match_operand:SI 1 "immediate_operand" ""))
7145 (clobber (match_operand:SI 2 "register_operand" ""))]
7147 [(set (match_dup 2) (match_dup 1))
7148 (set (match_dup 0) (match_dup 2))]
7151 ;; ------------------------------------------------------------------------
7152 ;; Define the real conditional branch instructions.
7153 ;; ------------------------------------------------------------------------
7155 (define_insn "branch_true"
7156 [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
7158 (label_ref (match_operand 0 "" ""))
7162 return output_branch (1, insn, operands);
7164 [(set_attr "type" "cbranch")])
7166 (define_insn "*branch_true_eq"
7167 [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
7169 (label_ref (match_operand 0 "" ""))
7173 return output_branch (1, insn, operands);
7175 [(set_attr "type" "cbranch")])
7177 (define_insn "branch_false"
7178 [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
7180 (label_ref (match_operand 0 "" ""))
7184 return output_branch (0, insn, operands);
7186 [(set_attr "type" "cbranch")])
7188 (define_insn "*branch_false_ne"
7189 [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
7191 (label_ref (match_operand 0 "" ""))
7195 return output_branch (0, insn, operands);
7197 [(set_attr "type" "cbranch")])
7199 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
7200 ;; which destination is too far away.
7201 ;; The const_int_operand is distinct for each branch target; it avoids
7202 ;; unwanted matches with redundant_insn.
7203 (define_insn "block_branch_redirect"
7204 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7207 [(set_attr "length" "0")])
7209 ;; This one has the additional purpose to record a possible scratch register
7210 ;; for the following branch.
7211 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7212 ;; because the insn then might be deemed dead and deleted. And we can't
7213 ;; make the use in the jump insn explicit because that would disable
7214 ;; delay slot scheduling from the target.
7215 (define_insn "indirect_jump_scratch"
7216 [(set (match_operand:SI 0 "register_operand" "=r")
7217 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7218 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7221 [(set_attr "length" "0")])
7223 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7224 ;; being pulled into the delay slot of a condbranch that has been made to
7225 ;; jump around the unconditional jump because it was out of range.
7226 (define_insn "stuff_delay_slot"
7228 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7229 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7232 [(set_attr "length" "0")
7233 (set_attr "cond_delay_slot" "yes")])
7235 ;; Conditional branch insns
7237 (define_expand "cbranchint4_media"
7239 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7240 [(match_operand 1 "" "")
7241 (match_operand 2 "" "")])
7242 (match_operand 3 "" "")
7246 enum machine_mode mode = GET_MODE (operands[1]);
7247 if (mode == VOIDmode)
7248 mode = GET_MODE (operands[2]);
7249 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7251 operands[1] = force_reg (mode, operands[1]);
7252 if (CONSTANT_P (operands[2])
7253 && (! satisfies_constraint_I06 (operands[2])))
7254 operands[2] = force_reg (mode, operands[2]);
7258 if (operands[1] != const0_rtx)
7259 operands[1] = force_reg (mode, operands[1]);
7260 if (operands[2] != const0_rtx)
7261 operands[2] = force_reg (mode, operands[2]);
7263 switch (GET_CODE (operands[0]))
7269 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7270 VOIDmode, operands[2], operands[1]);
7271 operands[1] = XEXP (operands[0], 0);
7272 operands[2] = XEXP (operands[0], 1);
7275 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7276 VOIDmode, operands[1], operands[2]);
7279 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7282 (define_expand "cbranchfp4_media"
7284 (if_then_else (match_operator 0 "sh_float_comparison_operator"
7285 [(match_operand 1 "" "")
7286 (match_operand 2 "" "")])
7287 (match_operand 3 "" "")
7291 rtx tmp = gen_reg_rtx (SImode);
7293 if (GET_CODE (operands[0]) == NE)
7294 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7296 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7297 operands[1], operands[2]);
7299 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7301 if (GET_CODE (cmp) == GET_CODE (operands[0]))
7302 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7304 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7306 operands[2] = const0_rtx;
7307 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7310 (define_insn "*beq_media_i"
7312 (if_then_else (match_operator 3 "equality_comparison_operator"
7313 [(match_operand:DI 1 "arith_reg_operand" "r,r")
7314 (match_operand:DI 2 "arith_operand" "r,I06")])
7315 (match_operand 0 "target_operand" "b,b")
7320 b%o3i%' %1, %2, %0%>"
7321 [(set_attr "type" "cbranch_media")])
7323 (define_insn "*beq_media_i32"
7325 (if_then_else (match_operator 3 "equality_comparison_operator"
7326 [(match_operand:SI 1 "arith_reg_operand" "r,r")
7327 (match_operand:SI 2 "arith_operand" "r,I06")])
7328 (match_operand 0 "target_operand" "b,b")
7333 b%o3i%' %1, %2, %0%>"
7334 [(set_attr "type" "cbranch_media")])
7336 (define_insn "*bgt_media_i"
7338 (if_then_else (match_operator 3 "greater_comparison_operator"
7339 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7340 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7341 (match_operand 0 "target_operand" "b")
7344 "b%o3%' %N1, %N2, %0%>"
7345 [(set_attr "type" "cbranch_media")])
7347 (define_insn "*bgt_media_i32"
7349 (if_then_else (match_operator 3 "greater_comparison_operator"
7350 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7351 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7352 (match_operand 0 "target_operand" "b")
7355 "b%o3%' %N1, %N2, %0%>"
7356 [(set_attr "type" "cbranch_media")])
7358 ;; These are only needed to make invert_jump() happy - otherwise, jump
7359 ;; optimization will be silently disabled.
7360 (define_insn "*blt_media_i"
7362 (if_then_else (match_operator 3 "less_comparison_operator"
7363 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7364 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7365 (match_operand 0 "target_operand" "b")
7368 "b%o3%' %N2, %N1, %0%>"
7369 [(set_attr "type" "cbranch_media")])
7371 (define_insn "*blt_media_i32"
7373 (if_then_else (match_operator 3 "less_comparison_operator"
7374 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7375 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7376 (match_operand 0 "target_operand" "b")
7379 "b%o3%' %N2, %N1, %0%>"
7380 [(set_attr "type" "cbranch_media")])
7382 ;; combiner splitter for test-and-branch on single bit in register. This
7383 ;; is endian dependent because the non-paradoxical subreg looks different
7388 (match_operator 3 "equality_comparison_operator"
7389 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7390 "extend_reg_operand" "")
7394 "const_int_operand" "")) 0)
7396 (match_operand 0 "target_operand" "")
7398 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7399 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7400 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7401 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7403 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7404 operands[6] = (GET_CODE (operands[3]) == EQ
7405 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7406 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7409 ; operand 0 is the loop count pseudo register
7410 ; operand 1 is the number of loop iterations or 0 if it is unknown
7411 ; operand 2 is the maximum number of loop iterations
7412 ; operand 3 is the number of levels of enclosed loops
7413 ; operand 4 is the label to jump to at the top of the loop
7415 (define_expand "doloop_end"
7416 [(parallel [(set (pc) (if_then_else
7417 (ne:SI (match_operand:SI 0 "" "")
7419 (label_ref (match_operand 4 "" ""))
7422 (plus:SI (match_dup 0) (const_int -1)))
7423 (clobber (reg:SI T_REG))])]
7426 if (GET_MODE (operands[0]) != SImode)
7430 (define_insn_and_split "doloop_end_split"
7432 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7434 (label_ref (match_operand 1 "" ""))
7436 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7437 (plus (match_dup 2) (const_int -1)))
7438 (clobber (reg:SI T_REG))]
7442 [(parallel [(set (reg:SI T_REG)
7443 (eq:SI (match_dup 2) (const_int 1)))
7444 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7445 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7446 (label_ref (match_dup 1))
7449 [(set_attr "type" "cbranch")])
7452 ;; ------------------------------------------------------------------------
7453 ;; Jump and linkage insns
7454 ;; ------------------------------------------------------------------------
7456 (define_insn "jump_compact"
7458 (label_ref (match_operand 0 "" "")))]
7459 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7461 /* The length is 16 if the delay slot is unfilled. */
7462 if (get_attr_length(insn) > 4)
7463 return output_far_jump(insn, operands[0]);
7467 [(set_attr "type" "jump")
7468 (set_attr "needs_delay_slot" "yes")])
7470 ;; ??? It would be much saner to explicitly use the scratch register
7471 ;; in the jump insn, and have indirect_jump_scratch only set it,
7472 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7473 ;; from the target then, as it uses simplejump_p.
7474 ;;(define_insn "jump_compact_far"
7476 ;; (label_ref (match_operand 0 "" "")))
7477 ;; (use (match_operand 1 "register_operand" "r")]
7479 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7480 ;; [(set_attr "type" "jump")
7481 ;; (set_attr "needs_delay_slot" "yes")])
7483 (define_insn "jump_media"
7485 (match_operand 0 "target_operand" "b"))]
7488 [(set_attr "type" "jump_media")])
7490 (define_expand "jump"
7492 (label_ref (match_operand 0 "" "")))]
7496 emit_jump_insn (gen_jump_compact (operands[0]));
7497 else if (TARGET_SHMEDIA)
7499 if (reload_in_progress || reload_completed)
7501 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7507 (define_insn "force_mode_for_call"
7508 [(use (reg:PSI FPSCR_REG))]
7511 [(set_attr "length" "0")
7512 (set (attr "fp_mode")
7513 (if_then_else (eq_attr "fpu_single" "yes")
7514 (const_string "single") (const_string "double")))])
7516 (define_insn "calli"
7517 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7518 (match_operand 1 "" ""))
7519 (use (reg:PSI FPSCR_REG))
7520 (clobber (reg:SI PR_REG))]
7523 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7524 return "jsr/n\\t@%0";
7526 return "jsr\\t@%0%#";
7528 [(set_attr "type" "call")
7529 (set (attr "fp_mode")
7530 (if_then_else (eq_attr "fpu_single" "yes")
7531 (const_string "single") (const_string "double")))
7532 (set_attr "needs_delay_slot" "yes")
7533 (set_attr "fp_set" "unknown")])
7535 ;; This is TBR relative jump instruction for SH2A architecture.
7536 ;; Its use is enabled assigning an attribute "function_vector"
7537 ;; and the vector number to a function during its declaration.
7539 (define_insn "calli_tbr_rel"
7540 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7541 (match_operand 1 "" ""))
7542 (use (reg:PSI FPSCR_REG))
7543 (clobber (reg:SI PR_REG))]
7544 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7546 unsigned HOST_WIDE_INT vect_num;
7547 vect_num = sh2a_get_function_vector_number (operands[0]);
7548 operands[2] = GEN_INT (vect_num * 4);
7550 return "jsr/n\\t@@(%O2,tbr)";
7552 [(set_attr "type" "call")
7553 (set (attr "fp_mode")
7554 (if_then_else (eq_attr "fpu_single" "yes")
7555 (const_string "single") (const_string "double")))
7556 (set_attr "needs_delay_slot" "no")
7557 (set_attr "fp_set" "unknown")])
7559 ;; This is a pc-rel call, using bsrf, for use with PIC.
7561 (define_insn "calli_pcrel"
7562 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7563 (match_operand 1 "" ""))
7564 (use (reg:PSI FPSCR_REG))
7565 (use (reg:SI PIC_REG))
7566 (use (match_operand 2 "" ""))
7567 (clobber (reg:SI PR_REG))]
7570 [(set_attr "type" "call")
7571 (set (attr "fp_mode")
7572 (if_then_else (eq_attr "fpu_single" "yes")
7573 (const_string "single") (const_string "double")))
7574 (set_attr "needs_delay_slot" "yes")
7575 (set_attr "fp_set" "unknown")])
7577 (define_insn_and_split "call_pcrel"
7578 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7579 (match_operand 1 "" ""))
7580 (use (reg:PSI FPSCR_REG))
7581 (use (reg:SI PIC_REG))
7582 (clobber (reg:SI PR_REG))
7583 (clobber (match_scratch:SI 2 "=r"))]
7589 rtx lab = PATTERN (gen_call_site ());
7591 if (SYMBOL_REF_LOCAL_P (operands[0]))
7592 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7594 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7595 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7598 [(set_attr "type" "call")
7599 (set (attr "fp_mode")
7600 (if_then_else (eq_attr "fpu_single" "yes")
7601 (const_string "single") (const_string "double")))
7602 (set_attr "needs_delay_slot" "yes")
7603 (set_attr "fp_set" "unknown")])
7605 (define_insn "call_compact"
7606 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7607 (match_operand 1 "" ""))
7608 (match_operand 2 "immediate_operand" "n")
7609 (use (reg:SI R0_REG))
7610 (use (reg:SI R1_REG))
7611 (use (reg:PSI FPSCR_REG))
7612 (clobber (reg:SI PR_REG))]
7613 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7615 [(set_attr "type" "call")
7616 (set (attr "fp_mode")
7617 (if_then_else (eq_attr "fpu_single" "yes")
7618 (const_string "single") (const_string "double")))
7619 (set_attr "needs_delay_slot" "yes")])
7621 (define_insn "call_compact_rettramp"
7622 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7623 (match_operand 1 "" ""))
7624 (match_operand 2 "immediate_operand" "n")
7625 (use (reg:SI R0_REG))
7626 (use (reg:SI R1_REG))
7627 (use (reg:PSI FPSCR_REG))
7628 (clobber (reg:SI R10_REG))
7629 (clobber (reg:SI PR_REG))]
7630 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7632 [(set_attr "type" "call")
7633 (set (attr "fp_mode")
7634 (if_then_else (eq_attr "fpu_single" "yes")
7635 (const_string "single") (const_string "double")))
7636 (set_attr "needs_delay_slot" "yes")])
7638 (define_insn "call_media"
7639 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7640 (match_operand 1 "" ""))
7641 (clobber (reg:DI PR_MEDIA_REG))]
7644 [(set_attr "type" "jump_media")])
7646 (define_insn "call_valuei"
7647 [(set (match_operand 0 "" "=rf")
7648 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7649 (match_operand 2 "" "")))
7650 (use (reg:PSI FPSCR_REG))
7651 (clobber (reg:SI PR_REG))]
7654 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7655 return "jsr/n\\t@%1";
7657 return "jsr\\t@%1%#";
7659 [(set_attr "type" "call")
7660 (set (attr "fp_mode")
7661 (if_then_else (eq_attr "fpu_single" "yes")
7662 (const_string "single") (const_string "double")))
7663 (set_attr "needs_delay_slot" "yes")
7664 (set_attr "fp_set" "unknown")])
7666 ;; This is TBR relative jump instruction for SH2A architecture.
7667 ;; Its use is enabled by assigning an attribute "function_vector"
7668 ;; and the vector number to a function during its declaration.
7670 (define_insn "call_valuei_tbr_rel"
7671 [(set (match_operand 0 "" "=rf")
7672 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7673 (match_operand 2 "" "")))
7674 (use (reg:PSI FPSCR_REG))
7675 (clobber (reg:SI PR_REG))]
7676 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7678 unsigned HOST_WIDE_INT vect_num;
7679 vect_num = sh2a_get_function_vector_number (operands[1]);
7680 operands[3] = GEN_INT (vect_num * 4);
7682 return "jsr/n\\t@@(%O3,tbr)";
7684 [(set_attr "type" "call")
7685 (set (attr "fp_mode")
7686 (if_then_else (eq_attr "fpu_single" "yes")
7687 (const_string "single") (const_string "double")))
7688 (set_attr "needs_delay_slot" "no")
7689 (set_attr "fp_set" "unknown")])
7691 (define_insn "call_valuei_pcrel"
7692 [(set (match_operand 0 "" "=rf")
7693 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7694 (match_operand 2 "" "")))
7695 (use (reg:PSI FPSCR_REG))
7696 (use (reg:SI PIC_REG))
7697 (use (match_operand 3 "" ""))
7698 (clobber (reg:SI PR_REG))]
7701 [(set_attr "type" "call")
7702 (set (attr "fp_mode")
7703 (if_then_else (eq_attr "fpu_single" "yes")
7704 (const_string "single") (const_string "double")))
7705 (set_attr "needs_delay_slot" "yes")
7706 (set_attr "fp_set" "unknown")])
7708 (define_insn_and_split "call_value_pcrel"
7709 [(set (match_operand 0 "" "=rf")
7710 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7711 (match_operand 2 "" "")))
7712 (use (reg:PSI FPSCR_REG))
7713 (use (reg:SI PIC_REG))
7714 (clobber (reg:SI PR_REG))
7715 (clobber (match_scratch:SI 3 "=r"))]
7721 rtx lab = PATTERN (gen_call_site ());
7723 if (SYMBOL_REF_LOCAL_P (operands[1]))
7724 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7726 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7727 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7728 operands[2], copy_rtx (lab)));
7731 [(set_attr "type" "call")
7732 (set (attr "fp_mode")
7733 (if_then_else (eq_attr "fpu_single" "yes")
7734 (const_string "single") (const_string "double")))
7735 (set_attr "needs_delay_slot" "yes")
7736 (set_attr "fp_set" "unknown")])
7738 (define_insn "call_value_compact"
7739 [(set (match_operand 0 "" "=rf")
7740 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7741 (match_operand 2 "" "")))
7742 (match_operand 3 "immediate_operand" "n")
7743 (use (reg:SI R0_REG))
7744 (use (reg:SI R1_REG))
7745 (use (reg:PSI FPSCR_REG))
7746 (clobber (reg:SI PR_REG))]
7747 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7749 [(set_attr "type" "call")
7750 (set (attr "fp_mode")
7751 (if_then_else (eq_attr "fpu_single" "yes")
7752 (const_string "single") (const_string "double")))
7753 (set_attr "needs_delay_slot" "yes")])
7755 (define_insn "call_value_compact_rettramp"
7756 [(set (match_operand 0 "" "=rf")
7757 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7758 (match_operand 2 "" "")))
7759 (match_operand 3 "immediate_operand" "n")
7760 (use (reg:SI R0_REG))
7761 (use (reg:SI R1_REG))
7762 (use (reg:PSI FPSCR_REG))
7763 (clobber (reg:SI R10_REG))
7764 (clobber (reg:SI PR_REG))]
7765 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7767 [(set_attr "type" "call")
7768 (set (attr "fp_mode")
7769 (if_then_else (eq_attr "fpu_single" "yes")
7770 (const_string "single") (const_string "double")))
7771 (set_attr "needs_delay_slot" "yes")])
7773 (define_insn "call_value_media"
7774 [(set (match_operand 0 "" "=rf")
7775 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7776 (match_operand 2 "" "")))
7777 (clobber (reg:DI PR_MEDIA_REG))]
7780 [(set_attr "type" "jump_media")])
7782 (define_expand "call"
7783 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7784 (match_operand 1 "" ""))
7785 (match_operand 2 "" "")
7786 (use (reg:PSI FPSCR_REG))
7787 (clobber (reg:SI PR_REG))])]
7792 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7793 emit_call_insn (gen_call_media (operands[0], operands[1]));
7796 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7798 rtx cookie_rtx = operands[2];
7799 long cookie = INTVAL (cookie_rtx);
7800 rtx func = XEXP (operands[0], 0);
7805 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7807 rtx reg = gen_reg_rtx (Pmode);
7809 emit_insn (gen_symGOTPLT2reg (reg, func));
7813 func = legitimize_pic_address (func, Pmode, 0);
7816 r0 = gen_rtx_REG (SImode, R0_REG);
7817 r1 = gen_rtx_REG (SImode, R1_REG);
7819 /* Since such a call function may use all call-clobbered
7820 registers, we force a mode switch earlier, so that we don't
7821 run out of registers when adjusting fpscr for the call. */
7822 emit_insn (gen_force_mode_for_call ());
7825 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
7826 operands[0] = force_reg (SImode, operands[0]);
7828 emit_move_insn (r0, func);
7829 emit_move_insn (r1, cookie_rtx);
7831 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7832 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7835 emit_call_insn (gen_call_compact (operands[0], operands[1],
7840 else if (TARGET_SHCOMPACT && flag_pic
7841 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7842 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7844 rtx reg = gen_reg_rtx (Pmode);
7846 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7847 XEXP (operands[0], 0) = reg;
7849 if (!flag_pic && TARGET_SH2A
7850 && MEM_P (operands[0])
7851 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7853 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7855 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7860 if (flag_pic && TARGET_SH2
7861 && MEM_P (operands[0])
7862 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7864 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7869 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7870 operands[1] = operands[2];
7873 emit_call_insn (gen_calli (operands[0], operands[1]));
7877 (define_insn "call_pop_compact"
7878 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7879 (match_operand 1 "" ""))
7880 (match_operand 2 "immediate_operand" "n")
7881 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7882 (match_operand 3 "immediate_operand" "n")))
7883 (use (reg:SI R0_REG))
7884 (use (reg:SI R1_REG))
7885 (use (reg:PSI FPSCR_REG))
7886 (clobber (reg:SI PR_REG))]
7887 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7889 [(set_attr "type" "call")
7890 (set (attr "fp_mode")
7891 (if_then_else (eq_attr "fpu_single" "yes")
7892 (const_string "single") (const_string "double")))
7893 (set_attr "needs_delay_slot" "yes")])
7895 (define_insn "call_pop_compact_rettramp"
7896 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7897 (match_operand 1 "" ""))
7898 (match_operand 2 "immediate_operand" "n")
7899 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7900 (match_operand 3 "immediate_operand" "n")))
7901 (use (reg:SI R0_REG))
7902 (use (reg:SI R1_REG))
7903 (use (reg:PSI FPSCR_REG))
7904 (clobber (reg:SI R10_REG))
7905 (clobber (reg:SI PR_REG))]
7906 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7908 [(set_attr "type" "call")
7909 (set (attr "fp_mode")
7910 (if_then_else (eq_attr "fpu_single" "yes")
7911 (const_string "single") (const_string "double")))
7912 (set_attr "needs_delay_slot" "yes")])
7914 (define_expand "call_pop"
7915 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7916 (match_operand 1 "" ""))
7917 (match_operand 2 "" "")
7918 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7919 (match_operand 3 "" "")))])]
7927 gcc_assert (operands[2] && INTVAL (operands[2]));
7928 cookie_rtx = operands[2];
7929 cookie = INTVAL (cookie_rtx);
7930 func = XEXP (operands[0], 0);
7934 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7936 rtx reg = gen_reg_rtx (Pmode);
7937 emit_insn (gen_symGOTPLT2reg (reg, func));
7941 func = legitimize_pic_address (func, Pmode, 0);
7944 r0 = gen_rtx_REG (SImode, R0_REG);
7945 r1 = gen_rtx_REG (SImode, R1_REG);
7947 /* Since such a call function may use all call-clobbered
7948 registers, we force a mode switch earlier, so that we don't
7949 run out of registers when adjusting fpscr for the call. */
7950 emit_insn (gen_force_mode_for_call ());
7952 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
7954 operands[0] = force_reg (SImode, operands[0]);
7956 emit_move_insn (r0, func);
7957 emit_move_insn (r1, cookie_rtx);
7959 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7960 emit_call_insn (gen_call_pop_compact_rettramp
7961 (operands[0], operands[1], operands[2], operands[3]));
7963 emit_call_insn (gen_call_pop_compact
7964 (operands[0], operands[1], operands[2], operands[3]));
7969 (define_expand "call_value"
7970 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7971 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7972 (match_operand 2 "" "")))
7973 (match_operand 3 "" "")
7974 (use (reg:PSI FPSCR_REG))
7975 (clobber (reg:SI PR_REG))])]
7980 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7981 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7985 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7987 rtx cookie_rtx = operands[3];
7988 long cookie = INTVAL (cookie_rtx);
7989 rtx func = XEXP (operands[1], 0);
7994 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7996 rtx reg = gen_reg_rtx (Pmode);
7998 emit_insn (gen_symGOTPLT2reg (reg, func));
8002 func = legitimize_pic_address (func, Pmode, 0);
8005 r0 = gen_rtx_REG (SImode, R0_REG);
8006 r1 = gen_rtx_REG (SImode, R1_REG);
8008 /* Since such a call function may use all call-clobbered
8009 registers, we force a mode switch earlier, so that we don't
8010 run out of registers when adjusting fpscr for the call. */
8011 emit_insn (gen_force_mode_for_call ());
8014 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8015 operands[1] = force_reg (SImode, operands[1]);
8017 emit_move_insn (r0, func);
8018 emit_move_insn (r1, cookie_rtx);
8020 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8021 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
8026 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
8027 operands[2], operands[3]));
8031 else if (TARGET_SHCOMPACT && flag_pic
8032 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8033 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8035 rtx reg = gen_reg_rtx (Pmode);
8037 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
8038 XEXP (operands[1], 0) = reg;
8040 if (!flag_pic && TARGET_SH2A
8041 && MEM_P (operands[1])
8042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8044 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
8046 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
8047 XEXP (operands[1], 0), operands[2]));
8051 if (flag_pic && TARGET_SH2
8052 && MEM_P (operands[1])
8053 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8055 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
8060 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8062 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
8066 (define_insn "sibcalli"
8067 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
8068 (match_operand 1 "" ""))
8069 (use (reg:PSI FPSCR_REG))
8073 [(set_attr "needs_delay_slot" "yes")
8074 (set (attr "fp_mode")
8075 (if_then_else (eq_attr "fpu_single" "yes")
8076 (const_string "single") (const_string "double")))
8077 (set_attr "type" "jump_ind")])
8079 (define_insn "sibcalli_pcrel"
8080 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
8081 (match_operand 1 "" ""))
8082 (use (match_operand 2 "" ""))
8083 (use (reg:PSI FPSCR_REG))
8087 [(set_attr "needs_delay_slot" "yes")
8088 (set (attr "fp_mode")
8089 (if_then_else (eq_attr "fpu_single" "yes")
8090 (const_string "single") (const_string "double")))
8091 (set_attr "type" "jump_ind")])
8093 ;; This uses an unspec to describe that the symbol_ref is very close.
8094 (define_insn "sibcalli_thunk"
8095 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
8097 (match_operand 1 "" ""))
8098 (use (reg:PSI FPSCR_REG))
8102 [(set_attr "needs_delay_slot" "yes")
8103 (set (attr "fp_mode")
8104 (if_then_else (eq_attr "fpu_single" "yes")
8105 (const_string "single") (const_string "double")))
8106 (set_attr "type" "jump")
8107 (set_attr "length" "2")])
8109 (define_insn_and_split "sibcall_pcrel"
8110 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8111 (match_operand 1 "" ""))
8112 (use (reg:PSI FPSCR_REG))
8113 (clobber (match_scratch:SI 2 "=k"))
8120 rtx lab = PATTERN (gen_call_site ());
8123 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8124 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
8126 SIBLING_CALL_P (call_insn) = 1;
8129 [(set_attr "needs_delay_slot" "yes")
8130 (set (attr "fp_mode")
8131 (if_then_else (eq_attr "fpu_single" "yes")
8132 (const_string "single") (const_string "double")))
8133 (set_attr "type" "jump_ind")])
8135 (define_insn "sibcall_compact"
8136 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8137 (match_operand 1 "" ""))
8139 (use (match_operand:SI 2 "register_operand" "z,x"))
8140 (use (reg:SI R1_REG))
8141 (use (reg:PSI FPSCR_REG))
8142 ;; We want to make sure the `x' above will only match MACH_REG
8143 ;; because sibcall_epilogue may clobber MACL_REG.
8144 (clobber (reg:SI MACL_REG))]
8148 jmp @%0\\n sts %2, r0"
8149 [(set_attr "needs_delay_slot" "yes,no")
8150 (set_attr "length" "2,4")
8151 (set (attr "fp_mode") (const_string "single"))
8152 (set_attr "type" "jump_ind")])
8154 (define_insn "sibcall_media"
8155 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8156 (match_operand 1 "" ""))
8157 (use (reg:SI PR_MEDIA_REG))
8161 [(set_attr "type" "jump_media")])
8163 (define_expand "sibcall"
8165 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8166 (match_operand 1 "" ""))
8167 (match_operand 2 "" "")
8168 (use (reg:PSI FPSCR_REG))
8174 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8175 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8178 else if (TARGET_SHCOMPACT && operands[2]
8179 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8181 rtx cookie_rtx = operands[2];
8182 long cookie = INTVAL (cookie_rtx);
8183 rtx func = XEXP (operands[0], 0);
8188 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8190 rtx reg = gen_reg_rtx (Pmode);
8192 emit_insn (gen_symGOT2reg (reg, func));
8196 func = legitimize_pic_address (func, Pmode, 0);
8199 /* FIXME: if we could tell whether all argument registers are
8200 already taken, we could decide whether to force the use of
8201 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8202 simple way to tell. We could use the CALL_COOKIE, but we
8203 can't currently tell a register used for regular argument
8204 passing from one that is unused. If we leave it up to reload
8205 to decide which register to use, it seems to always choose
8206 R0_REG, which leaves no available registers in SIBCALL_REGS
8207 to hold the address of the trampoline. */
8208 mach = gen_rtx_REG (SImode, MACH_REG);
8209 r1 = gen_rtx_REG (SImode, R1_REG);
8211 /* Since such a call function may use all call-clobbered
8212 registers, we force a mode switch earlier, so that we don't
8213 run out of registers when adjusting fpscr for the call. */
8214 emit_insn (gen_force_mode_for_call ());
8217 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8218 operands[0] = force_reg (SImode, operands[0]);
8220 /* We don't need a return trampoline, since the callee will
8221 return directly to the upper caller. */
8222 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8224 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8225 cookie_rtx = GEN_INT (cookie);
8228 emit_move_insn (mach, func);
8229 emit_move_insn (r1, cookie_rtx);
8231 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8234 else if (TARGET_SHCOMPACT && flag_pic
8235 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8236 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8238 rtx reg = gen_reg_rtx (Pmode);
8240 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8241 XEXP (operands[0], 0) = reg;
8243 if (flag_pic && TARGET_SH2
8244 && MEM_P (operands[0])
8245 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8246 /* The PLT needs the PIC register, but the epilogue would have
8247 to restore it, so we can only use PC-relative PIC calls for
8248 static functions. */
8249 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8251 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8255 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8257 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8261 (define_insn "sibcall_valuei"
8262 [(set (match_operand 0 "" "=rf")
8263 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8264 (match_operand 2 "" "")))
8265 (use (reg:PSI FPSCR_REG))
8269 [(set_attr "needs_delay_slot" "yes")
8270 (set (attr "fp_mode")
8271 (if_then_else (eq_attr "fpu_single" "yes")
8272 (const_string "single") (const_string "double")))
8273 (set_attr "type" "jump_ind")])
8275 (define_insn "sibcall_valuei_pcrel"
8276 [(set (match_operand 0 "" "=rf")
8277 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8278 (match_operand 2 "" "")))
8279 (use (match_operand 3 "" ""))
8280 (use (reg:PSI FPSCR_REG))
8284 [(set_attr "needs_delay_slot" "yes")
8285 (set (attr "fp_mode")
8286 (if_then_else (eq_attr "fpu_single" "yes")
8287 (const_string "single") (const_string "double")))
8288 (set_attr "type" "jump_ind")])
8290 (define_insn_and_split "sibcall_value_pcrel"
8291 [(set (match_operand 0 "" "=rf")
8292 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8293 (match_operand 2 "" "")))
8294 (use (reg:PSI FPSCR_REG))
8295 (clobber (match_scratch:SI 3 "=k"))
8302 rtx lab = PATTERN (gen_call_site ());
8305 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8306 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8310 SIBLING_CALL_P (call_insn) = 1;
8313 [(set_attr "needs_delay_slot" "yes")
8314 (set (attr "fp_mode")
8315 (if_then_else (eq_attr "fpu_single" "yes")
8316 (const_string "single") (const_string "double")))
8317 (set_attr "type" "jump_ind")])
8319 (define_insn "sibcall_value_compact"
8320 [(set (match_operand 0 "" "=rf,rf")
8321 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8322 (match_operand 2 "" "")))
8324 (use (match_operand:SI 3 "register_operand" "z,x"))
8325 (use (reg:SI R1_REG))
8326 (use (reg:PSI FPSCR_REG))
8327 ;; We want to make sure the `x' above will only match MACH_REG
8328 ;; because sibcall_epilogue may clobber MACL_REG.
8329 (clobber (reg:SI MACL_REG))]
8333 jmp @%1\\n sts %3, r0"
8334 [(set_attr "needs_delay_slot" "yes,no")
8335 (set_attr "length" "2,4")
8336 (set (attr "fp_mode") (const_string "single"))
8337 (set_attr "type" "jump_ind")])
8339 (define_insn "sibcall_value_media"
8340 [(set (match_operand 0 "" "=rf")
8341 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8342 (match_operand 2 "" "")))
8343 (use (reg:SI PR_MEDIA_REG))
8347 [(set_attr "type" "jump_media")])
8349 (define_expand "sibcall_value"
8351 [(set (match_operand 0 "arith_reg_operand" "")
8352 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8353 (match_operand 2 "" "")))
8354 (match_operand 3 "" "")
8355 (use (reg:PSI FPSCR_REG))
8361 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8362 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8366 else if (TARGET_SHCOMPACT && operands[3]
8367 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8369 rtx cookie_rtx = operands[3];
8370 long cookie = INTVAL (cookie_rtx);
8371 rtx func = XEXP (operands[1], 0);
8376 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8378 rtx reg = gen_reg_rtx (Pmode);
8380 emit_insn (gen_symGOT2reg (reg, func));
8384 func = legitimize_pic_address (func, Pmode, 0);
8387 /* FIXME: if we could tell whether all argument registers are
8388 already taken, we could decide whether to force the use of
8389 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8390 simple way to tell. We could use the CALL_COOKIE, but we
8391 can't currently tell a register used for regular argument
8392 passing from one that is unused. If we leave it up to reload
8393 to decide which register to use, it seems to always choose
8394 R0_REG, which leaves no available registers in SIBCALL_REGS
8395 to hold the address of the trampoline. */
8396 mach = gen_rtx_REG (SImode, MACH_REG);
8397 r1 = gen_rtx_REG (SImode, R1_REG);
8399 /* Since such a call function may use all call-clobbered
8400 registers, we force a mode switch earlier, so that we don't
8401 run out of registers when adjusting fpscr for the call. */
8402 emit_insn (gen_force_mode_for_call ());
8405 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8406 operands[1] = force_reg (SImode, operands[1]);
8408 /* We don't need a return trampoline, since the callee will
8409 return directly to the upper caller. */
8410 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8412 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8413 cookie_rtx = GEN_INT (cookie);
8416 emit_move_insn (mach, func);
8417 emit_move_insn (r1, cookie_rtx);
8419 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8420 operands[2], mach));
8423 else if (TARGET_SHCOMPACT && flag_pic
8424 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8425 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8427 rtx reg = gen_reg_rtx (Pmode);
8429 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8430 XEXP (operands[1], 0) = reg;
8432 if (flag_pic && TARGET_SH2
8433 && MEM_P (operands[1])
8434 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8435 /* The PLT needs the PIC register, but the epilogue would have
8436 to restore it, so we can only use PC-relative PIC calls for
8437 static functions. */
8438 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8440 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8441 XEXP (operands[1], 0),
8446 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8448 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8452 (define_insn "call_value_pop_compact"
8453 [(set (match_operand 0 "" "=rf")
8454 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8455 (match_operand 2 "" "")))
8456 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8457 (match_operand 4 "immediate_operand" "n")))
8458 (match_operand 3 "immediate_operand" "n")
8459 (use (reg:SI R0_REG))
8460 (use (reg:SI R1_REG))
8461 (use (reg:PSI FPSCR_REG))
8462 (clobber (reg:SI PR_REG))]
8463 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8465 [(set_attr "type" "call")
8466 (set (attr "fp_mode")
8467 (if_then_else (eq_attr "fpu_single" "yes")
8468 (const_string "single") (const_string "double")))
8469 (set_attr "needs_delay_slot" "yes")])
8471 (define_insn "call_value_pop_compact_rettramp"
8472 [(set (match_operand 0 "" "=rf")
8473 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8474 (match_operand 2 "" "")))
8475 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8476 (match_operand 4 "immediate_operand" "n")))
8477 (match_operand 3 "immediate_operand" "n")
8478 (use (reg:SI R0_REG))
8479 (use (reg:SI R1_REG))
8480 (use (reg:PSI FPSCR_REG))
8481 (clobber (reg:SI R10_REG))
8482 (clobber (reg:SI PR_REG))]
8483 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8485 [(set_attr "type" "call")
8486 (set (attr "fp_mode")
8487 (if_then_else (eq_attr "fpu_single" "yes")
8488 (const_string "single") (const_string "double")))
8489 (set_attr "needs_delay_slot" "yes")])
8491 (define_expand "call_value_pop"
8492 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8493 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8494 (match_operand 2 "" "")))
8495 (match_operand 3 "" "")
8496 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8497 (match_operand 4 "" "")))])]
8505 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8506 cookie_rtx = operands[3];
8507 cookie = INTVAL (cookie_rtx);
8508 func = XEXP (operands[1], 0);
8512 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8514 rtx reg = gen_reg_rtx (Pmode);
8516 emit_insn (gen_symGOTPLT2reg (reg, func));
8520 func = legitimize_pic_address (func, Pmode, 0);
8523 r0 = gen_rtx_REG (SImode, R0_REG);
8524 r1 = gen_rtx_REG (SImode, R1_REG);
8526 /* Since such a call function may use all call-clobbered
8527 registers, we force a mode switch earlier, so that we don't
8528 run out of registers when adjusting fpscr for the call. */
8529 emit_insn (gen_force_mode_for_call ());
8531 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
8533 operands[1] = force_reg (SImode, operands[1]);
8535 emit_move_insn (r0, func);
8536 emit_move_insn (r1, cookie_rtx);
8538 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8539 emit_call_insn (gen_call_value_pop_compact_rettramp
8540 (operands[0], operands[1], operands[2],
8541 operands[3], operands[4]));
8543 emit_call_insn (gen_call_value_pop_compact
8544 (operands[0], operands[1], operands[2],
8545 operands[3], operands[4]));
8550 (define_expand "sibcall_epilogue"
8554 sh_expand_epilogue (1);
8555 if (TARGET_SHCOMPACT)
8559 /* If epilogue clobbers r0, preserve it in macl. */
8560 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8561 if ((set = single_set (insn))
8562 && REG_P (SET_DEST (set))
8563 && REGNO (SET_DEST (set)) == R0_REG)
8565 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8566 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8568 /* We can't tell at this point whether the sibcall is a
8569 sibcall_compact and, if it is, whether it uses r0 or
8570 mach as operand 2, so let the instructions that
8571 preserve r0 be optimized away if r0 turns out to be
8573 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8574 emit_move_insn (r0, tmp);
8581 (define_insn "indirect_jump_compact"
8583 (match_operand:SI 0 "arith_reg_operand" "r"))]
8586 [(set_attr "needs_delay_slot" "yes")
8587 (set_attr "type" "jump_ind")])
8589 (define_expand "indirect_jump"
8591 (match_operand 0 "register_operand" ""))]
8594 if (GET_MODE (operands[0]) != Pmode)
8595 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8598 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8599 ;; which can be present in structured code from indirect jumps which can not
8600 ;; be present in structured code. This allows -fprofile-arcs to work.
8602 ;; For SH1 processors.
8603 (define_insn "casesi_jump_1"
8605 (match_operand:SI 0 "register_operand" "r"))
8606 (use (label_ref (match_operand 1 "" "")))]
8609 [(set_attr "needs_delay_slot" "yes")
8610 (set_attr "type" "jump_ind")])
8612 ;; For all later processors.
8613 (define_insn "casesi_jump_2"
8614 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8615 (label_ref (match_operand 1 "" ""))))
8616 (use (label_ref (match_operand 2 "" "")))]
8618 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8620 [(set_attr "needs_delay_slot" "yes")
8621 (set_attr "type" "jump_ind")])
8623 (define_insn "casesi_jump_media"
8624 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8625 (use (label_ref (match_operand 1 "" "")))]
8628 [(set_attr "type" "jump_media")])
8630 ;; Call subroutine returning any type.
8631 ;; ??? This probably doesn't work.
8633 (define_expand "untyped_call"
8634 [(parallel [(call (match_operand 0 "" "")
8636 (match_operand 1 "" "")
8637 (match_operand 2 "" "")])]
8638 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8642 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8644 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8646 rtx set = XVECEXP (operands[2], 0, i);
8647 emit_move_insn (SET_DEST (set), SET_SRC (set));
8650 /* The optimizer does not know that the call sets the function value
8651 registers we stored in the result block. We avoid problems by
8652 claiming that all hard registers are used and clobbered at this
8654 emit_insn (gen_blockage ());
8659 ;; ------------------------------------------------------------------------
8661 ;; ------------------------------------------------------------------------
8664 [(set (reg:SI T_REG)
8665 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8666 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8667 (plus:SI (match_dup 1) (const_int -1)))]
8670 [(set_attr "type" "arith")])
8677 ;; Load address of a label. This is only generated by the casesi expand,
8678 ;; and by machine_dependent_reorg (fixing up fp moves).
8679 ;; This must use unspec, because this only works for labels that are
8683 [(set (reg:SI R0_REG)
8684 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8687 [(set_attr "in_delay_slot" "no")
8688 (set_attr "type" "arith")])
8690 ;; machine_dependent_reorg will make this a `mova'.
8691 (define_insn "mova_const"
8692 [(set (reg:SI R0_REG)
8693 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8696 [(set_attr "in_delay_slot" "no")
8697 (set_attr "type" "arith")])
8699 (define_expand "GOTaddr2picreg"
8700 [(set (reg:SI R0_REG)
8701 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8703 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8704 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8707 if (TARGET_VXWORKS_RTP)
8709 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8710 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8711 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8715 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8716 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8720 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8721 rtx pic = operands[0];
8722 rtx lab = PATTERN (gen_call_site ());
8725 equiv = operands[1];
8726 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8727 UNSPEC_PCREL_SYMOFF);
8728 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8730 if (Pmode == SImode)
8732 emit_insn (gen_movsi_const (pic, operands[1]));
8733 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8737 emit_insn (gen_movdi_const (pic, operands[1]));
8738 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8741 insn = emit_move_insn (operands[0], tr);
8743 set_unique_reg_note (insn, REG_EQUAL, equiv);
8749 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8752 (define_expand "vxworks_picreg"
8753 [(set (reg:SI PIC_REG)
8754 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8755 (set (reg:SI R0_REG)
8756 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8757 (set (reg:SI PIC_REG)
8758 (mem:SI (reg:SI PIC_REG)))
8759 (set (reg:SI PIC_REG)
8760 (mem:SI (plus:SI (reg:SI PIC_REG)
8762 "TARGET_VXWORKS_RTP")
8765 [(set (match_operand 0 "target_reg_operand" "=b")
8766 (const (unspec [(match_operand 1 "" "Csy")]
8767 UNSPEC_DATALABEL)))]
8768 "TARGET_SHMEDIA && flag_pic
8769 && satisfies_constraint_Csy (operands[1])"
8770 "ptb/u datalabel %1, %0"
8771 [(set_attr "type" "ptabs_media")
8772 (set_attr "length" "*")])
8774 (define_insn "ptrel_si"
8775 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8776 (plus:SI (match_operand:SI 1 "register_operand" "r")
8778 (match_operand:SI 2 "" "")]
8780 "%O2: ptrel/u %1, %0"
8781 [(set_attr "type" "ptabs_media")])
8783 (define_insn "ptrel_di"
8784 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8785 (plus:DI (match_operand:DI 1 "register_operand" "r")
8787 (match_operand:DI 2 "" "")]
8789 "%O2: ptrel/u %1, %0"
8790 [(set_attr "type" "ptabs_media")])
8792 (define_expand "builtin_setjmp_receiver"
8793 [(match_operand 0 "" "")]
8796 emit_insn (gen_GOTaddr2picreg ());
8800 (define_expand "call_site"
8801 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8804 static HOST_WIDE_INT i = 0;
8805 operands[0] = GEN_INT (i);
8809 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8810 ;; in symGOT_load expand.
8812 (define_insn_and_split "chk_guard_add"
8813 [(set (match_operand:SI 0 "register_operand" "=&r")
8814 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8819 "TARGET_SH1 && reload_completed"
8820 [(set (match_dup 0) (reg:SI PIC_REG))
8821 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8823 [(set_attr "type" "arith")])
8825 (define_expand "sym_label2reg"
8826 [(set (match_operand:SI 0 "" "")
8827 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8828 (const (plus:SI (match_operand:SI 2 "" "")
8833 (define_expand "symGOT_load"
8834 [(set (match_dup 2) (match_operand 1 "" ""))
8835 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8836 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8841 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8842 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8846 rtx reg = operands[2];
8848 if (Pmode == DImode)
8851 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8853 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8858 emit_insn (gen_movsi_const (reg, operands[1]));
8860 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8864 emit_move_insn (operands[2], operands[1]);
8866 /* When stack protector inserts codes after the result is set to
8867 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8868 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8869 when rX is a GOT address for the guard symbol. Ugly but doesn't
8870 matter because this is a rare situation. */
8872 && flag_stack_protect
8873 && GET_CODE (operands[1]) == CONST
8874 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8875 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8876 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8877 "__stack_chk_guard") == 0)
8878 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8880 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8881 gen_rtx_REG (Pmode, PIC_REG)));
8883 /* N.B. This is not constant for a GOTPLT relocation. */
8884 mem = gen_rtx_MEM (Pmode, operands[3]);
8885 MEM_NOTRAP_P (mem) = 1;
8886 /* ??? Should we have a special alias set for the GOT? */
8887 emit_move_insn (operands[0], mem);
8892 (define_expand "sym2GOT"
8893 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8897 (define_expand "symGOT2reg"
8898 [(match_operand 0 "" "") (match_operand 1 "" "")]
8903 gotsym = gen_sym2GOT (operands[1]);
8904 PUT_MODE (gotsym, Pmode);
8905 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8907 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8912 (define_expand "symGOTPLT2reg"
8913 [(match_operand 0 "" "") (match_operand 1 "" "")]
8916 rtx pltsym = gen_rtx_CONST (Pmode,
8917 gen_rtx_UNSPEC (Pmode,
8918 gen_rtvec (1, operands[1]),
8920 emit_insn (gen_symGOT_load (operands[0], pltsym));
8924 (define_expand "sym2GOTOFF"
8925 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8929 (define_expand "symGOTOFF2reg"
8930 [(match_operand 0 "" "") (match_operand 1 "" "")]
8933 rtx gotoffsym, insn;
8934 rtx t = (!can_create_pseudo_p ()
8936 : gen_reg_rtx (GET_MODE (operands[0])));
8938 gotoffsym = gen_sym2GOTOFF (operands[1]);
8939 PUT_MODE (gotoffsym, Pmode);
8940 emit_move_insn (t, gotoffsym);
8941 insn = emit_move_insn (operands[0],
8942 gen_rtx_PLUS (Pmode, t,
8943 gen_rtx_REG (Pmode, PIC_REG)));
8945 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8950 (define_expand "symPLT_label2reg"
8951 [(set (match_operand:SI 0 "" "")
8954 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8955 (const:SI (plus:SI (match_operand:SI 2 "" "")
8956 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8957 ;; Even though the PIC register is not really used by the call
8958 ;; sequence in which this is expanded, the PLT code assumes the PIC
8959 ;; register is set, so we must not skip its initialization. Since
8960 ;; we only use this expand as part of calling sequences, and never
8961 ;; to take the address of a function, this is the best point to
8962 ;; insert the (use). Using the PLT to take the address of a
8963 ;; function would be wrong, not only because the PLT entry could
8964 ;; then be called from a function that doesn't initialize the PIC
8965 ;; register to the proper GOT, but also because pointers to the
8966 ;; same function might not compare equal, should they be set by
8967 ;; different shared libraries.
8968 (use (reg:SI PIC_REG))]
8972 (define_expand "sym2PIC"
8973 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8977 ;; TLS code generation.
8978 ;; ??? this should be a define_insn_and_split
8979 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8980 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8983 (define_insn "tls_global_dynamic"
8984 [(set (match_operand:SI 0 "register_operand" "=&z")
8985 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8988 (use (reg:PSI FPSCR_REG))
8989 (use (reg:SI PIC_REG))
8990 (clobber (reg:SI PR_REG))
8991 (clobber (scratch:SI))]
8994 return "mov.l 1f,r4" "\n"
9003 "1: .long %a1@TLSGD" "\n"
9004 "2: .long __tls_get_addr@PLT" "\n"
9007 [(set_attr "type" "tls_load")
9008 (set_attr "length" "26")])
9010 (define_insn "tls_local_dynamic"
9011 [(set (match_operand:SI 0 "register_operand" "=&z")
9012 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
9015 (use (reg:PSI FPSCR_REG))
9016 (use (reg:SI PIC_REG))
9017 (clobber (reg:SI PR_REG))
9018 (clobber (scratch:SI))]
9021 return "mov.l 1f,r4" "\n"
9030 "1: .long %a1@TLSLDM" "\n"
9031 "2: .long __tls_get_addr@PLT" "\n"
9034 [(set_attr "type" "tls_load")
9035 (set_attr "length" "26")])
9037 (define_expand "sym2DTPOFF"
9038 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
9042 (define_expand "symDTPOFF2reg"
9043 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
9047 rtx t = (!can_create_pseudo_p ()
9049 : gen_reg_rtx (GET_MODE (operands[0])));
9051 dtpoffsym = gen_sym2DTPOFF (operands[1]);
9052 PUT_MODE (dtpoffsym, Pmode);
9053 emit_move_insn (t, dtpoffsym);
9054 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
9058 (define_expand "sym2GOTTPOFF"
9059 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
9063 (define_insn "tls_initial_exec"
9064 [(set (match_operand:SI 0 "register_operand" "=&r")
9065 (unspec:SI [(match_operand:SI 1 "" "")]
9067 (use (reg:SI GBR_REG))
9068 (use (reg:SI PIC_REG))
9069 (clobber (reg:SI R0_REG))]
9072 return "mov.l 1f,r0" "\n"
9074 " mov.l @(r0,r12),r0" "\n"
9081 [(set_attr "type" "tls_load")
9082 (set_attr "length" "16")])
9084 (define_expand "sym2TPOFF"
9085 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
9089 (define_expand "symTPOFF2reg"
9090 [(match_operand 0 "" "") (match_operand 1 "" "")]
9095 tpoffsym = gen_sym2TPOFF (operands[1]);
9096 PUT_MODE (tpoffsym, Pmode);
9097 emit_move_insn (operands[0], tpoffsym);
9101 (define_insn "load_gbr"
9102 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
9103 (use (reg:SI GBR_REG))]
9106 [(set_attr "type" "tls_load")])
9108 ;; case instruction for switch statements.
9110 ;; Operand 0 is index
9111 ;; operand 1 is the minimum bound
9112 ;; operand 2 is the maximum bound - minimum bound + 1
9113 ;; operand 3 is CODE_LABEL for the table;
9114 ;; operand 4 is the CODE_LABEL to go to if index out of range.
9116 (define_expand "casesi"
9117 [(match_operand:SI 0 "arith_reg_operand" "")
9118 (match_operand:SI 1 "arith_reg_operand" "")
9119 (match_operand:SI 2 "arith_reg_operand" "")
9120 (match_operand 3 "" "") (match_operand 4 "" "")]
9123 rtx reg = gen_reg_rtx (SImode);
9124 rtx reg2 = gen_reg_rtx (SImode);
9127 rtx reg = gen_reg_rtx (DImode);
9128 rtx reg2 = gen_reg_rtx (DImode);
9129 rtx reg3 = gen_reg_rtx (Pmode);
9130 rtx reg4 = gen_reg_rtx (Pmode);
9131 rtx reg5 = gen_reg_rtx (Pmode);
9134 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9135 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9136 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9138 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
9139 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
9140 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9141 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
9142 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
9143 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9144 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9145 (Pmode, operands[3])));
9146 /* Messy: can we subreg to clean this up? */
9147 if (Pmode == DImode)
9148 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9150 load = gen_casesi_load_media (reg4,
9151 gen_rtx_SUBREG (DImode, reg3, 0),
9153 PUT_MODE (SET_SRC (load), Pmode);
9155 /* ??? The following add could be eliminated if we used ptrel. */
9156 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9157 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9161 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9162 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9163 /* If optimizing, casesi_worker depends on the mode of the instruction
9164 before label it 'uses' - operands[3]. */
9165 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9167 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9169 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9171 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9172 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9173 operands[3], but to lab. We will fix this up in
9174 machine_dependent_reorg. */
9179 (define_expand "casesi_0"
9180 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9181 (set (match_dup 4) (minus:SI (match_dup 4)
9182 (match_operand:SI 1 "arith_operand" "")))
9184 (gtu:SI (match_dup 4)
9185 (match_operand:SI 2 "arith_reg_operand" "")))
9187 (if_then_else (ne (reg:SI T_REG)
9189 (label_ref (match_operand 3 "" ""))
9194 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9195 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9196 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9198 (define_insn "casesi_worker_0"
9199 [(set (match_operand:SI 0 "register_operand" "=r,r")
9200 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9201 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9202 (clobber (match_scratch:SI 3 "=X,1"))
9203 (clobber (match_scratch:SI 4 "=&z,z"))]
9208 [(set (match_operand:SI 0 "register_operand" "")
9209 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9210 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9211 (clobber (match_scratch:SI 3 ""))
9212 (clobber (match_scratch:SI 4 ""))]
9213 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9214 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9215 (parallel [(set (match_dup 0)
9216 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9217 (label_ref (match_dup 2))] UNSPEC_CASESI))
9218 (clobber (match_dup 3))])
9219 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9221 if (GET_CODE (operands[2]) == CODE_LABEL)
9222 LABEL_NUSES (operands[2])++;
9226 [(set (match_operand:SI 0 "register_operand" "")
9227 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9228 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9229 (clobber (match_scratch:SI 3 ""))
9230 (clobber (match_scratch:SI 4 ""))]
9231 "TARGET_SH2 && reload_completed"
9232 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9233 (parallel [(set (match_dup 0)
9234 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9235 (label_ref (match_dup 2))] UNSPEC_CASESI))
9236 (clobber (match_dup 3))])]
9238 if (GET_CODE (operands[2]) == CODE_LABEL)
9239 LABEL_NUSES (operands[2])++;
9242 (define_insn "casesi_worker_1"
9243 [(set (match_operand:SI 0 "register_operand" "=r,r")
9244 (unspec:SI [(reg:SI R0_REG)
9245 (match_operand:SI 1 "register_operand" "0,r")
9246 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9247 (clobber (match_scratch:SI 3 "=X,1"))]
9250 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9252 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9254 switch (GET_MODE (diff_vec))
9257 return "shll2 %1\;mov.l @(r0,%1),%0";
9259 return "add %1,%1\;mov.w @(r0,%1),%0";
9261 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9262 return "mov.b @(r0,%1),%0\;extu.b %0,%0";
9263 return "mov.b @(r0,%1),%0";
9268 [(set_attr "length" "4")])
9270 (define_insn "casesi_worker_2"
9271 [(set (match_operand:SI 0 "register_operand" "=r,r")
9272 (unspec:SI [(reg:SI R0_REG)
9273 (match_operand:SI 1 "register_operand" "0,r")
9274 (label_ref (match_operand 2 "" ""))
9275 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9276 (clobber (match_operand:SI 4 "" "=X,1"))]
9277 "TARGET_SH2 && reload_completed && flag_pic"
9279 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9282 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9284 switch (GET_MODE (diff_vec))
9287 output_asm_insn ("shll2 %1", operands);
9288 load = "mov.l @(r0,%1),%0"; break;
9290 output_asm_insn ("add %1,%1", operands);
9291 load = "mov.w @(r0,%1),%0"; break;
9293 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9294 load = "mov.b @(r0,%1),%0\;extu.b %0,%0";
9296 load = "mov.b @(r0,%1),%0";
9301 output_asm_insn ("add\tr0,%1\;mova\t%O3,r0\\n", operands);
9304 [(set_attr "length" "8")])
9306 (define_insn "casesi_shift_media"
9307 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9308 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9309 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9313 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9315 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9317 switch (GET_MODE (diff_vec))
9320 return "shlli %1, 2, %0";
9322 return "shlli %1, 1, %0";
9324 if (rtx_equal_p (operands[0], operands[1]))
9326 return "add %1, r63, %0";
9331 [(set_attr "type" "arith_media")])
9333 (define_insn "casesi_load_media"
9334 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9335 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9336 (match_operand:DI 2 "arith_reg_operand" "r")
9337 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9340 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9342 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9344 switch (GET_MODE (diff_vec))
9347 return "ldx.l %1, %2, %0";
9350 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9351 return "ldx.uw %1, %2, %0";
9353 return "ldx.w %1, %2, %0";
9355 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9356 return "ldx.ub %1, %2, %0";
9357 return "ldx.b %1, %2, %0";
9362 [(set_attr "type" "load_media")])
9364 (define_expand "return"
9366 "reload_completed && ! sh_need_epilogue ()"
9370 emit_jump_insn (gen_return_media ());
9374 if (TARGET_SHCOMPACT
9375 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9377 emit_jump_insn (gen_shcompact_return_tramp ());
9382 (define_insn "*return_i"
9384 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9385 && (crtl->args.info.call_cookie
9386 & CALL_COOKIE_RET_TRAMP (1)))
9388 && ! sh_cfun_trap_exit_p ()"
9390 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9391 && !current_function_interrupt)
9396 [(set_attr "type" "return")
9397 (set_attr "needs_delay_slot" "yes")])
9399 ;; trapa has no delay slot.
9400 (define_insn "*return_trapa"
9402 "TARGET_SH1 && !TARGET_SHCOMPACT
9403 && reload_completed"
9405 [(set_attr "type" "return")])
9407 (define_expand "shcompact_return_tramp"
9410 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9412 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9414 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
9415 emit_jump_insn (gen_shcompact_return_tramp_i ());
9419 (define_insn "shcompact_return_tramp_i"
9420 [(parallel [(return) (use (reg:SI R0_REG))])]
9422 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9424 [(set_attr "type" "jump_ind")
9425 (set_attr "needs_delay_slot" "yes")])
9427 (define_insn "return_media_i"
9428 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9429 "TARGET_SHMEDIA && reload_completed"
9431 [(set_attr "type" "jump_media")])
9433 (define_insn "return_media_rte"
9435 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9437 [(set_attr "type" "jump_media")])
9439 (define_expand "return_media"
9441 "TARGET_SHMEDIA && reload_completed"
9443 int tr_regno = sh_media_register_for_return ();
9446 if (current_function_interrupt)
9448 emit_jump_insn (gen_return_media_rte ());
9453 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9455 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9457 tr = gen_rtx_REG (Pmode, tr_regno);
9458 emit_move_insn (tr, r18);
9461 tr = gen_rtx_REG (Pmode, tr_regno);
9463 emit_jump_insn (gen_return_media_i (tr));
9467 (define_insn "shcompact_preserve_incoming_args"
9468 [(set (match_operand:SI 0 "register_operand" "+r")
9469 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9472 [(set_attr "length" "0")])
9474 (define_insn "shcompact_incoming_args"
9475 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9476 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9477 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9478 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9479 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9480 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9481 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9482 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9483 (set (mem:BLK (reg:SI MACL_REG))
9484 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9485 (use (reg:SI R0_REG))
9486 (clobber (reg:SI R0_REG))
9487 (clobber (reg:SI MACL_REG))
9488 (clobber (reg:SI MACH_REG))
9489 (clobber (reg:SI PR_REG))]
9492 [(set_attr "needs_delay_slot" "yes")])
9494 (define_insn "shmedia_save_restore_regs_compact"
9495 [(set (reg:SI SP_REG)
9496 (plus:SI (reg:SI SP_REG)
9497 (match_operand:SI 0 "immediate_operand" "i")))
9498 (use (reg:SI R0_REG))
9499 (clobber (reg:SI PR_REG))]
9501 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9502 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9504 [(set_attr "needs_delay_slot" "yes")])
9506 (define_expand "prologue"
9510 sh_expand_prologue ();
9514 (define_expand "epilogue"
9518 sh_expand_epilogue (0);
9519 emit_jump_insn (gen_return ());
9523 (define_expand "eh_return"
9524 [(use (match_operand 0 "register_operand" ""))]
9527 rtx ra = operands[0];
9529 if (TARGET_SHMEDIA64)
9530 emit_insn (gen_eh_set_ra_di (ra));
9532 emit_insn (gen_eh_set_ra_si (ra));
9537 ;; Clobber the return address on the stack. We can't expand this
9538 ;; until we know where it will be put in the stack frame.
9540 (define_insn "eh_set_ra_si"
9541 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9543 (clobber (match_scratch:SI 1 "=&r"))]
9544 "! TARGET_SHMEDIA64"
9547 (define_insn "eh_set_ra_di"
9548 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9550 (clobber (match_scratch:DI 1 "=&r"))]
9555 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9557 (clobber (match_scratch 1 ""))]
9561 sh_set_return_address (operands[0], operands[1]);
9565 (define_insn "blockage"
9566 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9569 [(set_attr "length" "0")])
9571 ;; Define movml instructions for SH2A target. Currently they are
9572 ;; used to push and pop all banked registers only.
9574 (define_insn "movml_push_banked"
9575 [(set (match_operand:SI 0 "register_operand" "=r")
9576 (plus (match_dup 0) (const_int -32)))
9577 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9578 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9579 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9580 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9581 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9582 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9583 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9584 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9585 "TARGET_SH2A && REGNO (operands[0]) == 15"
9587 [(set_attr "in_delay_slot" "no")])
9589 (define_insn "movml_pop_banked"
9590 [(set (match_operand:SI 0 "register_operand" "=r")
9591 (plus (match_dup 0) (const_int 32)))
9592 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9593 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9594 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9595 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9596 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9597 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9598 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9599 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9600 "TARGET_SH2A && REGNO (operands[0]) == 15"
9602 [(set_attr "in_delay_slot" "no")])
9604 ;; ------------------------------------------------------------------------
9606 ;; ------------------------------------------------------------------------
9609 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9610 (match_operand:SI 1 "t_reg_operand"))]
9613 [(set_attr "type" "arith")])
9615 (define_insn "movrt"
9616 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9617 (xor:SI (reg:SI T_REG) (const_int 1)))]
9620 [(set_attr "type" "arith")])
9622 (define_expand "cstore4_media"
9623 [(set (match_operand:SI 0 "register_operand" "=r")
9624 (match_operator:SI 1 "sh_float_comparison_operator"
9625 [(match_operand 2 "logical_operand" "")
9626 (match_operand 3 "cmp_operand" "")]))]
9629 enum machine_mode mode = GET_MODE (operands[2]);
9630 enum rtx_code code = GET_CODE (operands[1]);
9632 if (mode == VOIDmode)
9633 mode = GET_MODE (operands[3]);
9634 if (operands[2] == const0_rtx)
9636 if (code == EQ || code == NE)
9637 operands[2] = operands[3], operands[3] = const0_rtx;
9640 operands[2] = force_reg (mode, operands[2]);
9641 if (operands[3] != const0_rtx)
9642 operands[3] = force_reg (mode, operands[3]);
9648 swap = invert = !FLOAT_MODE_P (mode);
9653 swap = FLOAT_MODE_P (mode), invert = !swap;
9658 swap = true, invert = false;
9665 swap = invert = false;
9669 swap = invert = true;
9678 rtx tem = operands[2];
9679 operands[2] = operands[3];
9681 code = swap_condition (code);
9686 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9687 code = reverse_condition (code);
9688 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9689 emit_insn (gen_cstore4_media (tem, operands[1],
9690 operands[2], operands[3]));
9693 operands[3] = const0_rtx;
9696 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9699 (define_expand "cstoresi4"
9700 [(set (match_operand:SI 0 "register_operand" "=r")
9701 (match_operator:SI 1 "comparison_operator"
9702 [(match_operand:SI 2 "cmpsi_operand" "")
9703 (match_operand:SI 3 "arith_operand" "")]))]
9704 "TARGET_SH1 || TARGET_SHMEDIA"
9708 emit_insn (gen_cstore4_media (operands[0], operands[1],
9709 operands[2], operands[3]));
9713 if (sh_expand_t_scc (operands))
9716 if (! currently_expanding_to_rtl)
9719 sh_emit_compare_and_set (operands, SImode);
9723 (define_expand "cstoredi4"
9724 [(set (match_operand:SI 0 "register_operand" "=r")
9725 (match_operator:SI 1 "comparison_operator"
9726 [(match_operand:DI 2 "arith_operand" "")
9727 (match_operand:DI 3 "arith_operand" "")]))]
9728 "TARGET_SH2 || TARGET_SHMEDIA"
9732 emit_insn (gen_cstore4_media (operands[0], operands[1],
9733 operands[2], operands[3]));
9737 if (sh_expand_t_scc (operands))
9740 if (! currently_expanding_to_rtl)
9743 sh_emit_compare_and_set (operands, DImode);
9747 ;; Move the complement of the T reg to a reg.
9748 ;; On SH2A the movrt insn can be used.
9749 ;; On anything else than SH2A this has to be done with multiple instructions.
9750 ;; One obvious way would be:
9755 ;; However, this puts pressure on r0 in most cases and thus the following is
9761 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
9762 ;; becomes a one instruction operation. Moreover, care must be taken that
9763 ;; the insn can still be combined with inverted compare and branch code
9764 ;; around it. On the other hand, if a function returns the complement of
9765 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
9766 ;; lead to better code.
9768 (define_expand "movnegt"
9769 [(set (match_operand:SI 0 "arith_reg_dest" "")
9770 (xor:SI (reg:SI T_REG) (const_int 1)))]
9774 emit_insn (gen_movrt (operands[0]));
9777 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
9778 emit_insn (gen_movrt_negc (operands[0], val));
9783 (define_insn "movrt_negc"
9784 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9785 (xor:SI (reg:SI T_REG) (const_int 1)))
9786 (set (reg:SI T_REG) (const_int 1))
9787 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
9790 [(set_attr "type" "arith")])
9792 ;; The *negnegt pattern helps the combine pass to figure out how to fold
9793 ;; an explicit double T bit negation.
9794 (define_insn_and_split "*negnegt"
9795 [(set (reg:SI T_REG)
9796 (eq:SI (match_operand 0 "negt_reg_operand" "") (const_int 0)))]
9802 ;; The *movtt pattern eliminates redundant T bit to T bit moves / tests.
9803 (define_insn_and_split "*movtt"
9804 [(set (reg:SI T_REG)
9805 (eq:SI (match_operand 0 "t_reg_operand" "") (const_int 1)))]
9811 (define_insn_and_split "nott"
9812 [(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))]
9815 gcc_assert (TARGET_SH2A);
9818 "! TARGET_SH2A && can_create_pseudo_p ()"
9819 [(set (match_dup 0) (reg:SI T_REG))
9820 (set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))]
9822 operands[0] = gen_reg_rtx (SImode);
9825 (define_expand "cstoresf4"
9826 [(set (match_operand:SI 0 "register_operand" "=r")
9827 (match_operator:SI 1 "sh_float_comparison_operator"
9828 [(match_operand:SF 2 "arith_operand" "")
9829 (match_operand:SF 3 "arith_operand" "")]))]
9830 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9834 emit_insn (gen_cstore4_media (operands[0], operands[1],
9835 operands[2], operands[3]));
9839 if (! currently_expanding_to_rtl)
9842 sh_emit_compare_and_set (operands, SFmode);
9846 (define_expand "cstoredf4"
9847 [(set (match_operand:SI 0 "register_operand" "=r")
9848 (match_operator:SI 1 "sh_float_comparison_operator"
9849 [(match_operand:DF 2 "arith_operand" "")
9850 (match_operand:DF 3 "arith_operand" "")]))]
9851 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9855 emit_insn (gen_cstore4_media (operands[0], operands[1],
9856 operands[2], operands[3]));
9860 if (! currently_expanding_to_rtl)
9863 sh_emit_compare_and_set (operands, DFmode);
9867 ;; -------------------------------------------------------------------------
9868 ;; Instructions to cope with inline literal tables
9869 ;; -------------------------------------------------------------------------
9871 ; 2 byte integer in line
9873 (define_insn "consttable_2"
9874 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9875 (match_operand 1 "" "")]
9879 if (operands[1] != const0_rtx)
9880 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9883 [(set_attr "length" "2")
9884 (set_attr "in_delay_slot" "no")])
9886 ; 4 byte integer in line
9888 (define_insn "consttable_4"
9889 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9890 (match_operand 1 "" "")]
9894 if (operands[1] != const0_rtx)
9896 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9897 mark_symbol_refs_as_used (operands[0]);
9901 [(set_attr "length" "4")
9902 (set_attr "in_delay_slot" "no")])
9904 ; 8 byte integer in line
9906 (define_insn "consttable_8"
9907 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9908 (match_operand 1 "" "")]
9912 if (operands[1] != const0_rtx)
9913 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9916 [(set_attr "length" "8")
9917 (set_attr "in_delay_slot" "no")])
9919 ; 4 byte floating point
9921 (define_insn "consttable_sf"
9922 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9923 (match_operand 1 "" "")]
9927 if (operands[1] != const0_rtx)
9930 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9931 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9935 [(set_attr "length" "4")
9936 (set_attr "in_delay_slot" "no")])
9938 ; 8 byte floating point
9940 (define_insn "consttable_df"
9941 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9942 (match_operand 1 "" "")]
9946 if (operands[1] != const0_rtx)
9949 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9950 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9954 [(set_attr "length" "8")
9955 (set_attr "in_delay_slot" "no")])
9957 ;; Alignment is needed for some constant tables; it may also be added for
9958 ;; Instructions at the start of loops, or after unconditional branches.
9959 ;; ??? We would get more accurate lengths if we did instruction
9960 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9961 ;; here is too conservative.
9963 ; align to a two byte boundary
9965 (define_expand "align_2"
9966 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9970 ; align to a four byte boundary
9971 ;; align_4 and align_log are instructions for the starts of loops, or
9972 ;; after unconditional branches, which may take up extra room.
9974 (define_expand "align_4"
9975 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9979 ; align to a cache line boundary
9981 (define_insn "align_log"
9982 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9985 [(set_attr "length" "0")
9986 (set_attr "in_delay_slot" "no")])
9988 ; emitted at the end of the literal table, used to emit the
9989 ; 32bit branch labels if needed.
9991 (define_insn "consttable_end"
9992 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9995 return output_jump_label_table ();
9997 [(set_attr "in_delay_slot" "no")])
9999 ; emitted at the end of the window in the literal table.
10001 (define_insn "consttable_window_end"
10002 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10005 [(set_attr "length" "0")
10006 (set_attr "in_delay_slot" "no")])
10008 ;; -------------------------------------------------------------------------
10010 ;; -------------------------------------------------------------------------
10012 ;; String/block move insn.
10014 (define_expand "movmemsi"
10015 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10016 (mem:BLK (match_operand:BLK 1 "" "")))
10017 (use (match_operand:SI 2 "nonmemory_operand" ""))
10018 (use (match_operand:SI 3 "immediate_operand" ""))
10019 (clobber (reg:SI PR_REG))
10020 (clobber (reg:SI R4_REG))
10021 (clobber (reg:SI R5_REG))
10022 (clobber (reg:SI R0_REG))])]
10023 "TARGET_SH1 && ! TARGET_SH5"
10025 if(expand_block_move (operands))
10030 (define_insn "block_move_real"
10031 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10032 (mem:BLK (reg:SI R5_REG)))
10033 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10034 (clobber (reg:SI PR_REG))
10035 (clobber (reg:SI R0_REG))])]
10036 "TARGET_SH1 && ! TARGET_HARD_SH4"
10038 [(set_attr "type" "sfunc")
10039 (set_attr "needs_delay_slot" "yes")])
10041 (define_insn "block_lump_real"
10042 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10043 (mem:BLK (reg:SI R5_REG)))
10044 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10045 (use (reg:SI R6_REG))
10046 (clobber (reg:SI PR_REG))
10047 (clobber (reg:SI T_REG))
10048 (clobber (reg:SI R4_REG))
10049 (clobber (reg:SI R5_REG))
10050 (clobber (reg:SI R6_REG))
10051 (clobber (reg:SI R0_REG))])]
10052 "TARGET_SH1 && ! TARGET_HARD_SH4"
10054 [(set_attr "type" "sfunc")
10055 (set_attr "needs_delay_slot" "yes")])
10057 (define_insn "block_move_real_i4"
10058 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10059 (mem:BLK (reg:SI R5_REG)))
10060 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10061 (clobber (reg:SI PR_REG))
10062 (clobber (reg:SI R0_REG))
10063 (clobber (reg:SI R1_REG))
10064 (clobber (reg:SI R2_REG))])]
10067 [(set_attr "type" "sfunc")
10068 (set_attr "needs_delay_slot" "yes")])
10070 (define_insn "block_lump_real_i4"
10071 [(parallel [(set (mem:BLK (reg:SI R4_REG))
10072 (mem:BLK (reg:SI R5_REG)))
10073 (use (match_operand:SI 0 "arith_reg_operand" "r"))
10074 (use (reg:SI R6_REG))
10075 (clobber (reg:SI PR_REG))
10076 (clobber (reg:SI T_REG))
10077 (clobber (reg:SI R4_REG))
10078 (clobber (reg:SI R5_REG))
10079 (clobber (reg:SI R6_REG))
10080 (clobber (reg:SI R0_REG))
10081 (clobber (reg:SI R1_REG))
10082 (clobber (reg:SI R2_REG))
10083 (clobber (reg:SI R3_REG))])]
10086 [(set_attr "type" "sfunc")
10087 (set_attr "needs_delay_slot" "yes")])
10089 ;; -------------------------------------------------------------------------
10090 ;; Floating point instructions.
10091 ;; -------------------------------------------------------------------------
10093 ;; ??? All patterns should have a type attribute.
10095 (define_expand "movpsi"
10096 [(set (match_operand:PSI 0 "register_operand" "")
10097 (match_operand:PSI 1 "general_movsrc_operand" ""))]
10098 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10101 ;; The c / m alternative is a fake to guide reload to load directly into
10102 ;; fpscr, since reload doesn't know how to use post-increment.
10103 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
10104 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10105 ;; predicate after reload.
10106 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10107 ;; like a mac -> gpr move.
10108 (define_insn "fpu_switch"
10109 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10110 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10112 && (! reload_completed
10113 || true_regnum (operands[0]) != FPSCR_REG
10114 || !MEM_P (operands[1])
10115 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10117 ! precision stays the same
10126 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10127 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10130 [(set (reg:PSI FPSCR_REG)
10131 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10132 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10135 rtx fpscr, mem, new_insn;
10137 fpscr = SET_DEST (PATTERN (curr_insn));
10138 mem = SET_SRC (PATTERN (curr_insn));
10139 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10141 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10142 add_reg_note (new_insn, REG_INC, operands[0]);
10147 [(set (reg:PSI FPSCR_REG)
10148 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10149 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10150 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10153 rtx fpscr, mem, new_insn;
10155 fpscr = SET_DEST (PATTERN (curr_insn));
10156 mem = SET_SRC (PATTERN (curr_insn));
10157 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10159 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10160 add_reg_note (new_insn, REG_INC, operands[0]);
10162 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10163 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10167 ;; ??? This uses the fp unit, but has no type indicating that.
10168 ;; If we did that, this would either give a bogus latency or introduce
10169 ;; a bogus FIFO constraint.
10170 ;; Since this insn is currently only used for prologues/epilogues,
10171 ;; it is probably best to claim no function unit, which matches the
10172 ;; current setting.
10173 (define_insn "toggle_sz"
10174 [(set (reg:PSI FPSCR_REG)
10175 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10176 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10178 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10180 ;; There's no way we can use it today, since optimize mode switching
10181 ;; doesn't enable us to know from which mode we're switching to the
10182 ;; mode it requests, to tell whether we can use a relative mode switch
10183 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10185 (define_insn "toggle_pr"
10186 [(set (reg:PSI FPSCR_REG)
10187 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10188 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10190 [(set_attr "type" "fpscr_toggle")])
10192 (define_expand "addsf3"
10193 [(set (match_operand:SF 0 "arith_reg_operand" "")
10194 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10195 (match_operand:SF 2 "arith_reg_operand" "")))]
10196 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10200 expand_sf_binop (&gen_addsf3_i, operands);
10205 (define_insn "*addsf3_media"
10206 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10207 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10208 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10209 "TARGET_SHMEDIA_FPU"
10210 "fadd.s %1, %2, %0"
10211 [(set_attr "type" "fparith_media")])
10213 (define_insn_and_split "unary_sf_op"
10214 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10219 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10220 (match_operator:SF 2 "unary_float_operator"
10221 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10222 (parallel [(match_operand 4
10223 "const_int_operand" "n")]))]))
10224 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10225 "TARGET_SHMEDIA_FPU"
10227 "TARGET_SHMEDIA_FPU && reload_completed"
10228 [(set (match_dup 5) (match_dup 6))]
10230 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10231 rtx op1 = gen_rtx_REG (SFmode,
10232 (true_regnum (operands[1])
10233 + (INTVAL (operands[4]) ^ endian)));
10235 operands[7] = gen_rtx_REG (SFmode,
10236 (true_regnum (operands[0])
10237 + (INTVAL (operands[3]) ^ endian)));
10238 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10240 [(set_attr "type" "fparith_media")])
10242 (define_insn_and_split "binary_sf_op0"
10243 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10245 (match_operator:SF 3 "binary_float_operator"
10246 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10247 (parallel [(const_int 0)]))
10248 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10249 (parallel [(const_int 0)]))])
10252 (parallel [(const_int 1)]))))]
10253 "TARGET_SHMEDIA_FPU"
10255 "&& reload_completed"
10256 [(set (match_dup 4) (match_dup 5))]
10258 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10259 rtx op1 = gen_rtx_REG (SFmode,
10260 true_regnum (operands[1]) + endian);
10261 rtx op2 = gen_rtx_REG (SFmode,
10262 true_regnum (operands[2]) + endian);
10264 operands[4] = gen_rtx_REG (SFmode,
10265 true_regnum (operands[0]) + endian);
10266 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10268 [(set_attr "type" "fparith_media")])
10270 (define_insn_and_split "binary_sf_op1"
10271 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10275 (parallel [(const_int 0)]))
10276 (match_operator:SF 3 "binary_float_operator"
10277 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10278 (parallel [(const_int 1)]))
10279 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10280 (parallel [(const_int 1)]))])))]
10281 "TARGET_SHMEDIA_FPU"
10283 "&& reload_completed"
10284 [(set (match_dup 4) (match_dup 5))]
10286 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10287 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
10288 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
10290 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
10291 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10293 [(set_attr "type" "fparith_media")])
10295 (define_insn "addsf3_i"
10296 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10297 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10298 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10299 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10302 [(set_attr "type" "fp")
10303 (set_attr "fp_mode" "single")])
10305 (define_expand "subsf3"
10306 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10307 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10308 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10309 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10313 expand_sf_binop (&gen_subsf3_i, operands);
10318 (define_insn "*subsf3_media"
10319 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10320 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10321 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10322 "TARGET_SHMEDIA_FPU"
10323 "fsub.s %1, %2, %0"
10324 [(set_attr "type" "fparith_media")])
10326 (define_insn "subsf3_i"
10327 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10328 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10329 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10330 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10333 [(set_attr "type" "fp")
10334 (set_attr "fp_mode" "single")])
10336 (define_expand "mulsf3"
10337 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10338 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10339 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10340 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10343 (define_insn "*mulsf3_media"
10344 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10345 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10346 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10347 "TARGET_SHMEDIA_FPU"
10348 "fmul.s %1, %2, %0"
10349 [(set_attr "type" "fparith_media")])
10351 ;; FIXME: These fmac combine pass assisting specifics are obsolete since
10352 ;; we now use the FMA patterns, which do not depend on the combine
10354 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10355 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10356 ;; we start out with a mulsf pattern that does not depend on fpscr.
10357 ;; This is split after combine to introduce the dependency, in order to
10358 ;; get mode switching and scheduling right.
10359 (define_insn_and_split "mulsf3_ie"
10360 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10361 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10362 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10365 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10368 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10369 get_fpscr_rtx ()));
10372 [(set_attr "type" "fp")])
10374 (define_insn "mulsf3_i4"
10375 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10376 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10377 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10378 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10381 [(set_attr "type" "fp")
10382 (set_attr "fp_mode" "single")])
10384 ;; FMA (fused multiply-add) patterns
10385 (define_expand "fmasf4"
10386 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10387 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10388 (match_operand:SF 2 "fp_arith_reg_operand" "")
10389 (match_operand:SF 3 "fp_arith_reg_operand" "")))]
10390 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10394 emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2],
10395 operands[3], get_fpscr_rtx ()));
10400 (define_insn "fmasf4_i"
10401 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10402 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w")
10403 (match_operand:SF 2 "fp_arith_reg_operand" "f")
10404 (match_operand:SF 3 "fp_arith_reg_operand" "0")))
10405 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10408 [(set_attr "type" "fp")
10409 (set_attr "fp_mode" "single")])
10411 (define_insn "fmasf4_media"
10412 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10413 (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10414 (match_operand:SF 2 "fp_arith_reg_operand" "f")
10415 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10416 "TARGET_SHMEDIA_FPU"
10417 "fmac.s %1, %2, %0"
10418 [(set_attr "type" "fparith_media")])
10420 (define_expand "divsf3"
10421 [(set (match_operand:SF 0 "arith_reg_operand" "")
10422 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10423 (match_operand:SF 2 "arith_reg_operand" "")))]
10424 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10428 expand_sf_binop (&gen_divsf3_i, operands);
10433 (define_insn "*divsf3_media"
10434 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10435 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10436 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10437 "TARGET_SHMEDIA_FPU"
10438 "fdiv.s %1, %2, %0"
10439 [(set_attr "type" "fdiv_media")])
10441 (define_insn "divsf3_i"
10442 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10443 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10444 (match_operand:SF 2 "arith_reg_operand" "f")))
10445 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10448 [(set_attr "type" "fdiv")
10449 (set_attr "fp_mode" "single")])
10451 (define_insn "floatdisf2"
10452 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10453 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10454 "TARGET_SHMEDIA_FPU"
10456 [(set_attr "type" "fpconv_media")])
10458 (define_expand "floatsisf2"
10459 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10460 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10461 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10463 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10465 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10470 (define_insn "*floatsisf2_media"
10471 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10472 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10473 "TARGET_SHMEDIA_FPU"
10475 [(set_attr "type" "fpconv_media")])
10477 (define_insn "floatsisf2_i4"
10478 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10479 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10480 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10481 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10483 [(set_attr "type" "fp")
10484 (set_attr "fp_mode" "single")])
10486 (define_insn "*floatsisf2_ie"
10487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10488 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10489 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10491 [(set_attr "type" "fp")])
10493 (define_insn "fix_truncsfdi2"
10494 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10495 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10496 "TARGET_SHMEDIA_FPU"
10498 [(set_attr "type" "fpconv_media")])
10500 (define_expand "fix_truncsfsi2"
10501 [(set (match_operand:SI 0 "fpul_operand" "=y")
10502 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10503 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10505 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10507 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10512 (define_insn "*fix_truncsfsi2_media"
10513 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10514 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10515 "TARGET_SHMEDIA_FPU"
10517 [(set_attr "type" "fpconv_media")])
10519 (define_insn "fix_truncsfsi2_i4"
10520 [(set (match_operand:SI 0 "fpul_operand" "=y")
10521 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10522 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10523 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10525 [(set_attr "type" "ftrc_s")
10526 (set_attr "fp_mode" "single")])
10528 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10529 ;; fix_truncsfsi2_i4.
10530 ;; (define_insn "fix_truncsfsi2_i4_2"
10531 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10532 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10533 ;; (use (reg:PSI FPSCR_REG))
10534 ;; (clobber (reg:SI FPUL_REG))]
10537 ;; [(set_attr "length" "4")
10538 ;; (set_attr "fp_mode" "single")])
10541 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10542 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10543 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10544 ;; (clobber (reg:SI FPUL_REG))]
10546 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10547 ;; (use (match_dup 2))])
10548 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10550 (define_insn "*fixsfsi"
10551 [(set (match_operand:SI 0 "fpul_operand" "=y")
10552 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10553 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10555 [(set_attr "type" "fp")])
10557 (define_insn "cmpgtsf_t"
10558 [(set (reg:SI T_REG)
10559 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10560 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10561 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10563 [(set_attr "type" "fp_cmp")
10564 (set_attr "fp_mode" "single")])
10566 (define_insn "cmpeqsf_t"
10567 [(set (reg:SI T_REG)
10568 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10569 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10570 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10572 [(set_attr "type" "fp_cmp")
10573 (set_attr "fp_mode" "single")])
10575 (define_insn "ieee_ccmpeqsf_t"
10576 [(set (reg:SI T_REG)
10577 (ior:SI (reg:SI T_REG)
10578 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10579 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10580 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10582 return output_ieee_ccmpeq (insn, operands);
10584 [(set_attr "length" "4")])
10587 (define_insn "cmpgtsf_t_i4"
10588 [(set (reg:SI T_REG)
10589 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10590 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10591 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10592 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10594 [(set_attr "type" "fp_cmp")
10595 (set_attr "fp_mode" "single")])
10597 (define_insn "cmpeqsf_t_i4"
10598 [(set (reg:SI T_REG)
10599 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10600 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10601 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10602 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10604 [(set_attr "type" "fp_cmp")
10605 (set_attr "fp_mode" "single")])
10607 (define_insn "*ieee_ccmpeqsf_t_4"
10608 [(set (reg:SI T_REG)
10609 (ior:SI (reg:SI T_REG)
10610 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10611 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10612 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10613 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10615 return output_ieee_ccmpeq (insn, operands);
10617 [(set_attr "length" "4")
10618 (set_attr "fp_mode" "single")])
10620 (define_insn "cmpeqsf_media"
10621 [(set (match_operand:SI 0 "register_operand" "=r")
10622 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10623 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10624 "TARGET_SHMEDIA_FPU"
10625 "fcmpeq.s %1, %2, %0"
10626 [(set_attr "type" "fcmp_media")])
10628 (define_insn "cmpgtsf_media"
10629 [(set (match_operand:SI 0 "register_operand" "=r")
10630 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10631 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10632 "TARGET_SHMEDIA_FPU"
10633 "fcmpgt.s %1, %2, %0"
10634 [(set_attr "type" "fcmp_media")])
10636 (define_insn "cmpgesf_media"
10637 [(set (match_operand:SI 0 "register_operand" "=r")
10638 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10639 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10640 "TARGET_SHMEDIA_FPU"
10641 "fcmpge.s %1, %2, %0"
10642 [(set_attr "type" "fcmp_media")])
10644 (define_insn "cmpunsf_media"
10645 [(set (match_operand:SI 0 "register_operand" "=r")
10646 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10647 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10648 "TARGET_SHMEDIA_FPU"
10649 "fcmpun.s %1, %2, %0"
10650 [(set_attr "type" "fcmp_media")])
10652 (define_expand "cbranchsf4"
10654 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10655 [(match_operand:SF 1 "arith_operand" "")
10656 (match_operand:SF 2 "arith_operand" "")])
10657 (match_operand 3 "" "")
10659 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10661 if (TARGET_SHMEDIA)
10662 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10665 sh_emit_compare_and_branch (operands, SFmode);
10669 (define_expand "negsf2"
10670 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10671 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10672 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10676 expand_sf_unop (&gen_negsf2_i, operands);
10681 (define_insn "*negsf2_media"
10682 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10683 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10684 "TARGET_SHMEDIA_FPU"
10686 [(set_attr "type" "fmove_media")])
10688 (define_insn "negsf2_i"
10689 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10690 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10691 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10694 [(set_attr "type" "fmove")
10695 (set_attr "fp_mode" "single")])
10697 (define_expand "sqrtsf2"
10698 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10699 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10700 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10704 expand_sf_unop (&gen_sqrtsf2_i, operands);
10709 (define_insn "*sqrtsf2_media"
10710 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10711 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10712 "TARGET_SHMEDIA_FPU"
10714 [(set_attr "type" "fdiv_media")])
10716 (define_insn "sqrtsf2_i"
10717 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10718 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10719 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10722 [(set_attr "type" "fdiv")
10723 (set_attr "fp_mode" "single")])
10725 (define_insn "rsqrtsf2"
10726 [(set (match_operand:SF 0 "register_operand" "=f")
10727 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10728 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10729 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10730 "TARGET_FPU_ANY && TARGET_FSRRA
10731 && operands[1] == CONST1_RTX (SFmode)"
10733 [(set_attr "type" "fsrra")
10734 (set_attr "fp_mode" "single")])
10736 (define_insn "fsca"
10737 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10739 (unspec:SF [(mult:SF
10740 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10741 (match_operand:SF 2 "immediate_operand" "i"))
10743 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10745 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10746 "TARGET_FPU_ANY && TARGET_FSCA
10747 && operands[2] == sh_fsca_int2sf ()"
10749 [(set_attr "type" "fsca")
10750 (set_attr "fp_mode" "single")])
10752 ;; When the sincos pattern is defined, the builtin functions sin and cos
10753 ;; will be expanded to the sincos pattern and one of the output values will
10755 (define_expand "sincossf3"
10756 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10757 (unspec:SF [(match_operand:SF 2 "fp_arith_reg_operand" "")]
10759 (set (match_operand:SF 1 "nonimmediate_operand" "")
10760 (unspec:SF [(match_dup 2)] UNSPEC_FCOSA))]
10761 "TARGET_FPU_ANY && TARGET_FSCA"
10763 rtx scaled = gen_reg_rtx (SFmode);
10764 rtx truncated = gen_reg_rtx (SImode);
10765 rtx fsca = gen_reg_rtx (V2SFmode);
10766 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10768 emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg));
10769 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10770 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10771 get_fpscr_rtx ()));
10773 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10774 emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 4));
10778 (define_expand "abssf2"
10779 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10780 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10781 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10785 expand_sf_unop (&gen_abssf2_i, operands);
10790 (define_insn "*abssf2_media"
10791 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10792 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10793 "TARGET_SHMEDIA_FPU"
10795 [(set_attr "type" "fmove_media")])
10797 (define_insn "abssf2_i"
10798 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10799 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10800 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10803 [(set_attr "type" "fmove")
10804 (set_attr "fp_mode" "single")])
10806 (define_expand "adddf3"
10807 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10808 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10809 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10810 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10812 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10814 expand_df_binop (&gen_adddf3_i, operands);
10819 (define_insn "*adddf3_media"
10820 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10821 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10822 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10823 "TARGET_SHMEDIA_FPU"
10824 "fadd.d %1, %2, %0"
10825 [(set_attr "type" "dfparith_media")])
10827 (define_insn "adddf3_i"
10828 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10829 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10830 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10831 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10832 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10834 [(set_attr "type" "dfp_arith")
10835 (set_attr "fp_mode" "double")])
10837 (define_expand "subdf3"
10838 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10839 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10840 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10841 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10843 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10845 expand_df_binop (&gen_subdf3_i, operands);
10850 (define_insn "*subdf3_media"
10851 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10852 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10853 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10854 "TARGET_SHMEDIA_FPU"
10855 "fsub.d %1, %2, %0"
10856 [(set_attr "type" "dfparith_media")])
10858 (define_insn "subdf3_i"
10859 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10860 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10861 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10862 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10863 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10865 [(set_attr "type" "dfp_arith")
10866 (set_attr "fp_mode" "double")])
10868 (define_expand "muldf3"
10869 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10870 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10871 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10872 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10874 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10876 expand_df_binop (&gen_muldf3_i, operands);
10881 (define_insn "*muldf3_media"
10882 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10883 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10884 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10885 "TARGET_SHMEDIA_FPU"
10886 "fmul.d %1, %2, %0"
10887 [(set_attr "type" "dfmul_media")])
10889 (define_insn "muldf3_i"
10890 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10891 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10892 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10893 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10894 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10896 [(set_attr "type" "dfp_mul")
10897 (set_attr "fp_mode" "double")])
10899 (define_expand "divdf3"
10900 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10901 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10902 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10903 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10905 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10907 expand_df_binop (&gen_divdf3_i, operands);
10912 (define_insn "*divdf3_media"
10913 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10914 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10915 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10916 "TARGET_SHMEDIA_FPU"
10917 "fdiv.d %1, %2, %0"
10918 [(set_attr "type" "dfdiv_media")])
10920 (define_insn "divdf3_i"
10921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10922 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10923 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10924 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10925 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10927 [(set_attr "type" "dfdiv")
10928 (set_attr "fp_mode" "double")])
10930 (define_insn "floatdidf2"
10931 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10932 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10933 "TARGET_SHMEDIA_FPU"
10935 [(set_attr "type" "dfpconv_media")])
10937 (define_expand "floatsidf2"
10938 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10939 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10940 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10942 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10944 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10945 get_fpscr_rtx ()));
10950 (define_insn "*floatsidf2_media"
10951 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10952 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10953 "TARGET_SHMEDIA_FPU"
10955 [(set_attr "type" "dfpconv_media")])
10957 (define_insn "floatsidf2_i"
10958 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10959 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10960 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10961 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10963 [(set_attr "type" "dfp_conv")
10964 (set_attr "fp_mode" "double")])
10966 (define_insn "fix_truncdfdi2"
10967 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10968 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10969 "TARGET_SHMEDIA_FPU"
10971 [(set_attr "type" "dfpconv_media")])
10973 (define_expand "fix_truncdfsi2"
10974 [(set (match_operand:SI 0 "fpul_operand" "")
10975 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10976 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10978 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10980 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10981 get_fpscr_rtx ()));
10986 (define_insn "*fix_truncdfsi2_media"
10987 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10988 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10989 "TARGET_SHMEDIA_FPU"
10991 [(set_attr "type" "dfpconv_media")])
10993 (define_insn "fix_truncdfsi2_i"
10994 [(set (match_operand:SI 0 "fpul_operand" "=y")
10995 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10996 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10997 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10999 [(set_attr "type" "dfp_conv")
11000 (set_attr "dfp_comp" "no")
11001 (set_attr "fp_mode" "double")])
11003 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
11004 ;; fix_truncdfsi2_i.
11005 ;; (define_insn "fix_truncdfsi2_i4"
11006 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11007 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11008 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11009 ;; (clobber (reg:SI FPUL_REG))]
11012 ;; [(set_attr "length" "4")
11013 ;; (set_attr "fp_mode" "double")])
11016 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11017 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11018 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
11019 ;; (clobber (reg:SI FPUL_REG))]
11021 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11022 ;; (use (match_dup 2))])
11023 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
11025 (define_insn "cmpgtdf_t"
11026 [(set (reg:SI T_REG)
11027 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11028 (match_operand:DF 1 "arith_reg_operand" "f")))
11029 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11030 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11032 [(set_attr "type" "dfp_cmp")
11033 (set_attr "fp_mode" "double")])
11035 (define_insn "cmpeqdf_t"
11036 [(set (reg:SI T_REG)
11037 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11038 (match_operand:DF 1 "arith_reg_operand" "f")))
11039 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11040 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11042 [(set_attr "type" "dfp_cmp")
11043 (set_attr "fp_mode" "double")])
11045 (define_insn "*ieee_ccmpeqdf_t"
11046 [(set (reg:SI T_REG)
11047 (ior:SI (reg:SI T_REG)
11048 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11049 (match_operand:DF 1 "arith_reg_operand" "f"))))
11050 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11051 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11053 return output_ieee_ccmpeq (insn, operands);
11055 [(set_attr "length" "4")
11056 (set_attr "fp_mode" "double")])
11058 (define_insn "cmpeqdf_media"
11059 [(set (match_operand:SI 0 "register_operand" "=r")
11060 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11061 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11062 "TARGET_SHMEDIA_FPU"
11063 "fcmpeq.d %1,%2,%0"
11064 [(set_attr "type" "fcmp_media")])
11066 (define_insn "cmpgtdf_media"
11067 [(set (match_operand:SI 0 "register_operand" "=r")
11068 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11069 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11070 "TARGET_SHMEDIA_FPU"
11071 "fcmpgt.d %1,%2,%0"
11072 [(set_attr "type" "fcmp_media")])
11074 (define_insn "cmpgedf_media"
11075 [(set (match_operand:SI 0 "register_operand" "=r")
11076 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11077 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11078 "TARGET_SHMEDIA_FPU"
11079 "fcmpge.d %1,%2,%0"
11080 [(set_attr "type" "fcmp_media")])
11082 (define_insn "cmpundf_media"
11083 [(set (match_operand:SI 0 "register_operand" "=r")
11084 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11085 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11086 "TARGET_SHMEDIA_FPU"
11087 "fcmpun.d %1,%2,%0"
11088 [(set_attr "type" "fcmp_media")])
11090 (define_expand "cbranchdf4"
11092 (if_then_else (match_operator 0 "sh_float_comparison_operator"
11093 [(match_operand:DF 1 "arith_operand" "")
11094 (match_operand:DF 2 "arith_operand" "")])
11095 (match_operand 3 "" "")
11097 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11099 if (TARGET_SHMEDIA)
11100 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
11103 sh_emit_compare_and_branch (operands, DFmode);
11108 (define_expand "negdf2"
11109 [(set (match_operand:DF 0 "arith_reg_operand" "")
11110 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11111 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11113 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11115 expand_df_unop (&gen_negdf2_i, operands);
11120 (define_insn "*negdf2_media"
11121 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11122 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11123 "TARGET_SHMEDIA_FPU"
11125 [(set_attr "type" "fmove_media")])
11127 (define_insn "negdf2_i"
11128 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11129 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11130 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11131 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11133 [(set_attr "type" "fmove")
11134 (set_attr "fp_mode" "double")])
11136 (define_expand "sqrtdf2"
11137 [(set (match_operand:DF 0 "arith_reg_operand" "")
11138 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11139 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11141 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11143 expand_df_unop (&gen_sqrtdf2_i, operands);
11148 (define_insn "*sqrtdf2_media"
11149 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11150 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11151 "TARGET_SHMEDIA_FPU"
11153 [(set_attr "type" "dfdiv_media")])
11155 (define_insn "sqrtdf2_i"
11156 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11157 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11158 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11159 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11161 [(set_attr "type" "dfdiv")
11162 (set_attr "fp_mode" "double")])
11164 (define_expand "absdf2"
11165 [(set (match_operand:DF 0 "arith_reg_operand" "")
11166 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11167 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11169 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11171 expand_df_unop (&gen_absdf2_i, operands);
11176 (define_insn "*absdf2_media"
11177 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11178 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11179 "TARGET_SHMEDIA_FPU"
11181 [(set_attr "type" "fmove_media")])
11183 (define_insn "absdf2_i"
11184 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11185 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11186 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11187 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11189 [(set_attr "type" "fmove")
11190 (set_attr "fp_mode" "double")])
11192 (define_expand "extendsfdf2"
11193 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11194 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11195 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11197 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11199 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11200 get_fpscr_rtx ()));
11205 (define_insn "*extendsfdf2_media"
11206 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11207 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11208 "TARGET_SHMEDIA_FPU"
11210 [(set_attr "type" "dfpconv_media")])
11212 (define_insn "extendsfdf2_i4"
11213 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11214 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11215 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11216 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11218 [(set_attr "type" "fp")
11219 (set_attr "fp_mode" "double")])
11221 (define_expand "truncdfsf2"
11222 [(set (match_operand:SF 0 "fpul_operand" "")
11223 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11224 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11226 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11228 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11229 get_fpscr_rtx ()));
11234 (define_insn "*truncdfsf2_media"
11235 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11236 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11237 "TARGET_SHMEDIA_FPU"
11239 [(set_attr "type" "dfpconv_media")])
11241 (define_insn "truncdfsf2_i4"
11242 [(set (match_operand:SF 0 "fpul_operand" "=y")
11243 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11244 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11245 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11247 [(set_attr "type" "fp")
11248 (set_attr "fp_mode" "double")])
11250 ;; Bit field extract patterns. These give better code for packed bitfields,
11251 ;; because they allow auto-increment addresses to be generated.
11253 (define_expand "insv"
11254 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11255 (match_operand:SI 1 "immediate_operand" "")
11256 (match_operand:SI 2 "immediate_operand" ""))
11257 (match_operand:SI 3 "general_operand" ""))]
11258 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11260 rtx addr_target, orig_address, shift_reg, qi_val;
11261 HOST_WIDE_INT bitsize, size, v = 0;
11262 rtx x = operands[3];
11264 if (TARGET_SH2A && TARGET_BITOPS
11265 && (satisfies_constraint_Sbw (operands[0])
11266 || satisfies_constraint_Sbv (operands[0]))
11267 && satisfies_constraint_M (operands[1])
11268 && satisfies_constraint_K03 (operands[2]))
11270 if (satisfies_constraint_N (operands[3]))
11272 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11275 else if (satisfies_constraint_M (operands[3]))
11277 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11280 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11281 && satisfies_constraint_M (operands[1]))
11283 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11286 else if (REG_P (operands[3])
11287 && satisfies_constraint_M (operands[1]))
11289 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11290 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11294 /* ??? expmed doesn't care for non-register predicates. */
11295 if (! memory_operand (operands[0], VOIDmode)
11296 || ! immediate_operand (operands[1], VOIDmode)
11297 || ! immediate_operand (operands[2], VOIDmode)
11298 || ! general_operand (x, VOIDmode))
11300 /* If this isn't a 16 / 24 / 32 bit field, or if
11301 it doesn't start on a byte boundary, then fail. */
11302 bitsize = INTVAL (operands[1]);
11303 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11304 || (INTVAL (operands[2]) % 8) != 0)
11307 size = bitsize / 8;
11308 orig_address = XEXP (operands[0], 0);
11309 shift_reg = gen_reg_rtx (SImode);
11310 if (CONST_INT_P (x))
11313 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11317 emit_insn (gen_movsi (shift_reg, operands[3]));
11318 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11320 addr_target = copy_addr_to_reg (plus_constant (Pmode,
11321 orig_address, size - 1));
11323 operands[0] = replace_equiv_address (operands[0], addr_target);
11324 emit_insn (gen_movqi (operands[0], qi_val));
11328 if (CONST_INT_P (x))
11330 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11333 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11334 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11336 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11337 emit_insn (gen_movqi (operands[0], qi_val));
11343 (define_insn "movua"
11344 [(set (match_operand:SI 0 "register_operand" "=z")
11345 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11349 [(set_attr "type" "movua")])
11351 ;; We shouldn't need this, but cse replaces increments with references
11352 ;; to other regs before flow has a chance to create post_inc
11353 ;; addressing modes, and only postreload's cse_move2add brings the
11354 ;; increments back to a usable form.
11356 [(set (match_operand:SI 0 "register_operand" "")
11357 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11358 (const_int 32) (const_int 0)))
11359 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11360 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11361 [(set (match_operand:SI 0 "register_operand" "")
11362 (sign_extract:SI (mem:SI (post_inc:SI
11363 (match_operand:SI 1 "register_operand" "")))
11364 (const_int 32) (const_int 0)))]
11367 (define_expand "extv"
11368 [(set (match_operand:SI 0 "register_operand" "")
11369 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11370 (match_operand 2 "const_int_operand" "")
11371 (match_operand 3 "const_int_operand" "")))]
11372 "TARGET_SH4A_ARCH || TARGET_SH2A"
11374 if (TARGET_SH2A && TARGET_BITOPS
11375 && (satisfies_constraint_Sbw (operands[1])
11376 || satisfies_constraint_Sbv (operands[1]))
11377 && satisfies_constraint_M (operands[2])
11378 && satisfies_constraint_K03 (operands[3]))
11380 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11381 if (REGNO (operands[0]) != T_REG)
11382 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11385 if (TARGET_SH4A_ARCH
11386 && INTVAL (operands[2]) == 32
11387 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11388 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11390 rtx src = adjust_address (operands[1], BLKmode, 0);
11391 set_mem_size (src, 4);
11392 emit_insn (gen_movua (operands[0], src));
11399 (define_expand "extzv"
11400 [(set (match_operand:SI 0 "register_operand" "")
11401 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11402 (match_operand 2 "const_int_operand" "")
11403 (match_operand 3 "const_int_operand" "")))]
11404 "TARGET_SH4A_ARCH || TARGET_SH2A"
11406 if (TARGET_SH2A && TARGET_BITOPS
11407 && (satisfies_constraint_Sbw (operands[1])
11408 || satisfies_constraint_Sbv (operands[1]))
11409 && satisfies_constraint_M (operands[2])
11410 && satisfies_constraint_K03 (operands[3]))
11412 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11413 if (REGNO (operands[0]) != T_REG)
11414 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11417 if (TARGET_SH4A_ARCH
11418 && INTVAL (operands[2]) == 32
11419 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11420 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11422 rtx src = adjust_address (operands[1], BLKmode, 0);
11423 set_mem_size (src, 4);
11424 emit_insn (gen_movua (operands[0], src));
11431 ;; SH2A instructions for bitwise operations.
11433 ;; Clear a bit in a memory location.
11434 (define_insn "bclr_m2a"
11435 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11437 (not:QI (ashift:QI (const_int 1)
11438 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11440 "TARGET_SH2A && TARGET_BITOPS"
11443 bclr.b\\t%1,@(0,%t0)"
11444 [(set_attr "length" "4,4")])
11446 (define_insn "bclrmem_m2a"
11447 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11448 (and:QI (match_dup 0)
11449 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11450 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11453 bclr.b\\t%W1,@(0,%t0)"
11454 [(set_attr "length" "4,4")])
11456 ;; Set a bit in a memory location.
11457 (define_insn "bset_m2a"
11458 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11460 (ashift:QI (const_int 1)
11461 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11463 "TARGET_SH2A && TARGET_BITOPS"
11466 bset.b\\t%1,@(0,%t0)"
11467 [(set_attr "length" "4,4")])
11469 (define_insn "bsetmem_m2a"
11470 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11471 (ior:QI (match_dup 0)
11472 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11473 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11476 bset.b\\t%V1,@(0,%t0)"
11477 [(set_attr "length" "4,4")])
11479 ;;; Transfer the contents of the T bit to a specified bit of memory.
11480 (define_insn "bst_m2a"
11481 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11482 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11484 (not:QI (ashift:QI (const_int 1)
11485 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11488 (ashift:QI (const_int 1) (match_dup 1))
11490 "TARGET_SH2A && TARGET_BITOPS"
11493 bst.b\\t%1,@(0,%t0)"
11494 [(set_attr "length" "4")])
11496 ;; Store a specified bit of memory in the T bit.
11497 (define_insn "bld_m2a"
11498 [(set (reg:SI T_REG)
11500 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11502 (match_operand 1 "const_int_operand" "K03,K03")))]
11503 "TARGET_SH2A && TARGET_BITOPS"
11506 bld.b\\t%1,@(0,%t0)"
11507 [(set_attr "length" "4,4")])
11509 ;; Store a specified bit of memory in the T bit.
11510 (define_insn "bldsign_m2a"
11511 [(set (reg:SI T_REG)
11513 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11515 (match_operand 1 "const_int_operand" "K03,K03")))]
11516 "TARGET_SH2A && TARGET_BITOPS"
11519 bld.b\\t%1,@(0,%t0)"
11520 [(set_attr "length" "4,4")])
11522 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11523 (define_insn "bld_reg"
11524 [(set (reg:SI T_REG)
11525 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11527 (match_operand 1 "const_int_operand" "K03")))]
11531 (define_insn "*bld_regqi"
11532 [(set (reg:SI T_REG)
11533 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11535 (match_operand 1 "const_int_operand" "K03")))]
11539 ;; Take logical and of a specified bit of memory with the T bit and
11540 ;; store its result in the T bit.
11541 (define_insn "band_m2a"
11542 [(set (reg:SI T_REG)
11543 (and:SI (reg:SI T_REG)
11545 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11547 (match_operand 1 "const_int_operand" "K03,K03"))))]
11548 "TARGET_SH2A && TARGET_BITOPS"
11551 band.b\\t%1,@(0,%t0)"
11552 [(set_attr "length" "4,4")])
11554 (define_insn "bandreg_m2a"
11555 [(set (match_operand:SI 0 "register_operand" "=r,r")
11556 (and:SI (zero_extract:SI
11557 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11559 (match_operand 2 "const_int_operand" "K03,K03"))
11560 (match_operand:SI 3 "register_operand" "r,r")))]
11561 "TARGET_SH2A && TARGET_BITOPS"
11563 band.b\\t%2,%1\;movt\\t%0
11564 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11565 [(set_attr "length" "6,6")])
11567 ;; Take logical or of a specified bit of memory with the T bit and
11568 ;; store its result in the T bit.
11569 (define_insn "bor_m2a"
11570 [(set (reg:SI T_REG)
11571 (ior:SI (reg:SI T_REG)
11573 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11575 (match_operand 1 "const_int_operand" "K03,K03"))))]
11576 "TARGET_SH2A && TARGET_BITOPS"
11579 bor.b\\t%1,@(0,%t0)"
11580 [(set_attr "length" "4,4")])
11582 (define_insn "borreg_m2a"
11583 [(set (match_operand:SI 0 "register_operand" "=r,r")
11584 (ior:SI (zero_extract:SI
11585 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11587 (match_operand 2 "const_int_operand" "K03,K03"))
11588 (match_operand:SI 3 "register_operand" "=r,r")))]
11589 "TARGET_SH2A && TARGET_BITOPS"
11591 bor.b\\t%2,%1\;movt\\t%0
11592 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11593 [(set_attr "length" "6,6")])
11595 ;; Take exclusive or of a specified bit of memory with the T bit and
11596 ;; store its result in the T bit.
11597 (define_insn "bxor_m2a"
11598 [(set (reg:SI T_REG)
11599 (xor:SI (reg:SI T_REG)
11601 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11603 (match_operand 1 "const_int_operand" "K03,K03"))))]
11604 "TARGET_SH2A && TARGET_BITOPS"
11607 bxor.b\\t%1,@(0,%t0)"
11608 [(set_attr "length" "4,4")])
11610 (define_insn "bxorreg_m2a"
11611 [(set (match_operand:SI 0 "register_operand" "=r,r")
11612 (xor:SI (zero_extract:SI
11613 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11615 (match_operand 2 "const_int_operand" "K03,K03"))
11616 (match_operand:SI 3 "register_operand" "=r,r")))]
11617 "TARGET_SH2A && TARGET_BITOPS"
11619 bxor.b\\t%2,%1\;movt\\t%0
11620 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11621 [(set_attr "length" "6,6")])
11624 ;; -------------------------------------------------------------------------
11626 ;; -------------------------------------------------------------------------
11627 ;; This matches cases where the bit in a memory location is set.
11629 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11630 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11632 (ior:SI (match_dup 0)
11633 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11635 (match_operand 3 "arith_reg_operand" "r,r"))]
11636 "TARGET_SH2A && TARGET_BITOPS
11637 && satisfies_constraint_Pso (operands[2])
11638 && REGNO (operands[0]) == REGNO (operands[3])"
11639 [(set (match_dup 1)
11640 (ior:QI (match_dup 1)
11644 ;; This matches cases where the bit in a memory location is cleared.
11646 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11647 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11649 (and:SI (match_dup 0)
11650 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11652 (match_operand 3 "arith_reg_operand" "r,r"))]
11653 "TARGET_SH2A && TARGET_BITOPS
11654 && satisfies_constraint_Psz (operands[2])
11655 && REGNO (operands[0]) == REGNO (operands[3])"
11656 [(set (match_dup 1)
11657 (and:QI (match_dup 1)
11661 ;; This matches cases where a stack pointer increment at the start of the
11662 ;; epilogue combines with a stack slot read loading the return value.
11665 [(set (match_operand:SI 0 "arith_reg_operand" "")
11666 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11667 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11668 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11671 ;; See the comment on the dt combiner pattern above.
11674 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11675 (plus:SI (match_dup 0)
11677 (set (reg:SI T_REG)
11678 (eq:SI (match_dup 0)
11683 ;; The following peepholes fold load sequences for which reload was not
11684 ;; able to generate a displacement addressing move insn.
11685 ;; This can happen when reload has to transform a move insn
11686 ;; without displacement into one with displacement. Or when reload can't
11687 ;; fit a displacement into the insn's constraints. In the latter case, the
11688 ;; load destination reg remains at r0, which reload compensates by inserting
11689 ;; another mov insn.
11693 ;; mov.{b,w} @(r0,r15),r0
11696 ;; mov.{b,w} @(54,r15),r3
11699 [(set (match_operand:SI 0 "arith_reg_dest" "")
11700 (match_operand:SI 1 "const_int_operand" ""))
11701 (set (match_operand:SI 2 "arith_reg_dest" "")
11703 (mem:QI (plus:SI (match_dup 0)
11704 (match_operand:SI 3 "arith_reg_operand" "")))))
11705 (set (match_operand:QI 4 "arith_reg_dest" "")
11706 (match_operand:QI 5 "arith_reg_operand" ""))]
11708 && sh_legitimate_index_p (QImode, operands[1], true, true)
11709 && REGNO (operands[2]) == REGNO (operands[5])
11710 && peep2_reg_dead_p (3, operands[5])"
11711 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
11715 [(set (match_operand:SI 0 "arith_reg_dest" "")
11716 (match_operand:SI 1 "const_int_operand" ""))
11717 (set (match_operand:SI 2 "arith_reg_dest" "")
11719 (mem:HI (plus:SI (match_dup 0)
11720 (match_operand:SI 3 "arith_reg_operand" "")))))
11721 (set (match_operand:HI 4 "arith_reg_dest" "")
11722 (match_operand:HI 5 "arith_reg_operand" ""))]
11724 && sh_legitimate_index_p (HImode, operands[1], true, true)
11725 && REGNO (operands[2]) == REGNO (operands[5])
11726 && peep2_reg_dead_p (3, operands[5])"
11727 [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))]
11732 ;; mov.{b,w} @(r0,r15),r1
11734 ;; mov.{b,w} @(54,r15),r1
11737 [(set (match_operand:SI 0 "arith_reg_dest" "")
11738 (match_operand:SI 1 "const_int_operand" ""))
11739 (set (match_operand:SI 2 "arith_reg_dest" "")
11741 (mem:QI (plus:SI (match_dup 0)
11742 (match_operand:SI 3 "arith_reg_operand" "")))))]
11744 && sh_legitimate_index_p (QImode, operands[1], true, true)
11745 && (peep2_reg_dead_p (2, operands[0])
11746 || REGNO (operands[0]) == REGNO (operands[2]))"
11747 [(set (match_dup 2)
11748 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
11752 [(set (match_operand:SI 0 "arith_reg_dest" "")
11753 (match_operand:SI 1 "const_int_operand" ""))
11754 (set (match_operand:SI 2 "arith_reg_dest" "")
11756 (mem:HI (plus:SI (match_dup 0)
11757 (match_operand:SI 3 "arith_reg_operand" "")))))]
11759 && sh_legitimate_index_p (HImode, operands[1], true, true)
11760 && (peep2_reg_dead_p (2, operands[0])
11761 || REGNO (operands[0]) == REGNO (operands[2]))"
11762 [(set (match_dup 2)
11763 (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))]
11767 ;; mov.{b,w} @(r0,r15),r0
11770 ;; mov.{b,w} @(r0,r15),r3
11772 ;; This can happen when initially a displacement address is picked, where
11773 ;; the destination reg is fixed to r0, and then the address is transformed
11774 ;; into 'r0 + reg'.
11776 [(set (match_operand:SI 0 "arith_reg_dest" "")
11778 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
11779 (match_operand:SI 2 "arith_reg_operand" "")))))
11780 (set (match_operand:QI 3 "arith_reg_dest" "")
11781 (match_operand:QI 4 "arith_reg_operand" ""))]
11783 && REGNO (operands[0]) == REGNO (operands[4])
11784 && peep2_reg_dead_p (2, operands[0])"
11785 [(set (match_dup 3)
11786 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
11790 [(set (match_operand:SI 0 "arith_reg_dest" "")
11792 (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
11793 (match_operand:SI 2 "arith_reg_operand" "")))))
11794 (set (match_operand:HI 3 "arith_reg_dest" "")
11795 (match_operand:HI 4 "arith_reg_operand" ""))]
11797 && REGNO (operands[0]) == REGNO (operands[4])
11798 && peep2_reg_dead_p (2, operands[0])"
11799 [(set (match_dup 3)
11800 (mem:HI (plus:SI (match_dup 1) (match_dup 2))))]
11803 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11804 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11805 ;; reload when the constant is too large for a reg+offset address.
11807 ;; ??? We would get much better code if this was done in reload. This would
11808 ;; require modifying find_reloads_address to recognize that if the constant
11809 ;; is out-of-range for an immediate add, then we get better code by reloading
11810 ;; the constant into a register than by reloading the sum into a register,
11811 ;; since the former is one instruction shorter if the address does not need
11812 ;; to be offsettable. Unfortunately this does not work, because there is
11813 ;; only one register, r0, that can be used as an index register. This register
11814 ;; is also the function return value register. So, if we try to force reload
11815 ;; to use double-reg addresses, then we end up with some instructions that
11816 ;; need to use r0 twice. The only way to fix this is to change the calling
11817 ;; convention so that r0 is not used to return values.
11820 [(set (match_operand:SI 0 "register_operand" "=r")
11821 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11822 (set (mem:SI (match_dup 0))
11823 (match_operand:SI 2 "general_movsrc_operand" ""))]
11824 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11825 "mov.l %2,@(%0,%1)")
11828 [(set (match_operand:SI 0 "register_operand" "=r")
11829 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11830 (set (match_operand:SI 2 "general_movdst_operand" "")
11831 (mem:SI (match_dup 0)))]
11832 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11833 "mov.l @(%0,%1),%2")
11836 [(set (match_operand:SI 0 "register_operand" "=r")
11837 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11838 (set (mem:HI (match_dup 0))
11839 (match_operand:HI 2 "general_movsrc_operand" ""))]
11840 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11841 "mov.w %2,@(%0,%1)")
11844 [(set (match_operand:SI 0 "register_operand" "=r")
11845 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11846 (set (match_operand:HI 2 "general_movdst_operand" "")
11847 (mem:HI (match_dup 0)))]
11848 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11849 "mov.w @(%0,%1),%2")
11852 [(set (match_operand:SI 0 "register_operand" "=r")
11853 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11854 (set (mem:QI (match_dup 0))
11855 (match_operand:QI 2 "general_movsrc_operand" ""))]
11856 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11857 "mov.b %2,@(%0,%1)")
11860 [(set (match_operand:SI 0 "register_operand" "=r")
11861 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11862 (set (match_operand:QI 2 "general_movdst_operand" "")
11863 (mem:QI (match_dup 0)))]
11864 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11865 "mov.b @(%0,%1),%2")
11868 [(set (match_operand:SI 0 "register_operand" "=r")
11869 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11870 (set (mem:SF (match_dup 0))
11871 (match_operand:SF 2 "general_movsrc_operand" ""))]
11872 "TARGET_SH1 && REGNO (operands[0]) == 0
11873 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11874 || (GET_CODE (operands[2]) == SUBREG
11875 && REGNO (SUBREG_REG (operands[2])) < 16))
11876 && reg_unused_after (operands[0], insn)"
11877 "mov.l %2,@(%0,%1)")
11880 [(set (match_operand:SI 0 "register_operand" "=r")
11881 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11882 (set (match_operand:SF 2 "general_movdst_operand" "")
11884 (mem:SF (match_dup 0)))]
11885 "TARGET_SH1 && REGNO (operands[0]) == 0
11886 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11887 || (GET_CODE (operands[2]) == SUBREG
11888 && REGNO (SUBREG_REG (operands[2])) < 16))
11889 && reg_unused_after (operands[0], insn)"
11890 "mov.l @(%0,%1),%2")
11893 [(set (match_operand:SI 0 "register_operand" "=r")
11894 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11895 (set (mem:SF (match_dup 0))
11896 (match_operand:SF 2 "general_movsrc_operand" ""))]
11897 "TARGET_SH2E && REGNO (operands[0]) == 0
11898 && ((REG_P (operands[2])
11899 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11900 || (GET_CODE (operands[2]) == SUBREG
11901 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11902 && reg_unused_after (operands[0], insn)"
11903 "fmov{.s|} %2,@(%0,%1)")
11906 [(set (match_operand:SI 0 "register_operand" "=r")
11907 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11908 (set (match_operand:SF 2 "general_movdst_operand" "")
11910 (mem:SF (match_dup 0)))]
11911 "TARGET_SH2E && REGNO (operands[0]) == 0
11912 && ((REG_P (operands[2])
11913 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11914 || (GET_CODE (operands[2]) == SUBREG
11915 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11916 && reg_unused_after (operands[0], insn)"
11917 "fmov{.s|} @(%0,%1),%2")
11919 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11920 (define_insn "sp_switch_1"
11921 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11924 output_asm_insn ("mov.l r0,@-r15\;mov.l %0,r0", operands);
11925 output_asm_insn ("mov.l @r0,r0\;mov.l r15,@-r0", operands);
11926 return "mov r0,r15";
11928 [(set_attr "length" "10")])
11930 ;; Switch back to the original stack for interrupt functions with the
11931 ;; sp_switch attribute. */
11932 (define_insn "sp_switch_2"
11935 "mov.l @r15+,r15\;mov.l @r15+,r0"
11936 [(set_attr "length" "4")])
11938 ;; Integer vector moves
11940 (define_expand "movv8qi"
11941 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11942 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11945 prepare_move_operands (operands, V8QImode);
11948 (define_insn "movv8qi_i"
11949 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11950 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11952 && (register_operand (operands[0], V8QImode)
11953 || sh_register_operand (operands[1], V8QImode))"
11960 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11961 (set_attr "length" "4,4,16,4,4")])
11964 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11965 (subreg:V8QI (const_int 0) 0))]
11967 [(set (match_dup 0)
11968 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11969 (const_int 0) (const_int 0) (const_int 0)
11970 (const_int 0) (const_int 0)]))])
11973 [(set (match_operand 0 "arith_reg_dest" "")
11974 (match_operand 1 "sh_rep_vec" ""))]
11975 "TARGET_SHMEDIA && reload_completed
11976 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11977 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11978 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11979 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11980 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11981 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11982 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11983 [(set (match_dup 0) (match_dup 1))
11986 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11987 rtx elt1 = XVECEXP (operands[1], 0, 1);
11990 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11994 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11995 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11997 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11998 operands[1] = XVECEXP (operands[1], 0, 0);
12001 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
12003 = GEN_INT (TARGET_LITTLE_ENDIAN
12004 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
12005 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
12008 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
12010 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
12016 [(set (match_operand 0 "arith_reg_dest" "")
12017 (match_operand 1 "sh_const_vec" ""))]
12018 "TARGET_SHMEDIA && reload_completed
12019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
12020 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
12021 [(set (match_dup 0) (match_dup 1))]
12023 rtx v = operands[1];
12024 enum machine_mode new_mode
12025 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
12027 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
12029 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
12032 (define_expand "movv2hi"
12033 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
12034 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
12037 prepare_move_operands (operands, V2HImode);
12040 (define_insn "movv2hi_i"
12041 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12042 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12044 && (register_operand (operands[0], V2HImode)
12045 || sh_register_operand (operands[1], V2HImode))"
12052 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12053 (set_attr "length" "4,4,16,4,4")
12054 (set (attr "highpart")
12055 (cond [(match_test "sh_contains_memref_p (insn)")
12056 (const_string "user")]
12057 (const_string "ignore")))])
12059 (define_expand "movv4hi"
12060 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
12061 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
12064 prepare_move_operands (operands, V4HImode);
12067 (define_insn "movv4hi_i"
12068 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12069 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12071 && (register_operand (operands[0], V4HImode)
12072 || sh_register_operand (operands[1], V4HImode))"
12079 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12080 (set_attr "length" "4,4,16,4,4")
12081 (set_attr "highpart" "depend")])
12083 (define_expand "movv2si"
12084 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
12085 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
12088 prepare_move_operands (operands, V2SImode);
12091 (define_insn "movv2si_i"
12092 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
12093 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12095 && (register_operand (operands[0], V2SImode)
12096 || sh_register_operand (operands[1], V2SImode))"
12103 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
12104 (set_attr "length" "4,4,16,4,4")
12105 (set_attr "highpart" "depend")])
12107 ;; Multimedia Intrinsics
12109 (define_insn "absv2si2"
12110 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12111 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
12114 [(set_attr "type" "mcmp_media")
12115 (set_attr "highpart" "depend")])
12117 (define_insn "absv4hi2"
12118 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12119 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
12122 [(set_attr "type" "mcmp_media")
12123 (set_attr "highpart" "depend")])
12125 (define_insn "addv2si3"
12126 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12127 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12128 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12130 "madd.l %1, %2, %0"
12131 [(set_attr "type" "arith_media")
12132 (set_attr "highpart" "depend")])
12134 (define_insn "addv4hi3"
12135 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12136 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12137 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12139 "madd.w %1, %2, %0"
12140 [(set_attr "type" "arith_media")
12141 (set_attr "highpart" "depend")])
12143 (define_insn_and_split "addv2hi3"
12144 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12145 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12146 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12152 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12153 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12154 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12155 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12156 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12158 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12159 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12162 [(set_attr "highpart" "must_split")])
12164 (define_insn "ssaddv2si3"
12165 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12166 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12167 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12169 "madds.l %1, %2, %0"
12170 [(set_attr "type" "mcmp_media")
12171 (set_attr "highpart" "depend")])
12173 (define_insn "usaddv8qi3"
12174 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12175 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12176 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12178 "madds.ub %1, %2, %0"
12179 [(set_attr "type" "mcmp_media")
12180 (set_attr "highpart" "depend")])
12182 (define_insn "ssaddv4hi3"
12183 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12184 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12185 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12187 "madds.w %1, %2, %0"
12188 [(set_attr "type" "mcmp_media")
12189 (set_attr "highpart" "depend")])
12191 (define_insn "negcmpeqv8qi"
12192 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12193 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12194 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12196 "mcmpeq.b %N1, %N2, %0"
12197 [(set_attr "type" "mcmp_media")
12198 (set_attr "highpart" "depend")])
12200 (define_insn "negcmpeqv2si"
12201 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12202 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12203 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12205 "mcmpeq.l %N1, %N2, %0"
12206 [(set_attr "type" "mcmp_media")
12207 (set_attr "highpart" "depend")])
12209 (define_insn "negcmpeqv4hi"
12210 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12211 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12212 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12214 "mcmpeq.w %N1, %N2, %0"
12215 [(set_attr "type" "mcmp_media")
12216 (set_attr "highpart" "depend")])
12218 (define_insn "negcmpgtuv8qi"
12219 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12220 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12221 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12223 "mcmpgt.ub %N1, %N2, %0"
12224 [(set_attr "type" "mcmp_media")
12225 (set_attr "highpart" "depend")])
12227 (define_insn "negcmpgtv2si"
12228 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12229 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12230 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12232 "mcmpgt.l %N1, %N2, %0"
12233 [(set_attr "type" "mcmp_media")
12234 (set_attr "highpart" "depend")])
12236 (define_insn "negcmpgtv4hi"
12237 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12238 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12239 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12241 "mcmpgt.w %N1, %N2, %0"
12242 [(set_attr "type" "mcmp_media")
12243 (set_attr "highpart" "depend")])
12245 (define_insn "mcmv"
12246 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12247 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12248 (match_operand:DI 2 "arith_reg_operand" "r"))
12249 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12250 (not:DI (match_dup 2)))))]
12253 [(set_attr "type" "arith_media")
12254 (set_attr "highpart" "depend")])
12256 (define_insn "mcnvs_lw"
12257 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12259 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12260 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12262 "mcnvs.lw %N1, %N2, %0"
12263 [(set_attr "type" "mcmp_media")])
12265 (define_insn "mcnvs_wb"
12266 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12268 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12269 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12271 "mcnvs.wb %N1, %N2, %0"
12272 [(set_attr "type" "mcmp_media")])
12274 (define_insn "mcnvs_wub"
12275 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12277 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12278 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12280 "mcnvs.wub %N1, %N2, %0"
12281 [(set_attr "type" "mcmp_media")])
12283 (define_insn "mextr_rl"
12284 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12285 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12286 (match_operand:HI 3 "mextr_bit_offset" "i"))
12287 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12288 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12289 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12291 static char templ[21];
12292 sprintf (templ, "mextr%d\\t%%N1, %%N2, %%0", (int) INTVAL (operands[3]) >> 3);
12295 [(set_attr "type" "arith_media")])
12297 (define_insn "*mextr_lr"
12298 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12299 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12300 (match_operand:HI 3 "mextr_bit_offset" "i"))
12301 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12302 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12303 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12305 static char templ[21];
12306 sprintf (templ, "mextr%d\\t%%N2, %%N1, %%0", (int) INTVAL (operands[4]) >> 3);
12309 [(set_attr "type" "arith_media")])
12311 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12312 ; vector then varies depending on endianness.
12313 (define_expand "mextr1"
12314 [(match_operand:DI 0 "arith_reg_dest" "")
12315 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12316 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12319 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12320 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12324 (define_expand "mextr2"
12325 [(match_operand:DI 0 "arith_reg_dest" "")
12326 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12327 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12330 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12331 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12335 (define_expand "mextr3"
12336 [(match_operand:DI 0 "arith_reg_dest" "")
12337 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12338 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12341 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12342 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12346 (define_expand "mextr4"
12347 [(match_operand:DI 0 "arith_reg_dest" "")
12348 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12349 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12352 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12353 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12357 (define_expand "mextr5"
12358 [(match_operand:DI 0 "arith_reg_dest" "")
12359 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12360 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12363 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12364 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12368 (define_expand "mextr6"
12369 [(match_operand:DI 0 "arith_reg_dest" "")
12370 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12371 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12374 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12375 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12379 (define_expand "mextr7"
12380 [(match_operand:DI 0 "arith_reg_dest" "")
12381 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12382 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12385 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12386 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12390 (define_expand "mmacfx_wl"
12391 [(match_operand:V2SI 0 "arith_reg_dest" "")
12392 (match_operand:V2HI 1 "extend_reg_operand" "")
12393 (match_operand:V2HI 2 "extend_reg_operand" "")
12394 (match_operand:V2SI 3 "arith_reg_operand" "")]
12397 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12398 operands[1], operands[2]));
12402 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12404 (define_insn "mmacfx_wl_i"
12405 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12407 (match_operand:V2SI 1 "arith_reg_operand" "0")
12412 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12413 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12416 "mmacfx.wl %2, %3, %0"
12417 [(set_attr "type" "mac_media")
12418 (set_attr "highpart" "depend")])
12420 (define_expand "mmacnfx_wl"
12421 [(match_operand:V2SI 0 "arith_reg_dest" "")
12422 (match_operand:V2HI 1 "extend_reg_operand" "")
12423 (match_operand:V2HI 2 "extend_reg_operand" "")
12424 (match_operand:V2SI 3 "arith_reg_operand" "")]
12427 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12428 operands[1], operands[2]));
12432 (define_insn "mmacnfx_wl_i"
12433 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12435 (match_operand:V2SI 1 "arith_reg_operand" "0")
12440 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12441 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12444 "mmacnfx.wl %2, %3, %0"
12445 [(set_attr "type" "mac_media")
12446 (set_attr "highpart" "depend")])
12448 (define_insn "mulv2si3"
12449 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12450 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12451 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12453 "mmul.l %1, %2, %0"
12454 [(set_attr "type" "d2mpy_media")
12455 (set_attr "highpart" "depend")])
12457 (define_insn "mulv4hi3"
12458 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12459 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12460 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12462 "mmul.w %1, %2, %0"
12463 [(set_attr "type" "dmpy_media")
12464 (set_attr "highpart" "depend")])
12466 (define_insn "mmulfx_l"
12467 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12471 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12472 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12475 "mmulfx.l %1, %2, %0"
12476 [(set_attr "type" "d2mpy_media")
12477 (set_attr "highpart" "depend")])
12479 (define_insn "mmulfx_w"
12480 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12484 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12485 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12488 "mmulfx.w %1, %2, %0"
12489 [(set_attr "type" "dmpy_media")
12490 (set_attr "highpart" "depend")])
12492 (define_insn "mmulfxrp_w"
12493 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12498 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12499 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12503 "mmulfxrp.w %1, %2, %0"
12504 [(set_attr "type" "dmpy_media")
12505 (set_attr "highpart" "depend")])
12508 (define_expand "mmulhi_wl"
12509 [(match_operand:V2SI 0 "arith_reg_dest" "")
12510 (match_operand:V4HI 1 "arith_reg_operand" "")
12511 (match_operand:V4HI 2 "arith_reg_operand" "")]
12514 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12515 (operands[0], operands[1], operands[2]));
12519 (define_expand "mmullo_wl"
12520 [(match_operand:V2SI 0 "arith_reg_dest" "")
12521 (match_operand:V4HI 1 "arith_reg_operand" "")
12522 (match_operand:V4HI 2 "arith_reg_operand" "")]
12525 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12526 (operands[0], operands[1], operands[2]));
12530 (define_insn "mmul23_wl"
12531 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12534 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12535 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12536 (parallel [(const_int 2) (const_int 3)])))]
12539 return (TARGET_LITTLE_ENDIAN
12540 ? "mmulhi.wl %1, %2, %0"
12541 : "mmullo.wl %1, %2, %0");
12543 [(set_attr "type" "dmpy_media")
12544 (set (attr "highpart")
12545 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12546 (const_string "user")))])
12548 (define_insn "mmul01_wl"
12549 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12552 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12553 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12554 (parallel [(const_int 0) (const_int 1)])))]
12557 return (TARGET_LITTLE_ENDIAN
12558 ? "mmullo.wl %1, %2, %0"
12559 : "mmulhi.wl %1, %2, %0");
12561 [(set_attr "type" "dmpy_media")
12562 (set (attr "highpart")
12563 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12564 (const_string "user")))])
12567 (define_expand "mmulsum_wq"
12568 [(match_operand:DI 0 "arith_reg_dest" "")
12569 (match_operand:V4HI 1 "arith_reg_operand" "")
12570 (match_operand:V4HI 2 "arith_reg_operand" "")
12571 (match_operand:DI 3 "arith_reg_operand" "")]
12574 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12575 operands[1], operands[2]));
12579 (define_insn "mmulsum_wq_i"
12580 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12581 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12586 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12587 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12588 (parallel [(const_int 0)]))
12589 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12590 (sign_extend:V4DI (match_dup 3)))
12591 (parallel [(const_int 1)])))
12593 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12594 (sign_extend:V4DI (match_dup 3)))
12595 (parallel [(const_int 2)]))
12596 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12597 (sign_extend:V4DI (match_dup 3)))
12598 (parallel [(const_int 3)]))))))]
12600 "mmulsum.wq %2, %3, %0"
12601 [(set_attr "type" "mac_media")])
12603 (define_expand "mperm_w"
12604 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12605 (match_operand:V4HI 1 "arith_reg_operand" "r")
12606 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12609 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12610 (operands[0], operands[1], operands[2]));
12614 ; This use of vec_select isn't exactly correct according to rtl.texi
12615 ; (because not constant), but it seems a straightforward extension.
12616 (define_insn "mperm_w_little"
12617 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12619 (match_operand:V4HI 1 "arith_reg_operand" "r")
12621 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12622 (const_int 2) (const_int 0))
12623 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12624 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12625 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12626 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12627 "mperm.w %1, %N2, %0"
12628 [(set_attr "type" "arith_media")])
12630 (define_insn "mperm_w_big"
12631 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12633 (match_operand:V4HI 1 "arith_reg_operand" "r")
12635 [(zero_extract:QI (not:QI (match_operand:QI 2
12636 "extend_reg_or_0_operand" "rZ"))
12637 (const_int 2) (const_int 0))
12638 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12639 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12640 (zero_extract:QI (not:QI (match_dup 2))
12641 (const_int 2) (const_int 6))])))]
12642 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12643 "mperm.w %1, %N2, %0"
12644 [(set_attr "type" "arith_media")])
12646 (define_insn "mperm_w0"
12647 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12648 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12649 "trunc_hi_operand" "r"))))]
12651 "mperm.w %1, r63, %0"
12652 [(set_attr "type" "arith_media")
12653 (set_attr "highpart" "ignore")])
12655 (define_expand "msad_ubq"
12656 [(match_operand:DI 0 "arith_reg_dest" "")
12657 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12658 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12659 (match_operand:DI 3 "arith_reg_operand" "")]
12662 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12663 operands[1], operands[2]));
12667 (define_insn "msad_ubq_i"
12668 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12673 (match_operand:DI 1 "arith_reg_operand" "0")
12674 (abs:DI (vec_select:DI
12677 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12679 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12680 (parallel [(const_int 0)]))))
12681 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12682 (zero_extend:V8DI (match_dup 3)))
12683 (parallel [(const_int 1)]))))
12685 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12686 (zero_extend:V8DI (match_dup 3)))
12687 (parallel [(const_int 2)])))
12688 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12689 (zero_extend:V8DI (match_dup 3)))
12690 (parallel [(const_int 3)])))))
12693 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12694 (zero_extend:V8DI (match_dup 3)))
12695 (parallel [(const_int 4)])))
12696 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12697 (zero_extend:V8DI (match_dup 3)))
12698 (parallel [(const_int 5)]))))
12700 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12701 (zero_extend:V8DI (match_dup 3)))
12702 (parallel [(const_int 6)])))
12703 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12704 (zero_extend:V8DI (match_dup 3)))
12705 (parallel [(const_int 7)])))))))]
12707 "msad.ubq %N2, %N3, %0"
12708 [(set_attr "type" "mac_media")])
12710 (define_insn "mshalds_l"
12711 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12714 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12715 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12716 (const_int 31)))))]
12718 "mshalds.l %1, %2, %0"
12719 [(set_attr "type" "mcmp_media")
12720 (set_attr "highpart" "depend")])
12722 (define_insn "mshalds_w"
12723 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12726 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12727 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12728 (const_int 15)))))]
12730 "mshalds.w %1, %2, %0"
12731 [(set_attr "type" "mcmp_media")
12732 (set_attr "highpart" "depend")])
12734 (define_insn "ashrv2si3"
12735 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12736 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12737 (match_operand:DI 2 "arith_reg_operand" "r")))]
12739 "mshard.l %1, %2, %0"
12740 [(set_attr "type" "arith_media")
12741 (set_attr "highpart" "depend")])
12743 (define_insn "ashrv4hi3"
12744 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12745 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12746 (match_operand:DI 2 "arith_reg_operand" "r")))]
12748 "mshard.w %1, %2, %0"
12749 [(set_attr "type" "arith_media")
12750 (set_attr "highpart" "depend")])
12752 (define_insn "mshards_q"
12753 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12755 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12756 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12758 "mshards.q %1, %N2, %0"
12759 [(set_attr "type" "mcmp_media")])
12761 (define_expand "mshfhi_b"
12762 [(match_operand:V8QI 0 "arith_reg_dest" "")
12763 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12764 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12767 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12768 (operands[0], operands[1], operands[2]));
12772 (define_expand "mshflo_b"
12773 [(match_operand:V8QI 0 "arith_reg_dest" "")
12774 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12775 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12778 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12779 (operands[0], operands[1], operands[2]));
12783 (define_insn "mshf4_b"
12785 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12787 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12788 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12789 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12790 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12793 return (TARGET_LITTLE_ENDIAN
12794 ? "mshfhi.b %N1, %N2, %0"
12795 : "mshflo.b %N1, %N2, %0");
12797 [(set_attr "type" "arith_media")
12798 (set (attr "highpart")
12799 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12800 (const_string "user")))])
12802 (define_insn "mshf0_b"
12804 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12806 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12807 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12808 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12809 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12812 return (TARGET_LITTLE_ENDIAN
12813 ? "mshflo.b %N1, %N2, %0"
12814 : "mshfhi.b %N1, %N2, %0");
12816 [(set_attr "type" "arith_media")
12817 (set (attr "highpart")
12818 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12819 (const_string "user")))])
12821 (define_expand "mshfhi_l"
12822 [(match_operand:V2SI 0 "arith_reg_dest" "")
12823 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12824 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12827 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12828 (operands[0], operands[1], operands[2]));
12832 (define_expand "mshflo_l"
12833 [(match_operand:V2SI 0 "arith_reg_dest" "")
12834 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12835 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12838 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12839 (operands[0], operands[1], operands[2]));
12843 (define_insn "mshf4_l"
12844 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12846 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12847 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12848 (parallel [(const_int 1) (const_int 3)])))]
12851 return (TARGET_LITTLE_ENDIAN
12852 ? "mshfhi.l %N1, %N2, %0"
12853 : "mshflo.l %N1, %N2, %0");
12855 [(set_attr "type" "arith_media")
12856 (set (attr "highpart")
12857 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12858 (const_string "user")))])
12860 (define_insn "mshf0_l"
12861 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12863 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12864 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12865 (parallel [(const_int 0) (const_int 2)])))]
12868 return (TARGET_LITTLE_ENDIAN
12869 ? "mshflo.l %N1, %N2, %0"
12870 : "mshfhi.l %N1, %N2, %0");
12872 [(set_attr "type" "arith_media")
12873 (set (attr "highpart")
12874 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12875 (const_string "user")))])
12877 (define_expand "mshfhi_w"
12878 [(match_operand:V4HI 0 "arith_reg_dest" "")
12879 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12880 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12883 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12884 (operands[0], operands[1], operands[2]));
12888 (define_expand "mshflo_w"
12889 [(match_operand:V4HI 0 "arith_reg_dest" "")
12890 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12891 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12894 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12895 (operands[0], operands[1], operands[2]));
12899 (define_insn "mshf4_w"
12900 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12902 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12903 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12904 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12907 return (TARGET_LITTLE_ENDIAN
12908 ? "mshfhi.w %N1, %N2, %0"
12909 : "mshflo.w %N1, %N2, %0");
12911 [(set_attr "type" "arith_media")
12912 (set (attr "highpart")
12913 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12914 (const_string "user")))])
12916 (define_insn "mshf0_w"
12917 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12919 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12920 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12921 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12924 return (TARGET_LITTLE_ENDIAN
12925 ? "mshflo.w %N1, %N2, %0"
12926 : "mshfhi.w %N1, %N2, %0");
12928 [(set_attr "type" "arith_media")
12929 (set (attr "highpart")
12930 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12931 (const_string "user")))])
12933 (define_insn "mshflo_w_x"
12934 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12936 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12937 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12938 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12940 "mshflo.w %N1, %N2, %0"
12941 [(set_attr "type" "arith_media")
12942 (set_attr "highpart" "ignore")])
12944 ;; These are useful to expand ANDs and as combiner patterns.
12945 (define_insn_and_split "mshfhi_l_di"
12946 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12947 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12949 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12950 (const_int -4294967296))))]
12953 mshfhi.l %N1, %N2, %0
12955 "TARGET_SHMEDIA && reload_completed
12956 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12957 [(set (match_dup 3) (match_dup 4))
12958 (set (match_dup 5) (match_dup 6))]
12960 operands[3] = gen_lowpart (SImode, operands[0]);
12961 operands[4] = gen_highpart (SImode, operands[1]);
12962 operands[5] = gen_highpart (SImode, operands[0]);
12963 operands[6] = gen_highpart (SImode, operands[2]);
12965 [(set_attr "type" "arith_media")])
12967 (define_insn "*mshfhi_l_di_rev"
12968 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12969 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12970 (const_int -4294967296))
12971 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12974 "mshfhi.l %N2, %N1, %0"
12975 [(set_attr "type" "arith_media")])
12978 [(set (match_operand:DI 0 "arith_reg_dest" "")
12979 (ior:DI (zero_extend:DI (match_operand:SI 1
12980 "extend_reg_or_0_operand" ""))
12981 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12982 (const_int -4294967296))))
12983 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12987 emit_insn (gen_ashldi3_media (operands[3],
12988 simplify_gen_subreg (DImode, operands[1],
12991 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12995 (define_insn "mshflo_l_di"
12996 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12997 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12998 (const_int 4294967295))
12999 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13003 "mshflo.l %N1, %N2, %0"
13004 [(set_attr "type" "arith_media")
13005 (set_attr "highpart" "ignore")])
13007 (define_insn "*mshflo_l_di_rev"
13008 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13009 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13011 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13012 (const_int 4294967295))))]
13015 "mshflo.l %N2, %N1, %0"
13016 [(set_attr "type" "arith_media")
13017 (set_attr "highpart" "ignore")])
13019 ;; Combiner pattern for trampoline initialization.
13020 (define_insn_and_split "*double_shori"
13021 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13022 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
13024 (match_operand:DI 2 "const_int_operand" "n")))]
13026 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
13028 "rtx_equal_p (operands[0], operands[1])"
13031 HOST_WIDE_INT v = INTVAL (operands[2]);
13033 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
13034 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
13037 [(set_attr "highpart" "ignore")])
13040 (define_insn "*mshflo_l_di_x"
13041 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13042 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
13044 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13048 "mshflo.l %N1, %N2, %0"
13049 [(set_attr "type" "arith_media")
13050 (set_attr "highpart" "ignore")])
13052 (define_insn_and_split "concat_v2sf"
13053 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
13054 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
13055 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
13056 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
13060 mshflo.l %N1, %N2, %0
13063 "TARGET_SHMEDIA && reload_completed
13064 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13065 [(set (match_dup 3) (match_dup 1))
13066 (set (match_dup 4) (match_dup 2))]
13068 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
13069 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
13071 [(set_attr "type" "arith_media")
13072 (set_attr "highpart" "ignore")])
13074 (define_insn "*mshflo_l_di_x_rev"
13075 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13076 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13078 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
13081 "mshflo.l %N2, %N1, %0"
13082 [(set_attr "type" "arith_media")
13083 (set_attr "highpart" "ignore")])
13085 (define_insn "ashlv2si3"
13086 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13087 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13088 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13090 "mshlld.l %1, %2, %0"
13091 [(set_attr "type" "arith_media")
13092 (set_attr "highpart" "depend")])
13095 [(set (match_operand 0 "any_register_operand" "")
13096 (match_operator 3 "shift_operator"
13097 [(match_operand 1 "any_register_operand" "")
13098 (match_operand 2 "shift_count_reg_operand" "")]))]
13099 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
13100 [(set (match_dup 0) (match_dup 3))]
13102 rtx count = operands[2];
13103 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
13105 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
13106 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
13107 || GET_CODE (count) == TRUNCATE)
13108 count = XEXP (count, 0);
13109 inner_mode = GET_MODE (count);
13110 count = simplify_gen_subreg (outer_mode, count, inner_mode,
13111 subreg_lowpart_offset (outer_mode, inner_mode));
13112 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
13113 operands[1], count);
13116 (define_insn "ashlv4hi3"
13117 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13118 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13119 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13121 "mshlld.w %1, %2, %0"
13122 [(set_attr "type" "arith_media")
13123 (set_attr "highpart" "depend")])
13125 (define_insn "lshrv2si3"
13126 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13127 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13128 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13130 "mshlrd.l %1, %2, %0"
13131 [(set_attr "type" "arith_media")
13132 (set_attr "highpart" "depend")])
13134 (define_insn "lshrv4hi3"
13135 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13136 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13137 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13139 "mshlrd.w %1, %2, %0"
13140 [(set_attr "type" "arith_media")
13141 (set_attr "highpart" "depend")])
13143 (define_insn "subv2si3"
13144 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13145 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13146 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13148 "msub.l %N1, %2, %0"
13149 [(set_attr "type" "arith_media")
13150 (set_attr "highpart" "depend")])
13152 (define_insn "subv4hi3"
13153 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13154 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13155 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13157 "msub.w %N1, %2, %0"
13158 [(set_attr "type" "arith_media")
13159 (set_attr "highpart" "depend")])
13161 (define_insn_and_split "subv2hi3"
13162 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13163 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13164 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13170 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13171 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13172 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13173 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13174 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13176 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13177 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13180 [(set_attr "highpart" "must_split")])
13182 (define_insn "sssubv2si3"
13183 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13184 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13185 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13187 "msubs.l %N1, %2, %0"
13188 [(set_attr "type" "mcmp_media")
13189 (set_attr "highpart" "depend")])
13191 (define_insn "ussubv8qi3"
13192 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13193 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13194 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13196 "msubs.ub %N1, %2, %0"
13197 [(set_attr "type" "mcmp_media")
13198 (set_attr "highpart" "depend")])
13200 (define_insn "sssubv4hi3"
13201 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13202 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13203 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13205 "msubs.w %N1, %2, %0"
13206 [(set_attr "type" "mcmp_media")
13207 (set_attr "highpart" "depend")])
13209 ;; Floating Point Intrinsics
13211 (define_insn "fcosa_s"
13212 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13213 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13217 [(set_attr "type" "atrans_media")])
13219 (define_insn "fsina_s"
13220 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13221 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13225 [(set_attr "type" "atrans_media")])
13227 (define_insn "fipr"
13228 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13229 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13230 "fp_arith_reg_operand" "f")
13231 (match_operand:V4SF 2
13232 "fp_arith_reg_operand" "f"))
13233 (parallel [(const_int 0)]))
13234 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13235 (parallel [(const_int 1)])))
13236 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13237 (parallel [(const_int 2)]))
13238 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13239 (parallel [(const_int 3)])))))]
13241 "fipr.s %1, %2, %0"
13242 [(set_attr "type" "fparith_media")])
13244 (define_insn "fsrra_s"
13245 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13246 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13250 [(set_attr "type" "atrans_media")])
13252 (define_insn "ftrv"
13253 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13257 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13258 (parallel [(const_int 0) (const_int 5)
13259 (const_int 10) (const_int 15)]))
13260 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13262 (vec_select:V4SF (match_dup 1)
13263 (parallel [(const_int 4) (const_int 9)
13264 (const_int 14) (const_int 3)]))
13265 (vec_select:V4SF (match_dup 2)
13266 (parallel [(const_int 1) (const_int 2)
13267 (const_int 3) (const_int 0)]))))
13270 (vec_select:V4SF (match_dup 1)
13271 (parallel [(const_int 8) (const_int 13)
13272 (const_int 2) (const_int 7)]))
13273 (vec_select:V4SF (match_dup 2)
13274 (parallel [(const_int 2) (const_int 3)
13275 (const_int 0) (const_int 1)])))
13277 (vec_select:V4SF (match_dup 1)
13278 (parallel [(const_int 12) (const_int 1)
13279 (const_int 6) (const_int 11)]))
13280 (vec_select:V4SF (match_dup 2)
13281 (parallel [(const_int 3) (const_int 0)
13282 (const_int 1) (const_int 2)]))))))]
13284 "ftrv.s %1, %2, %0"
13285 [(set_attr "type" "fparith_media")])
13287 (define_insn "ldhi_l"
13288 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13290 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13293 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13297 [(set_attr "type" "load_media")])
13299 (define_insn "ldhi_q"
13300 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13302 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13305 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13309 [(set_attr "type" "load_media")])
13311 (define_insn_and_split "*ldhi_q_comb0"
13312 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13314 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13315 "register_operand" "r")
13316 (match_operand:SI 2
13317 "ua_offset" "I06"))
13320 (plus:SI (and:SI (match_dup 1) (const_int 7))
13323 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13328 emit_insn (gen_ldhi_q (operands[0],
13329 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13333 (define_insn_and_split "*ldhi_q_comb1"
13334 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13336 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13337 "register_operand" "r")
13338 (match_operand:SI 2
13339 "ua_offset" "I06"))
13342 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13343 "ua_offset" "I06"))
13347 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13348 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13353 emit_insn (gen_ldhi_q (operands[0],
13354 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13358 (define_insn "ldlo_l"
13359 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13361 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13363 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13364 (and:SI (match_dup 1) (const_int 3))))]
13367 [(set_attr "type" "load_media")])
13369 (define_insn "ldlo_q"
13370 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13372 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13374 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13375 (and:SI (match_dup 1) (const_int 7))))]
13378 [(set_attr "type" "load_media")])
13380 (define_insn_and_split "*ldlo_q_comb0"
13381 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13383 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13384 (match_operand:SI 2 "ua_offset" "I06"))
13386 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13387 (and:SI (match_dup 1) (const_int 7))))]
13388 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13393 emit_insn (gen_ldlo_q (operands[0],
13394 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13398 (define_insn_and_split "*ldlo_q_comb1"
13399 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13401 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13402 (match_operand:SI 2 "ua_offset" "I06"))
13404 (minus:SI (const_int 8)
13405 (and:SI (plus:SI (match_dup 1)
13406 (match_operand:SI 3 "ua_offset" "I06"))
13408 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13409 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13410 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13415 emit_insn (gen_ldlo_q (operands[0],
13416 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13420 (define_insn "sthi_l"
13421 [(set (zero_extract:SI
13422 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13425 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13427 (match_operand:SI 1 "arith_reg_operand" "r"))]
13430 [(set_attr "type" "ustore_media")])
13432 ;; All unaligned stores are considered to be 'narrow' because they typically
13433 ;; operate on less that a quadword, and when they operate on a full quadword,
13434 ;; the vanilla store high / store low sequence will cause a stall if not
13435 ;; scheduled apart.
13436 (define_insn "sthi_q"
13437 [(set (zero_extract:DI
13438 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13441 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13443 (match_operand:DI 1 "arith_reg_operand" "r"))]
13446 [(set_attr "type" "ustore_media")])
13448 (define_insn_and_split "*sthi_q_comb0"
13449 [(set (zero_extract:DI
13450 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13451 "register_operand" "r")
13452 (match_operand:SI 1 "ua_offset"
13456 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13458 (match_operand:DI 2 "arith_reg_operand" "r"))]
13459 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13464 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13469 (define_insn_and_split "*sthi_q_comb1"
13470 [(set (zero_extract:DI
13471 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13472 "register_operand" "r")
13473 (match_operand:SI 1 "ua_offset"
13477 (plus:SI (and:SI (plus:SI (match_dup 0)
13478 (match_operand:SI 2 "ua_offset" "I06"))
13482 (match_operand:DI 3 "arith_reg_operand" "r"))]
13483 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13484 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13489 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13494 ;; This is highpart user because the address is used as full 64 bit.
13495 (define_insn "stlo_l"
13496 [(set (zero_extract:SI
13497 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13499 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13500 (and:SI (match_dup 0) (const_int 3)))
13501 (match_operand:SI 1 "arith_reg_operand" "r"))]
13504 [(set_attr "type" "ustore_media")])
13506 (define_insn "stlo_q"
13507 [(set (zero_extract:DI
13508 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13510 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13511 (and:SI (match_dup 0) (const_int 7)))
13512 (match_operand:DI 1 "arith_reg_operand" "r"))]
13515 [(set_attr "type" "ustore_media")])
13517 (define_insn_and_split "*stlo_q_comb0"
13518 [(set (zero_extract:DI
13519 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13520 (match_operand:SI 1 "ua_offset" "I06"))
13522 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13523 (and:SI (match_dup 0) (const_int 7)))
13524 (match_operand:DI 2 "arith_reg_operand" "r"))]
13525 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13530 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13535 (define_insn_and_split "*stlo_q_comb1"
13536 [(set (zero_extract:DI
13537 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13538 (match_operand:SI 1 "ua_offset" "I06"))
13540 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13541 (match_operand:SI 2
13542 "ua_offset" "I06"))
13544 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13545 (match_operand:DI 3 "arith_reg_operand" "r"))]
13546 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13551 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13556 (define_insn "ldhi_l64"
13557 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13559 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13562 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13566 [(set_attr "type" "load_media")])
13568 (define_insn "ldhi_q64"
13569 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13571 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13574 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13578 [(set_attr "type" "load_media")])
13580 (define_insn "ldlo_l64"
13581 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13583 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13585 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13586 (and:DI (match_dup 1) (const_int 3))))]
13589 [(set_attr "type" "load_media")])
13591 (define_insn "ldlo_q64"
13592 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13594 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13596 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13597 (and:DI (match_dup 1) (const_int 7))))]
13600 [(set_attr "type" "load_media")])
13602 (define_insn "sthi_l64"
13603 [(set (zero_extract:SI
13604 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13607 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13609 (match_operand:SI 1 "arith_reg_operand" "r"))]
13612 [(set_attr "type" "ustore_media")])
13614 (define_insn "sthi_q64"
13615 [(set (zero_extract:DI
13616 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13619 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13621 (match_operand:DI 1 "arith_reg_operand" "r"))]
13624 [(set_attr "type" "ustore_media")])
13626 (define_insn "stlo_l64"
13627 [(set (zero_extract:SI
13628 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13630 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13631 (and:DI (match_dup 0) (const_int 3)))
13632 (match_operand:SI 1 "arith_reg_operand" "r"))]
13635 [(set_attr "type" "ustore_media")])
13637 (define_insn "stlo_q64"
13638 [(set (zero_extract:DI
13639 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13641 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13642 (and:DI (match_dup 0) (const_int 7)))
13643 (match_operand:DI 1 "arith_reg_operand" "r"))]
13646 [(set_attr "type" "ustore_media")])
13649 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13650 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13654 [(set_attr "type" "arith_media")])
13656 (define_insn "nsbsi"
13657 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13659 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13663 [(set_attr "type" "arith_media")])
13665 (define_insn "nsbdi"
13666 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13668 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13672 [(set_attr "type" "arith_media")])
13674 (define_expand "ffsdi2"
13675 [(set (match_operand:DI 0 "arith_reg_dest" "")
13676 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13679 rtx scratch = gen_reg_rtx (DImode);
13682 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13683 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13684 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13685 emit_insn (gen_nsbdi (scratch, scratch));
13686 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13687 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13688 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13689 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13694 (define_expand "ffssi2"
13695 [(set (match_operand:SI 0 "arith_reg_dest" "")
13696 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13699 rtx scratch = gen_reg_rtx (SImode);
13700 rtx discratch = gen_reg_rtx (DImode);
13703 emit_insn (gen_adddi3 (discratch,
13704 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13706 emit_insn (gen_andcdi3 (discratch,
13707 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13709 emit_insn (gen_nsbsi (scratch, discratch));
13710 last = emit_insn (gen_subsi3 (operands[0],
13711 force_reg (SImode, GEN_INT (63)), scratch));
13712 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13717 (define_insn "byterev"
13718 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13719 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13720 (parallel [(const_int 7) (const_int 6) (const_int 5)
13721 (const_int 4) (const_int 3) (const_int 2)
13722 (const_int 1) (const_int 0)])))]
13725 [(set_attr "type" "arith_media")])
13727 (define_insn "*prefetch_media"
13728 [(prefetch (match_operand:QI 0 "address_operand" "p")
13729 (match_operand:SI 1 "const_int_operand" "n")
13730 (match_operand:SI 2 "const_int_operand" "n"))]
13733 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13734 output_asm_insn ("ld%M0.b %m0,r63", operands);
13737 [(set_attr "type" "other")])
13739 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13740 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13741 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13742 (define_expand "prefetch"
13743 [(prefetch (match_operand 0 "address_operand" "p")
13744 (match_operand:SI 1 "const_int_operand" "n")
13745 (match_operand:SI 2 "const_int_operand" "n"))]
13746 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13747 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13749 if (GET_MODE (operands[0]) != Pmode
13750 || !CONST_INT_P (operands[1])
13751 || !CONST_INT_P (operands[2]))
13753 if (! TARGET_SHMEDIA)
13754 operands[0] = force_reg (Pmode, operands[0]);
13757 (define_insn "*prefetch"
13758 [(prefetch (match_operand:SI 0 "register_operand" "r")
13759 (match_operand:SI 1 "const_int_operand" "n")
13760 (match_operand:SI 2 "const_int_operand" "n"))]
13761 "(TARGET_SH2A || TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13763 [(set_attr "type" "other")])
13765 (define_insn "alloco_i"
13766 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13767 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13772 if (GET_CODE (operands[0]) == PLUS)
13774 xops[0] = XEXP (operands[0], 0);
13775 xops[1] = XEXP (operands[0], 1);
13779 xops[0] = operands[0];
13780 xops[1] = const0_rtx;
13782 output_asm_insn ("alloco %0, %1", xops);
13785 [(set_attr "type" "other")])
13788 [(set (match_operand 0 "any_register_operand" "")
13789 (match_operand 1 "" ""))]
13790 "TARGET_SHMEDIA && reload_completed"
13791 [(set (match_dup 0) (match_dup 1))]
13795 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13800 ; Stack Protector Patterns
13802 (define_expand "stack_protect_set"
13803 [(set (match_operand 0 "memory_operand" "")
13804 (match_operand 1 "memory_operand" ""))]
13807 if (TARGET_SHMEDIA)
13809 if (TARGET_SHMEDIA64)
13810 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13812 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13815 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13820 (define_insn "stack_protect_set_si"
13821 [(set (match_operand:SI 0 "memory_operand" "=m")
13822 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13823 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13825 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13826 [(set_attr "type" "other")
13827 (set_attr "length" "6")])
13829 (define_insn "stack_protect_set_si_media"
13830 [(set (match_operand:SI 0 "memory_operand" "=m")
13831 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13832 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13834 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13835 [(set_attr "type" "other")
13836 (set_attr "length" "12")])
13838 (define_insn "stack_protect_set_di_media"
13839 [(set (match_operand:DI 0 "memory_operand" "=m")
13840 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13841 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13843 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13844 [(set_attr "type" "other")
13845 (set_attr "length" "12")])
13847 (define_expand "stack_protect_test"
13848 [(match_operand 0 "memory_operand" "")
13849 (match_operand 1 "memory_operand" "")
13850 (match_operand 2 "" "")]
13853 if (TARGET_SHMEDIA)
13855 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13858 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13859 if (TARGET_SHMEDIA64)
13861 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13863 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13867 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13869 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13874 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13875 emit_jump_insn (gen_branch_true (operands[2], get_t_reg_rtx ()));
13881 (define_insn "stack_protect_test_si"
13882 [(set (reg:SI T_REG)
13883 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13884 (match_operand:SI 1 "memory_operand" "m")]
13886 (set (match_scratch:SI 2 "=&r") (const_int 0))
13887 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13889 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13890 [(set_attr "type" "other")
13891 (set_attr "length" "10")])
13893 (define_insn "stack_protect_test_si_media"
13894 [(set (match_operand:SI 0 "register_operand" "=&r")
13895 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13896 (match_operand:SI 2 "memory_operand" "m")]
13898 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13900 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13901 [(set_attr "type" "other")
13902 (set_attr "length" "16")])
13904 (define_insn "stack_protect_test_di_media"
13905 [(set (match_operand:DI 0 "register_operand" "=&r")
13906 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13907 (match_operand:DI 2 "memory_operand" "m")]
13909 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13911 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13912 [(set_attr "type" "other")
13913 (set_attr "length" "16")])
13915 (include "sync.md")