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 ;; annuled 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 unecessary 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"))
912 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
914 [(set_attr "length" "6")
915 (set_attr "type" "arith3b")])
917 (define_insn "cmpeqdi_t"
919 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
920 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
923 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
924 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
925 [(set_attr "length" "6")
926 (set_attr "type" "arith3b")])
930 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
931 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
932 ;; If we applied this split when not optimizing, it would only be
933 ;; applied during the machine-dependent reorg, when no new basic blocks
935 "TARGET_SH1 && reload_completed && optimize"
936 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
937 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
938 (label_ref (match_dup 6))
940 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
944 = gen_rtx_REG (SImode,
945 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
947 = (operands[1] == const0_rtx
949 : gen_rtx_REG (SImode,
950 true_regnum (operands[1])
951 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
952 operands[4] = gen_lowpart (SImode, operands[0]);
953 operands[5] = gen_lowpart (SImode, operands[1]);
954 operands[6] = gen_label_rtx ();
957 (define_insn "cmpgtdi_t"
959 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
960 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
963 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
964 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
965 [(set_attr "length" "8")
966 (set_attr "type" "arith3")])
968 (define_insn "cmpgedi_t"
970 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
971 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
974 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
976 [(set_attr "length" "8,2")
977 (set_attr "type" "arith3,mt_group")])
979 ;; -------------------------------------------------------------------------
980 ;; DImode unsigned integer comparisons
981 ;; -------------------------------------------------------------------------
983 (define_insn "cmpgeudi_t"
985 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
986 (match_operand:DI 1 "arith_reg_operand" "r")))]
988 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
989 [(set_attr "length" "8")
990 (set_attr "type" "arith3")])
992 (define_insn "cmpgtudi_t"
994 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
995 (match_operand:DI 1 "arith_reg_operand" "r")))]
997 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
998 [(set_attr "length" "8")
999 (set_attr "type" "arith3")])
1001 (define_insn "cmpeqsi_media"
1002 [(set (match_operand:SI 0 "register_operand" "=r")
1003 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1004 (match_operand:SI 2 "cmp_operand" "Nr")))]
1007 [(set_attr "type" "cmp_media")])
1009 (define_insn "cmpeqdi_media"
1010 [(set (match_operand:SI 0 "register_operand" "=r")
1011 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1012 (match_operand:DI 2 "cmp_operand" "Nr")))]
1015 [(set_attr "type" "cmp_media")])
1017 (define_insn "cmpgtsi_media"
1018 [(set (match_operand:SI 0 "register_operand" "=r")
1019 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1020 (match_operand:SI 2 "cmp_operand" "rN")))]
1022 "cmpgt %N1, %N2, %0"
1023 [(set_attr "type" "cmp_media")])
1025 (define_insn "cmpgtdi_media"
1026 [(set (match_operand:SI 0 "register_operand" "=r")
1027 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1028 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1030 "cmpgt %N1, %N2, %0"
1031 [(set_attr "type" "cmp_media")])
1033 (define_insn "cmpgtusi_media"
1034 [(set (match_operand:SI 0 "register_operand" "=r")
1035 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1036 (match_operand:SI 2 "cmp_operand" "rN")))]
1038 "cmpgtu %N1, %N2, %0"
1039 [(set_attr "type" "cmp_media")])
1041 (define_insn "cmpgtudi_media"
1042 [(set (match_operand:SI 0 "register_operand" "=r")
1043 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1044 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1046 "cmpgtu %N1, %N2, %0"
1047 [(set_attr "type" "cmp_media")])
1049 ; These two patterns are for combine.
1050 (define_insn "*cmpne0sisi_media"
1051 [(set (match_operand:SI 0 "register_operand" "=r")
1052 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1055 [(set_attr "type" "cmp_media")])
1057 ;; -------------------------------------------------------------------------
1058 ;; Conditional move instructions
1059 ;; -------------------------------------------------------------------------
1061 ;; The insn names may seem reversed, but note that cmveq performs the move
1062 ;; if op1 == 0, and cmvne does it if op1 != 0.
1064 (define_insn "movdicc_false"
1065 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1066 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1068 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1069 (match_operand:DI 3 "arith_reg_operand" "0")))]
1072 [(set_attr "type" "arith_media")])
1074 (define_insn "movdicc_true"
1075 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1076 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1078 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1079 (match_operand:DI 3 "arith_reg_operand" "0")))]
1082 [(set_attr "type" "arith_media")])
1085 [(set (match_operand:DI 0 "arith_reg_dest" "")
1086 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1087 [(match_operand:DI 1 "arith_reg_operand" "")
1089 (match_operand:DI 2 "arith_reg_dest" "")
1091 (set (match_dup 2) (match_dup 0))]
1092 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1094 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1096 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1097 VOIDmode, operands[1], CONST0_RTX (DImode));
1101 [(set (match_operand:DI 0 "general_movdst_operand" "")
1102 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1103 (set (match_operand:DI 2 "arith_reg_dest" "")
1104 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1105 [(match_operand:DI 3 "arith_reg_operand" "")
1109 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1111 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1114 (define_expand "movdicc"
1115 [(set (match_operand:DI 0 "register_operand" "")
1116 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1117 (match_operand:DI 2 "register_operand" "")
1118 (match_operand:DI 3 "register_operand" "")))]
1121 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1122 && GET_MODE (XEXP (operands[1], 0)) == DImode
1123 && XEXP (operands[1], 1) == const0_rtx)
1127 if (!can_create_pseudo_p ())
1130 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1131 GET_CODE (operands[1]),
1132 XEXP (operands[1], 0),
1133 XEXP (operands[1], 1));
1139 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1140 ;; SImode to DImode.
1141 (define_insn "movsicc_false"
1142 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1143 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1145 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1146 (match_operand:SI 3 "arith_reg_operand" "0")))]
1149 [(set_attr "type" "arith_media")])
1151 (define_insn "movsicc_true"
1152 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1153 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1155 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1156 (match_operand:SI 3 "arith_reg_operand" "0")))]
1159 [(set_attr "type" "arith_media")])
1162 [(set (match_operand:SI 0 "arith_reg_dest" "")
1163 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1164 [(match_operand:SI 1 "arith_reg_operand" "")
1166 (match_operand:SI 2 "arith_reg_dest" "")
1168 (set (match_dup 2) (match_dup 0))]
1169 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1171 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1173 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1174 VOIDmode, operands[1], CONST0_RTX (SImode));
1178 [(set (match_operand:SI 0 "general_movdst_operand" "")
1179 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1180 (set (match_operand:SI 2 "arith_reg_dest" "")
1181 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1182 [(match_operand:SI 3 "arith_reg_operand" "")
1186 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1187 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1189 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1191 replace_rtx (operands[4], operands[0], operands[1]);
1195 [(set (match_operand 0 "any_register_operand" "")
1196 (match_operand 1 "any_register_operand" ""))
1197 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1198 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1199 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1200 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1201 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1202 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1203 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1204 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1205 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1206 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1207 && (REGNO_REG_CLASS (REGNO (operands[0]))
1208 == REGNO_REG_CLASS (REGNO (operands[2])))
1209 && (REGNO_REG_CLASS (REGNO (operands[1]))
1210 == REGNO_REG_CLASS (REGNO (operands[0])))"
1211 [(set (match_dup 0) (match_dup 3))
1212 (set (match_dup 4) (match_dup 5))]
1214 rtx set1, set2, insn2;
1215 rtx replacements[4];
1217 /* We want to replace occurrences of operands[0] with operands[1] and
1218 operands[2] with operands[0] in operands[4]/operands[5].
1219 Doing just two replace_rtx calls naively would result in the second
1220 replacement undoing all that the first did if operands[1] and operands[2]
1221 are identical, so we must do this simultaneously. */
1222 replacements[0] = operands[0];
1223 replacements[1] = operands[1];
1224 replacements[2] = operands[2];
1225 replacements[3] = operands[0];
1226 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1227 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1228 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1231 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1232 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1233 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1234 /* The operands array is aliased to recog_data.operand, which gets
1235 clobbered by extract_insn, so finish with it now. */
1236 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1237 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1238 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1239 always uses emit_insn. */
1240 /* Check that we don't violate matching constraints or earlyclobbers. */
1241 extract_insn (emit_insn (set1));
1242 if (! constrain_operands (1))
1244 insn2 = emit (set2);
1245 if (GET_CODE (insn2) == BARRIER)
1247 extract_insn (insn2);
1248 if (! constrain_operands (1))
1252 tmp = replacements[0];
1253 replacements[0] = replacements[1];
1254 replacements[1] = tmp;
1255 tmp = replacements[2];
1256 replacements[2] = replacements[3];
1257 replacements[3] = tmp;
1258 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1259 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1260 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1266 ;; The register allocator is rather clumsy in handling multi-way conditional
1267 ;; moves, so allow the combiner to make them, and we split them up after
1269 (define_insn_and_split "*movsicc_umin"
1270 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1271 (umin:SI (if_then_else:SI
1272 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1274 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1275 (match_operand:SI 3 "register_operand" "0"))
1276 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1277 (clobber (match_scratch:SI 5 "=&r"))]
1278 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1280 "TARGET_SHMEDIA && reload_completed"
1283 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1285 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1286 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1291 (define_insn "*movsicc_t_false"
1292 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1293 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1294 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1295 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1296 "TARGET_PRETEND_CMOVE
1297 && (arith_reg_operand (operands[1], SImode)
1298 || (immediate_operand (operands[1], SImode)
1299 && satisfies_constraint_I08 (operands[1])))"
1300 "bt 0f\;mov %1,%0\\n0:"
1301 [(set_attr "type" "mt_group,arith") ;; poor approximation
1302 (set_attr "length" "4")])
1304 (define_insn "*movsicc_t_true"
1305 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1306 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1307 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1308 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1309 "TARGET_PRETEND_CMOVE
1310 && (arith_reg_operand (operands[1], SImode)
1311 || (immediate_operand (operands[1], SImode)
1312 && satisfies_constraint_I08 (operands[1])))"
1313 "bf 0f\;mov %1,%0\\n0:"
1314 [(set_attr "type" "mt_group,arith") ;; poor approximation
1315 (set_attr "length" "4")])
1317 (define_expand "movsicc"
1318 [(set (match_operand:SI 0 "arith_reg_dest" "")
1319 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1320 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1321 (match_operand:SI 3 "arith_reg_operand" "")))]
1322 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1324 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1325 && GET_MODE (XEXP (operands[1], 0)) == SImode
1327 || (REG_P (XEXP (operands[1], 0))
1328 && REGNO (XEXP (operands[1], 0)) == T_REG))
1329 && XEXP (operands[1], 1) == const0_rtx)
1332 else if (TARGET_PRETEND_CMOVE)
1334 enum rtx_code code = GET_CODE (operands[1]);
1335 enum rtx_code new_code = code;
1336 rtx op0 = XEXP (operands[1], 0);
1337 rtx op1 = XEXP (operands[1], 1);
1339 if (! currently_expanding_to_rtl)
1343 case LT: case LE: case LEU: case LTU:
1344 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1347 new_code = reverse_condition (code);
1349 case EQ: case GT: case GE: case GEU: case GTU:
1354 sh_emit_scc_to_t (new_code, op0, op1);
1355 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1356 gen_rtx_REG (SImode, T_REG), const0_rtx);
1360 if (!can_create_pseudo_p ())
1363 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1364 GET_CODE (operands[1]),
1365 XEXP (operands[1], 0),
1366 XEXP (operands[1], 1));
1372 (define_expand "movqicc"
1373 [(set (match_operand:QI 0 "register_operand" "")
1374 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375 (match_operand:QI 2 "register_operand" "")
1376 (match_operand:QI 3 "register_operand" "")))]
1379 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1380 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1381 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1382 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1386 ;; -------------------------------------------------------------------------
1387 ;; Addition instructions
1388 ;; -------------------------------------------------------------------------
1390 (define_expand "adddi3"
1391 [(set (match_operand:DI 0 "arith_reg_operand" "")
1392 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1393 (match_operand:DI 2 "arith_operand" "")))]
1398 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1400 operands[2] = force_reg (DImode, operands[2]);
1401 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1406 (define_insn "*adddi3_media"
1407 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1408 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1409 (match_operand:DI 2 "arith_operand" "r,I10")))]
1414 [(set_attr "type" "arith_media")])
1416 (define_insn "*adddisi3_media"
1417 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1418 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1419 (match_operand:DI 2 "arith_operand" "r,I10")))]
1424 [(set_attr "type" "arith_media")
1425 (set_attr "highpart" "ignore")])
1427 (define_insn "adddi3z_media"
1428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1430 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1431 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1433 "addz.l %1, %N2, %0"
1434 [(set_attr "type" "arith_media")
1435 (set_attr "highpart" "ignore")])
1437 (define_insn "adddi3_compact"
1438 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1439 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1440 (match_operand:DI 2 "arith_reg_operand" "r")))
1441 (clobber (reg:SI T_REG))]
1444 [(set_attr "length" "6")])
1447 [(set (match_operand:DI 0 "arith_reg_dest" "")
1448 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1449 (match_operand:DI 2 "arith_reg_operand" "")))
1450 (clobber (reg:SI T_REG))]
1451 "TARGET_SH1 && reload_completed"
1454 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1455 high0 = gen_rtx_REG (SImode,
1456 true_regnum (operands[0])
1457 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1458 high2 = gen_rtx_REG (SImode,
1459 true_regnum (operands[2])
1460 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461 emit_insn (gen_clrt ());
1462 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1463 emit_insn (gen_addc1 (high0, high0, high2));
1468 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1469 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1470 (match_operand:SI 2 "arith_reg_operand" "r"))
1473 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1476 [(set_attr "type" "arith")])
1478 (define_insn "addc1"
1479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481 (match_operand:SI 2 "arith_reg_operand" "r"))
1483 (clobber (reg:SI T_REG))]
1486 [(set_attr "type" "arith")])
1488 (define_expand "addsi3"
1489 [(set (match_operand:SI 0 "arith_reg_operand" "")
1490 (plus:SI (match_operand:SI 1 "arith_operand" "")
1491 (match_operand:SI 2 "arith_operand" "")))]
1495 operands[1] = force_reg (SImode, operands[1]);
1498 (define_insn "addsi3_media"
1499 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1500 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1501 (match_operand:SI 2 "arith_operand" "r,I10")))]
1506 [(set_attr "type" "arith_media")
1507 (set_attr "highpart" "ignore")])
1509 (define_insn "addsidi3_media"
1510 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1511 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1513 (match_operand:SI 2 "arith_operand"
1519 [(set_attr "type" "arith_media")
1520 (set_attr "highpart" "ignore")])
1522 (define_insn "*addsi3_compact"
1523 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1524 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1525 (match_operand:SI 2 "arith_operand" "rI08")))]
1528 [(set_attr "type" "arith")])
1530 ;; -------------------------------------------------------------------------
1531 ;; Subtraction instructions
1532 ;; -------------------------------------------------------------------------
1534 (define_expand "subdi3"
1535 [(set (match_operand:DI 0 "arith_reg_operand" "")
1536 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1537 (match_operand:DI 2 "arith_reg_operand" "")))]
1542 operands[1] = force_reg (DImode, operands[1]);
1543 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1548 (define_insn "*subdi3_media"
1549 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1550 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1551 (match_operand:DI 2 "arith_reg_operand" "r")))]
1554 [(set_attr "type" "arith_media")])
1556 (define_insn "subdisi3_media"
1557 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1558 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1559 (match_operand:DI 2 "arith_reg_operand" "r")))]
1562 [(set_attr "type" "arith_media")
1563 (set_attr "highpart" "ignore")])
1565 (define_insn "subdi3_compact"
1566 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1567 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1568 (match_operand:DI 2 "arith_reg_operand" "r")))
1569 (clobber (reg:SI T_REG))]
1572 [(set_attr "length" "6")])
1575 [(set (match_operand:DI 0 "arith_reg_dest" "")
1576 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1577 (match_operand:DI 2 "arith_reg_operand" "")))
1578 (clobber (reg:SI T_REG))]
1579 "TARGET_SH1 && reload_completed"
1582 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1583 high0 = gen_rtx_REG (SImode,
1584 true_regnum (operands[0])
1585 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1586 high2 = gen_rtx_REG (SImode,
1587 true_regnum (operands[2])
1588 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1589 emit_insn (gen_clrt ());
1590 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1591 emit_insn (gen_subc1 (high0, high0, high2));
1596 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1597 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1598 (match_operand:SI 2 "arith_reg_operand" "r"))
1601 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1606 [(set_attr "type" "arith")])
1608 (define_insn "subc1"
1609 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1610 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1611 (match_operand:SI 2 "arith_reg_operand" "r"))
1613 (clobber (reg:SI T_REG))]
1616 [(set_attr "type" "arith")])
1618 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1619 ;; pattern for this case. This helps multimedia applications that compute
1620 ;; the sum of absolute differences.
1621 (define_insn "mov_neg_si_t"
1622 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1625 [(set_attr "type" "arith")])
1627 (define_insn "*subsi3_internal"
1628 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1629 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630 (match_operand:SI 2 "arith_reg_operand" "r")))]
1633 [(set_attr "type" "arith")])
1635 (define_insn_and_split "*subsi3_media"
1636 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1637 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1638 (match_operand:SI 2 "extend_reg_operand" "r")))]
1640 && (operands[1] != constm1_rtx
1641 || (GET_CODE (operands[2]) != TRUNCATE
1642 && GET_CODE (operands[2]) != SUBREG))"
1644 "operands[1] == constm1_rtx"
1645 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1647 [(set_attr "type" "arith_media")
1648 (set_attr "highpart" "ignore")])
1651 [(set (match_operand:SI 0 "arith_reg_dest" "")
1652 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1653 "general_extend_operand"
1655 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1656 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1657 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1661 [(set (match_operand:SI 0 "arith_reg_dest" "")
1662 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1663 "general_extend_operand"
1665 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1666 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1667 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1669 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1670 ;; will sometimes save one instruction. Otherwise we might get
1671 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1674 (define_expand "subsi3"
1675 [(set (match_operand:SI 0 "arith_reg_operand" "")
1676 (minus:SI (match_operand:SI 1 "arith_operand" "")
1677 (match_operand:SI 2 "arith_reg_operand" "")))]
1680 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1682 emit_insn (gen_negsi2 (operands[0], operands[2]));
1683 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1688 if (!can_create_pseudo_p ()
1689 && ! arith_reg_or_0_operand (operands[1], SImode))
1691 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1692 operands[1] = force_reg (SImode, operands[1]);
1696 ;; -------------------------------------------------------------------------
1697 ;; Division instructions
1698 ;; -------------------------------------------------------------------------
1700 ;; We take advantage of the library routines which don't clobber as many
1701 ;; registers as a normal function call would.
1703 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1704 ;; also has an effect on the register that holds the address of the sfunc.
1705 ;; To make this work, we have an extra dummy insn that shows the use
1706 ;; of this register for reorg.
1708 (define_insn "use_sfunc_addr"
1709 [(set (reg:SI PR_REG)
1710 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1711 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1713 [(set_attr "length" "0")])
1715 (define_insn "udivsi3_sh2a"
1716 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1717 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1718 (match_operand:SI 2 "arith_reg_operand" "z")))]
1721 [(set_attr "type" "arith")
1722 (set_attr "in_delay_slot" "no")])
1724 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1725 ;; hard register 0. If we used hard register 0, then the next instruction
1726 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1727 ;; gets allocated to a stack slot that needs its address reloaded, then
1728 ;; there is nothing to prevent reload from using r0 to reload the address.
1729 ;; This reload would clobber the value in r0 we are trying to store.
1730 ;; If we let reload allocate r0, then this problem can never happen.
1732 (define_insn "udivsi3_i1"
1733 [(set (match_operand:SI 0 "register_operand" "=z")
1734 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1735 (clobber (reg:SI T_REG))
1736 (clobber (reg:SI PR_REG))
1737 (clobber (reg:SI R4_REG))
1738 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1739 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1741 [(set_attr "type" "sfunc")
1742 (set_attr "needs_delay_slot" "yes")])
1744 ; Since shmedia-nofpu code could be linked against shcompact code, and
1745 ; the udivsi3 libcall has the same name, we must consider all registers
1746 ; clobbered that are in the union of the registers clobbered by the
1747 ; shmedia and the shcompact implementation. Note, if the shcompact
1748 ; implementation actually used shcompact code, we'd need to clobber
1749 ; also r23 and fr23.
1750 (define_insn "udivsi3_i1_media"
1751 [(set (match_operand:SI 0 "register_operand" "=z")
1752 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1753 (clobber (reg:SI T_MEDIA_REG))
1754 (clobber (reg:SI PR_MEDIA_REG))
1755 (clobber (reg:SI R20_REG))
1756 (clobber (reg:SI R21_REG))
1757 (clobber (reg:SI R22_REG))
1758 (clobber (reg:DI TR0_REG))
1759 (clobber (reg:DI TR1_REG))
1760 (clobber (reg:DI TR2_REG))
1761 (use (match_operand 1 "target_reg_operand" "b"))]
1762 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1764 [(set_attr "type" "sfunc")
1765 (set_attr "needs_delay_slot" "yes")])
1767 (define_expand "udivsi3_i4_media"
1769 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1771 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1772 (set (match_dup 5) (float:DF (match_dup 3)))
1773 (set (match_dup 6) (float:DF (match_dup 4)))
1774 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1775 (set (match_dup 8) (fix:DI (match_dup 7)))
1776 (set (match_operand:SI 0 "register_operand" "")
1777 (truncate:SI (match_dup 8)))]
1778 "TARGET_SHMEDIA_FPU"
1780 operands[3] = gen_reg_rtx (DImode);
1781 operands[4] = gen_reg_rtx (DImode);
1782 operands[5] = gen_reg_rtx (DFmode);
1783 operands[6] = gen_reg_rtx (DFmode);
1784 operands[7] = gen_reg_rtx (DFmode);
1785 operands[8] = gen_reg_rtx (DImode);
1788 (define_insn "udivsi3_i4"
1789 [(set (match_operand:SI 0 "register_operand" "=y")
1790 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1791 (clobber (reg:SI T_REG))
1792 (clobber (reg:SI PR_REG))
1793 (clobber (reg:DF DR0_REG))
1794 (clobber (reg:DF DR2_REG))
1795 (clobber (reg:DF DR4_REG))
1796 (clobber (reg:SI R0_REG))
1797 (clobber (reg:SI R1_REG))
1798 (clobber (reg:SI R4_REG))
1799 (clobber (reg:SI R5_REG))
1800 (use (reg:PSI FPSCR_REG))
1801 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1802 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1804 [(set_attr "type" "sfunc")
1805 (set_attr "fp_mode" "double")
1806 (set_attr "needs_delay_slot" "yes")])
1808 (define_insn "udivsi3_i4_single"
1809 [(set (match_operand:SI 0 "register_operand" "=y")
1810 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1811 (clobber (reg:SI T_REG))
1812 (clobber (reg:SI PR_REG))
1813 (clobber (reg:DF DR0_REG))
1814 (clobber (reg:DF DR2_REG))
1815 (clobber (reg:DF DR4_REG))
1816 (clobber (reg:SI R0_REG))
1817 (clobber (reg:SI R1_REG))
1818 (clobber (reg:SI R4_REG))
1819 (clobber (reg:SI R5_REG))
1820 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1821 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1823 [(set_attr "type" "sfunc")
1824 (set_attr "needs_delay_slot" "yes")])
1826 (define_insn "udivsi3_i4_int"
1827 [(set (match_operand:SI 0 "register_operand" "=z")
1828 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829 (clobber (reg:SI T_REG))
1830 (clobber (reg:SI R1_REG))
1831 (clobber (reg:SI PR_REG))
1832 (clobber (reg:SI MACH_REG))
1833 (clobber (reg:SI MACL_REG))
1834 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1837 [(set_attr "type" "sfunc")
1838 (set_attr "needs_delay_slot" "yes")])
1841 (define_expand "udivsi3"
1842 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1843 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1844 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1845 (parallel [(set (match_operand:SI 0 "register_operand" "")
1846 (udiv:SI (reg:SI R4_REG)
1848 (clobber (reg:SI T_REG))
1849 (clobber (reg:SI PR_REG))
1850 (clobber (reg:SI R4_REG))
1851 (use (match_dup 3))])]
1856 operands[3] = gen_reg_rtx (Pmode);
1857 /* Emit the move of the address to a pseudo outside of the libcall. */
1858 if (TARGET_DIVIDE_CALL_TABLE)
1860 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1861 that causes problems when the divide code is supposed to come from a
1862 separate library. Division by zero is undefined, so dividing 1 can be
1863 implemented by comparing with the divisor. */
1864 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1866 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1867 emit_insn (gen_cstoresi4 (operands[0], test,
1868 operands[1], operands[2]));
1871 else if (operands[2] == const0_rtx)
1873 emit_move_insn (operands[0], operands[2]);
1876 function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
1877 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1879 else if (TARGET_DIVIDE_CALL_FP)
1881 function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
1882 if (TARGET_FPU_SINGLE)
1883 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1885 last = gen_udivsi3_i4 (operands[0], operands[3]);
1887 else if (TARGET_SHMEDIA_FPU)
1889 operands[1] = force_reg (SImode, operands[1]);
1890 operands[2] = force_reg (SImode, operands[2]);
1891 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1894 else if (TARGET_SH2A)
1896 operands[1] = force_reg (SImode, operands[1]);
1897 operands[2] = force_reg (SImode, operands[2]);
1898 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1901 else if (TARGET_SH5)
1903 function_symbol (operands[3],
1904 TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
1908 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1909 else if (TARGET_FPU_ANY)
1910 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1912 last = gen_udivsi3_i1 (operands[0], operands[3]);
1916 function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
1917 last = gen_udivsi3_i1 (operands[0], operands[3]);
1919 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1920 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1925 (define_insn "divsi3_sh2a"
1926 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1927 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1928 (match_operand:SI 2 "arith_reg_operand" "z")))]
1931 [(set_attr "type" "arith")
1932 (set_attr "in_delay_slot" "no")])
1934 (define_insn "divsi3_i1"
1935 [(set (match_operand:SI 0 "register_operand" "=z")
1936 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1937 (clobber (reg:SI T_REG))
1938 (clobber (reg:SI PR_REG))
1939 (clobber (reg:SI R1_REG))
1940 (clobber (reg:SI R2_REG))
1941 (clobber (reg:SI R3_REG))
1942 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1943 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1945 [(set_attr "type" "sfunc")
1946 (set_attr "needs_delay_slot" "yes")])
1948 (define_insn "divsi3_i1_media"
1949 [(set (match_operand:SI 0 "register_operand" "=z")
1950 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1951 (clobber (reg:SI T_MEDIA_REG))
1952 (clobber (reg:SI PR_MEDIA_REG))
1953 (clobber (reg:SI R1_REG))
1954 (clobber (reg:SI R20_REG))
1955 (clobber (reg:SI R21_REG))
1956 (clobber (reg:SI TR0_REG))
1957 (use (match_operand 1 "target_reg_operand" "b"))]
1958 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1960 [(set_attr "type" "sfunc")])
1962 (define_insn "divsi3_media_2"
1963 [(set (match_operand:SI 0 "register_operand" "=z")
1964 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1965 (clobber (reg:SI T_MEDIA_REG))
1966 (clobber (reg:SI PR_MEDIA_REG))
1967 (clobber (reg:SI R1_REG))
1968 (clobber (reg:SI R21_REG))
1969 (clobber (reg:SI TR0_REG))
1970 (use (reg:SI R20_REG))
1971 (use (match_operand 1 "target_reg_operand" "b"))]
1972 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1974 [(set_attr "type" "sfunc")])
1976 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1977 ;; hard reg clobbers and data dependencies that we need when we want
1978 ;; to rematerialize the division into a call.
1979 (define_insn_and_split "divsi_inv_call"
1980 [(set (match_operand:SI 0 "register_operand" "=r")
1981 (div:SI (match_operand:SI 1 "register_operand" "r")
1982 (match_operand:SI 2 "register_operand" "r")))
1983 (clobber (reg:SI R4_REG))
1984 (clobber (reg:SI R5_REG))
1985 (clobber (reg:SI T_MEDIA_REG))
1986 (clobber (reg:SI PR_MEDIA_REG))
1987 (clobber (reg:SI R1_REG))
1988 (clobber (reg:SI R21_REG))
1989 (clobber (reg:SI TR0_REG))
1990 (clobber (reg:SI R20_REG))
1991 (use (match_operand:SI 3 "register_operand" "r"))]
1994 "&& (high_life_started || reload_completed)"
1995 [(set (match_dup 0) (match_dup 3))]
1997 [(set_attr "highpart" "must_split")])
1999 ;; This is the combiner pattern for -mdiv=inv:call .
2000 (define_insn_and_split "*divsi_inv_call_combine"
2001 [(set (match_operand:SI 0 "register_operand" "=z")
2002 (div:SI (match_operand:SI 1 "register_operand" "r")
2003 (match_operand:SI 2 "register_operand" "r")))
2004 (clobber (reg:SI R4_REG))
2005 (clobber (reg:SI R5_REG))
2006 (clobber (reg:SI T_MEDIA_REG))
2007 (clobber (reg:SI PR_MEDIA_REG))
2008 (clobber (reg:SI R1_REG))
2009 (clobber (reg:SI R21_REG))
2010 (clobber (reg:SI TR0_REG))
2011 (clobber (reg:SI R20_REG))
2012 (use (unspec:SI [(match_dup 1)
2013 (match_operand:SI 3 "" "")
2014 (unspec:SI [(match_operand:SI 4 "" "")
2016 (match_operand:DI 5 "" "")]
2018 (match_operand:DI 6 "" "")
2021 UNSPEC_DIV_INV_M3))]
2024 "&& (high_life_started || reload_completed)"
2027 const char *name = sh_divsi3_libfunc;
2028 enum sh_function_kind kind = SFUNC_GOT;
2031 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2032 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2033 while (TARGET_DIVIDE_INV_CALL2)
2035 rtx x = operands[3];
2037 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2039 x = XVECEXP (x, 0, 0);
2040 name = "__sdivsi3_2";
2041 kind = SFUNC_STATIC;
2042 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2045 sym = function_symbol (NULL, name, kind);
2046 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2049 [(set_attr "highpart" "must_split")])
2051 (define_expand "divsi3_i4_media"
2052 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2053 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2054 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2055 (set (match_operand:SI 0 "register_operand" "=r")
2056 (fix:SI (match_dup 5)))]
2057 "TARGET_SHMEDIA_FPU"
2059 operands[3] = gen_reg_rtx (DFmode);
2060 operands[4] = gen_reg_rtx (DFmode);
2061 operands[5] = gen_reg_rtx (DFmode);
2064 (define_insn "divsi3_i4"
2065 [(set (match_operand:SI 0 "register_operand" "=y")
2066 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2067 (clobber (reg:SI PR_REG))
2068 (clobber (reg:DF DR0_REG))
2069 (clobber (reg:DF DR2_REG))
2070 (use (reg:PSI FPSCR_REG))
2071 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2072 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2074 [(set_attr "type" "sfunc")
2075 (set_attr "fp_mode" "double")
2076 (set_attr "needs_delay_slot" "yes")])
2078 (define_insn "divsi3_i4_single"
2079 [(set (match_operand:SI 0 "register_operand" "=y")
2080 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2081 (clobber (reg:SI PR_REG))
2082 (clobber (reg:DF DR0_REG))
2083 (clobber (reg:DF DR2_REG))
2084 (clobber (reg:SI R2_REG))
2085 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2086 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2088 [(set_attr "type" "sfunc")
2089 (set_attr "needs_delay_slot" "yes")])
2091 (define_insn "divsi3_i4_int"
2092 [(set (match_operand:SI 0 "register_operand" "=z")
2093 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2094 (clobber (reg:SI T_REG))
2095 (clobber (reg:SI PR_REG))
2096 (clobber (reg:SI R1_REG))
2097 (clobber (reg:SI MACH_REG))
2098 (clobber (reg:SI MACL_REG))
2099 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2102 [(set_attr "type" "sfunc")
2103 (set_attr "needs_delay_slot" "yes")])
2105 (define_expand "divsi3"
2106 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2107 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2108 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2109 (parallel [(set (match_operand:SI 0 "register_operand" "")
2110 (div:SI (reg:SI R4_REG)
2112 (clobber (reg:SI T_REG))
2113 (clobber (reg:SI PR_REG))
2114 (clobber (reg:SI R1_REG))
2115 (clobber (reg:SI R2_REG))
2116 (clobber (reg:SI R3_REG))
2117 (use (match_dup 3))])]
2122 operands[3] = gen_reg_rtx (Pmode);
2123 /* Emit the move of the address to a pseudo outside of the libcall. */
2124 if (TARGET_DIVIDE_CALL_TABLE)
2126 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2127 last = gen_divsi3_i4_int (operands[0], operands[3]);
2129 else if (TARGET_DIVIDE_CALL_FP)
2131 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2132 if (TARGET_FPU_SINGLE)
2133 last = gen_divsi3_i4_single (operands[0], operands[3]);
2135 last = gen_divsi3_i4 (operands[0], operands[3]);
2137 else if (TARGET_SH2A)
2139 operands[1] = force_reg (SImode, operands[1]);
2140 operands[2] = force_reg (SImode, operands[2]);
2141 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2144 else if (TARGET_DIVIDE_INV)
2146 rtx dividend = operands[1];
2147 rtx divisor = operands[2];
2149 rtx nsb_res = gen_reg_rtx (DImode);
2150 rtx norm64 = gen_reg_rtx (DImode);
2151 rtx tab_ix = gen_reg_rtx (DImode);
2152 rtx norm32 = gen_reg_rtx (SImode);
2153 rtx i92 = force_reg (DImode, GEN_INT (92));
2154 rtx scratch0a = gen_reg_rtx (DImode);
2155 rtx scratch0b = gen_reg_rtx (DImode);
2156 rtx inv0 = gen_reg_rtx (SImode);
2157 rtx scratch1a = gen_reg_rtx (DImode);
2158 rtx scratch1b = gen_reg_rtx (DImode);
2159 rtx shift = gen_reg_rtx (DImode);
2161 rtx inv1 = gen_reg_rtx (SImode);
2162 rtx scratch2a = gen_reg_rtx (DImode);
2163 rtx scratch2b = gen_reg_rtx (SImode);
2164 rtx inv2 = gen_reg_rtx (SImode);
2165 rtx scratch3a = gen_reg_rtx (DImode);
2166 rtx scratch3b = gen_reg_rtx (DImode);
2167 rtx scratch3c = gen_reg_rtx (DImode);
2168 rtx scratch3d = gen_reg_rtx (SImode);
2169 rtx scratch3e = gen_reg_rtx (DImode);
2170 rtx result = gen_reg_rtx (SImode);
2172 if (! arith_reg_or_0_operand (dividend, SImode))
2173 dividend = force_reg (SImode, dividend);
2174 if (! arith_reg_operand (divisor, SImode))
2175 divisor = force_reg (SImode, divisor);
2176 if (flag_pic && Pmode != DImode)
2178 tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2179 tab_base = gen_datalabel_ref (tab_base);
2180 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2184 tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2185 tab_base = gen_datalabel_ref (tab_base);
2186 tab_base = force_reg (DImode, tab_base);
2188 if (TARGET_DIVIDE_INV20U)
2189 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2191 i2p27 = GEN_INT (0);
2192 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2193 i43 = force_reg (DImode, GEN_INT (43));
2196 emit_insn (gen_nsbdi (nsb_res,
2197 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2198 emit_insn (gen_ashldi3_media (norm64,
2199 gen_rtx_SUBREG (DImode, divisor, 0),
2201 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2202 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2203 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2204 inv0, scratch0a, scratch0b,
2205 scratch1a, scratch1b));
2206 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2207 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2209 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2211 scratch3a, scratch3b, scratch3c,
2212 scratch2a, scratch2b, scratch3d, scratch3e));
2213 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2214 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2215 else if (TARGET_DIVIDE_INV_FP)
2216 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2217 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2218 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2219 gen_reg_rtx (DFmode)));
2221 emit_move_insn (operands[0], result);
2224 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2226 operands[1] = force_reg (SImode, operands[1]);
2227 operands[2] = force_reg (SImode, operands[2]);
2228 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2231 else if (TARGET_SH5)
2233 if (TARGET_DIVIDE_CALL2)
2235 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2236 tab_base = gen_datalabel_ref (tab_base);
2237 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2239 if (TARGET_FPU_ANY && TARGET_SH1)
2240 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2241 else if (TARGET_DIVIDE_CALL2)
2242 function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2244 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2247 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2248 (operands[0], operands[3]));
2249 else if (TARGET_FPU_ANY)
2250 last = gen_divsi3_i4_single (operands[0], operands[3]);
2252 last = gen_divsi3_i1 (operands[0], operands[3]);
2256 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2257 last = gen_divsi3_i1 (operands[0], operands[3]);
2259 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2260 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2265 ;; operands: scratch, tab_base, tab_ix
2266 ;; These are unspecs because we could generate an indexed addressing mode
2267 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2268 ;; confuse reload. See PR27117.
2270 (define_insn "divsi_inv_qitable"
2271 [(set (match_operand:DI 0 "register_operand" "=r")
2272 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2273 (match_operand:DI 2 "register_operand" "r")]
2274 UNSPEC_DIV_INV_TABLE)))]
2278 [(set_attr "type" "load_media")
2279 (set_attr "highpart" "user")])
2281 ;; operands: scratch, tab_base, tab_ix
2282 (define_insn "divsi_inv_hitable"
2283 [(set (match_operand:DI 0 "register_operand" "=r")
2284 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2285 (match_operand:DI 2 "register_operand" "r")]
2286 UNSPEC_DIV_INV_TABLE)))]
2290 [(set_attr "type" "load_media")
2291 (set_attr "highpart" "user")])
2293 ;; operands: inv0, tab_base, tab_ix, norm32
2294 ;; scratch equiv in sdivsi3_2: r19, r21
2295 (define_expand "divsi_inv_m0"
2296 [(set (match_operand:SI 0 "register_operand" "=r")
2297 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2298 (match_operand:DI 2 "register_operand" "r")
2299 (match_operand:SI 3 "register_operand" "r")]
2301 (clobber (match_operand:DI 4 "register_operand" "=r"))
2302 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2309 ldx.ub r20, r21, r19 // u0.8
2311 muls.l r25, r19, r19 // s2.38
2312 ldx.w r20, r21, r21 // s2.14
2313 shari r19, 24, r19 // truncate to s2.14
2314 sub r21, r19, r19 // some 11 bit inverse in s1.14
2317 rtx inv0 = operands[0];
2318 rtx tab_base = operands[1];
2319 rtx tab_ix = operands[2];
2320 rtx norm32 = operands[3];
2321 rtx scratch0 = operands[4];
2322 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2323 rtx scratch1 = operands[5];
2325 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2326 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2327 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2328 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2329 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2330 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2334 ;; operands: inv1, tab_base, tab_ix, norm32
2335 (define_insn_and_split "divsi_inv_m1"
2336 [(set (match_operand:SI 0 "register_operand" "=r")
2337 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2338 (match_operand:DI 2 "register_operand" "r")
2339 (match_operand:SI 3 "register_operand" "r")]
2341 (clobber (match_operand:SI 4 "register_operand" "=r"))
2342 (clobber (match_operand:DI 5 "register_operand" "=r"))
2343 (clobber (match_operand:DI 6 "register_operand" "=r"))
2344 (clobber (match_operand:DI 7 "register_operand" "=r"))
2345 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2348 "&& !can_create_pseudo_p ()"
2352 muls.l r19, r19, r18 // u0.28
2353 muls.l r25, r18, r18 // s2.58
2354 shlli r19, 45, r0 // multiply by two and convert to s2.58
2356 shari r18, 28, r18 // some 18 bit inverse in s1.30
2359 rtx inv1 = operands[0];
2360 rtx tab_base = operands[1];
2361 rtx tab_ix = operands[2];
2362 rtx norm32 = operands[3];
2363 rtx inv0 = operands[4];
2364 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2365 rtx scratch0a = operands[5];
2366 rtx scratch0b = operands[6];
2367 rtx scratch0 = operands[7];
2368 rtx scratch1 = operands[8];
2369 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2371 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2372 scratch0a, scratch0b));
2373 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2374 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2375 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2376 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2377 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2381 ;; operands: inv2, norm32, inv1, i92
2382 (define_insn_and_split "divsi_inv_m2"
2383 [(set (match_operand:SI 0 "register_operand" "=r")
2384 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2385 (match_operand:SI 2 "register_operand" "r")
2386 (match_operand:DI 3 "register_operand" "r")]
2388 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2391 "&& !can_create_pseudo_p ()"
2395 muls.l r18, r25, r0 // s2.60
2396 shari r0, 16, r0 // s-16.44
2398 muls.l r0, r18, r19 // s-16.74
2399 shari r19, 30, r19 // s-16.44
2401 rtx inv2 = operands[0];
2402 rtx norm32 = operands[1];
2403 rtx inv1 = operands[2];
2404 rtx i92 = operands[3];
2405 rtx scratch0 = operands[4];
2406 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2408 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2409 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2410 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2411 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2412 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2416 (define_insn_and_split "divsi_inv_m3"
2417 [(set (match_operand:SI 0 "register_operand" "=r")
2418 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2419 (match_operand:SI 2 "register_operand" "r")
2420 (match_operand:SI 3 "register_operand" "r")
2421 (match_operand:DI 4 "register_operand" "r")
2422 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2423 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2425 (clobber (match_operand:DI 7 "register_operand" "=r"))
2426 (clobber (match_operand:DI 8 "register_operand" "=r"))
2427 (clobber (match_operand:DI 9 "register_operand" "=r"))
2428 (clobber (match_operand:DI 10 "register_operand" "=r"))
2429 (clobber (match_operand:SI 11 "register_operand" "=r"))
2430 (clobber (match_operand:SI 12 "register_operand" "=r"))
2431 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2434 "&& !can_create_pseudo_p ()"
2438 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2439 r0: scratch0 r19: scratch1 r21: scratch2
2441 muls.l r18, r4, r25 // s32.30
2442 muls.l r19, r4, r19 // s15.30
2444 shari r19, 14, r19 // s18.-14
2450 rtx result = operands[0];
2451 rtx dividend = operands[1];
2452 rtx inv1 = operands[2];
2453 rtx inv2 = operands[3];
2454 rtx shift = operands[4];
2455 rtx scratch0 = operands[7];
2456 rtx scratch1 = operands[8];
2457 rtx scratch2 = operands[9];
2459 if (satisfies_constraint_N (dividend))
2461 emit_move_insn (result, dividend);
2465 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2466 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2467 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2468 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2469 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2470 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2471 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2475 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2476 ;; inv1: tab_base, tab_ix, norm32
2477 ;; inv2: norm32, inv1, i92
2478 (define_insn_and_split "divsi_inv_m1_3"
2479 [(set (match_operand:SI 0 "register_operand" "=r")
2480 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2481 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2482 (match_operand:DI 3 "register_operand" "r")
2483 (match_operand:SI 4 "register_operand" "r")]
2485 (unspec:SI [(match_dup 4)
2486 (unspec:SI [(match_dup 2)
2488 (match_dup 4)] UNSPEC_DIV_INV_M1)
2489 (match_operand:SI 5 "" "")]
2491 (match_operand:DI 6 "register_operand" "r")
2492 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2493 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2495 (clobber (match_operand:DI 9 "register_operand" "=r"))
2496 (clobber (match_operand:DI 10 "register_operand" "=r"))
2497 (clobber (match_operand:DI 11 "register_operand" "=r"))
2498 (clobber (match_operand:DI 12 "register_operand" "=r"))
2499 (clobber (match_operand:SI 13 "register_operand" "=r"))
2500 (clobber (match_operand:SI 14 "register_operand" "=r"))
2501 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2503 && (TARGET_DIVIDE_INV_MINLAT
2504 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2506 "&& !can_create_pseudo_p ()"
2509 rtx result = operands[0];
2510 rtx dividend = operands[1];
2511 rtx tab_base = operands[2];
2512 rtx tab_ix = operands[3];
2513 rtx norm32 = operands[4];
2514 /* rtx i92 = operands[5]; */
2515 rtx shift = operands[6];
2516 rtx i2p27 = operands[7];
2517 rtx i43 = operands[8];
2518 rtx scratch0 = operands[9];
2519 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2520 rtx scratch1 = operands[10];
2521 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2522 rtx scratch2 = operands[11];
2523 rtx scratch3 = operands[12];
2524 rtx scratch4 = operands[13];
2525 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2526 rtx scratch5 = operands[14];
2527 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2528 rtx scratch6 = operands[15];
2530 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2531 scratch0, scratch1));
2532 /* inv0 == scratch4 */
2533 if (! TARGET_DIVIDE_INV20U)
2535 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2537 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2541 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2542 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2544 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2545 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2546 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2547 /* inv1 == scratch4 */
2549 if (TARGET_DIVIDE_INV_MINLAT)
2551 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2552 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2553 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2554 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2555 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2556 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2557 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2558 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2559 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2560 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2561 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2565 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2566 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2567 emit_insn (gen_nsbdi (scratch6,
2568 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2569 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2570 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2571 emit_insn (gen_divsi_inv20 (scratch2,
2572 norm32, scratch4, dividend,
2573 scratch6, scratch3, i43,
2574 /* scratch0 may be shared with i2p27. */
2575 scratch0, scratch1, scratch5,
2576 label, label, i2p27));
2578 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2579 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2583 (define_insn "divsi_inv20"
2584 [(set (match_operand:DI 0 "register_operand" "=&r")
2585 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2586 (match_operand:SI 2 "register_operand" "r")
2587 (match_operand:SI 3 "register_operand" "r")
2588 (match_operand:DI 4 "register_operand" "r")
2589 (match_operand:DI 5 "register_operand" "r")
2590 (match_operand:DI 6 "register_operand" "r")
2591 (match_operand:DI 12 "register_operand" "r")
2592 (match_operand 10 "target_operand" "b")
2593 (match_operand 11 "immediate_operand" "i")]
2595 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2596 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2597 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2599 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2601 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2602 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2603 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2604 %10 label (tr), %11 label (imm)
2606 muls.l inv1, norm32, scratch0 // s2.60
2607 muls.l inv1, dividend, result // s32.30
2608 xor i2p27, result_sign, round_scratch
2609 bge/u dividend_nsb, i43, tr.. (label)
2610 shari scratch0, 16, scratch0 // s-16.44
2611 muls.l sratch0_si, inv1, scratch0 // s-16.74
2612 sub result, round_scratch, result
2613 shari dividend, 14, scratch1 // s19.-14
2614 shari scratch0, 30, scratch0 // s-16.44
2615 muls.l scratch0, scratch1, round_scratch // s15.30
2617 sub result, round_scratch, result */
2619 int likely = TARGET_DIVIDE_INV20L;
2621 if (! likely) output_asm_insn ("muls.l\t%2, %1 , %8", operands);
2622 output_asm_insn ("muls.l\t%2, %3, %0\;xor\t%12, %5, %7", operands);
2623 output_asm_insn (likely
2624 ? "bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8"
2625 : "bge/u\t%4, %6, %10", operands);
2626 output_asm_insn ("shari\t%8, 16, %8\;muls.l\t%8, %2, %8", operands);
2627 if (! likely) output_asm_insn ("sub\t%0, %7, %0", operands);
2628 output_asm_insn ("shari\t%3, 14, %9\;shari\t%8, 30, %8", operands);
2630 ? "muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0"
2631 : "muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0");
2634 (define_insn_and_split "divsi_inv_fp"
2635 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2636 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2637 (match_operand:SI 2 "register_operand" "rf")))
2638 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2639 (clobber (match_operand:SI 4 "register_operand" "=r"))
2640 (clobber (match_operand:SI 5 "register_operand" "=r"))
2641 (clobber (match_operand:DF 6 "register_operand" "=r"))
2642 (clobber (match_operand:DF 7 "register_operand" "=r"))
2643 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2644 "TARGET_SHMEDIA_FPU"
2646 "&& (high_life_started || reload_completed)"
2647 [(set (match_dup 0) (match_dup 3))]
2649 [(set_attr "highpart" "must_split")])
2651 ;; If a matching group of divide-by-inverse instructions is in the same
2652 ;; basic block after gcse & loop optimizations, we want to transform them
2653 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2654 (define_insn_and_split "*divsi_inv_fp_combine"
2655 [(set (match_operand:SI 0 "register_operand" "=f")
2656 (div:SI (match_operand:SI 1 "register_operand" "f")
2657 (match_operand:SI 2 "register_operand" "f")))
2658 (use (unspec:SI [(match_dup 1)
2659 (match_operand:SI 3 "" "")
2660 (unspec:SI [(match_operand:SI 4 "" "")
2662 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2663 (match_operand:DI 6 "" "")
2665 (const_int 0)] UNSPEC_DIV_INV_M3))
2666 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2667 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2668 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2669 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2670 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2671 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2674 [(set (match_dup 9) (float:DF (match_dup 1)))
2675 (set (match_dup 10) (float:DF (match_dup 2)))
2676 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2678 (fix:SI (match_dup 11)))
2679 (set (match_dup 0) (match_dup 8))]
2681 if (! fp_arith_reg_operand (operands[1], SImode))
2683 emit_move_insn (operands[7], operands[1]);
2684 operands[1] = operands[7];
2686 if (! fp_arith_reg_operand (operands[2], SImode))
2688 emit_move_insn (operands[8], operands[2]);
2689 operands[2] = operands[8];
2692 [(set_attr "highpart" "must_split")])
2694 ;; -------------------------------------------------------------------------
2695 ;; Multiplication instructions
2696 ;; -------------------------------------------------------------------------
2698 (define_insn "umulhisi3_i"
2699 [(set (reg:SI MACL_REG)
2700 (mult:SI (zero_extend:SI
2701 (match_operand:HI 0 "arith_reg_operand" "r"))
2703 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2706 [(set_attr "type" "smpy")])
2708 (define_insn "mulhisi3_i"
2709 [(set (reg:SI MACL_REG)
2710 (mult:SI (sign_extend:SI
2711 (match_operand:HI 0 "arith_reg_operand" "r"))
2713 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2716 [(set_attr "type" "smpy")])
2718 (define_expand "mulhisi3"
2719 [(set (reg:SI MACL_REG)
2720 (mult:SI (sign_extend:SI
2721 (match_operand:HI 1 "arith_reg_operand" ""))
2723 (match_operand:HI 2 "arith_reg_operand" ""))))
2724 (set (match_operand:SI 0 "arith_reg_operand" "")
2730 macl = gen_rtx_REG (SImode, MACL_REG);
2732 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2733 insn = get_insns ();
2735 /* expand_binop can't find a suitable code in umul_widen_optab to
2736 make a REG_EQUAL note from, so make one here.
2737 See also smulsi3_highpart.
2738 ??? Alternatively, we could put this at the calling site of expand_binop,
2739 i.e. expand_expr. */
2740 /* Use emit_libcall_block for loop invariant code motion and to make
2741 a REG_EQUAL note. */
2742 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2747 (define_expand "umulhisi3"
2748 [(set (reg:SI MACL_REG)
2749 (mult:SI (zero_extend:SI
2750 (match_operand:HI 1 "arith_reg_operand" ""))
2752 (match_operand:HI 2 "arith_reg_operand" ""))))
2753 (set (match_operand:SI 0 "arith_reg_operand" "")
2759 macl = gen_rtx_REG (SImode, MACL_REG);
2761 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2762 insn = get_insns ();
2764 /* expand_binop can't find a suitable code in umul_widen_optab to
2765 make a REG_EQUAL note from, so make one here.
2766 See also smulsi3_highpart.
2767 ??? Alternatively, we could put this at the calling site of expand_binop,
2768 i.e. expand_expr. */
2769 /* Use emit_libcall_block for loop invariant code motion and to make
2770 a REG_EQUAL note. */
2771 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2776 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2777 ;; a call to a routine which clobbers known registers.
2780 [(set (match_operand:SI 1 "register_operand" "=z")
2781 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2782 (clobber (reg:SI MACL_REG))
2783 (clobber (reg:SI T_REG))
2784 (clobber (reg:SI PR_REG))
2785 (clobber (reg:SI R3_REG))
2786 (clobber (reg:SI R2_REG))
2787 (clobber (reg:SI R1_REG))
2788 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2791 [(set_attr "type" "sfunc")
2792 (set_attr "needs_delay_slot" "yes")])
2794 (define_expand "mulsi3_call"
2795 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2796 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2797 (parallel[(set (match_operand:SI 0 "register_operand" "")
2798 (mult:SI (reg:SI R4_REG)
2800 (clobber (reg:SI MACL_REG))
2801 (clobber (reg:SI T_REG))
2802 (clobber (reg:SI PR_REG))
2803 (clobber (reg:SI R3_REG))
2804 (clobber (reg:SI R2_REG))
2805 (clobber (reg:SI R1_REG))
2806 (use (match_operand:SI 3 "register_operand" ""))])]
2810 (define_insn "mul_r"
2811 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2812 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2813 (match_operand:SI 2 "arith_reg_operand" "z")))]
2816 [(set_attr "type" "dmpy")])
2818 (define_insn "mul_l"
2819 [(set (reg:SI MACL_REG)
2820 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2821 (match_operand:SI 1 "arith_reg_operand" "r")))]
2824 [(set_attr "type" "dmpy")])
2826 (define_expand "mulsi3"
2827 [(set (reg:SI MACL_REG)
2828 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2829 (match_operand:SI 2 "arith_reg_operand" "")))
2830 (set (match_operand:SI 0 "arith_reg_operand" "")
2836 /* The address must be set outside the libcall,
2837 since it goes into a pseudo. */
2838 rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
2839 rtx addr = force_reg (SImode, sym);
2840 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2846 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2848 emit_insn (gen_mul_l (operands[1], operands[2]));
2849 /* consec_sets_giv can only recognize the first insn that sets a
2850 giv as the giv insn. So we must tag this also with a REG_EQUAL
2852 emit_insn (gen_movsi_i ((operands[0]), macl));
2857 (define_insn "mulsidi3_i"
2858 [(set (reg:SI MACH_REG)
2862 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2863 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2865 (set (reg:SI MACL_REG)
2866 (mult:SI (match_dup 0)
2870 [(set_attr "type" "dmpy")])
2872 (define_expand "mulsidi3"
2873 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2874 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2875 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2876 "TARGET_SH2 || TARGET_SHMEDIA"
2880 emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
2885 (define_insn "mulsidi3_media"
2886 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2887 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2888 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2891 [(set_attr "type" "dmpy_media")
2892 (set_attr "highpart" "ignore")])
2894 (define_insn "mulsidi3_compact"
2895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2897 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2898 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2899 (clobber (reg:SI MACH_REG))
2900 (clobber (reg:SI MACL_REG))]
2905 [(set (match_operand:DI 0 "arith_reg_dest" "")
2907 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2908 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2909 (clobber (reg:SI MACH_REG))
2910 (clobber (reg:SI MACL_REG))]
2914 rtx low_dst = gen_lowpart (SImode, operands[0]);
2915 rtx high_dst = gen_highpart (SImode, operands[0]);
2917 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2919 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2920 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2921 /* We need something to tag the possible REG_EQUAL notes on to. */
2922 emit_move_insn (operands[0], operands[0]);
2926 (define_insn "umulsidi3_i"
2927 [(set (reg:SI MACH_REG)
2931 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2932 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2934 (set (reg:SI MACL_REG)
2935 (mult:SI (match_dup 0)
2939 [(set_attr "type" "dmpy")])
2941 (define_expand "umulsidi3"
2942 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2943 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2944 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2945 "TARGET_SH2 || TARGET_SHMEDIA"
2949 emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
2954 (define_insn "umulsidi3_media"
2955 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2956 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2957 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2960 [(set_attr "type" "dmpy_media")
2961 (set_attr "highpart" "ignore")])
2963 (define_insn "umulsidi3_compact"
2964 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2966 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2967 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2968 (clobber (reg:SI MACH_REG))
2969 (clobber (reg:SI MACL_REG))]
2974 [(set (match_operand:DI 0 "arith_reg_dest" "")
2975 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2976 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2977 (clobber (reg:SI MACH_REG))
2978 (clobber (reg:SI MACL_REG))]
2982 rtx low_dst = gen_lowpart (SImode, operands[0]);
2983 rtx high_dst = gen_highpart (SImode, operands[0]);
2985 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2987 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2988 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2989 /* We need something to tag the possible REG_EQUAL notes on to. */
2990 emit_move_insn (operands[0], operands[0]);
2994 (define_insn "smulsi3_highpart_i"
2995 [(set (reg:SI MACH_REG)
2999 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3000 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3002 (clobber (reg:SI MACL_REG))]
3005 [(set_attr "type" "dmpy")])
3007 (define_expand "smulsi3_highpart"
3009 [(set (reg:SI MACH_REG)
3013 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3014 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3016 (clobber (reg:SI MACL_REG))])
3017 (set (match_operand:SI 0 "arith_reg_operand" "")
3023 mach = gen_rtx_REG (SImode, MACH_REG);
3025 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3026 insn = get_insns ();
3028 /* expand_binop can't find a suitable code in mul_highpart_optab to
3029 make a REG_EQUAL note from, so make one here.
3030 See also {,u}mulhisi.
3031 ??? Alternatively, we could put this at the calling site of expand_binop,
3032 i.e. expand_mult_highpart. */
3033 /* Use emit_libcall_block for loop invariant code motion and to make
3034 a REG_EQUAL note. */
3035 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3040 (define_insn "umulsi3_highpart_i"
3041 [(set (reg:SI MACH_REG)
3045 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3046 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3048 (clobber (reg:SI MACL_REG))]
3051 [(set_attr "type" "dmpy")])
3053 (define_expand "umulsi3_highpart"
3055 [(set (reg:SI MACH_REG)
3059 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3060 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3062 (clobber (reg:SI MACL_REG))])
3063 (set (match_operand:SI 0 "arith_reg_operand" "")
3069 mach = gen_rtx_REG (SImode, MACH_REG);
3071 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3072 insn = get_insns ();
3074 /* Use emit_libcall_block for loop invariant code motion and to make
3075 a REG_EQUAL note. */
3076 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3081 (define_insn_and_split "muldi3"
3082 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3083 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3084 (match_operand:DI 2 "arith_reg_operand" "r")))
3085 (clobber (match_scratch:DI 3 "=&r"))
3086 (clobber (match_scratch:DI 4 "=r"))]
3092 rtx op3_v2si, op2_v2si;
3094 op3_v2si = operands[3];
3095 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3097 op3_v2si = XEXP (op3_v2si, 0);
3098 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3100 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3101 op2_v2si = operands[2];
3102 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3104 op2_v2si = XEXP (op2_v2si, 0);
3105 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3107 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3108 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3109 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3110 emit_insn (gen_umulsidi3_media (operands[4],
3111 sh_gen_truncate (SImode, operands[1], 0),
3112 sh_gen_truncate (SImode, operands[2], 0)));
3113 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3114 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3115 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3116 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3121 ;; -------------------------------------------------------------------------
3122 ;; Logical operations
3123 ;; -------------------------------------------------------------------------
3125 (define_insn "*andsi3_compact"
3126 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3127 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3128 (match_operand:SI 2 "logical_operand" "K08,r")))]
3131 [(set_attr "type" "arith")])
3133 (define_insn "*andsi3_media"
3134 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3135 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3136 (match_operand:SI 2 "logical_operand" "r,I10")))]
3141 [(set_attr "type" "arith_media")])
3143 (define_insn "*andsi3_bclr"
3144 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3145 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3146 (match_operand:SI 2 "const_int_operand" "Psz")))]
3147 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3149 [(set_attr "type" "arith")])
3151 ;; If the constant is 255, then emit an extu.b instruction instead of an
3152 ;; and, since that will give better code.
3154 (define_expand "andsi3"
3155 [(set (match_operand:SI 0 "arith_reg_operand" "")
3156 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3157 (match_operand:SI 2 "logical_operand" "")))]
3162 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3164 emit_insn (gen_zero_extendqisi2 (operands[0],
3165 gen_lowpart (QImode, operands[1])));
3170 (define_insn_and_split "anddi3"
3171 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3172 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3173 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3180 && ! logical_operand (operands[2], DImode)"
3184 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3185 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3187 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3190 [(set_attr "type" "arith_media")])
3192 (define_insn "andcsi3"
3193 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3194 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3195 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3198 [(set_attr "type" "arith_media")])
3200 (define_insn "andcdi3"
3201 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3202 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3203 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3206 [(set_attr "type" "arith_media")])
3208 (define_expand "iorsi3"
3209 [(set (match_operand:SI 0 "arith_reg_operand" "")
3210 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3211 (match_operand:SI 2 "logical_operand" "")))]
3215 (define_insn "*iorsi3_compact"
3216 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3217 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3218 (match_operand:SI 2 "logical_operand" "r,K08")))]
3220 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3222 [(set_attr "type" "arith")])
3224 (define_insn "*iorsi3_media"
3225 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3226 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3227 (match_operand:SI 2 "logical_operand" "r,I10")))]
3232 [(set_attr "type" "arith_media")])
3234 (define_insn "*iorsi3_bset"
3235 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3236 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3237 (match_operand:SI 2 "const_int_operand" "Pso")))]
3238 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3240 [(set_attr "type" "arith")])
3242 (define_insn "iordi3"
3243 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3244 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3245 (match_operand:DI 2 "logical_operand" "r,I10")))]
3250 [(set_attr "type" "arith_media")])
3252 (define_insn_and_split "*logical_sidi3"
3253 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3254 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3255 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3256 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3259 "&& reload_completed"
3260 [(set (match_dup 0) (match_dup 3))]
3263 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3264 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3265 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3268 (define_insn_and_split "*logical_sidisi3"
3269 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3270 (truncate:SI (sign_extend:DI
3271 (match_operator:SI 3 "logical_operator"
3272 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3273 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3277 [(set (match_dup 0) (match_dup 3))])
3279 (define_insn_and_split "*logical_sidi3_2"
3280 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3281 (sign_extend:DI (truncate:SI (sign_extend:DI
3282 (match_operator:SI 3 "logical_operator"
3283 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3284 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3288 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3290 (define_expand "xorsi3"
3291 [(set (match_operand:SI 0 "arith_reg_operand" "")
3292 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3293 (match_operand:SI 2 "xor_operand" "")))]
3297 (define_insn "*xorsi3_compact"
3298 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3299 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3300 (match_operand:SI 2 "logical_operand" "K08,r")))]
3303 [(set_attr "type" "arith")])
3305 (define_insn "*xorsi3_media"
3306 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3307 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3308 (match_operand:SI 2 "xor_operand" "r,I06")))]
3313 [(set_attr "type" "arith_media")])
3315 (define_insn "xordi3"
3316 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3317 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3318 (match_operand:DI 2 "xor_operand" "r,I06")))]
3323 [(set_attr "type" "arith_media")])
3325 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3326 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3328 [(set (match_operand:DI 0 "arith_reg_dest" "")
3329 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3330 [(match_operand 1 "any_register_operand" "")
3331 (match_operand 2 "any_register_operand" "")])))]
3333 [(set (match_dup 5) (match_dup 4))
3334 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3336 enum machine_mode inmode = GET_MODE (operands[1]);
3339 if (GET_CODE (operands[0]) == SUBREG)
3341 offset = SUBREG_BYTE (operands[0]);
3342 operands[0] = SUBREG_REG (operands[0]);
3344 gcc_assert (REG_P (operands[0]));
3345 if (! TARGET_LITTLE_ENDIAN)
3346 offset += 8 - GET_MODE_SIZE (inmode);
3347 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3350 ;; -------------------------------------------------------------------------
3351 ;; Shifts and rotates
3352 ;; -------------------------------------------------------------------------
3354 (define_expand "rotldi3"
3355 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3356 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3357 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3359 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3361 (define_insn "rotldi3_mextr"
3362 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3363 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3364 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3367 static char templ[16];
3369 sprintf (templ, "mextr%d\\t%%1,%%1,%%0",
3370 8 - (int) (INTVAL (operands[2]) >> 3));
3373 [(set_attr "type" "arith_media")])
3375 (define_expand "rotrdi3"
3376 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3377 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3378 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3381 if (! mextr_bit_offset (operands[2], HImode))
3385 (define_insn "rotrdi3_mextr"
3386 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3391 static char templ[16];
3393 sprintf (templ, "mextr%d\\t%%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3396 [(set_attr "type" "arith_media")])
3399 [(set (match_operand:DI 0 "arith_reg_dest" "")
3400 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3401 "ua_address_operand" "")))
3402 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3404 (clobber (match_operand:DI 3 "register_operand" ""))]
3406 [(match_dup 4) (match_dup 5)]
3408 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3409 (operands[3], operands[1]));
3410 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3411 GEN_INT (56), GEN_INT (8));
3414 (define_insn "rotlsi3_1"
3415 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3419 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3422 [(set_attr "type" "arith")])
3424 (define_insn "rotlsi3_31"
3425 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3426 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428 (clobber (reg:SI T_REG))]
3431 [(set_attr "type" "arith")])
3433 (define_insn "rotlsi3_16"
3434 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3439 [(set_attr "type" "arith")])
3441 (define_expand "rotlsi3"
3442 [(set (match_operand:SI 0 "arith_reg_dest" "")
3443 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3444 (match_operand:SI 2 "immediate_operand" "")))]
3447 static const char rot_tab[] = {
3448 000, 000, 000, 000, 000, 000, 010, 001,
3449 001, 001, 011, 013, 003, 003, 003, 003,
3450 003, 003, 003, 003, 003, 013, 012, 002,
3451 002, 002, 010, 000, 000, 000, 000, 000,
3456 if (!CONST_INT_P (operands[2]))
3458 count = INTVAL (operands[2]);
3459 choice = rot_tab[count];
3460 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3466 emit_move_insn (operands[0], operands[1]);
3467 count -= (count & 16) * 2;
3470 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3477 parts[0] = gen_reg_rtx (SImode);
3478 parts[1] = gen_reg_rtx (SImode);
3479 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3480 emit_move_insn (parts[choice-1], operands[1]);
3481 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3482 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3483 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3484 count = (count & ~16) - 8;
3488 for (; count > 0; count--)
3489 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3490 for (; count < 0; count++)
3491 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3496 (define_insn "*rotlhi3_8"
3497 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3498 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3502 [(set_attr "type" "arith")])
3504 (define_expand "rotlhi3"
3505 [(set (match_operand:HI 0 "arith_reg_operand" "")
3506 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3507 (match_operand:HI 2 "immediate_operand" "")))]
3510 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3517 ;; This pattern is used by init_expmed for computing the costs of shift
3520 (define_insn_and_split "ashlsi3_std"
3521 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3522 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3523 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3524 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3525 "(TARGET_SH3 || TARGET_SH2A)
3526 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3532 "(TARGET_SH3 || TARGET_SH2A)
3534 && CONST_INT_P (operands[2])
3535 && ! satisfies_constraint_P27 (operands[2])"
3536 [(set (match_dup 3) (match_dup 2))
3538 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3539 (clobber (match_dup 4))])]
3541 operands[4] = gen_rtx_SCRATCH (SImode);
3543 [(set_attr "length" "*,*,*,4")
3544 (set_attr "type" "dyn_shift,arith,arith,arith")])
3546 (define_insn "ashlhi3_k"
3547 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3548 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3549 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3550 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3554 [(set_attr "type" "arith")])
3556 (define_insn "ashlsi3_n"
3557 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3559 (match_operand:SI 2 "const_int_operand" "n")))
3560 (clobber (reg:SI T_REG))]
3561 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3563 [(set (attr "length")
3564 (cond [(match_test "shift_insns_rtx (insn)")
3566 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3568 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3570 (const_string "8")))
3571 (set_attr "type" "arith")])
3574 [(set (match_operand:SI 0 "arith_reg_dest" "")
3575 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3576 (match_operand:SI 2 "const_int_operand" "")))
3577 (clobber (reg:SI T_REG))]
3578 "TARGET_SH1 && reload_completed"
3579 [(use (reg:SI R0_REG))]
3581 gen_shifty_op (ASHIFT, operands);
3585 (define_insn "ashlsi3_media"
3586 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3587 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3588 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3593 [(set_attr "type" "arith_media")
3594 (set_attr "highpart" "ignore")])
3596 (define_expand "ashlsi3"
3597 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3598 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3599 (match_operand:SI 2 "nonmemory_operand" "")))
3600 (clobber (reg:SI T_REG))])]
3605 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3608 if (CONST_INT_P (operands[2])
3609 && sh_dynamicalize_shift_p (operands[2]))
3610 operands[2] = force_reg (SImode, operands[2]);
3611 if (TARGET_SH3 || TARGET_SH2A)
3613 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3616 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3620 (define_insn "*ashlhi3_n"
3621 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3622 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3623 (match_operand:HI 2 "const_int_operand" "n")))
3624 (clobber (reg:SI T_REG))]
3627 [(set (attr "length")
3628 (cond [(match_test "shift_insns_rtx (insn)")
3630 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3632 (const_string "6")))
3633 (set_attr "type" "arith")])
3635 (define_expand "ashlhi3"
3636 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3637 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3638 (match_operand:SI 2 "nonmemory_operand" "")))
3639 (clobber (reg:SI T_REG))])]
3642 if (!CONST_INT_P (operands[2]))
3644 /* It may be possible to call gen_ashlhi3 directly with more generic
3645 operands. Make sure operands[1] is a HImode register here. */
3646 if (!arith_reg_operand (operands[1], HImode))
3647 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3651 [(set (match_operand:HI 0 "arith_reg_dest" "")
3652 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3653 (match_operand:HI 2 "const_int_operand" "")))
3654 (clobber (reg:SI T_REG))]
3655 "TARGET_SH1 && reload_completed"
3656 [(use (reg:SI R0_REG))]
3658 gen_shifty_hi_op (ASHIFT, operands);
3663 ;; arithmetic shift right
3666 (define_insn "ashrsi3_k"
3667 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3668 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3669 (match_operand:SI 2 "const_int_operand" "M")))
3670 (clobber (reg:SI T_REG))]
3671 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3673 [(set_attr "type" "arith")])
3675 ;; We can't do HImode right shifts correctly unless we start out with an
3676 ;; explicit zero / sign extension; doing that would result in worse overall
3677 ;; code, so just let the machine independent code widen the mode.
3678 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3681 ;; ??? This should be a define expand.
3683 (define_insn "ashrsi2_16"
3684 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3685 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3689 [(set_attr "length" "4")])
3692 [(set (match_operand:SI 0 "arith_reg_dest" "")
3693 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3696 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3697 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3699 operands[2] = gen_lowpart (HImode, operands[0]);
3702 ;; ??? This should be a define expand.
3704 (define_insn "ashrsi2_31"
3705 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3706 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3708 (clobber (reg:SI T_REG))]
3711 [(set_attr "length" "4")])
3714 [(set (match_operand:SI 0 "arith_reg_dest" "")
3715 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3717 (clobber (reg:SI T_REG))]
3721 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3722 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3727 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3729 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3731 && peep2_reg_dead_p (2, operands[0])
3732 && peep2_reg_dead_p (2, operands[1])"
3735 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3739 (define_insn "ashlsi_c"
3740 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3743 (lt:SI (match_dup 1) (const_int 0)))]
3746 [(set_attr "type" "arith")])
3748 (define_insn "*ashlsi_c_void"
3749 [(set (reg:SI T_REG)
3750 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3751 (clobber (match_scratch:SI 1 "=0"))]
3752 "TARGET_SH1 && cse_not_expected"
3754 [(set_attr "type" "arith")])
3756 (define_insn "ashrsi3_d"
3757 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3758 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3759 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3760 "TARGET_SH3 || TARGET_SH2A"
3762 [(set_attr "type" "dyn_shift")])
3764 (define_insn "ashrsi3_n"
3765 [(set (reg:SI R4_REG)
3766 (ashiftrt:SI (reg:SI R4_REG)
3767 (match_operand:SI 0 "const_int_operand" "i")))
3768 (clobber (reg:SI T_REG))
3769 (clobber (reg:SI PR_REG))
3770 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3773 [(set_attr "type" "sfunc")
3774 (set_attr "needs_delay_slot" "yes")])
3776 (define_insn "ashrsi3_media"
3777 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3778 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3779 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3784 [(set_attr "type" "arith_media")
3785 (set_attr "highpart" "ignore")])
3787 (define_expand "ashrsi3"
3788 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3789 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3790 (match_operand:SI 2 "nonmemory_operand" "")))
3791 (clobber (reg:SI T_REG))])]
3796 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3799 if (expand_ashiftrt (operands))
3805 ;; logical shift right
3807 (define_insn "lshrsi3_d"
3808 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3809 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3810 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3811 "TARGET_SH3 || TARGET_SH2A"
3813 [(set_attr "type" "dyn_shift")])
3815 ;; Only the single bit shift clobbers the T bit.
3817 (define_insn "lshrsi3_m"
3818 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3819 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3820 (match_operand:SI 2 "const_int_operand" "M")))
3821 (clobber (reg:SI T_REG))]
3822 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3824 [(set_attr "type" "arith")])
3826 (define_insn "lshrsi3_k"
3827 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3828 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3829 (match_operand:SI 2 "const_int_operand" "P27")))]
3830 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3831 && ! satisfies_constraint_M (operands[2])"
3833 [(set_attr "type" "arith")])
3835 (define_insn "lshrsi3_n"
3836 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3837 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3838 (match_operand:SI 2 "const_int_operand" "n")))
3839 (clobber (reg:SI T_REG))]
3840 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3842 [(set (attr "length")
3843 (cond [(match_test "shift_insns_rtx (insn)")
3845 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3847 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3849 (const_string "8")))
3850 (set_attr "type" "arith")])
3853 [(set (match_operand:SI 0 "arith_reg_dest" "")
3854 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3855 (match_operand:SI 2 "const_int_operand" "")))
3856 (clobber (reg:SI T_REG))]
3857 "TARGET_SH1 && reload_completed"
3858 [(use (reg:SI R0_REG))]
3860 gen_shifty_op (LSHIFTRT, operands);
3864 (define_insn "lshrsi3_media"
3865 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3866 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3867 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3872 [(set_attr "type" "arith_media")
3873 (set_attr "highpart" "ignore")])
3875 (define_expand "lshrsi3"
3876 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3877 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3878 (match_operand:SI 2 "nonmemory_operand" "")))
3879 (clobber (reg:SI T_REG))])]
3884 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3887 if (CONST_INT_P (operands[2])
3888 && sh_dynamicalize_shift_p (operands[2]))
3889 operands[2] = force_reg (SImode, operands[2]);
3890 if ((TARGET_SH3 || TARGET_SH2A)
3891 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3893 rtx count = copy_to_mode_reg (SImode, operands[2]);
3894 emit_insn (gen_negsi2 (count, count));
3895 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3898 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3902 ;; ??? This should be a define expand.
3904 (define_insn "ashldi3_k"
3905 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3906 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3908 (clobber (reg:SI T_REG))]
3910 "shll %R0\;rotcl %S0"
3911 [(set_attr "length" "4")
3912 (set_attr "type" "arith")])
3914 ;; Expander for DImode shift left with SImode operations.
3916 (define_expand "ashldi3_std"
3917 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3918 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3919 (match_operand:DI 2 "const_int_operand" "n")))]
3920 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3922 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3923 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3924 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3925 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3926 rtx dst = gen_reg_rtx (DImode);
3927 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3928 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3931 tmp0 = gen_reg_rtx (SImode);
3932 tmp1 = gen_reg_rtx (SImode);
3933 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3934 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3935 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3936 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3937 emit_move_insn (operands[0], dst);
3941 (define_insn "ashldi3_media"
3942 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3943 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944 (match_operand:DI 2 "shift_count_operand" "r,n")))]
3949 [(set_attr "type" "arith_media")])
3951 (define_insn "*ashldisi3_media"
3952 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3953 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3954 (match_operand:DI 2 "const_int_operand" "n")))]
3955 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3956 "shlli.l %1, %2, %0"
3957 [(set_attr "type" "arith_media")
3958 (set_attr "highpart" "ignore")])
3960 (define_expand "ashldi3"
3961 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3962 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3963 (match_operand:DI 2 "immediate_operand" "")))
3964 (clobber (reg:SI T_REG))])]
3969 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3972 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
3974 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3977 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
3979 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3986 ;; ??? This should be a define expand.
3988 (define_insn "lshrdi3_k"
3989 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3990 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3992 (clobber (reg:SI T_REG))]
3994 "shlr %S0\;rotcr %R0"
3995 [(set_attr "length" "4")
3996 (set_attr "type" "arith")])
3998 (define_insn "lshrdi3_media"
3999 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4000 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4001 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4003 && (arith_reg_dest (operands[0], DImode)
4004 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4008 [(set_attr "type" "arith_media")])
4010 (define_insn "*lshrdisi3_media"
4011 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4012 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4013 (match_operand:DI 2 "const_int_operand" "n")))]
4014 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4015 "shlri.l %1, %2, %0"
4016 [(set_attr "type" "arith_media")
4017 (set_attr "highpart" "ignore")])
4019 (define_expand "lshrdi3"
4020 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4021 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4022 (match_operand:DI 2 "immediate_operand" "")))
4023 (clobber (reg:SI T_REG))])]
4028 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4031 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4035 ;; ??? This should be a define expand.
4037 (define_insn "ashrdi3_k"
4038 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4039 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4041 (clobber (reg:SI T_REG))]
4043 "shar %S0\;rotcr %R0"
4044 [(set_attr "length" "4")
4045 (set_attr "type" "arith")])
4047 (define_insn "ashrdi3_media"
4048 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4049 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4050 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4052 && (arith_reg_dest (operands[0], DImode)
4053 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4057 [(set_attr "type" "arith_media")])
4059 (define_insn "*ashrdisi3_media"
4060 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4061 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4062 (match_operand:DI 2 "const_int_operand" "n")))]
4063 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4064 "shari.l %1, %2, %0"
4065 [(set_attr "type" "arith_media")
4066 (set_attr "highpart" "ignore")])
4068 (define_insn "ashrdisi3_media_high"
4069 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4071 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4072 (match_operand:DI 2 "const_int_operand" "n"))))]
4073 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4075 [(set_attr "type" "arith_media")])
4077 (define_insn "ashrdisi3_media_opaque"
4078 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4079 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4080 (match_operand:DI 2 "const_int_operand" "n")]
4084 [(set_attr "type" "arith_media")])
4086 (define_expand "ashrdi3"
4087 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4088 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4089 (match_operand:DI 2 "immediate_operand" "")))
4090 (clobber (reg:SI T_REG))])]
4095 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4098 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4102 ;; combined left/right shift
4105 [(set (match_operand:SI 0 "register_operand" "")
4106 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4107 (match_operand:SI 2 "const_int_operand" ""))
4108 (match_operand:SI 3 "const_int_operand" "")))]
4109 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4110 [(use (reg:SI R0_REG))]
4112 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4118 [(set (match_operand:SI 0 "register_operand" "")
4119 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4120 (match_operand:SI 2 "const_int_operand" ""))
4121 (match_operand:SI 3 "const_int_operand" "")))
4122 (clobber (reg:SI T_REG))]
4123 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4124 [(use (reg:SI R0_REG))]
4126 if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4132 [(set (match_operand:SI 0 "register_operand" "=r")
4133 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4134 (match_operand:SI 2 "const_int_operand" "n"))
4135 (match_operand:SI 3 "const_int_operand" "n")))
4136 (clobber (reg:SI T_REG))]
4137 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4139 [(set (attr "length")
4140 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4142 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4144 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4146 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4148 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4150 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4152 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4153 (const_string "16")]
4154 (const_string "18")))
4155 (set_attr "type" "arith")])
4158 [(set (match_operand:SI 0 "register_operand" "=z")
4159 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4160 (match_operand:SI 2 "const_int_operand" "n"))
4161 (match_operand:SI 3 "const_int_operand" "n")))
4162 (clobber (reg:SI T_REG))]
4163 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4165 [(set (attr "length")
4166 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4168 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4170 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4172 (const_string "10")))
4173 (set_attr "type" "arith")])
4175 ;; shift left / and combination with a scratch register: The combine pass
4176 ;; does not accept the individual instructions, even though they are
4177 ;; cheap. But it needs a precise description so that it is usable after
4179 (define_insn "and_shl_scratch"
4180 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4184 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4185 (match_operand:SI 2 "const_int_operand" "N,n"))
4186 (match_operand:SI 3 "" "0,r"))
4187 (match_operand:SI 4 "const_int_operand" "n,n"))
4188 (match_operand:SI 5 "const_int_operand" "n,n")))
4189 (clobber (reg:SI T_REG))]
4192 [(set (attr "length")
4193 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4195 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4197 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4199 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4200 (const_string "10")]
4201 (const_string "12")))
4202 (set_attr "type" "arith")])
4205 [(set (match_operand:SI 0 "register_operand" "")
4209 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4210 (match_operand:SI 2 "const_int_operand" ""))
4211 (match_operand:SI 3 "register_operand" ""))
4212 (match_operand:SI 4 "const_int_operand" ""))
4213 (match_operand:SI 5 "const_int_operand" "")))
4214 (clobber (reg:SI T_REG))]
4216 [(use (reg:SI R0_REG))]
4218 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4220 if (INTVAL (operands[2]))
4222 gen_shifty_op (LSHIFTRT, operands);
4224 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4225 operands[2] = operands[4];
4226 gen_shifty_op (ASHIFT, operands);
4227 if (INTVAL (operands[5]))
4229 operands[2] = operands[5];
4230 gen_shifty_op (LSHIFTRT, operands);
4235 ;; signed left/right shift combination.
4237 [(set (match_operand:SI 0 "register_operand" "")
4239 (ashift:SI (match_operand:SI 1 "register_operand" "")
4240 (match_operand:SI 2 "const_int_operand" ""))
4241 (match_operand:SI 3 "const_int_operand" "")
4243 (clobber (reg:SI T_REG))]
4245 [(use (reg:SI R0_REG))]
4247 if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
4252 (define_insn "shl_sext_ext"
4253 [(set (match_operand:SI 0 "register_operand" "=r")
4255 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4256 (match_operand:SI 2 "const_int_operand" "n"))
4257 (match_operand:SI 3 "const_int_operand" "n")
4259 (clobber (reg:SI T_REG))]
4260 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4262 [(set (attr "length")
4263 (cond [(match_test "shl_sext_length (insn)")
4265 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4267 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4269 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4271 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4273 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4275 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4277 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4278 (const_string "16")]
4279 (const_string "18")))
4280 (set_attr "type" "arith")])
4282 (define_insn "shl_sext_sub"
4283 [(set (match_operand:SI 0 "register_operand" "=z")
4285 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4286 (match_operand:SI 2 "const_int_operand" "n"))
4287 (match_operand:SI 3 "const_int_operand" "n")
4289 (clobber (reg:SI T_REG))]
4290 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4292 [(set (attr "length")
4293 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4295 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4297 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4299 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4300 (const_string "12")]
4301 (const_string "14")))
4302 (set_attr "type" "arith")])
4304 ;; These patterns are found in expansions of DImode shifts by 16, and
4305 ;; allow the xtrct instruction to be generated from C source.
4307 (define_insn "xtrct_left"
4308 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4309 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4311 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4315 [(set_attr "type" "arith")])
4317 (define_insn "xtrct_right"
4318 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4319 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4321 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4325 [(set_attr "type" "arith")])
4327 ;; -------------------------------------------------------------------------
4329 ;; -------------------------------------------------------------------------
4331 (define_expand "negc"
4332 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4333 (neg:SI (plus:SI (reg:SI T_REG)
4334 (match_operand:SI 1 "arith_reg_operand" ""))))
4336 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4341 (define_insn "*negc"
4342 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4343 (neg:SI (plus:SI (reg:SI T_REG)
4344 (match_operand:SI 1 "arith_reg_operand" "r"))))
4346 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4350 [(set_attr "type" "arith")])
4352 (define_insn "*negdi_media"
4353 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4354 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4357 [(set_attr "type" "arith_media")])
4359 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4361 (define_expand "negdi2"
4362 [(set (match_operand:DI 0 "arith_reg_dest" "")
4363 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4364 (clobber (reg:SI T_REG))]
4368 (define_insn_and_split "*negdi2"
4369 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4370 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4376 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4377 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4379 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4380 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4382 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4383 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4385 emit_insn (gen_clrt ());
4386 emit_insn (gen_negc (low_dst, low_src));
4387 emit_insn (gen_negc (high_dst, high_src));
4391 (define_insn "negsi2"
4392 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4393 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4396 [(set_attr "type" "arith")])
4398 (define_insn "one_cmplsi2"
4399 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4400 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4403 [(set_attr "type" "arith")])
4405 (define_expand "one_cmpldi2"
4406 [(set (match_operand:DI 0 "arith_reg_dest" "")
4407 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4409 "TARGET_SHMEDIA" "")
4411 (define_expand "abssi2"
4412 [(set (match_operand:SI 0 "arith_reg_dest" "")
4413 (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4414 (clobber (reg:SI T_REG))]
4418 (define_insn_and_split "*abssi2"
4419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4420 (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4426 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4427 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4432 (define_insn_and_split "*negabssi2"
4433 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4434 (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4440 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4441 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4446 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4447 ;; This can be used as some kind of conditional execution, which is useful
4449 ;; Actually the instruction scheduling should decide whether to use a
4450 ;; zero-offset branch or not for any generic case involving a single
4451 ;; instruction on SH4 202.
4453 (define_insn_and_split "negsi_cond"
4454 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4455 (if_then_else:SI (eq:SI (reg:SI T_REG)
4456 (match_operand:SI 3 "const_int_operand" "M,N"))
4457 (match_operand:SI 1 "arith_reg_operand" "0,0")
4458 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4461 bt\\t0f\;neg\\t%2,%0\\n0:
4462 bf\\t0f\;neg\\t%2,%0\\n0:"
4466 rtx skip_neg_label = gen_label_rtx ();
4468 emit_insn (gen_movsi (operands[0], operands[1]));
4470 emit_jump_insn (INTVAL (operands[3])
4471 ? gen_branch_true (skip_neg_label)
4472 : gen_branch_false (skip_neg_label));
4474 emit_label_after (skip_neg_label,
4475 emit_insn (gen_negsi2 (operands[0], operands[1])));
4478 [(set_attr "type" "arith") ;; poor approximation
4479 (set_attr "length" "4")])
4481 (define_expand "absdi2"
4482 [(set (match_operand:DI 0 "arith_reg_dest" "")
4483 (abs:DI (match_operand:DI 1 "arith_reg_operand" "")))
4484 (clobber (reg:SI T_REG))]
4488 (define_insn_and_split "*absdi2"
4489 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4490 (abs:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4493 "&& reload_completed"
4496 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4497 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4498 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4499 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4504 (define_insn_and_split "*negabsdi2"
4505 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4506 (neg:DI (abs:DI (match_operand:DI 1 "arith_reg_operand" "r"))))]
4509 "&& reload_completed"
4512 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4513 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4515 emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4516 emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4521 (define_insn_and_split "negdi_cond"
4522 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4523 (if_then_else:DI (eq:SI (reg:SI T_REG)
4524 (match_operand:SI 3 "const_int_operand" "M,N"))
4525 (match_operand:DI 1 "arith_reg_operand" "r,r")
4526 (neg:DI (match_operand:DI 2 "arith_reg_operand" "1,1"))))]
4532 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4533 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4535 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4536 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4538 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4539 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
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)
4548 : gen_branch_false (skip_neg_label));
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 ;; -------------------------------------------------------------------------
4559 ;; Zero extension instructions
4560 ;; -------------------------------------------------------------------------
4562 (define_insn "zero_extendsidi2"
4563 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4564 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4566 "addz.l %1, r63, %0"
4567 [(set_attr "type" "arith_media")
4568 (set_attr "highpart" "extend")])
4570 (define_insn "zero_extendhidi2"
4571 [(set (match_operand:DI 0 "register_operand" "=r,r")
4572 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4577 [(set_attr "type" "*,load_media")
4578 (set (attr "highpart")
4579 (cond [(match_test "sh_contains_memref_p (insn)")
4580 (const_string "user")]
4581 (const_string "ignore")))])
4584 [(set (match_operand:DI 0 "register_operand" "")
4585 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4586 "TARGET_SHMEDIA && reload_completed"
4587 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4588 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4590 if (GET_CODE (operands[1]) == TRUNCATE)
4591 operands[1] = XEXP (operands[1], 0);
4594 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4595 ;; reload the entire truncate expression.
4596 (define_insn_and_split "*loaddi_trunc"
4597 [(set (match_operand 0 "any_register_operand" "=r")
4598 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4599 "TARGET_SHMEDIA && reload_completed"
4601 "TARGET_SHMEDIA && reload_completed"
4602 [(set (match_dup 0) (match_dup 1))]
4604 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4607 (define_insn "zero_extendqidi2"
4608 [(set (match_operand:DI 0 "register_operand" "=r,r")
4609 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4614 [(set_attr "type" "arith_media,load_media")
4615 (set (attr "highpart")
4616 (cond [(match_test "sh_contains_memref_p (insn)")
4617 (const_string "user")]
4618 (const_string "ignore")))])
4620 (define_expand "zero_extendhisi2"
4621 [(set (match_operand:SI 0 "arith_reg_operand" "")
4622 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4625 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4626 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4629 (define_insn "*zero_extendhisi2_compact"
4630 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4631 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4634 [(set_attr "type" "arith")])
4636 (define_insn "*zero_extendhisi2_media"
4637 [(set (match_operand:SI 0 "register_operand" "=r,r")
4638 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4643 [(set_attr "type" "arith_media,load_media")
4644 (set (attr "highpart")
4645 (cond [(match_test "sh_contains_memref_p (insn)")
4646 (const_string "user")]
4647 (const_string "ignore")))])
4650 [(set (match_operand:SI 0 "register_operand" "")
4651 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4652 "TARGET_SHMEDIA && reload_completed"
4653 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4654 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4656 rtx op1 = operands[1];
4658 if (GET_CODE (op1) == TRUNCATE)
4659 op1 = XEXP (op1, 0);
4661 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4662 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4665 (define_expand "zero_extendqisi2"
4666 [(set (match_operand:SI 0 "arith_reg_operand" "")
4667 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4670 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4671 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4674 (define_insn "*zero_extendqisi2_compact"
4675 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4676 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4679 [(set_attr "type" "arith")])
4681 (define_insn "*zero_extendqisi2_media"
4682 [(set (match_operand:SI 0 "register_operand" "=r,r")
4683 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4688 [(set_attr "type" "arith_media,load_media")
4689 (set (attr "highpart")
4690 (cond [(match_test "sh_contains_memref_p (insn)")
4691 (const_string "user")]
4692 (const_string "ignore")))])
4694 (define_insn "zero_extendqihi2"
4695 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4696 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4699 [(set_attr "type" "arith")])
4701 ;; -------------------------------------------------------------------------
4702 ;; Sign extension instructions
4703 ;; -------------------------------------------------------------------------
4705 ;; ??? This should be a define expand.
4706 ;; ??? Or perhaps it should be dropped?
4708 ;; convert_move generates good code for SH[1-4].
4709 (define_insn "extendsidi2"
4710 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4711 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4717 [(set_attr "type" "arith_media,load_media,fpconv_media")
4718 (set (attr "highpart")
4719 (cond [(match_test "sh_contains_memref_p (insn)")
4720 (const_string "user")]
4721 (const_string "extend")))])
4723 (define_insn "extendhidi2"
4724 [(set (match_operand:DI 0 "register_operand" "=r,r")
4725 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4730 [(set_attr "type" "*,load_media")
4731 (set (attr "highpart")
4732 (cond [(match_test "sh_contains_memref_p (insn)")
4733 (const_string "user")]
4734 (const_string "ignore")))])
4737 [(set (match_operand:DI 0 "register_operand" "")
4738 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4739 "TARGET_SHMEDIA && reload_completed"
4740 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4741 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4743 if (GET_CODE (operands[1]) == TRUNCATE)
4744 operands[1] = XEXP (operands[1], 0);
4747 (define_insn "extendqidi2"
4748 [(set (match_operand:DI 0 "register_operand" "=r,r")
4749 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4754 [(set_attr "type" "*,load_media")
4755 (set (attr "highpart")
4756 (cond [(match_test "sh_contains_memref_p (insn)")
4757 (const_string "user")]
4758 (const_string "ignore")))])
4761 [(set (match_operand:DI 0 "register_operand" "")
4762 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4763 "TARGET_SHMEDIA && reload_completed"
4764 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4765 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4767 if (GET_CODE (operands[1]) == TRUNCATE)
4768 operands[1] = XEXP (operands[1], 0);
4771 (define_expand "extendhisi2"
4772 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4773 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4777 (define_insn "*extendhisi2_compact"
4778 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4779 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4784 [(set_attr "type" "arith,load")])
4786 (define_insn "*extendhisi2_media"
4787 [(set (match_operand:SI 0 "register_operand" "=r,r")
4788 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4793 [(set_attr "type" "arith_media,load_media")
4794 (set (attr "highpart")
4795 (cond [(match_test "sh_contains_memref_p (insn)")
4796 (const_string "user")]
4797 (const_string "ignore")))])
4800 [(set (match_operand:SI 0 "register_operand" "")
4801 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4802 "TARGET_SHMEDIA && reload_completed"
4803 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4804 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4806 rtx op1 = operands[1];
4807 if (GET_CODE (op1) == TRUNCATE)
4808 op1 = XEXP (op1, 0);
4810 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4811 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4814 (define_expand "extendqisi2"
4815 [(set (match_operand:SI 0 "arith_reg_dest" "")
4816 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4820 (define_insn "*extendqisi2_compact_reg"
4821 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4822 (sign_extend:SI (match_operand:QI 1 "register_operand" "r,t")))]
4827 [(set_attr "type" "arith,arith")])
4829 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
4831 (define_insn "*extendqisi2_compact_mem_disp"
4832 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
4834 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
4835 (match_operand:SI 2 "const_int_operand" "K04,N")))))]
4836 "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))"
4840 [(set_attr "type" "load")])
4842 (define_insn "*extendqisi2_compact_mem_disp"
4843 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
4845 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
4846 (match_operand:SI 2 "const_int_operand" "K04,N,K12")))))]
4848 && (CONST_OK_FOR_K04 (INTVAL (operands[2]))
4849 || (CONST_OK_FOR_K12 (INTVAL (operands[2]))))"
4854 [(set_attr "type" "load")
4855 (set_attr "length" "2,2,4")])
4857 ;; This will take care of other QImode addressing modes than displacement
4859 (define_insn "*extendqisi2_compact_snd"
4860 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4861 (sign_extend:SI (match_operand:QI 1 "movsrc_no_disp_mem_operand" "Snd")))]
4864 [(set_attr "type" "load")])
4866 (define_insn "*extendqisi2_media"
4867 [(set (match_operand:SI 0 "register_operand" "=r,r")
4868 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4873 [(set_attr "type" "arith_media,load_media")
4874 (set (attr "highpart")
4875 (cond [(match_test "sh_contains_memref_p (insn)")
4876 (const_string "user")]
4877 (const_string "ignore")))])
4880 [(set (match_operand:SI 0 "register_operand" "")
4881 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4882 "TARGET_SHMEDIA && reload_completed"
4883 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4884 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4886 rtx op1 = operands[1];
4887 if (GET_CODE (op1) == TRUNCATE)
4888 op1 = XEXP (op1, 0);
4890 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4891 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4894 (define_expand "extendqihi2"
4895 [(set (match_operand:HI 0 "arith_reg_dest" "")
4896 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
4900 (define_insn "*extendqihi2_compact_reg"
4901 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4902 (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4905 [(set_attr "type" "arith")])
4907 ;; It would seem useful to combine the truncXi patterns into the movXi
4908 ;; patterns, but unary operators are ignored when matching constraints,
4909 ;; so we need separate patterns.
4910 (define_insn "truncdisi2"
4911 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4912 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4921 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4922 (set (attr "highpart")
4923 (cond [(match_test "sh_contains_memref_p (insn)")
4924 (const_string "user")]
4925 (const_string "extend")))])
4927 (define_insn "truncdihi2"
4928 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4929 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4932 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4934 [(set_attr "type" "arith_media,store_media")
4935 (set_attr "length" "8,4")
4936 (set (attr "highpart")
4937 (cond [(match_test "sh_contains_memref_p (insn)")
4938 (const_string "user")]
4939 (const_string "extend")))])
4941 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4942 ; Because we use zero extension, we can't provide signed QImode compares
4943 ; using a simple compare or conditional branch insn.
4944 (define_insn "truncdiqi2"
4945 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4946 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4951 [(set_attr "type" "arith_media,store")
4952 (set (attr "highpart")
4953 (cond [(match_test "sh_contains_memref_p (insn)")
4954 (const_string "user")]
4955 (const_string "extend")))])
4956 ;; -------------------------------------------------------------------------
4957 ;; Move instructions
4958 ;; -------------------------------------------------------------------------
4960 ;; define push and pop so it is easy for sh.c
4961 ;; We can't use push and pop on SHcompact because the stack must always
4962 ;; be 8-byte aligned.
4964 (define_expand "push"
4965 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4966 (match_operand:SI 0 "register_operand" "r,l,x"))]
4967 "TARGET_SH1 && ! TARGET_SH5"
4970 (define_expand "pop"
4971 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4972 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4973 "TARGET_SH1 && ! TARGET_SH5"
4976 (define_expand "push_e"
4977 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4978 (match_operand:SF 0 "" ""))
4979 (use (reg:PSI FPSCR_REG))
4980 (clobber (scratch:SI))])]
4981 "TARGET_SH1 && ! TARGET_SH5"
4984 (define_insn "push_fpul"
4985 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4986 "TARGET_SH2E && ! TARGET_SH5"
4988 [(set_attr "type" "fstore")
4989 (set_attr "late_fp_use" "yes")
4990 (set_attr "hit_stack" "yes")])
4992 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4994 (define_expand "push_4"
4995 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4996 (match_operand:DF 0 "" ""))
4997 (use (reg:PSI FPSCR_REG))
4998 (clobber (scratch:SI))])]
4999 "TARGET_SH1 && ! TARGET_SH5"
5002 (define_expand "pop_e"
5003 [(parallel [(set (match_operand:SF 0 "" "")
5004 (mem:SF (post_inc:SI (reg:SI SP_REG))))
5005 (use (reg:PSI FPSCR_REG))
5006 (clobber (scratch:SI))])]
5007 "TARGET_SH1 && ! TARGET_SH5"
5010 (define_insn "pop_fpul"
5011 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
5012 "TARGET_SH2E && ! TARGET_SH5"
5014 [(set_attr "type" "load")
5015 (set_attr "hit_stack" "yes")])
5017 (define_expand "pop_4"
5018 [(parallel [(set (match_operand:DF 0 "" "")
5019 (mem:DF (post_inc:SI (reg:SI SP_REG))))
5020 (use (reg:PSI FPSCR_REG))
5021 (clobber (scratch:SI))])]
5022 "TARGET_SH1 && ! TARGET_SH5"
5025 (define_expand "push_fpscr"
5029 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
5030 gen_rtx_PRE_DEC (Pmode,
5031 stack_pointer_rtx)),
5033 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5037 (define_expand "pop_fpscr"
5041 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
5042 gen_frame_mem (PSImode,
5043 gen_rtx_POST_INC (Pmode,
5044 stack_pointer_rtx))));
5045 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5049 ;; These two patterns can happen as the result of optimization, when
5050 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5051 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5054 [(set (reg:SI T_REG) (const_int 0))]
5059 [(set (reg:SI T_REG) (const_int 1))]
5063 ;; Define additional pop for SH1 and SH2 so it does not get
5064 ;; placed in the delay slot.
5065 (define_insn "*movsi_pop"
5066 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5067 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5068 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5074 [(set_attr "type" "load_si,mem_mac,pload")
5075 (set_attr "length" "2,2,2")
5076 (set_attr "in_delay_slot" "no,no,no")])
5078 ;; t/r must come after r/r, lest reload will try to reload stuff like
5079 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5080 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5081 (define_insn "movsi_i"
5082 [(set (match_operand:SI 0 "general_movdst_operand"
5083 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5084 (match_operand:SI 1 "general_movsrc_operand"
5085 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5089 && (register_operand (operands[0], SImode)
5090 || register_operand (operands[1], SImode))"
5108 [(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")
5109 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5111 ;; t/r must come after r/r, lest reload will try to reload stuff like
5112 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5113 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5114 ;; will require a reload.
5115 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5116 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5117 (define_insn "movsi_ie"
5118 [(set (match_operand:SI 0 "general_movdst_operand"
5119 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5120 (match_operand:SI 1 "general_movsrc_operand"
5121 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5122 "(TARGET_SH2E || TARGET_SH2A)
5123 && (register_operand (operands[0], SImode)
5124 || register_operand (operands[1], SImode))"
5151 ! move optimized away"
5152 [(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")
5153 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5154 (set_attr_alternative "length"
5162 (match_test "TARGET_SH2A")
5163 (const_int 4) (const_int 2))
5168 (match_test "TARGET_SH2A")
5169 (const_int 4) (const_int 2))
5186 (define_insn "movsi_i_lowpart"
5187 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5188 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5190 && (register_operand (operands[0], SImode)
5191 || register_operand (operands[1], SImode))"
5202 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5204 (define_insn_and_split "load_ra"
5205 [(set (match_operand:SI 0 "general_movdst_operand" "")
5206 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5209 "&& ! currently_expanding_to_rtl"
5210 [(set (match_dup 0) (match_dup 1))]
5212 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5213 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5216 ;; The '?'s in the following constraints may not reflect the time taken
5217 ;; to perform the move. They are there to discourage the use of floating-
5218 ;; point registers for storing integer values.
5219 (define_insn "*movsi_media"
5220 [(set (match_operand:SI 0 "general_movdst_operand"
5221 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5222 (match_operand:SI 1 "general_movsrc_operand"
5223 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5225 && (register_operand (operands[0], SImode)
5226 || sh_register_operand (operands[1], SImode)
5227 || GET_CODE (operands[1]) == TRUNCATE)"
5242 [(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")
5243 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5244 (set (attr "highpart")
5245 (cond [(match_test "sh_contains_memref_p (insn)")
5246 (const_string "user")]
5247 (const_string "ignore")))])
5249 (define_insn "*movsi_media_nofpu"
5250 [(set (match_operand:SI 0 "general_movdst_operand"
5251 "=r,r,r,r,m,*b,r,*b")
5252 (match_operand:SI 1 "general_movsrc_operand"
5253 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5255 && (register_operand (operands[0], SImode)
5256 || sh_register_operand (operands[1], SImode)
5257 || GET_CODE (operands[1]) == TRUNCATE)"
5267 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5268 (set_attr "length" "4,4,8,4,4,4,4,12")
5269 (set (attr "highpart")
5270 (cond [(match_test "sh_contains_memref_p (insn)")
5271 (const_string "user")]
5272 (const_string "ignore")))])
5274 (define_expand "movsi_const"
5275 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5276 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5277 (const_int 16)] UNSPEC_EXTRACT_S16)))
5279 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5280 (const:SI (unspec:SI [(match_dup 1)
5281 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5282 "TARGET_SHMEDIA && reload_completed
5283 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5285 if (GET_CODE (operands[1]) == LABEL_REF
5286 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5287 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5288 else if (GOTOFF_P (operands[1]))
5290 rtx unspec = XEXP (operands[1], 0);
5292 if (! UNSPEC_GOTOFF_P (unspec))
5294 unspec = XEXP (unspec, 0);
5295 if (! UNSPEC_GOTOFF_P (unspec))
5298 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5299 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5300 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5304 (define_expand "movsi_const_16bit"
5305 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5306 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5307 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5308 "TARGET_SHMEDIA && flag_pic && reload_completed
5309 && GET_CODE (operands[1]) == SYMBOL_REF"
5313 [(set (match_operand:SI 0 "arith_reg_dest" "")
5314 (match_operand:SI 1 "immediate_operand" ""))]
5315 "TARGET_SHMEDIA && reload_completed
5316 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5319 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5321 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5327 [(set (match_operand:SI 0 "register_operand" "")
5328 (match_operand:SI 1 "immediate_operand" ""))]
5329 "TARGET_SHMEDIA && reload_completed
5330 && ((CONST_INT_P (operands[1])
5331 && ! satisfies_constraint_I16 (operands[1]))
5332 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5333 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5335 (define_expand "movsi"
5336 [(set (match_operand:SI 0 "general_movdst_operand" "")
5337 (match_operand:SI 1 "general_movsrc_operand" ""))]
5340 if (prepare_move_operands (operands, SImode))
5344 (define_expand "ic_invalidate_line"
5345 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5346 (match_dup 1)] UNSPEC_ICACHE)
5347 (clobber (scratch:SI))])]
5348 "TARGET_HARD_SH4 || TARGET_SH5"
5352 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5355 else if (TARGET_SHCOMPACT)
5357 operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
5358 operands[1] = force_reg (Pmode, operands[1]);
5359 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5362 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5364 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5367 operands[0] = force_reg (Pmode, operands[0]);
5368 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5372 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5373 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5374 ;; the requirement *1*00 for associative address writes. The alignment of
5375 ;; %0 implies that its least significant bit is cleared,
5376 ;; thus we clear the V bit of a matching entry if there is one.
5377 (define_insn "ic_invalidate_line_i"
5378 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5379 (match_operand:SI 1 "register_operand" "r")]
5381 (clobber (match_scratch:SI 2 "=&r"))]
5383 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5384 [(set_attr "length" "8")
5385 (set_attr "type" "cwb")])
5387 (define_insn "ic_invalidate_line_sh4a"
5388 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5390 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5391 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5392 [(set_attr "length" "16")
5393 (set_attr "type" "cwb")])
5395 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5396 ;; an add in the code that calculates the address.
5397 (define_insn "ic_invalidate_line_media"
5398 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5401 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5402 [(set_attr "length" "16")
5403 (set_attr "type" "invalidate_line_media")])
5405 (define_insn "ic_invalidate_line_compact"
5406 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5407 (match_operand:SI 1 "register_operand" "r")]
5409 (clobber (reg:SI PR_REG))]
5412 [(set_attr "type" "sfunc")
5413 (set_attr "needs_delay_slot" "yes")])
5415 (define_expand "initialize_trampoline"
5416 [(match_operand:SI 0 "" "")
5417 (match_operand:SI 1 "" "")
5418 (match_operand:SI 2 "" "")]
5423 tramp = force_reg (Pmode, operands[0]);
5424 sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
5426 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5427 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5429 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5433 (define_insn "initialize_trampoline_compact"
5434 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5435 (match_operand:SI 1 "register_operand" "r")
5436 (reg:SI R2_REG) (reg:SI R3_REG)]
5439 (clobber (reg:SI PR_REG))]
5442 [(set_attr "type" "sfunc")
5443 (set_attr "needs_delay_slot" "yes")])
5445 (define_expand "movqi"
5446 [(set (match_operand:QI 0 "general_operand" "")
5447 (match_operand:QI 1 "general_operand" ""))]
5450 if (prepare_move_operands (operands, QImode))
5454 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
5455 ;; selected to copy QImode regs. If one of them happens to be allocated
5456 ;; on the stack, reload will stick to movqi insn and generate wrong
5457 ;; displacement addressing because of the generic m alternatives.
5458 ;; With the movqi_reg_reg being specified before movqi it will be intially
5459 ;; picked to load/store regs. If the regs regs are on the stack reload will
5460 ;; try other insns and not stick to movqi_reg_reg.
5461 (define_insn "*movqi_reg_reg"
5462 [(set (match_operand:QI 0 "arith_reg_dest" "=r,r")
5463 (match_operand:QI 1 "register_operand" "r,t"))]
5468 [(set_attr "type" "move,arith")])
5470 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
5471 ;; "enabled" attribute as it is done in other targets.
5472 (define_insn "*movqi_store_mem_disp04"
5473 [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
5474 (match_operand:SI 1 "const_int_operand" "K04,N")))
5475 (match_operand:QI 2 "arith_reg_operand" "z,r"))]
5476 "TARGET_SH1 && CONST_OK_FOR_K04 (INTVAL (operands[1]))"
5480 [(set_attr "type" "store")])
5482 (define_insn "*movqi_store_mem_disp12"
5483 [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
5484 (match_operand:SI 1 "const_int_operand" "K12")))
5485 (match_operand:QI 2 "arith_reg_operand" "r"))]
5486 "TARGET_SH2A && CONST_OK_FOR_K12 (INTVAL (operands[1]))"
5487 "mov.b %2,@(%O1,%0)"
5488 [(set_attr "type" "store")
5489 (set_attr "length" "4")])
5491 (define_insn "*movqi_load_mem_disp"
5492 [(set (match_operand:QI 0 "arith_reg_dest" "=z,r")
5493 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
5494 (match_operand:SI 2 "const_int_operand" "K04,N"))))]
5495 "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))"
5499 [(set_attr "type" "load")])
5501 (define_insn "*movqi_load_mem_disp"
5502 [(set (match_operand:QI 0 "arith_reg_dest" "=z,r,r")
5503 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
5504 (match_operand:SI 2 "const_int_operand" "K04,N,K12"))))]
5506 && (CONST_OK_FOR_K04 (INTVAL (operands[2]))
5507 || CONST_OK_FOR_K12 (INTVAL (operands[2])))"
5512 [(set_attr "type" "load")
5513 (set_attr "length" "2,2,4")])
5515 ;; The m constraints basically allow any kind of addresses to be used with any
5516 ;; source/target register as the other operand. This is not true for
5517 ;; displacement addressing modes on anything but SH2A. That's why the
5518 ;; specialized load/store insns are specified above.
5519 (define_insn "*movqi"
5520 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
5521 (match_operand:QI 1 "general_movsrc_operand" "i,m,r,l,r"))]
5523 && (arith_reg_operand (operands[0], QImode)
5524 || arith_reg_operand (operands[1], QImode))"
5531 [(set_attr "type" "movi8,load,store,prget,prset")])
5533 (define_insn "*movqi_media"
5534 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5535 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5537 && (arith_reg_operand (operands[0], QImode)
5538 || extend_reg_or_0_operand (operands[1], QImode))"
5544 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5545 (set (attr "highpart")
5546 (cond [(match_test "sh_contains_memref_p (insn)")
5547 (const_string "user")]
5548 (const_string "ignore")))])
5550 (define_expand "reload_inqi"
5551 [(set (match_operand:SI 2 "" "=&r")
5552 (match_operand:QI 1 "inqhi_operand" ""))
5553 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5554 (truncate:QI (match_dup 3)))]
5557 rtx inner = XEXP (operands[1], 0);
5558 int regno = REGNO (inner);
5560 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5561 operands[1] = gen_rtx_REG (SImode, regno);
5562 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5565 ;; When storing r0, we have to avoid reg+reg addressing.
5566 (define_insn "movhi_i"
5567 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5568 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5570 && (arith_reg_operand (operands[0], HImode)
5571 || arith_reg_operand (operands[1], HImode))
5572 && (!MEM_P (operands[0])
5573 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5574 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5575 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5585 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5587 (define_insn "*movhi_media"
5588 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5589 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5591 && (arith_reg_operand (operands[0], HImode)
5592 || arith_reg_or_0_operand (operands[1], HImode))"
5599 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5600 (set (attr "highpart")
5601 (cond [(match_test "sh_contains_memref_p (insn)")
5602 (const_string "user")]
5603 (const_string "ignore")))])
5606 [(set (match_operand:HI 0 "register_operand" "")
5607 (match_operand:HI 1 "immediate_operand" ""))]
5608 "TARGET_SHMEDIA && reload_completed
5609 && ! satisfies_constraint_I16 (operands[1])"
5610 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5612 (define_expand "movhi"
5613 [(set (match_operand:HI 0 "general_movdst_operand" "")
5614 (match_operand:HI 1 "general_movsrc_operand" ""))]
5617 if (prepare_move_operands (operands, HImode))
5621 (define_expand "reload_inhi"
5622 [(set (match_operand:SI 2 "" "=&r")
5623 (match_operand:HI 1 "inqhi_operand" ""))
5624 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5625 (truncate:HI (match_dup 3)))]
5628 rtx inner = XEXP (operands[1], 0);
5629 int regno = REGNO (inner);
5631 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5632 operands[1] = gen_rtx_REG (SImode, regno);
5633 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5636 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5637 ;; compiled with -m2 -ml -O3 -funroll-loops
5638 (define_insn "*movdi_i"
5639 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5640 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5642 && (arith_reg_operand (operands[0], DImode)
5643 || arith_reg_operand (operands[1], DImode))"
5644 "* return output_movedouble (insn, operands, DImode);"
5645 [(set_attr "length" "4")
5646 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5648 ;; If the output is a register and the input is memory or a register, we have
5649 ;; to be careful and see which word needs to be loaded first.
5652 [(set (match_operand:DI 0 "general_movdst_operand" "")
5653 (match_operand:DI 1 "general_movsrc_operand" ""))]
5654 "TARGET_SH1 && reload_completed"
5655 [(set (match_dup 2) (match_dup 3))
5656 (set (match_dup 4) (match_dup 5))]
5660 if ((MEM_P (operands[0])
5661 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5662 || (MEM_P (operands[1])
5663 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5666 switch (GET_CODE (operands[0]))
5669 regno = REGNO (operands[0]);
5672 regno = subreg_regno (operands[0]);
5682 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5684 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5685 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5686 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5687 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5691 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5692 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5693 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5694 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5697 if (operands[2] == 0 || operands[3] == 0
5698 || operands[4] == 0 || operands[5] == 0)
5702 ;; The '?'s in the following constraints may not reflect the time taken
5703 ;; to perform the move. They are there to discourage the use of floating-
5704 ;; point registers for storing integer values.
5705 (define_insn "*movdi_media"
5706 [(set (match_operand:DI 0 "general_movdst_operand"
5707 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5708 (match_operand:DI 1 "general_movsrc_operand"
5709 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5711 && (register_operand (operands[0], DImode)
5712 || sh_register_operand (operands[1], DImode))"
5727 [(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")
5728 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5730 (define_insn "*movdi_media_nofpu"
5731 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5732 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5734 && (register_operand (operands[0], DImode)
5735 || sh_register_operand (operands[1], DImode))"
5745 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5746 (set_attr "length" "4,4,16,4,4,4,4,*")])
5748 (define_insn "*movdi_media_I16"
5749 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5750 (match_operand:DI 1 "const_int_operand" "I16"))]
5751 "TARGET_SHMEDIA && reload_completed"
5753 [(set_attr "type" "arith_media")
5754 (set_attr "length" "4")])
5757 [(set (match_operand:DI 0 "arith_reg_dest" "")
5758 (match_operand:DI 1 "immediate_operand" ""))]
5759 "TARGET_SHMEDIA && reload_completed
5760 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5761 [(set (match_dup 0) (match_dup 1))]
5765 if (TARGET_SHMEDIA64)
5766 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5768 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5770 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5775 (define_expand "movdi_const"
5776 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5777 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5778 (const_int 48)] UNSPEC_EXTRACT_S16)))
5780 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5781 (const:DI (unspec:DI [(match_dup 1)
5782 (const_int 32)] UNSPEC_EXTRACT_U16))))
5784 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5785 (const:DI (unspec:DI [(match_dup 1)
5786 (const_int 16)] UNSPEC_EXTRACT_U16))))
5788 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5789 (const:DI (unspec:DI [(match_dup 1)
5790 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5791 "TARGET_SHMEDIA64 && reload_completed
5792 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5794 sh_mark_label (operands[1], 4);
5797 (define_expand "movdi_const_32bit"
5798 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5799 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5800 (const_int 16)] UNSPEC_EXTRACT_S16)))
5802 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5803 (const:DI (unspec:DI [(match_dup 1)
5804 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5805 "TARGET_SHMEDIA32 && reload_completed
5806 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5808 sh_mark_label (operands[1], 2);
5811 (define_expand "movdi_const_16bit"
5812 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5813 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5814 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5815 "TARGET_SHMEDIA && flag_pic && reload_completed
5816 && GET_CODE (operands[1]) == SYMBOL_REF"
5820 [(set (match_operand:DI 0 "ext_dest_operand" "")
5821 (match_operand:DI 1 "immediate_operand" ""))]
5822 "TARGET_SHMEDIA && reload_completed
5823 && CONST_INT_P (operands[1])
5824 && ! satisfies_constraint_I16 (operands[1])"
5825 [(set (match_dup 0) (match_dup 2))
5828 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5829 unsigned HOST_WIDE_INT low = val;
5830 unsigned HOST_WIDE_INT high = val;
5831 unsigned HOST_WIDE_INT sign;
5832 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5834 /* Zero-extend the 16 least-significant bits. */
5837 /* Arithmetic shift right the word by 16 bits. */
5839 if (GET_CODE (operands[0]) == SUBREG
5840 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5849 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5855 /* If we can't generate the constant with a two-insn movi / shori
5856 sequence, try some other strategies. */
5857 if (! CONST_OK_FOR_I16 (high))
5859 /* Try constant load / left shift. We know VAL != 0. */
5860 val2 = val ^ (val-1);
5863 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5865 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5866 || (! CONST_OK_FOR_I16 (high >> 16)
5867 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5869 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5870 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5871 GEN_INT (trailing_zeroes));
5875 /* Try constant load / right shift. */
5876 val2 = (val >> 15) + 1;
5877 if (val2 == (val2 & -val2))
5879 int shift = 49 - exact_log2 (val2);
5881 val2 = trunc_int_for_mode (val << shift, DImode);
5882 if (CONST_OK_FOR_I16 (val2))
5884 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5890 val2 = val & 0xffff;
5891 if ((val >> 16 & 0xffff) == val2
5892 && (val >> 32 & 0xffff) == val2
5893 && (val >> 48 & 0xffff) == val2)
5895 val2 = (HOST_WIDE_INT) val >> 48;
5896 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5897 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5900 /* Try movi / mshflo.l */
5901 val2 = (HOST_WIDE_INT) val >> 32;
5902 if (val2 == ((unsigned HOST_WIDE_INT)
5903 trunc_int_for_mode (val, SImode)))
5905 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5909 /* Try movi / mshflo.l w/ r63. */
5910 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5911 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5913 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5919 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5922 operands[2] = GEN_INT (val2);
5926 [(set (match_operand:DI 0 "ext_dest_operand" "")
5927 (match_operand:DI 1 "immediate_operand" ""))]
5928 "TARGET_SHMEDIA && reload_completed
5929 && GET_CODE (operands[1]) == CONST_DOUBLE"
5930 [(set (match_dup 0) (match_dup 2))
5932 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5934 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5935 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5936 unsigned HOST_WIDE_INT val = low;
5937 unsigned HOST_WIDE_INT sign;
5939 /* Zero-extend the 16 least-significant bits. */
5941 operands[1] = GEN_INT (val);
5943 /* Arithmetic shift right the double-word by 16 bits. */
5945 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5948 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5952 /* This will only be true if high is a sign-extension of low, i.e.,
5953 it must be either 0 or (unsigned)-1, and be zero iff the
5954 most-significant bit of low is set. */
5955 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5956 operands[2] = GEN_INT (low);
5958 operands[2] = immed_double_const (low, high, DImode);
5961 (define_insn "shori_media"
5962 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5963 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5965 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5966 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5970 [(set_attr "type" "arith_media,*")])
5972 (define_insn "*shori_media_si"
5973 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5974 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5976 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5980 (define_expand "movdi"
5981 [(set (match_operand:DI 0 "general_movdst_operand" "")
5982 (match_operand:DI 1 "general_movsrc_operand" ""))]
5985 if (prepare_move_operands (operands, DImode))
5989 (define_insn "movdf_media"
5990 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5991 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5993 && (register_operand (operands[0], DFmode)
5994 || sh_register_operand (operands[1], DFmode))"
6005 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
6007 (define_insn "movdf_media_nofpu"
6008 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6009 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6011 && (register_operand (operands[0], DFmode)
6012 || sh_register_operand (operands[1], DFmode))"
6018 [(set_attr "type" "arith_media,*,load_media,store_media")])
6021 [(set (match_operand:DF 0 "arith_reg_dest" "")
6022 (match_operand:DF 1 "immediate_operand" ""))]
6023 "TARGET_SHMEDIA && reload_completed"
6024 [(set (match_dup 3) (match_dup 2))]
6026 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
6028 REAL_VALUE_TYPE value;
6030 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6031 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
6033 if (HOST_BITS_PER_WIDE_INT >= 64)
6034 operands[2] = immed_double_const ((unsigned long) values[endian]
6035 | ((HOST_WIDE_INT) values[1 - endian]
6039 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
6040 operands[2] = immed_double_const (values[endian], values[1 - endian],
6044 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6047 ;; ??? This should be a define expand.
6049 (define_insn "movdf_k"
6050 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6051 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
6053 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
6054 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
6055 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6056 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6057 && (arith_reg_operand (operands[0], DFmode)
6058 || arith_reg_operand (operands[1], DFmode))"
6060 return output_movedouble (insn, operands, DFmode);
6062 [(set_attr "length" "4")
6063 (set_attr "type" "move,pcload,load,store")])
6065 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
6066 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
6067 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
6068 ;; the d/m/c/X alternative, which is split later into single-precision
6069 ;; instructions. And when not optimizing, no splits are done before fixing
6070 ;; up pcloads, so we need usable length information for that.
6071 (define_insn "movdf_i4"
6072 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
6073 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
6074 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
6075 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
6076 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6077 && (arith_reg_operand (operands[0], DFmode)
6078 || arith_reg_operand (operands[1], DFmode))"
6080 switch (which_alternative)
6084 return "fmov %1,%0";
6085 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
6086 return "fmov %R1,%R0\n\tfmov %S1,%S0";
6088 return "fmov %S1,%S0\n\tfmov %R1,%R0";
6091 return "fmov.d %1,%0";
6096 [(set_attr_alternative "length"
6097 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6099 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6100 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6101 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6103 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6104 ;; We can't use 4-byte push/pop on SHcompact, so we have to
6105 ;; increment or decrement r15 explicitly.
6107 (match_test "TARGET_SHCOMPACT")
6108 (const_int 10) (const_int 8))
6110 (match_test "TARGET_SHCOMPACT")
6111 (const_int 10) (const_int 8))])
6112 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6113 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6114 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6115 (const_string "double")
6116 (const_string "none")))])
6118 ;; Moving DFmode between fp/general registers through memory
6119 ;; (the top of the stack) is faster than moving through fpul even for
6120 ;; little endian. Because the type of an instruction is important for its
6121 ;; scheduling, it is beneficial to split these operations, rather than
6122 ;; emitting them in one single chunk, even if this will expose a stack
6123 ;; use that will prevent scheduling of other stack accesses beyond this
6126 [(set (match_operand:DF 0 "register_operand" "")
6127 (match_operand:DF 1 "register_operand" ""))
6128 (use (match_operand:PSI 2 "fpscr_operand" ""))
6129 (clobber (match_scratch:SI 3 "=X"))]
6130 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6131 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6136 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6138 emit_move_insn (stack_pointer_rtx,
6139 plus_constant (stack_pointer_rtx, -8));
6140 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6143 tos = gen_tmp_stack_mem (DFmode,
6144 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6145 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6146 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6147 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6148 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6149 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6151 tos = gen_tmp_stack_mem (DFmode,
6152 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6153 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6154 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6155 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6157 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6161 ;; local-alloc sometimes allocates scratch registers even when not required,
6162 ;; so we must be prepared to handle these.
6164 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6166 [(set (match_operand:DF 0 "general_movdst_operand" "")
6167 (match_operand:DF 1 "general_movsrc_operand" ""))
6168 (use (match_operand:PSI 2 "fpscr_operand" ""))
6169 (clobber (match_scratch:SI 3 ""))]
6170 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6172 && true_regnum (operands[0]) < 16
6173 && true_regnum (operands[1]) < 16"
6174 [(set (match_dup 0) (match_dup 1))]
6176 /* If this was a reg <-> mem operation with base + index reg addressing,
6177 we have to handle this in a special way. */
6178 rtx mem = operands[0];
6180 if (! memory_operand (mem, DFmode))
6185 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6186 mem = SUBREG_REG (mem);
6189 rtx addr = XEXP (mem, 0);
6190 if (GET_CODE (addr) == PLUS
6191 && REG_P (XEXP (addr, 0))
6192 && REG_P (XEXP (addr, 1)))
6195 rtx reg0 = gen_rtx_REG (Pmode, 0);
6196 rtx regop = operands[store_p], word0 ,word1;
6198 if (GET_CODE (regop) == SUBREG)
6199 alter_subreg (®op);
6200 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6204 mem = copy_rtx (mem);
6205 PUT_MODE (mem, SImode);
6206 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6207 alter_subreg (&word0);
6208 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6209 alter_subreg (&word1);
6210 if (store_p || ! refers_to_regno_p (REGNO (word0),
6211 REGNO (word0) + 1, addr, 0))
6214 ? gen_movsi_ie (mem, word0)
6215 : gen_movsi_ie (word0, mem));
6216 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6217 mem = copy_rtx (mem);
6219 ? gen_movsi_ie (mem, word1)
6220 : gen_movsi_ie (word1, mem));
6221 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6225 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6226 emit_insn (gen_movsi_ie (word1, mem));
6227 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6228 mem = copy_rtx (mem);
6229 emit_insn (gen_movsi_ie (word0, mem));
6236 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6238 [(set (match_operand:DF 0 "register_operand" "")
6239 (match_operand:DF 1 "memory_operand" ""))
6240 (use (match_operand:PSI 2 "fpscr_operand" ""))
6241 (clobber (reg:SI R0_REG))]
6242 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6243 [(parallel [(set (match_dup 0) (match_dup 1))
6245 (clobber (scratch:SI))])]
6248 (define_expand "reload_indf__frn"
6249 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6250 (match_operand:DF 1 "immediate_operand" "FQ"))
6251 (use (reg:PSI FPSCR_REG))
6252 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6256 (define_expand "reload_outdf__RnFRm"
6257 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6258 (match_operand:DF 1 "register_operand" "af,r"))
6259 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6263 ;; Simplify no-op moves.
6265 [(set (match_operand:SF 0 "register_operand" "")
6266 (match_operand:SF 1 "register_operand" ""))
6267 (use (match_operand:PSI 2 "fpscr_operand" ""))
6268 (clobber (match_scratch:SI 3 ""))]
6269 "TARGET_SH2E && reload_completed
6270 && true_regnum (operands[0]) == true_regnum (operands[1])"
6271 [(set (match_dup 0) (match_dup 0))]
6274 ;; fmovd substitute post-reload splits
6276 [(set (match_operand:DF 0 "register_operand" "")
6277 (match_operand:DF 1 "register_operand" ""))
6278 (use (match_operand:PSI 2 "fpscr_operand" ""))
6279 (clobber (match_scratch:SI 3 ""))]
6280 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6281 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6282 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6285 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6286 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6287 gen_rtx_REG (SFmode, src), operands[2]));
6288 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6289 gen_rtx_REG (SFmode, src + 1), operands[2]));
6294 [(set (match_operand:DF 0 "register_operand" "")
6295 (mem:DF (match_operand:SI 1 "register_operand" "")))
6296 (use (match_operand:PSI 2 "fpscr_operand" ""))
6297 (clobber (match_scratch:SI 3 ""))]
6298 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6299 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6300 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6303 int regno = true_regnum (operands[0]);
6305 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6307 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6308 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6309 regno + !! TARGET_LITTLE_ENDIAN),
6310 mem2, operands[2]));
6311 add_reg_note (insn, REG_INC, operands[1]);
6312 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6313 regno + ! TARGET_LITTLE_ENDIAN),
6314 change_address (mem, SFmode, NULL_RTX),
6320 [(set (match_operand:DF 0 "register_operand" "")
6321 (match_operand:DF 1 "memory_operand" ""))
6322 (use (match_operand:PSI 2 "fpscr_operand" ""))
6323 (clobber (match_scratch:SI 3 ""))]
6324 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6325 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6328 int regno = true_regnum (operands[0]);
6330 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6331 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6332 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6334 operands[1] = copy_rtx (mem2);
6335 addr = XEXP (mem2, 0);
6337 switch (GET_CODE (addr))
6340 /* This is complicated. If the register is an arithmetic register
6341 we can just fall through to the REG+DISP case below. Otherwise
6342 we have to use a combination of POST_INC and REG addressing... */
6343 if (! arith_reg_operand (operands[1], SFmode))
6345 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6346 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6347 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6349 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6351 /* If we have modified the stack pointer, the value that we have
6352 read with post-increment might be modified by an interrupt,
6353 so write it back. */
6354 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6355 emit_insn (gen_push_e (reg0));
6357 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6363 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6364 operands[1] = copy_rtx (operands[1]);
6365 XEXP (operands[1], 0) = plus_constant (addr, 4);
6366 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6370 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6371 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6373 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6374 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6386 [(set (match_operand:DF 0 "memory_operand" "")
6387 (match_operand:DF 1 "register_operand" ""))
6388 (use (match_operand:PSI 2 "fpscr_operand" ""))
6389 (clobber (match_scratch:SI 3 ""))]
6390 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6391 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6394 int regno = true_regnum (operands[1]);
6396 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6397 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6399 operands[0] = copy_rtx (operands[0]);
6400 PUT_MODE (operands[0], SFmode);
6401 addr = XEXP (operands[0], 0);
6403 switch (GET_CODE (addr))
6406 /* This is complicated. If the register is an arithmetic register
6407 we can just fall through to the REG+DISP case below. Otherwise
6408 we have to use a combination of REG and PRE_DEC addressing... */
6409 if (! arith_reg_operand (operands[0], SFmode))
6411 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6412 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6414 operands[0] = copy_rtx (operands[0]);
6415 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6417 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6418 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6424 /* Since REG+DISP addressing has already been decided upon by gcc
6425 we can rely upon it having chosen an arithmetic register as the
6426 register component of the address. Just emit the lower numbered
6427 register first, to the lower address, then the higher numbered
6428 register to the higher address. */
6429 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6431 operands[0] = copy_rtx (operands[0]);
6432 XEXP (operands[0], 0) = plus_constant (addr, 4);
6434 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6438 /* This is easy. Output the word to go to the higher address
6439 first (ie the word in the higher numbered register) then the
6440 word to go to the lower address. */
6442 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6443 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6445 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6446 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6458 ;; If the output is a register and the input is memory or a register, we have
6459 ;; to be careful and see which word needs to be loaded first.
6462 [(set (match_operand:DF 0 "general_movdst_operand" "")
6463 (match_operand:DF 1 "general_movsrc_operand" ""))]
6464 "TARGET_SH1 && reload_completed"
6465 [(set (match_dup 2) (match_dup 3))
6466 (set (match_dup 4) (match_dup 5))]
6470 if ((MEM_P (operands[0])
6471 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6472 || (MEM_P (operands[1])
6473 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6476 switch (GET_CODE (operands[0]))
6479 regno = REGNO (operands[0]);
6482 regno = subreg_regno (operands[0]);
6492 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6494 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6495 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6496 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6497 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6501 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6502 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6503 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6504 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6507 if (operands[2] == 0 || operands[3] == 0
6508 || operands[4] == 0 || operands[5] == 0)
6512 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6513 ;; used only once, let combine add in the index again.
6516 [(set (match_operand:SI 0 "register_operand" "")
6517 (match_operand:SI 1 "" ""))
6518 (clobber (match_operand 2 "register_operand" ""))]
6519 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6520 && ALLOW_INDEXED_ADDRESS"
6521 [(use (reg:SI R0_REG))]
6523 rtx addr, reg, const_int;
6525 if (!MEM_P (operands[1]))
6527 addr = XEXP (operands[1], 0);
6528 if (GET_CODE (addr) != PLUS)
6530 reg = XEXP (addr, 0);
6531 const_int = XEXP (addr, 1);
6532 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6533 && CONST_INT_P (const_int)))
6535 emit_move_insn (operands[2], const_int);
6536 emit_move_insn (operands[0],
6537 change_address (operands[1], VOIDmode,
6538 gen_rtx_PLUS (SImode, reg, operands[2])));
6543 [(set (match_operand:SI 1 "" "")
6544 (match_operand:SI 0 "register_operand" ""))
6545 (clobber (match_operand 2 "register_operand" ""))]
6546 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6547 && ALLOW_INDEXED_ADDRESS"
6548 [(use (reg:SI R0_REG))]
6550 rtx addr, reg, const_int;
6552 if (!MEM_P (operands[1]))
6554 addr = XEXP (operands[1], 0);
6555 if (GET_CODE (addr) != PLUS)
6557 reg = XEXP (addr, 0);
6558 const_int = XEXP (addr, 1);
6559 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6560 && CONST_INT_P (const_int)))
6562 emit_move_insn (operands[2], const_int);
6563 emit_move_insn (change_address (operands[1], VOIDmode,
6564 gen_rtx_PLUS (SImode, reg, operands[2])),
6569 (define_expand "movdf"
6570 [(set (match_operand:DF 0 "general_movdst_operand" "")
6571 (match_operand:DF 1 "general_movsrc_operand" ""))]
6574 if (prepare_move_operands (operands, DFmode))
6578 if (TARGET_SHMEDIA_FPU)
6579 emit_insn (gen_movdf_media (operands[0], operands[1]));
6581 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6584 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6586 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6591 ;;This is incompatible with the way gcc uses subregs.
6592 ;;(define_insn "movv2sf_i"
6593 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6594 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6595 ;; "TARGET_SHMEDIA_FPU
6596 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6597 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6601 ;; fst%M0.p %m0, %1"
6602 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6604 (define_insn_and_split "movv2sf_i"
6605 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6606 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6607 "TARGET_SHMEDIA_FPU"
6609 "TARGET_SHMEDIA_FPU && reload_completed"
6610 [(set (match_dup 0) (match_dup 1))]
6612 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6613 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6616 (define_expand "movv2sf"
6617 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6618 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6619 "TARGET_SHMEDIA_FPU"
6621 if (prepare_move_operands (operands, V2SFmode))
6625 (define_expand "addv2sf3"
6626 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6627 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6628 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6629 "TARGET_SHMEDIA_FPU"
6631 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6635 (define_expand "subv2sf3"
6636 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6637 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6638 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6639 "TARGET_SHMEDIA_FPU"
6641 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6645 (define_expand "mulv2sf3"
6646 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6647 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6648 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6649 "TARGET_SHMEDIA_FPU"
6651 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6655 (define_expand "divv2sf3"
6656 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6657 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6658 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6659 "TARGET_SHMEDIA_FPU"
6661 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6665 (define_insn_and_split "*movv4sf_i"
6666 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6667 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6668 "TARGET_SHMEDIA_FPU"
6670 "&& reload_completed"
6675 for (i = 0; i < 4/2; i++)
6679 if (MEM_P (operands[0]))
6680 x = adjust_address (operands[0], V2SFmode,
6681 i * GET_MODE_SIZE (V2SFmode));
6683 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6685 if (MEM_P (operands[1]))
6686 y = adjust_address (operands[1], V2SFmode,
6687 i * GET_MODE_SIZE (V2SFmode));
6689 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6691 emit_insn (gen_movv2sf_i (x, y));
6696 [(set_attr "length" "8")])
6698 (define_expand "movv4sf"
6699 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6700 (match_operand:V4SF 1 "general_operand" ""))]
6701 "TARGET_SHMEDIA_FPU"
6703 if (prepare_move_operands (operands, V4SFmode))
6707 (define_insn_and_split "*movv16sf_i"
6708 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6709 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6710 "TARGET_SHMEDIA_FPU"
6712 "&& reload_completed"
6717 for (i = 0; i < 16/2; i++)
6721 if (MEM_P (operands[0]))
6722 x = adjust_address (operands[0], V2SFmode,
6723 i * GET_MODE_SIZE (V2SFmode));
6726 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6730 if (MEM_P (operands[1]))
6731 y = adjust_address (operands[1], V2SFmode,
6732 i * GET_MODE_SIZE (V2SFmode));
6735 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6739 emit_insn (gen_movv2sf_i (x, y));
6744 [(set_attr "length" "32")])
6746 (define_expand "movv16sf"
6747 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6748 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6749 "TARGET_SHMEDIA_FPU"
6751 if (prepare_move_operands (operands, V16SFmode))
6755 (define_insn "movsf_media"
6756 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6757 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6759 && (register_operand (operands[0], SFmode)
6760 || sh_register_operand (operands[1], SFmode))"
6771 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6772 (set (attr "highpart")
6773 (cond [(match_test "sh_contains_memref_p (insn)")
6774 (const_string "user")]
6775 (const_string "ignore")))])
6777 (define_insn "movsf_media_nofpu"
6778 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6779 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6781 && (register_operand (operands[0], SFmode)
6782 || sh_register_operand (operands[1], SFmode))"
6788 [(set_attr "type" "arith_media,*,load_media,store_media")
6789 (set (attr "highpart")
6790 (cond [(match_test "sh_contains_memref_p (insn)")
6791 (const_string "user")]
6792 (const_string "ignore")))])
6795 [(set (match_operand:SF 0 "arith_reg_dest" "")
6796 (match_operand:SF 1 "immediate_operand" ""))]
6797 "TARGET_SHMEDIA && reload_completed
6798 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6799 [(set (match_dup 3) (match_dup 2))]
6802 REAL_VALUE_TYPE value;
6804 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6805 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6806 operands[2] = GEN_INT (values);
6808 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6811 (define_insn "movsf_i"
6812 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6813 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6816 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6817 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6818 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6819 && (arith_reg_operand (operands[0], SFmode)
6820 || arith_reg_operand (operands[1], SFmode))"
6829 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6831 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6832 ;; update_flow_info would not know where to put REG_EQUAL notes
6833 ;; when the destination changes mode.
6834 (define_insn "movsf_ie"
6835 [(set (match_operand:SF 0 "general_movdst_operand"
6836 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6837 (match_operand:SF 1 "general_movsrc_operand"
6838 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6839 (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"))
6840 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6842 && (arith_reg_operand (operands[0], SFmode)
6843 || arith_reg_operand (operands[1], SFmode)
6844 || arith_reg_operand (operands[3], SImode)
6845 || (fpul_operand (operands[0], SFmode)
6846 && memory_operand (operands[1], SFmode)
6847 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6848 || (fpul_operand (operands[1], SFmode)
6849 && memory_operand (operands[0], SFmode)
6850 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6870 ! move optimized away"
6871 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6872 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6873 (set_attr_alternative "length"
6880 (match_test "TARGET_SH2A")
6881 (const_int 4) (const_int 2))
6883 (match_test "TARGET_SH2A")
6884 (const_int 4) (const_int 2))
6887 (match_test "TARGET_SH2A")
6888 (const_int 4) (const_int 2))
6890 (match_test "TARGET_SH2A")
6891 (const_int 4) (const_int 2))
6901 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6902 (const_string "single")
6903 (const_string "single")))])
6906 [(set (match_operand:SF 0 "register_operand" "")
6907 (match_operand:SF 1 "register_operand" ""))
6908 (use (match_operand:PSI 2 "fpscr_operand" ""))
6909 (clobber (reg:SI FPUL_REG))]
6911 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6913 (clobber (scratch:SI))])
6914 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6916 (clobber (scratch:SI))])]
6919 (define_expand "movsf"
6920 [(set (match_operand:SF 0 "general_movdst_operand" "")
6921 (match_operand:SF 1 "general_movsrc_operand" ""))]
6924 if (prepare_move_operands (operands, SFmode))
6928 if (TARGET_SHMEDIA_FPU)
6929 emit_insn (gen_movsf_media (operands[0], operands[1]));
6931 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6936 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6941 (define_insn "mov_nop"
6942 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6945 [(set_attr "length" "0")
6946 (set_attr "type" "nil")])
6948 (define_expand "reload_insf__frn"
6949 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6950 (match_operand:SF 1 "immediate_operand" "FQ"))
6951 (use (reg:PSI FPSCR_REG))
6952 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6956 (define_expand "reload_insi__i_fpul"
6957 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6958 (match_operand:SI 1 "immediate_operand" "i"))
6959 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6963 (define_expand "ptabs"
6964 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6967 if (!TARGET_PT_FIXED)
6969 rtx eq = operands[1];
6971 /* ??? For canonical RTL we really should remove any CONST from EQ
6972 before wrapping it in the AND, and finally wrap the EQ into a
6973 const if is constant. However, for reload we must expose the
6974 input register or symbolic constant, and we can't have
6975 different insn structures outside of the operands for different
6976 alternatives of the same pattern. */
6977 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6980 = (gen_rtx_IF_THEN_ELSE
6983 gen_rtx_MEM (PDImode, operands[1]),
6984 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6985 PDImode, operands[1])));
6989 ;; expanded by ptabs expander.
6990 (define_insn "*extendsipdi_media"
6991 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6992 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6996 (mem:PDI (match_dup 1))
6997 (sign_extend:PDI (match_dup 1))))]
6998 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
7002 [(set_attr "type" "ptabs_media,pt_media")
7003 (set_attr "length" "4,*")])
7005 (define_insn "*truncdipdi_media"
7006 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
7007 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
7011 (mem:PDI (match_dup 1))
7012 (truncate:PDI (match_dup 1))))]
7013 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
7017 [(set_attr "type" "ptabs_media,pt_media")
7018 (set_attr "length" "4,*")])
7020 (define_insn "*movsi_y"
7021 [(set (match_operand:SI 0 "register_operand" "=y,y")
7022 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
7023 (clobber (match_scratch:SI 2 "=&z,r"))]
7025 && (reload_in_progress || reload_completed)"
7027 [(set_attr "length" "4")
7028 (set_attr "type" "pcload,move")])
7031 [(set (match_operand:SI 0 "register_operand" "")
7032 (match_operand:SI 1 "immediate_operand" ""))
7033 (clobber (match_operand:SI 2 "register_operand" ""))]
7035 [(set (match_dup 2) (match_dup 1))
7036 (set (match_dup 0) (match_dup 2))]
7039 ;; ------------------------------------------------------------------------
7040 ;; Define the real conditional branch instructions.
7041 ;; ------------------------------------------------------------------------
7043 (define_insn "branch_true"
7044 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
7045 (label_ref (match_operand 0 "" ""))
7049 return output_branch (1, insn, operands);
7051 [(set_attr "type" "cbranch")])
7053 (define_insn "branch_false"
7054 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7055 (label_ref (match_operand 0 "" ""))
7059 return output_branch (0, insn, operands);
7061 [(set_attr "type" "cbranch")])
7063 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
7064 ;; which destination is too far away.
7065 ;; The const_int_operand is distinct for each branch target; it avoids
7066 ;; unwanted matches with redundant_insn.
7067 (define_insn "block_branch_redirect"
7068 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7071 [(set_attr "length" "0")])
7073 ;; This one has the additional purpose to record a possible scratch register
7074 ;; for the following branch.
7075 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7076 ;; because the insn then might be deemed dead and deleted. And we can't
7077 ;; make the use in the jump insn explicit because that would disable
7078 ;; delay slot scheduling from the target.
7079 (define_insn "indirect_jump_scratch"
7080 [(set (match_operand:SI 0 "register_operand" "=r")
7081 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7082 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7085 [(set_attr "length" "0")])
7087 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7088 ;; being pulled into the delay slot of a condbranch that has been made to
7089 ;; jump around the unconditional jump because it was out of range.
7090 (define_insn "stuff_delay_slot"
7092 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7093 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7096 [(set_attr "length" "0")
7097 (set_attr "cond_delay_slot" "yes")])
7099 ;; Conditional branch insns
7101 (define_expand "cbranchint4_media"
7103 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7104 [(match_operand 1 "" "")
7105 (match_operand 2 "" "")])
7106 (match_operand 3 "" "")
7110 enum machine_mode mode = GET_MODE (operands[1]);
7111 if (mode == VOIDmode)
7112 mode = GET_MODE (operands[2]);
7113 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7115 operands[1] = force_reg (mode, operands[1]);
7116 if (CONSTANT_P (operands[2])
7117 && (! satisfies_constraint_I06 (operands[2])))
7118 operands[2] = force_reg (mode, operands[2]);
7122 if (operands[1] != const0_rtx)
7123 operands[1] = force_reg (mode, operands[1]);
7124 if (operands[2] != const0_rtx)
7125 operands[2] = force_reg (mode, operands[2]);
7127 switch (GET_CODE (operands[0]))
7133 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7134 VOIDmode, operands[2], operands[1]);
7135 operands[1] = XEXP (operands[0], 0);
7136 operands[2] = XEXP (operands[0], 1);
7139 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7140 VOIDmode, operands[1], operands[2]);
7143 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7146 (define_expand "cbranchfp4_media"
7148 (if_then_else (match_operator 0 "sh_float_comparison_operator"
7149 [(match_operand 1 "" "")
7150 (match_operand 2 "" "")])
7151 (match_operand 3 "" "")
7155 rtx tmp = gen_reg_rtx (SImode);
7157 if (GET_CODE (operands[0]) == NE)
7158 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7160 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7161 operands[1], operands[2]);
7163 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7165 if (GET_CODE (cmp) == GET_CODE (operands[0]))
7166 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7168 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7170 operands[2] = const0_rtx;
7171 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7174 (define_insn "*beq_media_i"
7176 (if_then_else (match_operator 3 "equality_comparison_operator"
7177 [(match_operand:DI 1 "arith_reg_operand" "r,r")
7178 (match_operand:DI 2 "arith_operand" "r,I06")])
7179 (match_operand 0 "target_operand" "b,b")
7184 b%o3i%' %1, %2, %0%>"
7185 [(set_attr "type" "cbranch_media")])
7187 (define_insn "*beq_media_i32"
7189 (if_then_else (match_operator 3 "equality_comparison_operator"
7190 [(match_operand:SI 1 "arith_reg_operand" "r,r")
7191 (match_operand:SI 2 "arith_operand" "r,I06")])
7192 (match_operand 0 "target_operand" "b,b")
7197 b%o3i%' %1, %2, %0%>"
7198 [(set_attr "type" "cbranch_media")])
7200 (define_insn "*bgt_media_i"
7202 (if_then_else (match_operator 3 "greater_comparison_operator"
7203 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7204 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7205 (match_operand 0 "target_operand" "b")
7208 "b%o3%' %N1, %N2, %0%>"
7209 [(set_attr "type" "cbranch_media")])
7211 (define_insn "*bgt_media_i32"
7213 (if_then_else (match_operator 3 "greater_comparison_operator"
7214 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7215 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7216 (match_operand 0 "target_operand" "b")
7219 "b%o3%' %N1, %N2, %0%>"
7220 [(set_attr "type" "cbranch_media")])
7222 ;; These are only needed to make invert_jump() happy - otherwise, jump
7223 ;; optimization will be silently disabled.
7224 (define_insn "*blt_media_i"
7226 (if_then_else (match_operator 3 "less_comparison_operator"
7227 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7228 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7229 (match_operand 0 "target_operand" "b")
7232 "b%o3%' %N2, %N1, %0%>"
7233 [(set_attr "type" "cbranch_media")])
7235 (define_insn "*blt_media_i32"
7237 (if_then_else (match_operator 3 "less_comparison_operator"
7238 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7239 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7240 (match_operand 0 "target_operand" "b")
7243 "b%o3%' %N2, %N1, %0%>"
7244 [(set_attr "type" "cbranch_media")])
7246 ;; combiner splitter for test-and-branch on single bit in register. This
7247 ;; is endian dependent because the non-paradoxical subreg looks different
7252 (match_operator 3 "equality_comparison_operator"
7253 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7254 "extend_reg_operand" "")
7258 "const_int_operand" "")) 0)
7260 (match_operand 0 "target_operand" "")
7262 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7263 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7264 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7265 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7267 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7268 operands[6] = (GET_CODE (operands[3]) == EQ
7269 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7270 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7273 ; operand 0 is the loop count pseudo register
7274 ; operand 1 is the number of loop iterations or 0 if it is unknown
7275 ; operand 2 is the maximum number of loop iterations
7276 ; operand 3 is the number of levels of enclosed loops
7277 ; operand 4 is the label to jump to at the top of the loop
7279 (define_expand "doloop_end"
7280 [(parallel [(set (pc) (if_then_else
7281 (ne:SI (match_operand:SI 0 "" "")
7283 (label_ref (match_operand 4 "" ""))
7286 (plus:SI (match_dup 0) (const_int -1)))
7287 (clobber (reg:SI T_REG))])]
7290 if (GET_MODE (operands[0]) != SImode)
7294 (define_insn_and_split "doloop_end_split"
7296 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7298 (label_ref (match_operand 1 "" ""))
7300 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7301 (plus (match_dup 2) (const_int -1)))
7302 (clobber (reg:SI T_REG))]
7306 [(parallel [(set (reg:SI T_REG)
7307 (eq:SI (match_dup 2) (const_int 1)))
7308 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7309 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7310 (label_ref (match_dup 1))
7313 [(set_attr "type" "cbranch")])
7316 ;; ------------------------------------------------------------------------
7317 ;; Jump and linkage insns
7318 ;; ------------------------------------------------------------------------
7320 (define_insn "jump_compact"
7322 (label_ref (match_operand 0 "" "")))]
7323 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7325 /* The length is 16 if the delay slot is unfilled. */
7326 if (get_attr_length(insn) > 4)
7327 return output_far_jump(insn, operands[0]);
7331 [(set_attr "type" "jump")
7332 (set_attr "needs_delay_slot" "yes")])
7334 ;; ??? It would be much saner to explicitly use the scratch register
7335 ;; in the jump insn, and have indirect_jump_scratch only set it,
7336 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7337 ;; from the target then, as it uses simplejump_p.
7338 ;;(define_insn "jump_compact_far"
7340 ;; (label_ref (match_operand 0 "" "")))
7341 ;; (use (match_operand 1 "register_operand" "r")]
7343 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7344 ;; [(set_attr "type" "jump")
7345 ;; (set_attr "needs_delay_slot" "yes")])
7347 (define_insn "jump_media"
7349 (match_operand 0 "target_operand" "b"))]
7352 [(set_attr "type" "jump_media")])
7354 (define_expand "jump"
7356 (label_ref (match_operand 0 "" "")))]
7360 emit_jump_insn (gen_jump_compact (operands[0]));
7361 else if (TARGET_SHMEDIA)
7363 if (reload_in_progress || reload_completed)
7365 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7371 (define_insn "force_mode_for_call"
7372 [(use (reg:PSI FPSCR_REG))]
7375 [(set_attr "length" "0")
7376 (set (attr "fp_mode")
7377 (if_then_else (eq_attr "fpu_single" "yes")
7378 (const_string "single") (const_string "double")))])
7380 (define_insn "calli"
7381 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7382 (match_operand 1 "" ""))
7383 (use (reg:PSI FPSCR_REG))
7384 (clobber (reg:SI PR_REG))]
7387 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7388 return "jsr/n\\t@%0";
7390 return "jsr\\t@%0%#";
7392 [(set_attr "type" "call")
7393 (set (attr "fp_mode")
7394 (if_then_else (eq_attr "fpu_single" "yes")
7395 (const_string "single") (const_string "double")))
7396 (set_attr "needs_delay_slot" "yes")
7397 (set_attr "fp_set" "unknown")])
7399 ;; This is TBR relative jump instruction for SH2A architecture.
7400 ;; Its use is enabled assigning an attribute "function_vector"
7401 ;; and the vector number to a function during its declaration.
7403 (define_insn "calli_tbr_rel"
7404 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7405 (match_operand 1 "" ""))
7406 (use (reg:PSI FPSCR_REG))
7407 (clobber (reg:SI PR_REG))]
7408 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7410 unsigned HOST_WIDE_INT vect_num;
7411 vect_num = sh2a_get_function_vector_number (operands[0]);
7412 operands[2] = GEN_INT (vect_num * 4);
7414 return "jsr/n\\t@@(%O2,tbr)";
7416 [(set_attr "type" "call")
7417 (set (attr "fp_mode")
7418 (if_then_else (eq_attr "fpu_single" "yes")
7419 (const_string "single") (const_string "double")))
7420 (set_attr "needs_delay_slot" "no")
7421 (set_attr "fp_set" "unknown")])
7423 ;; This is a pc-rel call, using bsrf, for use with PIC.
7425 (define_insn "calli_pcrel"
7426 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7427 (match_operand 1 "" ""))
7428 (use (reg:PSI FPSCR_REG))
7429 (use (reg:SI PIC_REG))
7430 (use (match_operand 2 "" ""))
7431 (clobber (reg:SI PR_REG))]
7434 [(set_attr "type" "call")
7435 (set (attr "fp_mode")
7436 (if_then_else (eq_attr "fpu_single" "yes")
7437 (const_string "single") (const_string "double")))
7438 (set_attr "needs_delay_slot" "yes")
7439 (set_attr "fp_set" "unknown")])
7441 (define_insn_and_split "call_pcrel"
7442 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7443 (match_operand 1 "" ""))
7444 (use (reg:PSI FPSCR_REG))
7445 (use (reg:SI PIC_REG))
7446 (clobber (reg:SI PR_REG))
7447 (clobber (match_scratch:SI 2 "=r"))]
7453 rtx lab = PATTERN (gen_call_site ());
7455 if (SYMBOL_REF_LOCAL_P (operands[0]))
7456 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7458 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7459 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7462 [(set_attr "type" "call")
7463 (set (attr "fp_mode")
7464 (if_then_else (eq_attr "fpu_single" "yes")
7465 (const_string "single") (const_string "double")))
7466 (set_attr "needs_delay_slot" "yes")
7467 (set_attr "fp_set" "unknown")])
7469 (define_insn "call_compact"
7470 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7471 (match_operand 1 "" ""))
7472 (match_operand 2 "immediate_operand" "n")
7473 (use (reg:SI R0_REG))
7474 (use (reg:SI R1_REG))
7475 (use (reg:PSI FPSCR_REG))
7476 (clobber (reg:SI PR_REG))]
7477 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7479 [(set_attr "type" "call")
7480 (set (attr "fp_mode")
7481 (if_then_else (eq_attr "fpu_single" "yes")
7482 (const_string "single") (const_string "double")))
7483 (set_attr "needs_delay_slot" "yes")])
7485 (define_insn "call_compact_rettramp"
7486 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7487 (match_operand 1 "" ""))
7488 (match_operand 2 "immediate_operand" "n")
7489 (use (reg:SI R0_REG))
7490 (use (reg:SI R1_REG))
7491 (use (reg:PSI FPSCR_REG))
7492 (clobber (reg:SI R10_REG))
7493 (clobber (reg:SI PR_REG))]
7494 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7496 [(set_attr "type" "call")
7497 (set (attr "fp_mode")
7498 (if_then_else (eq_attr "fpu_single" "yes")
7499 (const_string "single") (const_string "double")))
7500 (set_attr "needs_delay_slot" "yes")])
7502 (define_insn "call_media"
7503 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7504 (match_operand 1 "" ""))
7505 (clobber (reg:DI PR_MEDIA_REG))]
7508 [(set_attr "type" "jump_media")])
7510 (define_insn "call_valuei"
7511 [(set (match_operand 0 "" "=rf")
7512 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7513 (match_operand 2 "" "")))
7514 (use (reg:PSI FPSCR_REG))
7515 (clobber (reg:SI PR_REG))]
7518 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7519 return "jsr/n\\t@%1";
7521 return "jsr\\t@%1%#";
7523 [(set_attr "type" "call")
7524 (set (attr "fp_mode")
7525 (if_then_else (eq_attr "fpu_single" "yes")
7526 (const_string "single") (const_string "double")))
7527 (set_attr "needs_delay_slot" "yes")
7528 (set_attr "fp_set" "unknown")])
7530 ;; This is TBR relative jump instruction for SH2A architecture.
7531 ;; Its use is enabled by assigning an attribute "function_vector"
7532 ;; and the vector number to a function during its declaration.
7534 (define_insn "call_valuei_tbr_rel"
7535 [(set (match_operand 0 "" "=rf")
7536 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7537 (match_operand 2 "" "")))
7538 (use (reg:PSI FPSCR_REG))
7539 (clobber (reg:SI PR_REG))]
7540 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7542 unsigned HOST_WIDE_INT vect_num;
7543 vect_num = sh2a_get_function_vector_number (operands[1]);
7544 operands[3] = GEN_INT (vect_num * 4);
7546 return "jsr/n\\t@@(%O3,tbr)";
7548 [(set_attr "type" "call")
7549 (set (attr "fp_mode")
7550 (if_then_else (eq_attr "fpu_single" "yes")
7551 (const_string "single") (const_string "double")))
7552 (set_attr "needs_delay_slot" "no")
7553 (set_attr "fp_set" "unknown")])
7555 (define_insn "call_valuei_pcrel"
7556 [(set (match_operand 0 "" "=rf")
7557 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7558 (match_operand 2 "" "")))
7559 (use (reg:PSI FPSCR_REG))
7560 (use (reg:SI PIC_REG))
7561 (use (match_operand 3 "" ""))
7562 (clobber (reg:SI PR_REG))]
7565 [(set_attr "type" "call")
7566 (set (attr "fp_mode")
7567 (if_then_else (eq_attr "fpu_single" "yes")
7568 (const_string "single") (const_string "double")))
7569 (set_attr "needs_delay_slot" "yes")
7570 (set_attr "fp_set" "unknown")])
7572 (define_insn_and_split "call_value_pcrel"
7573 [(set (match_operand 0 "" "=rf")
7574 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7575 (match_operand 2 "" "")))
7576 (use (reg:PSI FPSCR_REG))
7577 (use (reg:SI PIC_REG))
7578 (clobber (reg:SI PR_REG))
7579 (clobber (match_scratch:SI 3 "=r"))]
7585 rtx lab = PATTERN (gen_call_site ());
7587 if (SYMBOL_REF_LOCAL_P (operands[1]))
7588 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7590 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7591 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7592 operands[2], copy_rtx (lab)));
7595 [(set_attr "type" "call")
7596 (set (attr "fp_mode")
7597 (if_then_else (eq_attr "fpu_single" "yes")
7598 (const_string "single") (const_string "double")))
7599 (set_attr "needs_delay_slot" "yes")
7600 (set_attr "fp_set" "unknown")])
7602 (define_insn "call_value_compact"
7603 [(set (match_operand 0 "" "=rf")
7604 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7605 (match_operand 2 "" "")))
7606 (match_operand 3 "immediate_operand" "n")
7607 (use (reg:SI R0_REG))
7608 (use (reg:SI R1_REG))
7609 (use (reg:PSI FPSCR_REG))
7610 (clobber (reg:SI PR_REG))]
7611 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7613 [(set_attr "type" "call")
7614 (set (attr "fp_mode")
7615 (if_then_else (eq_attr "fpu_single" "yes")
7616 (const_string "single") (const_string "double")))
7617 (set_attr "needs_delay_slot" "yes")])
7619 (define_insn "call_value_compact_rettramp"
7620 [(set (match_operand 0 "" "=rf")
7621 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7622 (match_operand 2 "" "")))
7623 (match_operand 3 "immediate_operand" "n")
7624 (use (reg:SI R0_REG))
7625 (use (reg:SI R1_REG))
7626 (use (reg:PSI FPSCR_REG))
7627 (clobber (reg:SI R10_REG))
7628 (clobber (reg:SI PR_REG))]
7629 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7631 [(set_attr "type" "call")
7632 (set (attr "fp_mode")
7633 (if_then_else (eq_attr "fpu_single" "yes")
7634 (const_string "single") (const_string "double")))
7635 (set_attr "needs_delay_slot" "yes")])
7637 (define_insn "call_value_media"
7638 [(set (match_operand 0 "" "=rf")
7639 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7640 (match_operand 2 "" "")))
7641 (clobber (reg:DI PR_MEDIA_REG))]
7644 [(set_attr "type" "jump_media")])
7646 (define_expand "call"
7647 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7648 (match_operand 1 "" ""))
7649 (match_operand 2 "" "")
7650 (use (reg:PSI FPSCR_REG))
7651 (clobber (reg:SI PR_REG))])]
7656 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7657 emit_call_insn (gen_call_media (operands[0], operands[1]));
7660 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7662 rtx cookie_rtx = operands[2];
7663 long cookie = INTVAL (cookie_rtx);
7664 rtx func = XEXP (operands[0], 0);
7669 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7671 rtx reg = gen_reg_rtx (Pmode);
7673 emit_insn (gen_symGOTPLT2reg (reg, func));
7677 func = legitimize_pic_address (func, Pmode, 0);
7680 r0 = gen_rtx_REG (SImode, R0_REG);
7681 r1 = gen_rtx_REG (SImode, R1_REG);
7683 /* Since such a call function may use all call-clobbered
7684 registers, we force a mode switch earlier, so that we don't
7685 run out of registers when adjusting fpscr for the call. */
7686 emit_insn (gen_force_mode_for_call ());
7689 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
7690 operands[0] = force_reg (SImode, operands[0]);
7692 emit_move_insn (r0, func);
7693 emit_move_insn (r1, cookie_rtx);
7695 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7696 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7699 emit_call_insn (gen_call_compact (operands[0], operands[1],
7704 else if (TARGET_SHCOMPACT && flag_pic
7705 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7706 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7708 rtx reg = gen_reg_rtx (Pmode);
7710 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7711 XEXP (operands[0], 0) = reg;
7713 if (!flag_pic && TARGET_SH2A
7714 && MEM_P (operands[0])
7715 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7717 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7719 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7724 if (flag_pic && TARGET_SH2
7725 && MEM_P (operands[0])
7726 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7728 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7733 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7734 operands[1] = operands[2];
7737 emit_call_insn (gen_calli (operands[0], operands[1]));
7741 (define_insn "call_pop_compact"
7742 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7743 (match_operand 1 "" ""))
7744 (match_operand 2 "immediate_operand" "n")
7745 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7746 (match_operand 3 "immediate_operand" "n")))
7747 (use (reg:SI R0_REG))
7748 (use (reg:SI R1_REG))
7749 (use (reg:PSI FPSCR_REG))
7750 (clobber (reg:SI PR_REG))]
7751 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7753 [(set_attr "type" "call")
7754 (set (attr "fp_mode")
7755 (if_then_else (eq_attr "fpu_single" "yes")
7756 (const_string "single") (const_string "double")))
7757 (set_attr "needs_delay_slot" "yes")])
7759 (define_insn "call_pop_compact_rettramp"
7760 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7761 (match_operand 1 "" ""))
7762 (match_operand 2 "immediate_operand" "n")
7763 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7764 (match_operand 3 "immediate_operand" "n")))
7765 (use (reg:SI R0_REG))
7766 (use (reg:SI R1_REG))
7767 (use (reg:PSI FPSCR_REG))
7768 (clobber (reg:SI R10_REG))
7769 (clobber (reg:SI PR_REG))]
7770 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7772 [(set_attr "type" "call")
7773 (set (attr "fp_mode")
7774 (if_then_else (eq_attr "fpu_single" "yes")
7775 (const_string "single") (const_string "double")))
7776 (set_attr "needs_delay_slot" "yes")])
7778 (define_expand "call_pop"
7779 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7780 (match_operand 1 "" ""))
7781 (match_operand 2 "" "")
7782 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7783 (match_operand 3 "" "")))])]
7791 gcc_assert (operands[2] && INTVAL (operands[2]));
7792 cookie_rtx = operands[2];
7793 cookie = INTVAL (cookie_rtx);
7794 func = XEXP (operands[0], 0);
7798 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7800 rtx reg = gen_reg_rtx (Pmode);
7801 emit_insn (gen_symGOTPLT2reg (reg, func));
7805 func = legitimize_pic_address (func, Pmode, 0);
7808 r0 = gen_rtx_REG (SImode, R0_REG);
7809 r1 = gen_rtx_REG (SImode, R1_REG);
7811 /* Since such a call function may use all call-clobbered
7812 registers, we force a mode switch earlier, so that we don't
7813 run out of registers when adjusting fpscr for the call. */
7814 emit_insn (gen_force_mode_for_call ());
7816 operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
7818 operands[0] = force_reg (SImode, operands[0]);
7820 emit_move_insn (r0, func);
7821 emit_move_insn (r1, cookie_rtx);
7823 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7824 emit_call_insn (gen_call_pop_compact_rettramp
7825 (operands[0], operands[1], operands[2], operands[3]));
7827 emit_call_insn (gen_call_pop_compact
7828 (operands[0], operands[1], operands[2], operands[3]));
7833 (define_expand "call_value"
7834 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7835 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7836 (match_operand 2 "" "")))
7837 (match_operand 3 "" "")
7838 (use (reg:PSI FPSCR_REG))
7839 (clobber (reg:SI PR_REG))])]
7844 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7845 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7849 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7851 rtx cookie_rtx = operands[3];
7852 long cookie = INTVAL (cookie_rtx);
7853 rtx func = XEXP (operands[1], 0);
7858 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7860 rtx reg = gen_reg_rtx (Pmode);
7862 emit_insn (gen_symGOTPLT2reg (reg, func));
7866 func = legitimize_pic_address (func, Pmode, 0);
7869 r0 = gen_rtx_REG (SImode, R0_REG);
7870 r1 = gen_rtx_REG (SImode, R1_REG);
7872 /* Since such a call function may use all call-clobbered
7873 registers, we force a mode switch earlier, so that we don't
7874 run out of registers when adjusting fpscr for the call. */
7875 emit_insn (gen_force_mode_for_call ());
7878 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
7879 operands[1] = force_reg (SImode, operands[1]);
7881 emit_move_insn (r0, func);
7882 emit_move_insn (r1, cookie_rtx);
7884 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7885 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7890 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7891 operands[2], operands[3]));
7895 else if (TARGET_SHCOMPACT && flag_pic
7896 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7897 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7899 rtx reg = gen_reg_rtx (Pmode);
7901 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7902 XEXP (operands[1], 0) = reg;
7904 if (!flag_pic && TARGET_SH2A
7905 && MEM_P (operands[1])
7906 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7908 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7910 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7911 XEXP (operands[1], 0), operands[2]));
7915 if (flag_pic && TARGET_SH2
7916 && MEM_P (operands[1])
7917 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7919 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7924 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7926 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7930 (define_insn "sibcalli"
7931 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7932 (match_operand 1 "" ""))
7933 (use (reg:PSI FPSCR_REG))
7937 [(set_attr "needs_delay_slot" "yes")
7938 (set (attr "fp_mode")
7939 (if_then_else (eq_attr "fpu_single" "yes")
7940 (const_string "single") (const_string "double")))
7941 (set_attr "type" "jump_ind")])
7943 (define_insn "sibcalli_pcrel"
7944 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7945 (match_operand 1 "" ""))
7946 (use (match_operand 2 "" ""))
7947 (use (reg:PSI FPSCR_REG))
7951 [(set_attr "needs_delay_slot" "yes")
7952 (set (attr "fp_mode")
7953 (if_then_else (eq_attr "fpu_single" "yes")
7954 (const_string "single") (const_string "double")))
7955 (set_attr "type" "jump_ind")])
7957 ;; This uses an unspec to describe that the symbol_ref is very close.
7958 (define_insn "sibcalli_thunk"
7959 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7961 (match_operand 1 "" ""))
7962 (use (reg:PSI FPSCR_REG))
7966 [(set_attr "needs_delay_slot" "yes")
7967 (set (attr "fp_mode")
7968 (if_then_else (eq_attr "fpu_single" "yes")
7969 (const_string "single") (const_string "double")))
7970 (set_attr "type" "jump")
7971 (set_attr "length" "2")])
7973 (define_insn_and_split "sibcall_pcrel"
7974 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7975 (match_operand 1 "" ""))
7976 (use (reg:PSI FPSCR_REG))
7977 (clobber (match_scratch:SI 2 "=k"))
7984 rtx lab = PATTERN (gen_call_site ());
7987 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7988 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7990 SIBLING_CALL_P (call_insn) = 1;
7993 [(set_attr "needs_delay_slot" "yes")
7994 (set (attr "fp_mode")
7995 (if_then_else (eq_attr "fpu_single" "yes")
7996 (const_string "single") (const_string "double")))
7997 (set_attr "type" "jump_ind")])
7999 (define_insn "sibcall_compact"
8000 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8001 (match_operand 1 "" ""))
8003 (use (match_operand:SI 2 "register_operand" "z,x"))
8004 (use (reg:SI R1_REG))
8005 (use (reg:PSI FPSCR_REG))
8006 ;; We want to make sure the `x' above will only match MACH_REG
8007 ;; because sibcall_epilogue may clobber MACL_REG.
8008 (clobber (reg:SI MACL_REG))]
8012 jmp @%0\\n sts %2, r0"
8013 [(set_attr "needs_delay_slot" "yes,no")
8014 (set_attr "length" "2,4")
8015 (set (attr "fp_mode") (const_string "single"))
8016 (set_attr "type" "jump_ind")])
8018 (define_insn "sibcall_media"
8019 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8020 (match_operand 1 "" ""))
8021 (use (reg:SI PR_MEDIA_REG))
8025 [(set_attr "type" "jump_media")])
8027 (define_expand "sibcall"
8029 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8030 (match_operand 1 "" ""))
8031 (match_operand 2 "" "")
8032 (use (reg:PSI FPSCR_REG))
8038 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8039 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8042 else if (TARGET_SHCOMPACT && operands[2]
8043 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8045 rtx cookie_rtx = operands[2];
8046 long cookie = INTVAL (cookie_rtx);
8047 rtx func = XEXP (operands[0], 0);
8052 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8054 rtx reg = gen_reg_rtx (Pmode);
8056 emit_insn (gen_symGOT2reg (reg, func));
8060 func = legitimize_pic_address (func, Pmode, 0);
8063 /* FIXME: if we could tell whether all argument registers are
8064 already taken, we could decide whether to force the use of
8065 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8066 simple way to tell. We could use the CALL_COOKIE, but we
8067 can't currently tell a register used for regular argument
8068 passing from one that is unused. If we leave it up to reload
8069 to decide which register to use, it seems to always choose
8070 R0_REG, which leaves no available registers in SIBCALL_REGS
8071 to hold the address of the trampoline. */
8072 mach = gen_rtx_REG (SImode, MACH_REG);
8073 r1 = gen_rtx_REG (SImode, R1_REG);
8075 /* Since such a call function may use all call-clobbered
8076 registers, we force a mode switch earlier, so that we don't
8077 run out of registers when adjusting fpscr for the call. */
8078 emit_insn (gen_force_mode_for_call ());
8081 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8082 operands[0] = force_reg (SImode, operands[0]);
8084 /* We don't need a return trampoline, since the callee will
8085 return directly to the upper caller. */
8086 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8088 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8089 cookie_rtx = GEN_INT (cookie);
8092 emit_move_insn (mach, func);
8093 emit_move_insn (r1, cookie_rtx);
8095 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8098 else if (TARGET_SHCOMPACT && flag_pic
8099 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8100 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8102 rtx reg = gen_reg_rtx (Pmode);
8104 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8105 XEXP (operands[0], 0) = reg;
8107 if (flag_pic && TARGET_SH2
8108 && MEM_P (operands[0])
8109 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8110 /* The PLT needs the PIC register, but the epilogue would have
8111 to restore it, so we can only use PC-relative PIC calls for
8112 static functions. */
8113 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8115 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8119 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8121 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8125 (define_insn "sibcall_valuei"
8126 [(set (match_operand 0 "" "=rf")
8127 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8128 (match_operand 2 "" "")))
8129 (use (reg:PSI FPSCR_REG))
8133 [(set_attr "needs_delay_slot" "yes")
8134 (set (attr "fp_mode")
8135 (if_then_else (eq_attr "fpu_single" "yes")
8136 (const_string "single") (const_string "double")))
8137 (set_attr "type" "jump_ind")])
8139 (define_insn "sibcall_valuei_pcrel"
8140 [(set (match_operand 0 "" "=rf")
8141 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8142 (match_operand 2 "" "")))
8143 (use (match_operand 3 "" ""))
8144 (use (reg:PSI FPSCR_REG))
8148 [(set_attr "needs_delay_slot" "yes")
8149 (set (attr "fp_mode")
8150 (if_then_else (eq_attr "fpu_single" "yes")
8151 (const_string "single") (const_string "double")))
8152 (set_attr "type" "jump_ind")])
8154 (define_insn_and_split "sibcall_value_pcrel"
8155 [(set (match_operand 0 "" "=rf")
8156 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8157 (match_operand 2 "" "")))
8158 (use (reg:PSI FPSCR_REG))
8159 (clobber (match_scratch:SI 3 "=k"))
8166 rtx lab = PATTERN (gen_call_site ());
8169 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8170 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8174 SIBLING_CALL_P (call_insn) = 1;
8177 [(set_attr "needs_delay_slot" "yes")
8178 (set (attr "fp_mode")
8179 (if_then_else (eq_attr "fpu_single" "yes")
8180 (const_string "single") (const_string "double")))
8181 (set_attr "type" "jump_ind")])
8183 (define_insn "sibcall_value_compact"
8184 [(set (match_operand 0 "" "=rf,rf")
8185 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8186 (match_operand 2 "" "")))
8188 (use (match_operand:SI 3 "register_operand" "z,x"))
8189 (use (reg:SI R1_REG))
8190 (use (reg:PSI FPSCR_REG))
8191 ;; We want to make sure the `x' above will only match MACH_REG
8192 ;; because sibcall_epilogue may clobber MACL_REG.
8193 (clobber (reg:SI MACL_REG))]
8197 jmp @%1\\n sts %3, r0"
8198 [(set_attr "needs_delay_slot" "yes,no")
8199 (set_attr "length" "2,4")
8200 (set (attr "fp_mode") (const_string "single"))
8201 (set_attr "type" "jump_ind")])
8203 (define_insn "sibcall_value_media"
8204 [(set (match_operand 0 "" "=rf")
8205 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8206 (match_operand 2 "" "")))
8207 (use (reg:SI PR_MEDIA_REG))
8211 [(set_attr "type" "jump_media")])
8213 (define_expand "sibcall_value"
8215 [(set (match_operand 0 "arith_reg_operand" "")
8216 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8217 (match_operand 2 "" "")))
8218 (match_operand 3 "" "")
8219 (use (reg:PSI FPSCR_REG))
8225 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8226 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8230 else if (TARGET_SHCOMPACT && operands[3]
8231 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8233 rtx cookie_rtx = operands[3];
8234 long cookie = INTVAL (cookie_rtx);
8235 rtx func = XEXP (operands[1], 0);
8240 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8242 rtx reg = gen_reg_rtx (Pmode);
8244 emit_insn (gen_symGOT2reg (reg, func));
8248 func = legitimize_pic_address (func, Pmode, 0);
8251 /* FIXME: if we could tell whether all argument registers are
8252 already taken, we could decide whether to force the use of
8253 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8254 simple way to tell. We could use the CALL_COOKIE, but we
8255 can't currently tell a register used for regular argument
8256 passing from one that is unused. If we leave it up to reload
8257 to decide which register to use, it seems to always choose
8258 R0_REG, which leaves no available registers in SIBCALL_REGS
8259 to hold the address of the trampoline. */
8260 mach = gen_rtx_REG (SImode, MACH_REG);
8261 r1 = gen_rtx_REG (SImode, R1_REG);
8263 /* Since such a call function may use all call-clobbered
8264 registers, we force a mode switch earlier, so that we don't
8265 run out of registers when adjusting fpscr for the call. */
8266 emit_insn (gen_force_mode_for_call ());
8269 = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8270 operands[1] = force_reg (SImode, operands[1]);
8272 /* We don't need a return trampoline, since the callee will
8273 return directly to the upper caller. */
8274 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8276 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8277 cookie_rtx = GEN_INT (cookie);
8280 emit_move_insn (mach, func);
8281 emit_move_insn (r1, cookie_rtx);
8283 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8284 operands[2], mach));
8287 else if (TARGET_SHCOMPACT && flag_pic
8288 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8289 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8291 rtx reg = gen_reg_rtx (Pmode);
8293 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8294 XEXP (operands[1], 0) = reg;
8296 if (flag_pic && TARGET_SH2
8297 && MEM_P (operands[1])
8298 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8299 /* The PLT needs the PIC register, but the epilogue would have
8300 to restore it, so we can only use PC-relative PIC calls for
8301 static functions. */
8302 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8304 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8305 XEXP (operands[1], 0),
8310 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8312 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8316 (define_insn "call_value_pop_compact"
8317 [(set (match_operand 0 "" "=rf")
8318 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8319 (match_operand 2 "" "")))
8320 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8321 (match_operand 4 "immediate_operand" "n")))
8322 (match_operand 3 "immediate_operand" "n")
8323 (use (reg:SI R0_REG))
8324 (use (reg:SI R1_REG))
8325 (use (reg:PSI FPSCR_REG))
8326 (clobber (reg:SI PR_REG))]
8327 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8329 [(set_attr "type" "call")
8330 (set (attr "fp_mode")
8331 (if_then_else (eq_attr "fpu_single" "yes")
8332 (const_string "single") (const_string "double")))
8333 (set_attr "needs_delay_slot" "yes")])
8335 (define_insn "call_value_pop_compact_rettramp"
8336 [(set (match_operand 0 "" "=rf")
8337 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8338 (match_operand 2 "" "")))
8339 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8340 (match_operand 4 "immediate_operand" "n")))
8341 (match_operand 3 "immediate_operand" "n")
8342 (use (reg:SI R0_REG))
8343 (use (reg:SI R1_REG))
8344 (use (reg:PSI FPSCR_REG))
8345 (clobber (reg:SI R10_REG))
8346 (clobber (reg:SI PR_REG))]
8347 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8349 [(set_attr "type" "call")
8350 (set (attr "fp_mode")
8351 (if_then_else (eq_attr "fpu_single" "yes")
8352 (const_string "single") (const_string "double")))
8353 (set_attr "needs_delay_slot" "yes")])
8355 (define_expand "call_value_pop"
8356 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8357 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8358 (match_operand 2 "" "")))
8359 (match_operand 3 "" "")
8360 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8361 (match_operand 4 "" "")))])]
8369 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8370 cookie_rtx = operands[3];
8371 cookie = INTVAL (cookie_rtx);
8372 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_symGOTPLT2reg (reg, func));
8384 func = legitimize_pic_address (func, Pmode, 0);
8387 r0 = gen_rtx_REG (SImode, R0_REG);
8388 r1 = gen_rtx_REG (SImode, R1_REG);
8390 /* Since such a call function may use all call-clobbered
8391 registers, we force a mode switch earlier, so that we don't
8392 run out of registers when adjusting fpscr for the call. */
8393 emit_insn (gen_force_mode_for_call ());
8395 operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
8397 operands[1] = force_reg (SImode, operands[1]);
8399 emit_move_insn (r0, func);
8400 emit_move_insn (r1, cookie_rtx);
8402 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8403 emit_call_insn (gen_call_value_pop_compact_rettramp
8404 (operands[0], operands[1], operands[2],
8405 operands[3], operands[4]));
8407 emit_call_insn (gen_call_value_pop_compact
8408 (operands[0], operands[1], operands[2],
8409 operands[3], operands[4]));
8414 (define_expand "sibcall_epilogue"
8418 sh_expand_epilogue (1);
8419 if (TARGET_SHCOMPACT)
8423 /* If epilogue clobbers r0, preserve it in macl. */
8424 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8425 if ((set = single_set (insn))
8426 && REG_P (SET_DEST (set))
8427 && REGNO (SET_DEST (set)) == R0_REG)
8429 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8430 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8432 /* We can't tell at this point whether the sibcall is a
8433 sibcall_compact and, if it is, whether it uses r0 or
8434 mach as operand 2, so let the instructions that
8435 preserve r0 be optimized away if r0 turns out to be
8437 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8438 emit_move_insn (r0, tmp);
8445 (define_insn "indirect_jump_compact"
8447 (match_operand:SI 0 "arith_reg_operand" "r"))]
8450 [(set_attr "needs_delay_slot" "yes")
8451 (set_attr "type" "jump_ind")])
8453 (define_expand "indirect_jump"
8455 (match_operand 0 "register_operand" ""))]
8458 if (GET_MODE (operands[0]) != Pmode)
8459 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8462 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8463 ;; which can be present in structured code from indirect jumps which can not
8464 ;; be present in structured code. This allows -fprofile-arcs to work.
8466 ;; For SH1 processors.
8467 (define_insn "casesi_jump_1"
8469 (match_operand:SI 0 "register_operand" "r"))
8470 (use (label_ref (match_operand 1 "" "")))]
8473 [(set_attr "needs_delay_slot" "yes")
8474 (set_attr "type" "jump_ind")])
8476 ;; For all later processors.
8477 (define_insn "casesi_jump_2"
8478 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8479 (label_ref (match_operand 1 "" ""))))
8480 (use (label_ref (match_operand 2 "" "")))]
8482 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8484 [(set_attr "needs_delay_slot" "yes")
8485 (set_attr "type" "jump_ind")])
8487 (define_insn "casesi_jump_media"
8488 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8489 (use (label_ref (match_operand 1 "" "")))]
8492 [(set_attr "type" "jump_media")])
8494 ;; Call subroutine returning any type.
8495 ;; ??? This probably doesn't work.
8497 (define_expand "untyped_call"
8498 [(parallel [(call (match_operand 0 "" "")
8500 (match_operand 1 "" "")
8501 (match_operand 2 "" "")])]
8502 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8506 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8508 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8510 rtx set = XVECEXP (operands[2], 0, i);
8511 emit_move_insn (SET_DEST (set), SET_SRC (set));
8514 /* The optimizer does not know that the call sets the function value
8515 registers we stored in the result block. We avoid problems by
8516 claiming that all hard registers are used and clobbered at this
8518 emit_insn (gen_blockage ());
8523 ;; ------------------------------------------------------------------------
8525 ;; ------------------------------------------------------------------------
8528 [(set (reg:SI T_REG)
8529 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8530 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8531 (plus:SI (match_dup 1) (const_int -1)))]
8534 [(set_attr "type" "arith")])
8541 ;; Load address of a label. This is only generated by the casesi expand,
8542 ;; and by machine_dependent_reorg (fixing up fp moves).
8543 ;; This must use unspec, because this only works for labels that are
8547 [(set (reg:SI R0_REG)
8548 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8551 [(set_attr "in_delay_slot" "no")
8552 (set_attr "type" "arith")])
8554 ;; machine_dependent_reorg will make this a `mova'.
8555 (define_insn "mova_const"
8556 [(set (reg:SI R0_REG)
8557 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8560 [(set_attr "in_delay_slot" "no")
8561 (set_attr "type" "arith")])
8563 (define_expand "GOTaddr2picreg"
8564 [(set (reg:SI R0_REG)
8565 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8567 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8568 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8571 if (TARGET_VXWORKS_RTP)
8573 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8574 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8575 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8579 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8580 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8584 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8585 rtx pic = operands[0];
8586 rtx lab = PATTERN (gen_call_site ());
8589 equiv = operands[1];
8590 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8591 UNSPEC_PCREL_SYMOFF);
8592 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8594 if (Pmode == SImode)
8596 emit_insn (gen_movsi_const (pic, operands[1]));
8597 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8601 emit_insn (gen_movdi_const (pic, operands[1]));
8602 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8605 insn = emit_move_insn (operands[0], tr);
8607 set_unique_reg_note (insn, REG_EQUAL, equiv);
8613 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8616 (define_expand "vxworks_picreg"
8617 [(set (reg:SI PIC_REG)
8618 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8619 (set (reg:SI R0_REG)
8620 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8621 (set (reg:SI PIC_REG)
8622 (mem:SI (reg:SI PIC_REG)))
8623 (set (reg:SI PIC_REG)
8624 (mem:SI (plus:SI (reg:SI PIC_REG)
8626 "TARGET_VXWORKS_RTP")
8629 [(set (match_operand 0 "target_reg_operand" "=b")
8630 (const (unspec [(match_operand 1 "" "Csy")]
8631 UNSPEC_DATALABEL)))]
8632 "TARGET_SHMEDIA && flag_pic
8633 && satisfies_constraint_Csy (operands[1])"
8634 "ptb/u datalabel %1, %0"
8635 [(set_attr "type" "ptabs_media")
8636 (set_attr "length" "*")])
8638 (define_insn "ptrel_si"
8639 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8640 (plus:SI (match_operand:SI 1 "register_operand" "r")
8642 (match_operand:SI 2 "" "")]
8644 "%O2: ptrel/u %1, %0"
8645 [(set_attr "type" "ptabs_media")])
8647 (define_insn "ptrel_di"
8648 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8649 (plus:DI (match_operand:DI 1 "register_operand" "r")
8651 (match_operand:DI 2 "" "")]
8653 "%O2: ptrel/u %1, %0"
8654 [(set_attr "type" "ptabs_media")])
8656 (define_expand "builtin_setjmp_receiver"
8657 [(match_operand 0 "" "")]
8660 emit_insn (gen_GOTaddr2picreg ());
8664 (define_expand "call_site"
8665 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8668 static HOST_WIDE_INT i = 0;
8669 operands[0] = GEN_INT (i);
8673 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8674 ;; in symGOT_load expand.
8676 (define_insn_and_split "chk_guard_add"
8677 [(set (match_operand:SI 0 "register_operand" "=&r")
8678 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8683 "TARGET_SH1 && reload_completed"
8684 [(set (match_dup 0) (reg:SI PIC_REG))
8685 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8687 [(set_attr "type" "arith")])
8689 (define_expand "sym_label2reg"
8690 [(set (match_operand:SI 0 "" "")
8691 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8692 (const (plus:SI (match_operand:SI 2 "" "")
8697 (define_expand "symGOT_load"
8698 [(set (match_dup 2) (match_operand 1 "" ""))
8699 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8700 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8705 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8706 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8710 rtx reg = operands[2];
8712 if (Pmode == DImode)
8715 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8717 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8722 emit_insn (gen_movsi_const (reg, operands[1]));
8724 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8728 emit_move_insn (operands[2], operands[1]);
8730 /* When stack protector inserts codes after the result is set to
8731 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8732 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8733 when rX is a GOT address for the guard symbol. Ugly but doesn't
8734 matter because this is a rare situation. */
8736 && flag_stack_protect
8737 && GET_CODE (operands[1]) == CONST
8738 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8739 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8740 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8741 "__stack_chk_guard") == 0)
8742 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8744 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8745 gen_rtx_REG (Pmode, PIC_REG)));
8747 /* N.B. This is not constant for a GOTPLT relocation. */
8748 mem = gen_rtx_MEM (Pmode, operands[3]);
8749 MEM_NOTRAP_P (mem) = 1;
8750 /* ??? Should we have a special alias set for the GOT? */
8751 emit_move_insn (operands[0], mem);
8756 (define_expand "sym2GOT"
8757 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8761 (define_expand "symGOT2reg"
8762 [(match_operand 0 "" "") (match_operand 1 "" "")]
8767 gotsym = gen_sym2GOT (operands[1]);
8768 PUT_MODE (gotsym, Pmode);
8769 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8771 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8776 (define_expand "symGOTPLT2reg"
8777 [(match_operand 0 "" "") (match_operand 1 "" "")]
8780 rtx pltsym = gen_rtx_CONST (Pmode,
8781 gen_rtx_UNSPEC (Pmode,
8782 gen_rtvec (1, operands[1]),
8784 emit_insn (gen_symGOT_load (operands[0], pltsym));
8788 (define_expand "sym2GOTOFF"
8789 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8793 (define_expand "symGOTOFF2reg"
8794 [(match_operand 0 "" "") (match_operand 1 "" "")]
8797 rtx gotoffsym, insn;
8798 rtx t = (!can_create_pseudo_p ()
8800 : gen_reg_rtx (GET_MODE (operands[0])));
8802 gotoffsym = gen_sym2GOTOFF (operands[1]);
8803 PUT_MODE (gotoffsym, Pmode);
8804 emit_move_insn (t, gotoffsym);
8805 insn = emit_move_insn (operands[0],
8806 gen_rtx_PLUS (Pmode, t,
8807 gen_rtx_REG (Pmode, PIC_REG)));
8809 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8814 (define_expand "symPLT_label2reg"
8815 [(set (match_operand:SI 0 "" "")
8818 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8819 (const:SI (plus:SI (match_operand:SI 2 "" "")
8820 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8821 ;; Even though the PIC register is not really used by the call
8822 ;; sequence in which this is expanded, the PLT code assumes the PIC
8823 ;; register is set, so we must not skip its initialization. Since
8824 ;; we only use this expand as part of calling sequences, and never
8825 ;; to take the address of a function, this is the best point to
8826 ;; insert the (use). Using the PLT to take the address of a
8827 ;; function would be wrong, not only because the PLT entry could
8828 ;; then be called from a function that doesn't initialize the PIC
8829 ;; register to the proper GOT, but also because pointers to the
8830 ;; same function might not compare equal, should they be set by
8831 ;; different shared libraries.
8832 (use (reg:SI PIC_REG))]
8836 (define_expand "sym2PIC"
8837 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8841 ;; TLS code generation.
8842 ;; ??? this should be a define_insn_and_split
8843 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8844 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8847 (define_insn "tls_global_dynamic"
8848 [(set (match_operand:SI 0 "register_operand" "=&z")
8849 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8852 (use (reg:PSI FPSCR_REG))
8853 (use (reg:SI PIC_REG))
8854 (clobber (reg:SI PR_REG))
8855 (clobber (scratch:SI))]
8858 return "mov.l 1f,r4" "\n"
8867 "1: .long %a1@TLSGD" "\n"
8868 "2: .long __tls_get_addr@PLT" "\n"
8871 [(set_attr "type" "tls_load")
8872 (set_attr "length" "26")])
8874 (define_insn "tls_local_dynamic"
8875 [(set (match_operand:SI 0 "register_operand" "=&z")
8876 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8879 (use (reg:PSI FPSCR_REG))
8880 (use (reg:SI PIC_REG))
8881 (clobber (reg:SI PR_REG))
8882 (clobber (scratch:SI))]
8885 return "mov.l 1f,r4" "\n"
8894 "1: .long %a1@TLSLDM" "\n"
8895 "2: .long __tls_get_addr@PLT" "\n"
8898 [(set_attr "type" "tls_load")
8899 (set_attr "length" "26")])
8901 (define_expand "sym2DTPOFF"
8902 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8906 (define_expand "symDTPOFF2reg"
8907 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8911 rtx t = (!can_create_pseudo_p ()
8913 : gen_reg_rtx (GET_MODE (operands[0])));
8915 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8916 PUT_MODE (dtpoffsym, Pmode);
8917 emit_move_insn (t, dtpoffsym);
8918 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8922 (define_expand "sym2GOTTPOFF"
8923 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8927 (define_insn "tls_initial_exec"
8928 [(set (match_operand:SI 0 "register_operand" "=&r")
8929 (unspec:SI [(match_operand:SI 1 "" "")]
8931 (use (reg:SI GBR_REG))
8932 (use (reg:SI PIC_REG))
8933 (clobber (reg:SI R0_REG))]
8936 return "mov.l 1f,r0" "\n"
8938 " mov.l @(r0,r12),r0" "\n"
8945 [(set_attr "type" "tls_load")
8946 (set_attr "length" "16")])
8948 (define_expand "sym2TPOFF"
8949 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8953 (define_expand "symTPOFF2reg"
8954 [(match_operand 0 "" "") (match_operand 1 "" "")]
8959 tpoffsym = gen_sym2TPOFF (operands[1]);
8960 PUT_MODE (tpoffsym, Pmode);
8961 emit_move_insn (operands[0], tpoffsym);
8965 (define_insn "load_gbr"
8966 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8967 (use (reg:SI GBR_REG))]
8970 [(set_attr "type" "tls_load")])
8972 ;; case instruction for switch statements.
8974 ;; Operand 0 is index
8975 ;; operand 1 is the minimum bound
8976 ;; operand 2 is the maximum bound - minimum bound + 1
8977 ;; operand 3 is CODE_LABEL for the table;
8978 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8980 (define_expand "casesi"
8981 [(match_operand:SI 0 "arith_reg_operand" "")
8982 (match_operand:SI 1 "arith_reg_operand" "")
8983 (match_operand:SI 2 "arith_reg_operand" "")
8984 (match_operand 3 "" "") (match_operand 4 "" "")]
8987 rtx reg = gen_reg_rtx (SImode);
8988 rtx reg2 = gen_reg_rtx (SImode);
8991 rtx reg = gen_reg_rtx (DImode);
8992 rtx reg2 = gen_reg_rtx (DImode);
8993 rtx reg3 = gen_reg_rtx (Pmode);
8994 rtx reg4 = gen_reg_rtx (Pmode);
8995 rtx reg5 = gen_reg_rtx (Pmode);
8998 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8999 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9000 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9002 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
9003 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
9004 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9005 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
9006 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
9007 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9008 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9009 (Pmode, operands[3])));
9010 /* Messy: can we subreg to clean this up? */
9011 if (Pmode == DImode)
9012 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9014 load = gen_casesi_load_media (reg4,
9015 gen_rtx_SUBREG (DImode, reg3, 0),
9017 PUT_MODE (SET_SRC (load), Pmode);
9019 /* ??? The following add could be eliminated if we used ptrel. */
9020 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9021 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9025 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9026 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9027 /* If optimizing, casesi_worker depends on the mode of the instruction
9028 before label it 'uses' - operands[3]. */
9029 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9031 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9033 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9035 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9036 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9037 operands[3], but to lab. We will fix this up in
9038 machine_dependent_reorg. */
9043 (define_expand "casesi_0"
9044 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9045 (set (match_dup 4) (minus:SI (match_dup 4)
9046 (match_operand:SI 1 "arith_operand" "")))
9048 (gtu:SI (match_dup 4)
9049 (match_operand:SI 2 "arith_reg_operand" "")))
9051 (if_then_else (ne (reg:SI T_REG)
9053 (label_ref (match_operand 3 "" ""))
9058 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9059 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9060 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9062 (define_insn "casesi_worker_0"
9063 [(set (match_operand:SI 0 "register_operand" "=r,r")
9064 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9065 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9066 (clobber (match_scratch:SI 3 "=X,1"))
9067 (clobber (match_scratch:SI 4 "=&z,z"))]
9072 [(set (match_operand:SI 0 "register_operand" "")
9073 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9074 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9075 (clobber (match_scratch:SI 3 ""))
9076 (clobber (match_scratch:SI 4 ""))]
9077 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9078 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9079 (parallel [(set (match_dup 0)
9080 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9081 (label_ref (match_dup 2))] UNSPEC_CASESI))
9082 (clobber (match_dup 3))])
9083 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9085 if (GET_CODE (operands[2]) == CODE_LABEL)
9086 LABEL_NUSES (operands[2])++;
9090 [(set (match_operand:SI 0 "register_operand" "")
9091 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9092 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9093 (clobber (match_scratch:SI 3 ""))
9094 (clobber (match_scratch:SI 4 ""))]
9095 "TARGET_SH2 && reload_completed"
9096 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9097 (parallel [(set (match_dup 0)
9098 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9099 (label_ref (match_dup 2))] UNSPEC_CASESI))
9100 (clobber (match_dup 3))])]
9102 if (GET_CODE (operands[2]) == CODE_LABEL)
9103 LABEL_NUSES (operands[2])++;
9106 (define_insn "casesi_worker_1"
9107 [(set (match_operand:SI 0 "register_operand" "=r,r")
9108 (unspec:SI [(reg:SI R0_REG)
9109 (match_operand:SI 1 "register_operand" "0,r")
9110 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9111 (clobber (match_scratch:SI 3 "=X,1"))]
9114 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9116 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9118 switch (GET_MODE (diff_vec))
9121 return "shll2 %1\;mov.l @(r0,%1),%0";
9123 return "add %1,%1\;mov.w @(r0,%1),%0";
9125 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9126 return "mov.b @(r0,%1),%0\;extu.b %0,%0";
9127 return "mov.b @(r0,%1),%0";
9132 [(set_attr "length" "4")])
9134 (define_insn "casesi_worker_2"
9135 [(set (match_operand:SI 0 "register_operand" "=r,r")
9136 (unspec:SI [(reg:SI R0_REG)
9137 (match_operand:SI 1 "register_operand" "0,r")
9138 (label_ref (match_operand 2 "" ""))
9139 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9140 (clobber (match_operand:SI 4 "" "=X,1"))]
9141 "TARGET_SH2 && reload_completed && flag_pic"
9143 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9146 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9148 switch (GET_MODE (diff_vec))
9151 output_asm_insn ("shll2 %1", operands);
9152 load = "mov.l @(r0,%1),%0"; break;
9154 output_asm_insn ("add %1,%1", operands);
9155 load = "mov.w @(r0,%1),%0"; break;
9157 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9158 load = "mov.b @(r0,%1),%0\;extu.b %0,%0";
9160 load = "mov.b @(r0,%1),%0";
9165 output_asm_insn ("add\tr0,%1\;mova\t%O3,r0\\n", operands);
9168 [(set_attr "length" "8")])
9170 (define_insn "casesi_shift_media"
9171 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9172 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9173 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9177 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9179 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9181 switch (GET_MODE (diff_vec))
9184 return "shlli %1, 2, %0";
9186 return "shlli %1, 1, %0";
9188 if (rtx_equal_p (operands[0], operands[1]))
9190 return "add %1, r63, %0";
9195 [(set_attr "type" "arith_media")])
9197 (define_insn "casesi_load_media"
9198 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9199 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9200 (match_operand:DI 2 "arith_reg_operand" "r")
9201 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9204 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9206 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9208 switch (GET_MODE (diff_vec))
9211 return "ldx.l %1, %2, %0";
9214 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9215 return "ldx.uw %1, %2, %0";
9217 return "ldx.w %1, %2, %0";
9219 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9220 return "ldx.ub %1, %2, %0";
9221 return "ldx.b %1, %2, %0";
9226 [(set_attr "type" "load_media")])
9228 (define_expand "return"
9230 "reload_completed && ! sh_need_epilogue ()"
9234 emit_jump_insn (gen_return_media ());
9238 if (TARGET_SHCOMPACT
9239 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9241 emit_jump_insn (gen_shcompact_return_tramp ());
9246 (define_insn "*return_i"
9248 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9249 && (crtl->args.info.call_cookie
9250 & CALL_COOKIE_RET_TRAMP (1)))
9252 && lookup_attribute (\"trap_exit\",
9253 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9255 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9256 && !current_function_interrupt)
9261 [(set_attr "type" "return")
9262 (set_attr "needs_delay_slot" "yes")])
9264 ;; trapa has no delay slot.
9265 (define_insn "*return_trapa"
9267 "TARGET_SH1 && !TARGET_SHCOMPACT
9268 && reload_completed"
9270 [(set_attr "type" "return")])
9272 (define_expand "shcompact_return_tramp"
9275 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9277 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9279 function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
9280 emit_jump_insn (gen_shcompact_return_tramp_i ());
9284 (define_insn "shcompact_return_tramp_i"
9285 [(parallel [(return) (use (reg:SI R0_REG))])]
9287 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9289 [(set_attr "type" "jump_ind")
9290 (set_attr "needs_delay_slot" "yes")])
9292 (define_insn "return_media_i"
9293 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9294 "TARGET_SHMEDIA && reload_completed"
9296 [(set_attr "type" "jump_media")])
9298 (define_insn "return_media_rte"
9300 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9302 [(set_attr "type" "jump_media")])
9304 (define_expand "return_media"
9306 "TARGET_SHMEDIA && reload_completed"
9308 int tr_regno = sh_media_register_for_return ();
9311 if (current_function_interrupt)
9313 emit_jump_insn (gen_return_media_rte ());
9318 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9320 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9322 tr = gen_rtx_REG (Pmode, tr_regno);
9323 emit_move_insn (tr, r18);
9326 tr = gen_rtx_REG (Pmode, tr_regno);
9328 emit_jump_insn (gen_return_media_i (tr));
9332 (define_insn "shcompact_preserve_incoming_args"
9333 [(set (match_operand:SI 0 "register_operand" "+r")
9334 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9337 [(set_attr "length" "0")])
9339 (define_insn "shcompact_incoming_args"
9340 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9341 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9342 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9343 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9344 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9345 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9346 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9347 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (mem:BLK (reg:SI MACL_REG))
9349 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9350 (use (reg:SI R0_REG))
9351 (clobber (reg:SI R0_REG))
9352 (clobber (reg:SI MACL_REG))
9353 (clobber (reg:SI MACH_REG))
9354 (clobber (reg:SI PR_REG))]
9357 [(set_attr "needs_delay_slot" "yes")])
9359 (define_insn "shmedia_save_restore_regs_compact"
9360 [(set (reg:SI SP_REG)
9361 (plus:SI (reg:SI SP_REG)
9362 (match_operand:SI 0 "immediate_operand" "i")))
9363 (use (reg:SI R0_REG))
9364 (clobber (reg:SI PR_REG))]
9366 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9367 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9369 [(set_attr "needs_delay_slot" "yes")])
9371 (define_expand "prologue"
9375 sh_expand_prologue ();
9379 (define_expand "epilogue"
9383 sh_expand_epilogue (0);
9384 emit_jump_insn (gen_return ());
9388 (define_expand "eh_return"
9389 [(use (match_operand 0 "register_operand" ""))]
9392 rtx ra = operands[0];
9394 if (TARGET_SHMEDIA64)
9395 emit_insn (gen_eh_set_ra_di (ra));
9397 emit_insn (gen_eh_set_ra_si (ra));
9402 ;; Clobber the return address on the stack. We can't expand this
9403 ;; until we know where it will be put in the stack frame.
9405 (define_insn "eh_set_ra_si"
9406 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9408 (clobber (match_scratch:SI 1 "=&r"))]
9409 "! TARGET_SHMEDIA64"
9412 (define_insn "eh_set_ra_di"
9413 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9415 (clobber (match_scratch:DI 1 "=&r"))]
9420 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9422 (clobber (match_scratch 1 ""))]
9426 sh_set_return_address (operands[0], operands[1]);
9430 (define_insn "blockage"
9431 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9434 [(set_attr "length" "0")])
9436 ;; Define movml instructions for SH2A target. Currently they are
9437 ;; used to push and pop all banked registers only.
9439 (define_insn "movml_push_banked"
9440 [(set (match_operand:SI 0 "register_operand" "=r")
9441 (plus (match_dup 0) (const_int -32)))
9442 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9443 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9444 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9445 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9446 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9447 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9448 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9449 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9450 "TARGET_SH2A && REGNO (operands[0]) == 15"
9452 [(set_attr "in_delay_slot" "no")])
9454 (define_insn "movml_pop_banked"
9455 [(set (match_operand:SI 0 "register_operand" "=r")
9456 (plus (match_dup 0) (const_int 32)))
9457 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9458 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9459 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9460 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9461 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9462 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9463 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9464 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9465 "TARGET_SH2A && REGNO (operands[0]) == 15"
9467 [(set_attr "in_delay_slot" "no")])
9469 ;; ------------------------------------------------------------------------
9471 ;; ------------------------------------------------------------------------
9474 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9475 (eq:SI (reg:SI T_REG) (const_int 1)))]
9478 [(set_attr "type" "arith")])
9480 (define_insn "movrt"
9481 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9482 (xor:SI (reg:SI T_REG) (const_int 1)))]
9485 [(set_attr "type" "arith")])
9487 (define_expand "cstore4_media"
9488 [(set (match_operand:SI 0 "register_operand" "=r")
9489 (match_operator:SI 1 "sh_float_comparison_operator"
9490 [(match_operand 2 "logical_operand" "")
9491 (match_operand 3 "cmp_operand" "")]))]
9494 enum machine_mode mode = GET_MODE (operands[2]);
9495 enum rtx_code code = GET_CODE (operands[1]);
9497 if (mode == VOIDmode)
9498 mode = GET_MODE (operands[3]);
9499 if (operands[2] == const0_rtx)
9501 if (code == EQ || code == NE)
9502 operands[2] = operands[3], operands[3] = const0_rtx;
9505 operands[2] = force_reg (mode, operands[2]);
9506 if (operands[3] != const0_rtx)
9507 operands[3] = force_reg (mode, operands[3]);
9513 swap = invert = !FLOAT_MODE_P (mode);
9518 swap = FLOAT_MODE_P (mode), invert = !swap;
9523 swap = true, invert = false;
9530 swap = invert = false;
9534 swap = invert = true;
9543 rtx tem = operands[2];
9544 operands[2] = operands[3];
9546 code = swap_condition (code);
9551 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9552 code = reverse_condition (code);
9553 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9554 emit_insn (gen_cstore4_media (tem, operands[1],
9555 operands[2], operands[3]));
9558 operands[3] = const0_rtx;
9561 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9564 (define_expand "cstoresi4"
9565 [(set (match_operand:SI 0 "register_operand" "=r")
9566 (match_operator:SI 1 "comparison_operator"
9567 [(match_operand:SI 2 "cmpsi_operand" "")
9568 (match_operand:SI 3 "arith_operand" "")]))]
9569 "TARGET_SH1 || TARGET_SHMEDIA"
9573 emit_insn (gen_cstore4_media (operands[0], operands[1],
9574 operands[2], operands[3]));
9578 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9579 && sh_expand_t_scc (operands))
9582 if (! currently_expanding_to_rtl)
9585 sh_emit_compare_and_set (operands, SImode);
9589 (define_expand "cstoredi4"
9590 [(set (match_operand:SI 0 "register_operand" "=r")
9591 (match_operator:SI 1 "comparison_operator"
9592 [(match_operand:DI 2 "arith_operand" "")
9593 (match_operand:DI 3 "arith_operand" "")]))]
9594 "TARGET_SH2 || TARGET_SHMEDIA"
9598 emit_insn (gen_cstore4_media (operands[0], operands[1],
9599 operands[2], operands[3]));
9603 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9604 && sh_expand_t_scc (operands))
9607 if (! currently_expanding_to_rtl)
9610 sh_emit_compare_and_set (operands, DImode);
9614 ;; Move the complement of the T reg to a reg.
9615 ;; On SH2A the movrt insn can be used.
9616 ;; On anything else than SH2A this has to be done with multiple instructions.
9617 ;; One obvious way would be:
9622 ;; However, this puts pressure on r0 in most cases and thus the following is
9628 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
9629 ;; becomes a one instruction operation. Moreover, care must be taken that
9630 ;; the insn can still be combined with inverted compare and branch code
9631 ;; around it. On the other hand, if a function returns the complement of
9632 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
9633 ;; lead to better code.
9635 (define_expand "movnegt"
9636 [(set (match_operand:SI 0 "arith_reg_dest" "")
9637 (xor:SI (reg:SI T_REG) (const_int 1)))]
9641 emit_insn (gen_movrt (operands[0]));
9644 rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
9645 emit_insn (gen_movrt_negc (operands[0], val));
9650 (define_insn "movrt_negc"
9651 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9652 (xor:SI (reg:SI T_REG) (const_int 1)))
9653 (set (reg:SI T_REG) (const_int 1))
9654 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
9657 [(set_attr "type" "arith")])
9659 ;; The *negnegt patterns help the combine pass to figure out how to fold
9660 ;; an explicit double T bit negation.
9661 (define_insn_and_split "*negnegt"
9662 [(set (reg:SI T_REG)
9663 (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 3)
9665 "! TARGET_LITTLE_ENDIAN"
9670 (define_insn_and_split "*negnegt"
9671 [(set (reg:SI T_REG)
9672 (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 0)
9674 "TARGET_LITTLE_ENDIAN"
9679 ;; The *movtt patterns improve code at -O1.
9680 (define_insn_and_split "*movtt"
9681 [(set (reg:SI T_REG)
9682 (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 3))
9684 "! TARGET_LITTLE_ENDIAN"
9689 (define_insn_and_split "*movtt"
9690 [(set (reg:SI T_REG)
9691 (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 0))
9693 "TARGET_LITTLE_ENDIAN"
9698 ;; The *movt_qi patterns help the combine pass convert a movrt_negc pattern
9699 ;; into a movt Rn, xor #1 Rn pattern. This can happen when e.g. a function
9700 ;; returns the inverted T bit value.
9701 (define_insn "*movt_qi"
9702 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9703 (zero_extend:SI (subreg:QI (reg:SI T_REG) 3)))]
9704 "! TARGET_LITTLE_ENDIAN"
9706 [(set_attr "type" "arith")])
9708 (define_insn "*movt_qi"
9709 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9710 (zero_extend:SI (subreg:QI (reg:SI T_REG) 0)))]
9711 "TARGET_LITTLE_ENDIAN"
9713 [(set_attr "type" "arith")])
9715 (define_expand "cstoresf4"
9716 [(set (match_operand:SI 0 "register_operand" "=r")
9717 (match_operator:SI 1 "sh_float_comparison_operator"
9718 [(match_operand:SF 2 "arith_operand" "")
9719 (match_operand:SF 3 "arith_operand" "")]))]
9720 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9724 emit_insn (gen_cstore4_media (operands[0], operands[1],
9725 operands[2], operands[3]));
9729 if (! currently_expanding_to_rtl)
9732 sh_emit_compare_and_set (operands, SFmode);
9736 (define_expand "cstoredf4"
9737 [(set (match_operand:SI 0 "register_operand" "=r")
9738 (match_operator:SI 1 "sh_float_comparison_operator"
9739 [(match_operand:DF 2 "arith_operand" "")
9740 (match_operand:DF 3 "arith_operand" "")]))]
9741 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9745 emit_insn (gen_cstore4_media (operands[0], operands[1],
9746 operands[2], operands[3]));
9750 if (! currently_expanding_to_rtl)
9753 sh_emit_compare_and_set (operands, DFmode);
9757 ;; -------------------------------------------------------------------------
9758 ;; Instructions to cope with inline literal tables
9759 ;; -------------------------------------------------------------------------
9761 ; 2 byte integer in line
9763 (define_insn "consttable_2"
9764 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9765 (match_operand 1 "" "")]
9769 if (operands[1] != const0_rtx)
9770 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9773 [(set_attr "length" "2")
9774 (set_attr "in_delay_slot" "no")])
9776 ; 4 byte integer in line
9778 (define_insn "consttable_4"
9779 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9780 (match_operand 1 "" "")]
9784 if (operands[1] != const0_rtx)
9786 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9787 mark_symbol_refs_as_used (operands[0]);
9791 [(set_attr "length" "4")
9792 (set_attr "in_delay_slot" "no")])
9794 ; 8 byte integer in line
9796 (define_insn "consttable_8"
9797 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9798 (match_operand 1 "" "")]
9802 if (operands[1] != const0_rtx)
9803 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9806 [(set_attr "length" "8")
9807 (set_attr "in_delay_slot" "no")])
9809 ; 4 byte floating point
9811 (define_insn "consttable_sf"
9812 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9813 (match_operand 1 "" "")]
9817 if (operands[1] != const0_rtx)
9820 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9821 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9825 [(set_attr "length" "4")
9826 (set_attr "in_delay_slot" "no")])
9828 ; 8 byte floating point
9830 (define_insn "consttable_df"
9831 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9832 (match_operand 1 "" "")]
9836 if (operands[1] != const0_rtx)
9839 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9840 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9844 [(set_attr "length" "8")
9845 (set_attr "in_delay_slot" "no")])
9847 ;; Alignment is needed for some constant tables; it may also be added for
9848 ;; Instructions at the start of loops, or after unconditional branches.
9849 ;; ??? We would get more accurate lengths if we did instruction
9850 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9851 ;; here is too conservative.
9853 ; align to a two byte boundary
9855 (define_expand "align_2"
9856 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9860 ; align to a four byte boundary
9861 ;; align_4 and align_log are instructions for the starts of loops, or
9862 ;; after unconditional branches, which may take up extra room.
9864 (define_expand "align_4"
9865 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9869 ; align to a cache line boundary
9871 (define_insn "align_log"
9872 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9875 [(set_attr "length" "0")
9876 (set_attr "in_delay_slot" "no")])
9878 ; emitted at the end of the literal table, used to emit the
9879 ; 32bit branch labels if needed.
9881 (define_insn "consttable_end"
9882 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9885 return output_jump_label_table ();
9887 [(set_attr "in_delay_slot" "no")])
9889 ; emitted at the end of the window in the literal table.
9891 (define_insn "consttable_window_end"
9892 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9895 [(set_attr "length" "0")
9896 (set_attr "in_delay_slot" "no")])
9898 ;; -------------------------------------------------------------------------
9900 ;; -------------------------------------------------------------------------
9902 ;; String/block move insn.
9904 (define_expand "movmemsi"
9905 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9906 (mem:BLK (match_operand:BLK 1 "" "")))
9907 (use (match_operand:SI 2 "nonmemory_operand" ""))
9908 (use (match_operand:SI 3 "immediate_operand" ""))
9909 (clobber (reg:SI PR_REG))
9910 (clobber (reg:SI R4_REG))
9911 (clobber (reg:SI R5_REG))
9912 (clobber (reg:SI R0_REG))])]
9913 "TARGET_SH1 && ! TARGET_SH5"
9915 if(expand_block_move (operands))
9920 (define_insn "block_move_real"
9921 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9922 (mem:BLK (reg:SI R5_REG)))
9923 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9924 (clobber (reg:SI PR_REG))
9925 (clobber (reg:SI R0_REG))])]
9926 "TARGET_SH1 && ! TARGET_HARD_SH4"
9928 [(set_attr "type" "sfunc")
9929 (set_attr "needs_delay_slot" "yes")])
9931 (define_insn "block_lump_real"
9932 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9933 (mem:BLK (reg:SI R5_REG)))
9934 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9935 (use (reg:SI R6_REG))
9936 (clobber (reg:SI PR_REG))
9937 (clobber (reg:SI T_REG))
9938 (clobber (reg:SI R4_REG))
9939 (clobber (reg:SI R5_REG))
9940 (clobber (reg:SI R6_REG))
9941 (clobber (reg:SI R0_REG))])]
9942 "TARGET_SH1 && ! TARGET_HARD_SH4"
9944 [(set_attr "type" "sfunc")
9945 (set_attr "needs_delay_slot" "yes")])
9947 (define_insn "block_move_real_i4"
9948 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9949 (mem:BLK (reg:SI R5_REG)))
9950 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9951 (clobber (reg:SI PR_REG))
9952 (clobber (reg:SI R0_REG))
9953 (clobber (reg:SI R1_REG))
9954 (clobber (reg:SI R2_REG))])]
9957 [(set_attr "type" "sfunc")
9958 (set_attr "needs_delay_slot" "yes")])
9960 (define_insn "block_lump_real_i4"
9961 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9962 (mem:BLK (reg:SI R5_REG)))
9963 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9964 (use (reg:SI R6_REG))
9965 (clobber (reg:SI PR_REG))
9966 (clobber (reg:SI T_REG))
9967 (clobber (reg:SI R4_REG))
9968 (clobber (reg:SI R5_REG))
9969 (clobber (reg:SI R6_REG))
9970 (clobber (reg:SI R0_REG))
9971 (clobber (reg:SI R1_REG))
9972 (clobber (reg:SI R2_REG))
9973 (clobber (reg:SI R3_REG))])]
9976 [(set_attr "type" "sfunc")
9977 (set_attr "needs_delay_slot" "yes")])
9979 ;; -------------------------------------------------------------------------
9980 ;; Floating point instructions.
9981 ;; -------------------------------------------------------------------------
9983 ;; ??? All patterns should have a type attribute.
9985 (define_expand "movpsi"
9986 [(set (match_operand:PSI 0 "register_operand" "")
9987 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9988 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9991 ;; The c / m alternative is a fake to guide reload to load directly into
9992 ;; fpscr, since reload doesn't know how to use post-increment.
9993 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9994 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9995 ;; predicate after reload.
9996 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9997 ;; like a mac -> gpr move.
9998 (define_insn "fpu_switch"
9999 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10000 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10002 && (! reload_completed
10003 || true_regnum (operands[0]) != FPSCR_REG
10004 || !MEM_P (operands[1])
10005 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10007 ! precision stays the same
10016 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10017 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10020 [(set (reg:PSI FPSCR_REG)
10021 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10022 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10025 rtx fpscr, mem, new_insn;
10027 fpscr = SET_DEST (PATTERN (curr_insn));
10028 mem = SET_SRC (PATTERN (curr_insn));
10029 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10031 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10032 add_reg_note (new_insn, REG_INC, operands[0]);
10037 [(set (reg:PSI FPSCR_REG)
10038 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10039 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10040 && (flag_peephole2 ? epilogue_completed : reload_completed)"
10043 rtx fpscr, mem, new_insn;
10045 fpscr = SET_DEST (PATTERN (curr_insn));
10046 mem = SET_SRC (PATTERN (curr_insn));
10047 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10049 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10050 add_reg_note (new_insn, REG_INC, operands[0]);
10052 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10053 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10057 ;; ??? This uses the fp unit, but has no type indicating that.
10058 ;; If we did that, this would either give a bogus latency or introduce
10059 ;; a bogus FIFO constraint.
10060 ;; Since this insn is currently only used for prologues/epilogues,
10061 ;; it is probably best to claim no function unit, which matches the
10062 ;; current setting.
10063 (define_insn "toggle_sz"
10064 [(set (reg:PSI FPSCR_REG)
10065 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10066 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10068 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10070 ;; There's no way we can use it today, since optimize mode switching
10071 ;; doesn't enable us to know from which mode we're switching to the
10072 ;; mode it requests, to tell whether we can use a relative mode switch
10073 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10075 (define_insn "toggle_pr"
10076 [(set (reg:PSI FPSCR_REG)
10077 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10078 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10080 [(set_attr "type" "fpscr_toggle")])
10082 (define_expand "addsf3"
10083 [(set (match_operand:SF 0 "arith_reg_operand" "")
10084 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10085 (match_operand:SF 2 "arith_reg_operand" "")))]
10086 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10090 expand_sf_binop (&gen_addsf3_i, operands);
10095 (define_insn "*addsf3_media"
10096 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10097 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10098 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10099 "TARGET_SHMEDIA_FPU"
10100 "fadd.s %1, %2, %0"
10101 [(set_attr "type" "fparith_media")])
10103 (define_insn_and_split "unary_sf_op"
10104 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10109 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10110 (match_operator:SF 2 "unary_float_operator"
10111 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10112 (parallel [(match_operand 4
10113 "const_int_operand" "n")]))]))
10114 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10115 "TARGET_SHMEDIA_FPU"
10117 "TARGET_SHMEDIA_FPU && reload_completed"
10118 [(set (match_dup 5) (match_dup 6))]
10120 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10121 rtx op1 = gen_rtx_REG (SFmode,
10122 (true_regnum (operands[1])
10123 + (INTVAL (operands[4]) ^ endian)));
10125 operands[7] = gen_rtx_REG (SFmode,
10126 (true_regnum (operands[0])
10127 + (INTVAL (operands[3]) ^ endian)));
10128 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10130 [(set_attr "type" "fparith_media")])
10132 (define_insn_and_split "binary_sf_op0"
10133 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10135 (match_operator:SF 3 "binary_float_operator"
10136 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10137 (parallel [(const_int 0)]))
10138 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10139 (parallel [(const_int 0)]))])
10142 (parallel [(const_int 1)]))))]
10143 "TARGET_SHMEDIA_FPU"
10145 "&& reload_completed"
10146 [(set (match_dup 4) (match_dup 5))]
10148 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10149 rtx op1 = gen_rtx_REG (SFmode,
10150 true_regnum (operands[1]) + endian);
10151 rtx op2 = gen_rtx_REG (SFmode,
10152 true_regnum (operands[2]) + endian);
10154 operands[4] = gen_rtx_REG (SFmode,
10155 true_regnum (operands[0]) + endian);
10156 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10158 [(set_attr "type" "fparith_media")])
10160 (define_insn_and_split "binary_sf_op1"
10161 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10165 (parallel [(const_int 0)]))
10166 (match_operator:SF 3 "binary_float_operator"
10167 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10168 (parallel [(const_int 1)]))
10169 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10170 (parallel [(const_int 1)]))])))]
10171 "TARGET_SHMEDIA_FPU"
10173 "&& reload_completed"
10174 [(set (match_dup 4) (match_dup 5))]
10176 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10177 rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
10178 rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
10180 operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
10181 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10183 [(set_attr "type" "fparith_media")])
10185 (define_insn "addsf3_i"
10186 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10187 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10188 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10189 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10192 [(set_attr "type" "fp")
10193 (set_attr "fp_mode" "single")])
10195 (define_expand "subsf3"
10196 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10197 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10198 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10199 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10203 expand_sf_binop (&gen_subsf3_i, operands);
10208 (define_insn "*subsf3_media"
10209 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10210 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10211 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10212 "TARGET_SHMEDIA_FPU"
10213 "fsub.s %1, %2, %0"
10214 [(set_attr "type" "fparith_media")])
10216 (define_insn "subsf3_i"
10217 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10218 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10219 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10220 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10223 [(set_attr "type" "fp")
10224 (set_attr "fp_mode" "single")])
10226 (define_expand "mulsf3"
10227 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10228 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10229 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10230 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10233 (define_insn "*mulsf3_media"
10234 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10235 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10236 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10237 "TARGET_SHMEDIA_FPU"
10238 "fmul.s %1, %2, %0"
10239 [(set_attr "type" "fparith_media")])
10241 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10242 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10243 ;; we start out with a mulsf pattern that does not depend on fpscr.
10244 ;; This is split after combine to introduce the dependency, in order to
10245 ;; get mode switching and scheduling right.
10246 (define_insn_and_split "mulsf3_ie"
10247 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10248 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10249 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10252 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10255 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10256 get_fpscr_rtx ()));
10259 [(set_attr "type" "fp")])
10261 (define_insn "mulsf3_i4"
10262 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10263 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10264 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10265 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10268 [(set_attr "type" "fp")
10269 (set_attr "fp_mode" "single")])
10271 (define_insn "mac_media"
10272 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10273 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10274 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10275 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10276 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10277 "fmac.s %1, %2, %0"
10278 [(set_attr "type" "fparith_media")])
10280 (define_insn "*macsf3"
10281 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10282 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10283 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10284 (match_operand:SF 3 "arith_reg_operand" "0")))
10285 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10286 "TARGET_SH2E && TARGET_FMAC"
10288 [(set_attr "type" "fp")
10289 (set_attr "fp_mode" "single")])
10291 (define_expand "divsf3"
10292 [(set (match_operand:SF 0 "arith_reg_operand" "")
10293 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10294 (match_operand:SF 2 "arith_reg_operand" "")))]
10295 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10299 expand_sf_binop (&gen_divsf3_i, operands);
10304 (define_insn "*divsf3_media"
10305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10307 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10308 "TARGET_SHMEDIA_FPU"
10309 "fdiv.s %1, %2, %0"
10310 [(set_attr "type" "fdiv_media")])
10312 (define_insn "divsf3_i"
10313 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10314 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10315 (match_operand:SF 2 "arith_reg_operand" "f")))
10316 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10319 [(set_attr "type" "fdiv")
10320 (set_attr "fp_mode" "single")])
10322 (define_insn "floatdisf2"
10323 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10324 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10325 "TARGET_SHMEDIA_FPU"
10327 [(set_attr "type" "fpconv_media")])
10329 (define_expand "floatsisf2"
10330 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10331 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10332 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10334 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10336 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10341 (define_insn "*floatsisf2_media"
10342 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10343 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10344 "TARGET_SHMEDIA_FPU"
10346 [(set_attr "type" "fpconv_media")])
10348 (define_insn "floatsisf2_i4"
10349 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10350 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10351 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10352 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10354 [(set_attr "type" "fp")
10355 (set_attr "fp_mode" "single")])
10357 (define_insn "*floatsisf2_ie"
10358 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10359 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10360 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10362 [(set_attr "type" "fp")])
10364 (define_insn "fix_truncsfdi2"
10365 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10366 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10367 "TARGET_SHMEDIA_FPU"
10369 [(set_attr "type" "fpconv_media")])
10371 (define_expand "fix_truncsfsi2"
10372 [(set (match_operand:SI 0 "fpul_operand" "=y")
10373 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10374 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10376 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10378 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10383 (define_insn "*fix_truncsfsi2_media"
10384 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10385 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10386 "TARGET_SHMEDIA_FPU"
10388 [(set_attr "type" "fpconv_media")])
10390 (define_insn "fix_truncsfsi2_i4"
10391 [(set (match_operand:SI 0 "fpul_operand" "=y")
10392 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10393 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10394 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10396 [(set_attr "type" "ftrc_s")
10397 (set_attr "fp_mode" "single")])
10399 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10400 ;; fix_truncsfsi2_i4.
10401 ;; (define_insn "fix_truncsfsi2_i4_2"
10402 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10403 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10404 ;; (use (reg:PSI FPSCR_REG))
10405 ;; (clobber (reg:SI FPUL_REG))]
10408 ;; [(set_attr "length" "4")
10409 ;; (set_attr "fp_mode" "single")])
10412 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10413 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10414 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10415 ;; (clobber (reg:SI FPUL_REG))]
10417 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10418 ;; (use (match_dup 2))])
10419 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10421 (define_insn "*fixsfsi"
10422 [(set (match_operand:SI 0 "fpul_operand" "=y")
10423 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10424 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10426 [(set_attr "type" "fp")])
10428 (define_insn "cmpgtsf_t"
10429 [(set (reg:SI T_REG)
10430 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10431 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10432 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10434 [(set_attr "type" "fp_cmp")
10435 (set_attr "fp_mode" "single")])
10437 (define_insn "cmpeqsf_t"
10438 [(set (reg:SI T_REG)
10439 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10440 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10441 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10443 [(set_attr "type" "fp_cmp")
10444 (set_attr "fp_mode" "single")])
10446 (define_insn "ieee_ccmpeqsf_t"
10447 [(set (reg:SI T_REG)
10448 (ior:SI (reg:SI T_REG)
10449 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10450 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10451 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10453 return output_ieee_ccmpeq (insn, operands);
10455 [(set_attr "length" "4")])
10458 (define_insn "cmpgtsf_t_i4"
10459 [(set (reg:SI T_REG)
10460 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10461 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10462 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10463 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10465 [(set_attr "type" "fp_cmp")
10466 (set_attr "fp_mode" "single")])
10468 (define_insn "cmpeqsf_t_i4"
10469 [(set (reg:SI T_REG)
10470 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10471 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10472 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10473 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10475 [(set_attr "type" "fp_cmp")
10476 (set_attr "fp_mode" "single")])
10478 (define_insn "*ieee_ccmpeqsf_t_4"
10479 [(set (reg:SI T_REG)
10480 (ior:SI (reg:SI T_REG)
10481 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10482 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10483 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10484 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10486 return output_ieee_ccmpeq (insn, operands);
10488 [(set_attr "length" "4")
10489 (set_attr "fp_mode" "single")])
10491 (define_insn "cmpeqsf_media"
10492 [(set (match_operand:SI 0 "register_operand" "=r")
10493 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10494 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10495 "TARGET_SHMEDIA_FPU"
10496 "fcmpeq.s %1, %2, %0"
10497 [(set_attr "type" "fcmp_media")])
10499 (define_insn "cmpgtsf_media"
10500 [(set (match_operand:SI 0 "register_operand" "=r")
10501 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10502 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10503 "TARGET_SHMEDIA_FPU"
10504 "fcmpgt.s %1, %2, %0"
10505 [(set_attr "type" "fcmp_media")])
10507 (define_insn "cmpgesf_media"
10508 [(set (match_operand:SI 0 "register_operand" "=r")
10509 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10510 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10511 "TARGET_SHMEDIA_FPU"
10512 "fcmpge.s %1, %2, %0"
10513 [(set_attr "type" "fcmp_media")])
10515 (define_insn "cmpunsf_media"
10516 [(set (match_operand:SI 0 "register_operand" "=r")
10517 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10518 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10519 "TARGET_SHMEDIA_FPU"
10520 "fcmpun.s %1, %2, %0"
10521 [(set_attr "type" "fcmp_media")])
10523 (define_expand "cbranchsf4"
10525 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10526 [(match_operand:SF 1 "arith_operand" "")
10527 (match_operand:SF 2 "arith_operand" "")])
10528 (match_operand 3 "" "")
10530 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10532 if (TARGET_SHMEDIA)
10533 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10536 sh_emit_compare_and_branch (operands, SFmode);
10540 (define_expand "negsf2"
10541 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10542 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10543 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10547 expand_sf_unop (&gen_negsf2_i, operands);
10552 (define_insn "*negsf2_media"
10553 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10554 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10555 "TARGET_SHMEDIA_FPU"
10557 [(set_attr "type" "fmove_media")])
10559 (define_insn "negsf2_i"
10560 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10561 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10562 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10565 [(set_attr "type" "fmove")
10566 (set_attr "fp_mode" "single")])
10568 (define_expand "sqrtsf2"
10569 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10570 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10571 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10575 expand_sf_unop (&gen_sqrtsf2_i, operands);
10580 (define_insn "*sqrtsf2_media"
10581 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10582 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10583 "TARGET_SHMEDIA_FPU"
10585 [(set_attr "type" "fdiv_media")])
10587 (define_insn "sqrtsf2_i"
10588 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10589 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10590 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10593 [(set_attr "type" "fdiv")
10594 (set_attr "fp_mode" "single")])
10596 (define_insn "rsqrtsf2"
10597 [(set (match_operand:SF 0 "register_operand" "=f")
10598 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10599 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10600 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10601 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10602 && operands[1] == CONST1_RTX (SFmode)"
10604 [(set_attr "type" "fsrra")
10605 (set_attr "fp_mode" "single")])
10607 (define_insn "fsca"
10608 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10610 (unspec:SF [(mult:SF
10611 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10612 (match_operand:SF 2 "immediate_operand" "i"))
10614 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10616 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10617 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10618 && operands[2] == sh_fsca_int2sf ()"
10620 [(set_attr "type" "fsca")
10621 (set_attr "fp_mode" "single")])
10623 (define_expand "sinsf2"
10624 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10625 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10627 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10629 rtx scaled = gen_reg_rtx (SFmode);
10630 rtx truncated = gen_reg_rtx (SImode);
10631 rtx fsca = gen_reg_rtx (V2SFmode);
10632 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10634 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10635 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10636 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10637 get_fpscr_rtx ()));
10638 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10642 (define_expand "cossf2"
10643 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10644 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10646 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10648 rtx scaled = gen_reg_rtx (SFmode);
10649 rtx truncated = gen_reg_rtx (SImode);
10650 rtx fsca = gen_reg_rtx (V2SFmode);
10651 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10653 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10654 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10655 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10656 get_fpscr_rtx ()));
10657 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10661 (define_expand "abssf2"
10662 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10663 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10664 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10668 expand_sf_unop (&gen_abssf2_i, operands);
10673 (define_insn "*abssf2_media"
10674 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10676 "TARGET_SHMEDIA_FPU"
10678 [(set_attr "type" "fmove_media")])
10680 (define_insn "abssf2_i"
10681 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10682 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10683 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10686 [(set_attr "type" "fmove")
10687 (set_attr "fp_mode" "single")])
10689 (define_expand "adddf3"
10690 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10691 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10692 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10693 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10695 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10697 expand_df_binop (&gen_adddf3_i, operands);
10702 (define_insn "*adddf3_media"
10703 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10704 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10705 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10706 "TARGET_SHMEDIA_FPU"
10707 "fadd.d %1, %2, %0"
10708 [(set_attr "type" "dfparith_media")])
10710 (define_insn "adddf3_i"
10711 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10712 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10713 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10714 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10715 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10717 [(set_attr "type" "dfp_arith")
10718 (set_attr "fp_mode" "double")])
10720 (define_expand "subdf3"
10721 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10722 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10723 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10724 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10726 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10728 expand_df_binop (&gen_subdf3_i, operands);
10733 (define_insn "*subdf3_media"
10734 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10735 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10736 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10737 "TARGET_SHMEDIA_FPU"
10738 "fsub.d %1, %2, %0"
10739 [(set_attr "type" "dfparith_media")])
10741 (define_insn "subdf3_i"
10742 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10743 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10744 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10745 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10746 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10748 [(set_attr "type" "dfp_arith")
10749 (set_attr "fp_mode" "double")])
10751 (define_expand "muldf3"
10752 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10753 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10754 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10755 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10757 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10759 expand_df_binop (&gen_muldf3_i, operands);
10764 (define_insn "*muldf3_media"
10765 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10766 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10767 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10768 "TARGET_SHMEDIA_FPU"
10769 "fmul.d %1, %2, %0"
10770 [(set_attr "type" "dfmul_media")])
10772 (define_insn "muldf3_i"
10773 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10774 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10775 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10776 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10777 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10779 [(set_attr "type" "dfp_mul")
10780 (set_attr "fp_mode" "double")])
10782 (define_expand "divdf3"
10783 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10784 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10785 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10786 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10788 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10790 expand_df_binop (&gen_divdf3_i, operands);
10795 (define_insn "*divdf3_media"
10796 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10797 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10798 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10799 "TARGET_SHMEDIA_FPU"
10800 "fdiv.d %1, %2, %0"
10801 [(set_attr "type" "dfdiv_media")])
10803 (define_insn "divdf3_i"
10804 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10805 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10806 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10807 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10808 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10810 [(set_attr "type" "dfdiv")
10811 (set_attr "fp_mode" "double")])
10813 (define_insn "floatdidf2"
10814 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10815 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10816 "TARGET_SHMEDIA_FPU"
10818 [(set_attr "type" "dfpconv_media")])
10820 (define_expand "floatsidf2"
10821 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10822 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10823 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10825 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10827 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10828 get_fpscr_rtx ()));
10833 (define_insn "*floatsidf2_media"
10834 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10835 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10836 "TARGET_SHMEDIA_FPU"
10838 [(set_attr "type" "dfpconv_media")])
10840 (define_insn "floatsidf2_i"
10841 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10843 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10844 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10846 [(set_attr "type" "dfp_conv")
10847 (set_attr "fp_mode" "double")])
10849 (define_insn "fix_truncdfdi2"
10850 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10851 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10852 "TARGET_SHMEDIA_FPU"
10854 [(set_attr "type" "dfpconv_media")])
10856 (define_expand "fix_truncdfsi2"
10857 [(set (match_operand:SI 0 "fpul_operand" "")
10858 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10859 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10861 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10863 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10864 get_fpscr_rtx ()));
10869 (define_insn "*fix_truncdfsi2_media"
10870 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10871 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872 "TARGET_SHMEDIA_FPU"
10874 [(set_attr "type" "dfpconv_media")])
10876 (define_insn "fix_truncdfsi2_i"
10877 [(set (match_operand:SI 0 "fpul_operand" "=y")
10878 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10879 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882 [(set_attr "type" "dfp_conv")
10883 (set_attr "dfp_comp" "no")
10884 (set_attr "fp_mode" "double")])
10886 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10887 ;; fix_truncdfsi2_i.
10888 ;; (define_insn "fix_truncdfsi2_i4"
10889 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10890 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10891 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10892 ;; (clobber (reg:SI FPUL_REG))]
10895 ;; [(set_attr "length" "4")
10896 ;; (set_attr "fp_mode" "double")])
10899 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10900 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10901 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10902 ;; (clobber (reg:SI FPUL_REG))]
10904 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10905 ;; (use (match_dup 2))])
10906 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10908 (define_insn "cmpgtdf_t"
10909 [(set (reg:SI T_REG)
10910 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10911 (match_operand:DF 1 "arith_reg_operand" "f")))
10912 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10913 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10915 [(set_attr "type" "dfp_cmp")
10916 (set_attr "fp_mode" "double")])
10918 (define_insn "cmpeqdf_t"
10919 [(set (reg:SI T_REG)
10920 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10921 (match_operand:DF 1 "arith_reg_operand" "f")))
10922 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10923 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10925 [(set_attr "type" "dfp_cmp")
10926 (set_attr "fp_mode" "double")])
10928 (define_insn "*ieee_ccmpeqdf_t"
10929 [(set (reg:SI T_REG)
10930 (ior:SI (reg:SI T_REG)
10931 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10932 (match_operand:DF 1 "arith_reg_operand" "f"))))
10933 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10934 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10936 return output_ieee_ccmpeq (insn, operands);
10938 [(set_attr "length" "4")
10939 (set_attr "fp_mode" "double")])
10941 (define_insn "cmpeqdf_media"
10942 [(set (match_operand:SI 0 "register_operand" "=r")
10943 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10944 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10945 "TARGET_SHMEDIA_FPU"
10946 "fcmpeq.d %1,%2,%0"
10947 [(set_attr "type" "fcmp_media")])
10949 (define_insn "cmpgtdf_media"
10950 [(set (match_operand:SI 0 "register_operand" "=r")
10951 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10952 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10953 "TARGET_SHMEDIA_FPU"
10954 "fcmpgt.d %1,%2,%0"
10955 [(set_attr "type" "fcmp_media")])
10957 (define_insn "cmpgedf_media"
10958 [(set (match_operand:SI 0 "register_operand" "=r")
10959 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10960 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10961 "TARGET_SHMEDIA_FPU"
10962 "fcmpge.d %1,%2,%0"
10963 [(set_attr "type" "fcmp_media")])
10965 (define_insn "cmpundf_media"
10966 [(set (match_operand:SI 0 "register_operand" "=r")
10967 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10968 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10969 "TARGET_SHMEDIA_FPU"
10970 "fcmpun.d %1,%2,%0"
10971 [(set_attr "type" "fcmp_media")])
10973 (define_expand "cbranchdf4"
10975 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10976 [(match_operand:DF 1 "arith_operand" "")
10977 (match_operand:DF 2 "arith_operand" "")])
10978 (match_operand 3 "" "")
10980 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10982 if (TARGET_SHMEDIA)
10983 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10986 sh_emit_compare_and_branch (operands, DFmode);
10991 (define_expand "negdf2"
10992 [(set (match_operand:DF 0 "arith_reg_operand" "")
10993 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10994 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10996 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10998 expand_df_unop (&gen_negdf2_i, operands);
11003 (define_insn "*negdf2_media"
11004 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11006 "TARGET_SHMEDIA_FPU"
11008 [(set_attr "type" "fmove_media")])
11010 (define_insn "negdf2_i"
11011 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11012 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11013 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11014 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11016 [(set_attr "type" "fmove")
11017 (set_attr "fp_mode" "double")])
11019 (define_expand "sqrtdf2"
11020 [(set (match_operand:DF 0 "arith_reg_operand" "")
11021 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11022 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11024 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11026 expand_df_unop (&gen_sqrtdf2_i, operands);
11031 (define_insn "*sqrtdf2_media"
11032 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11033 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11034 "TARGET_SHMEDIA_FPU"
11036 [(set_attr "type" "dfdiv_media")])
11038 (define_insn "sqrtdf2_i"
11039 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11040 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11041 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11042 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11044 [(set_attr "type" "dfdiv")
11045 (set_attr "fp_mode" "double")])
11047 (define_expand "absdf2"
11048 [(set (match_operand:DF 0 "arith_reg_operand" "")
11049 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11050 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11052 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11054 expand_df_unop (&gen_absdf2_i, operands);
11059 (define_insn "*absdf2_media"
11060 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11061 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11062 "TARGET_SHMEDIA_FPU"
11064 [(set_attr "type" "fmove_media")])
11066 (define_insn "absdf2_i"
11067 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11068 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11069 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11070 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11072 [(set_attr "type" "fmove")
11073 (set_attr "fp_mode" "double")])
11075 (define_expand "extendsfdf2"
11076 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11077 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11078 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11080 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11082 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11083 get_fpscr_rtx ()));
11088 (define_insn "*extendsfdf2_media"
11089 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11090 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11091 "TARGET_SHMEDIA_FPU"
11093 [(set_attr "type" "dfpconv_media")])
11095 (define_insn "extendsfdf2_i4"
11096 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11097 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11098 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11099 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11101 [(set_attr "type" "fp")
11102 (set_attr "fp_mode" "double")])
11104 (define_expand "truncdfsf2"
11105 [(set (match_operand:SF 0 "fpul_operand" "")
11106 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11107 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11109 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11111 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11112 get_fpscr_rtx ()));
11117 (define_insn "*truncdfsf2_media"
11118 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11119 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11120 "TARGET_SHMEDIA_FPU"
11122 [(set_attr "type" "dfpconv_media")])
11124 (define_insn "truncdfsf2_i4"
11125 [(set (match_operand:SF 0 "fpul_operand" "=y")
11126 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11127 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11128 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11130 [(set_attr "type" "fp")
11131 (set_attr "fp_mode" "double")])
11133 ;; Bit field extract patterns. These give better code for packed bitfields,
11134 ;; because they allow auto-increment addresses to be generated.
11136 (define_expand "insv"
11137 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11138 (match_operand:SI 1 "immediate_operand" "")
11139 (match_operand:SI 2 "immediate_operand" ""))
11140 (match_operand:SI 3 "general_operand" ""))]
11141 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11143 rtx addr_target, orig_address, shift_reg, qi_val;
11144 HOST_WIDE_INT bitsize, size, v = 0;
11145 rtx x = operands[3];
11147 if (TARGET_SH2A && TARGET_BITOPS
11148 && (satisfies_constraint_Sbw (operands[0])
11149 || satisfies_constraint_Sbv (operands[0]))
11150 && satisfies_constraint_M (operands[1])
11151 && satisfies_constraint_K03 (operands[2]))
11153 if (satisfies_constraint_N (operands[3]))
11155 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11158 else if (satisfies_constraint_M (operands[3]))
11160 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11163 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11164 && satisfies_constraint_M (operands[1]))
11166 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11169 else if (REG_P (operands[3])
11170 && satisfies_constraint_M (operands[1]))
11172 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11173 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11177 /* ??? expmed doesn't care for non-register predicates. */
11178 if (! memory_operand (operands[0], VOIDmode)
11179 || ! immediate_operand (operands[1], VOIDmode)
11180 || ! immediate_operand (operands[2], VOIDmode)
11181 || ! general_operand (x, VOIDmode))
11183 /* If this isn't a 16 / 24 / 32 bit field, or if
11184 it doesn't start on a byte boundary, then fail. */
11185 bitsize = INTVAL (operands[1]);
11186 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11187 || (INTVAL (operands[2]) % 8) != 0)
11190 size = bitsize / 8;
11191 orig_address = XEXP (operands[0], 0);
11192 shift_reg = gen_reg_rtx (SImode);
11193 if (CONST_INT_P (x))
11196 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11200 emit_insn (gen_movsi (shift_reg, operands[3]));
11201 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11203 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11205 operands[0] = replace_equiv_address (operands[0], addr_target);
11206 emit_insn (gen_movqi (operands[0], qi_val));
11210 if (CONST_INT_P (x))
11212 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11215 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11216 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11218 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11219 emit_insn (gen_movqi (operands[0], qi_val));
11225 (define_insn "movua"
11226 [(set (match_operand:SI 0 "register_operand" "=z")
11227 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11231 [(set_attr "type" "movua")])
11233 ;; We shouldn't need this, but cse replaces increments with references
11234 ;; to other regs before flow has a chance to create post_inc
11235 ;; addressing modes, and only postreload's cse_move2add brings the
11236 ;; increments back to a usable form.
11238 [(set (match_operand:SI 0 "register_operand" "")
11239 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11240 (const_int 32) (const_int 0)))
11241 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11242 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11243 [(set (match_operand:SI 0 "register_operand" "")
11244 (sign_extract:SI (mem:SI (post_inc:SI
11245 (match_operand:SI 1 "register_operand" "")))
11246 (const_int 32) (const_int 0)))]
11249 (define_expand "extv"
11250 [(set (match_operand:SI 0 "register_operand" "")
11251 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11252 (match_operand 2 "const_int_operand" "")
11253 (match_operand 3 "const_int_operand" "")))]
11254 "TARGET_SH4A_ARCH || TARGET_SH2A"
11256 if (TARGET_SH2A && TARGET_BITOPS
11257 && (satisfies_constraint_Sbw (operands[1])
11258 || satisfies_constraint_Sbv (operands[1]))
11259 && satisfies_constraint_M (operands[2])
11260 && satisfies_constraint_K03 (operands[3]))
11262 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11263 if (REGNO (operands[0]) != T_REG)
11264 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11267 if (TARGET_SH4A_ARCH
11268 && INTVAL (operands[2]) == 32
11269 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11270 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11272 rtx src = adjust_address (operands[1], BLKmode, 0);
11273 set_mem_size (src, 4);
11274 emit_insn (gen_movua (operands[0], src));
11281 (define_expand "extzv"
11282 [(set (match_operand:SI 0 "register_operand" "")
11283 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11284 (match_operand 2 "const_int_operand" "")
11285 (match_operand 3 "const_int_operand" "")))]
11286 "TARGET_SH4A_ARCH || TARGET_SH2A"
11288 if (TARGET_SH2A && TARGET_BITOPS
11289 && (satisfies_constraint_Sbw (operands[1])
11290 || satisfies_constraint_Sbv (operands[1]))
11291 && satisfies_constraint_M (operands[2])
11292 && satisfies_constraint_K03 (operands[3]))
11294 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11295 if (REGNO (operands[0]) != T_REG)
11296 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11299 if (TARGET_SH4A_ARCH
11300 && INTVAL (operands[2]) == 32
11301 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11302 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11304 rtx src = adjust_address (operands[1], BLKmode, 0);
11305 set_mem_size (src, 4);
11306 emit_insn (gen_movua (operands[0], src));
11313 ;; SH2A instructions for bitwise operations.
11315 ;; Clear a bit in a memory location.
11316 (define_insn "bclr_m2a"
11317 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11319 (not:QI (ashift:QI (const_int 1)
11320 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11322 "TARGET_SH2A && TARGET_BITOPS"
11325 bclr.b\\t%1,@(0,%t0)"
11326 [(set_attr "length" "4,4")])
11328 (define_insn "bclrmem_m2a"
11329 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11330 (and:QI (match_dup 0)
11331 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11332 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11335 bclr.b\\t%W1,@(0,%t0)"
11336 [(set_attr "length" "4,4")])
11338 ;; Set a bit in a memory location.
11339 (define_insn "bset_m2a"
11340 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11342 (ashift:QI (const_int 1)
11343 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11345 "TARGET_SH2A && TARGET_BITOPS"
11348 bset.b\\t%1,@(0,%t0)"
11349 [(set_attr "length" "4,4")])
11351 (define_insn "bsetmem_m2a"
11352 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11353 (ior:QI (match_dup 0)
11354 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11355 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11358 bset.b\\t%V1,@(0,%t0)"
11359 [(set_attr "length" "4,4")])
11361 ;;; Transfer the contents of the T bit to a specified bit of memory.
11362 (define_insn "bst_m2a"
11363 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11364 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11366 (not:QI (ashift:QI (const_int 1)
11367 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11370 (ashift:QI (const_int 1) (match_dup 1))
11372 "TARGET_SH2A && TARGET_BITOPS"
11375 bst.b\\t%1,@(0,%t0)"
11376 [(set_attr "length" "4")])
11378 ;; Store a specified bit of memory in the T bit.
11379 (define_insn "bld_m2a"
11380 [(set (reg:SI T_REG)
11382 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11384 (match_operand 1 "const_int_operand" "K03,K03")))]
11385 "TARGET_SH2A && TARGET_BITOPS"
11388 bld.b\\t%1,@(0,%t0)"
11389 [(set_attr "length" "4,4")])
11391 ;; Store a specified bit of memory in the T bit.
11392 (define_insn "bldsign_m2a"
11393 [(set (reg:SI T_REG)
11395 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11397 (match_operand 1 "const_int_operand" "K03,K03")))]
11398 "TARGET_SH2A && TARGET_BITOPS"
11401 bld.b\\t%1,@(0,%t0)"
11402 [(set_attr "length" "4,4")])
11404 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11405 (define_insn "bld_reg"
11406 [(set (reg:SI T_REG)
11407 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11409 (match_operand 1 "const_int_operand" "K03")))]
11413 (define_insn "*bld_regqi"
11414 [(set (reg:SI T_REG)
11415 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11417 (match_operand 1 "const_int_operand" "K03")))]
11421 ;; Take logical and of a specified bit of memory with the T bit and
11422 ;; store its result in the T bit.
11423 (define_insn "band_m2a"
11424 [(set (reg:SI T_REG)
11425 (and:SI (reg:SI T_REG)
11427 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11429 (match_operand 1 "const_int_operand" "K03,K03"))))]
11430 "TARGET_SH2A && TARGET_BITOPS"
11433 band.b\\t%1,@(0,%t0)"
11434 [(set_attr "length" "4,4")])
11436 (define_insn "bandreg_m2a"
11437 [(set (match_operand:SI 0 "register_operand" "=r,r")
11438 (and:SI (zero_extract:SI
11439 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11441 (match_operand 2 "const_int_operand" "K03,K03"))
11442 (match_operand:SI 3 "register_operand" "r,r")))]
11443 "TARGET_SH2A && TARGET_BITOPS"
11445 band.b\\t%2,%1\;movt\\t%0
11446 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11447 [(set_attr "length" "6,6")])
11449 ;; Take logical or of a specified bit of memory with the T bit and
11450 ;; store its result in the T bit.
11451 (define_insn "bor_m2a"
11452 [(set (reg:SI T_REG)
11453 (ior:SI (reg:SI T_REG)
11455 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11457 (match_operand 1 "const_int_operand" "K03,K03"))))]
11458 "TARGET_SH2A && TARGET_BITOPS"
11461 bor.b\\t%1,@(0,%t0)"
11462 [(set_attr "length" "4,4")])
11464 (define_insn "borreg_m2a"
11465 [(set (match_operand:SI 0 "register_operand" "=r,r")
11466 (ior:SI (zero_extract:SI
11467 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11469 (match_operand 2 "const_int_operand" "K03,K03"))
11470 (match_operand:SI 3 "register_operand" "=r,r")))]
11471 "TARGET_SH2A && TARGET_BITOPS"
11473 bor.b\\t%2,%1\;movt\\t%0
11474 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11475 [(set_attr "length" "6,6")])
11477 ;; Take exclusive or of a specified bit of memory with the T bit and
11478 ;; store its result in the T bit.
11479 (define_insn "bxor_m2a"
11480 [(set (reg:SI T_REG)
11481 (xor:SI (reg:SI T_REG)
11483 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11485 (match_operand 1 "const_int_operand" "K03,K03"))))]
11486 "TARGET_SH2A && TARGET_BITOPS"
11489 bxor.b\\t%1,@(0,%t0)"
11490 [(set_attr "length" "4,4")])
11492 (define_insn "bxorreg_m2a"
11493 [(set (match_operand:SI 0 "register_operand" "=r,r")
11494 (xor:SI (zero_extract:SI
11495 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11497 (match_operand 2 "const_int_operand" "K03,K03"))
11498 (match_operand:SI 3 "register_operand" "=r,r")))]
11499 "TARGET_SH2A && TARGET_BITOPS"
11501 bxor.b\\t%2,%1\;movt\\t%0
11502 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11503 [(set_attr "length" "6,6")])
11506 ;; -------------------------------------------------------------------------
11508 ;; -------------------------------------------------------------------------
11509 ;; This matches cases where the bit in a memory location is set.
11511 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11512 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11514 (ior:SI (match_dup 0)
11515 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11517 (match_operand 3 "arith_reg_operand" "r,r"))]
11518 "TARGET_SH2A && TARGET_BITOPS
11519 && satisfies_constraint_Pso (operands[2])
11520 && REGNO (operands[0]) == REGNO (operands[3])"
11521 [(set (match_dup 1)
11522 (ior:QI (match_dup 1)
11526 ;; This matches cases where the bit in a memory location is cleared.
11528 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11529 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11531 (and:SI (match_dup 0)
11532 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11534 (match_operand 3 "arith_reg_operand" "r,r"))]
11535 "TARGET_SH2A && TARGET_BITOPS
11536 && satisfies_constraint_Psz (operands[2])
11537 && REGNO (operands[0]) == REGNO (operands[3])"
11538 [(set (match_dup 1)
11539 (and:QI (match_dup 1)
11543 ;; This matches cases where a stack pointer increment at the start of the
11544 ;; epilogue combines with a stack slot read loading the return value.
11547 [(set (match_operand:SI 0 "arith_reg_operand" "")
11548 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11549 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11550 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11553 ;; See the comment on the dt combiner pattern above.
11556 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11557 (plus:SI (match_dup 0)
11559 (set (reg:SI T_REG)
11560 (eq:SI (match_dup 0)
11565 ;; The following peepholes fold load sequences for which reload was not
11566 ;; able to generate a displacement addressing move insn.
11567 ;; This can happen when reload has to transform a move insn
11568 ;; without displacement into one with displacement. Or when reload can't
11569 ;; fit a displacement into the insn's constraints. In the latter case, the
11570 ;; load destination reg remains at r0, which reload compensates by inserting
11571 ;; another mov insn.
11575 ;; mov.b @(r0,r15),r0
11578 ;; mov.b @(54,r15),r3
11581 [(set (match_operand:SI 0 "arith_reg_dest" "")
11582 (match_operand:SI 1 "const_int_operand" ""))
11583 (set (match_operand:SI 2 "arith_reg_dest" "")
11585 (mem:QI (plus:SI (match_dup 0)
11586 (match_operand:SI 3 "arith_reg_operand" "")))))
11587 (set (match_operand:QI 4 "arith_reg_dest" "")
11588 (match_operand:QI 5 "arith_reg_operand" ""))]
11590 && CONST_OK_FOR_K12 (INTVAL (operands[1]))
11591 && REGNO (operands[2]) == REGNO (operands[5])
11592 && peep2_reg_dead_p (3, operands[5])"
11593 [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
11598 ;; mov.b @(r0,r15),r1
11600 ;; mov.b @(54,r15),r1
11603 [(set (match_operand:SI 0 "arith_reg_dest" "")
11604 (match_operand:SI 1 "const_int_operand" ""))
11605 (set (match_operand:SI 2 "arith_reg_dest" "")
11607 (mem:QI (plus:SI (match_dup 0)
11608 (match_operand:SI 3 "arith_reg_operand" "")))))]
11610 && CONST_OK_FOR_K12 (INTVAL (operands[1]))
11611 && (peep2_reg_dead_p (2, operands[0])
11612 || REGNO (operands[0]) == REGNO (operands[2]))"
11613 [(set (match_dup 2)
11614 (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
11618 ;; mov.b @(r0,r15),r0
11621 ;; mov.b @(r0,r15),r3
11624 [(set (match_operand:SI 0 "arith_reg_dest" "")
11626 (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
11627 (match_operand:SI 2 "arith_reg_operand" "")))))
11628 (set (match_operand:QI 3 "arith_reg_dest" "")
11629 (match_operand:QI 4 "arith_reg_operand" ""))]
11631 && REGNO (operands[0]) == REGNO (operands[4])
11632 && peep2_reg_dead_p (2, operands[0])"
11633 [(set (match_dup 3)
11634 (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
11637 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11638 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11639 ;; reload when the constant is too large for a reg+offset address.
11641 ;; ??? We would get much better code if this was done in reload. This would
11642 ;; require modifying find_reloads_address to recognize that if the constant
11643 ;; is out-of-range for an immediate add, then we get better code by reloading
11644 ;; the constant into a register than by reloading the sum into a register,
11645 ;; since the former is one instruction shorter if the address does not need
11646 ;; to be offsettable. Unfortunately this does not work, because there is
11647 ;; only one register, r0, that can be used as an index register. This register
11648 ;; is also the function return value register. So, if we try to force reload
11649 ;; to use double-reg addresses, then we end up with some instructions that
11650 ;; need to use r0 twice. The only way to fix this is to change the calling
11651 ;; convention so that r0 is not used to return values.
11654 [(set (match_operand:SI 0 "register_operand" "=r")
11655 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11656 (set (mem:SI (match_dup 0))
11657 (match_operand:SI 2 "general_movsrc_operand" ""))]
11658 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11659 "mov.l %2,@(%0,%1)")
11662 [(set (match_operand:SI 0 "register_operand" "=r")
11663 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11664 (set (match_operand:SI 2 "general_movdst_operand" "")
11665 (mem:SI (match_dup 0)))]
11666 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11667 "mov.l @(%0,%1),%2")
11670 [(set (match_operand:SI 0 "register_operand" "=r")
11671 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11672 (set (mem:HI (match_dup 0))
11673 (match_operand:HI 2 "general_movsrc_operand" ""))]
11674 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11675 "mov.w %2,@(%0,%1)")
11678 [(set (match_operand:SI 0 "register_operand" "=r")
11679 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11680 (set (match_operand:HI 2 "general_movdst_operand" "")
11681 (mem:HI (match_dup 0)))]
11682 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11683 "mov.w @(%0,%1),%2")
11686 [(set (match_operand:SI 0 "register_operand" "=r")
11687 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11688 (set (mem:QI (match_dup 0))
11689 (match_operand:QI 2 "general_movsrc_operand" ""))]
11690 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11691 "mov.b %2,@(%0,%1)")
11694 [(set (match_operand:SI 0 "register_operand" "=r")
11695 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11696 (set (match_operand:QI 2 "general_movdst_operand" "")
11697 (mem:QI (match_dup 0)))]
11698 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11699 "mov.b @(%0,%1),%2")
11702 [(set (match_operand:SI 0 "register_operand" "=r")
11703 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11704 (set (mem:SF (match_dup 0))
11705 (match_operand:SF 2 "general_movsrc_operand" ""))]
11706 "TARGET_SH1 && REGNO (operands[0]) == 0
11707 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11708 || (GET_CODE (operands[2]) == SUBREG
11709 && REGNO (SUBREG_REG (operands[2])) < 16))
11710 && reg_unused_after (operands[0], insn)"
11711 "mov.l %2,@(%0,%1)")
11714 [(set (match_operand:SI 0 "register_operand" "=r")
11715 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11716 (set (match_operand:SF 2 "general_movdst_operand" "")
11718 (mem:SF (match_dup 0)))]
11719 "TARGET_SH1 && REGNO (operands[0]) == 0
11720 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11721 || (GET_CODE (operands[2]) == SUBREG
11722 && REGNO (SUBREG_REG (operands[2])) < 16))
11723 && reg_unused_after (operands[0], insn)"
11724 "mov.l @(%0,%1),%2")
11727 [(set (match_operand:SI 0 "register_operand" "=r")
11728 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11729 (set (mem:SF (match_dup 0))
11730 (match_operand:SF 2 "general_movsrc_operand" ""))]
11731 "TARGET_SH2E && REGNO (operands[0]) == 0
11732 && ((REG_P (operands[2])
11733 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11734 || (GET_CODE (operands[2]) == SUBREG
11735 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11736 && reg_unused_after (operands[0], insn)"
11737 "fmov{.s|} %2,@(%0,%1)")
11740 [(set (match_operand:SI 0 "register_operand" "=r")
11741 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11742 (set (match_operand:SF 2 "general_movdst_operand" "")
11744 (mem:SF (match_dup 0)))]
11745 "TARGET_SH2E && REGNO (operands[0]) == 0
11746 && ((REG_P (operands[2])
11747 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11748 || (GET_CODE (operands[2]) == SUBREG
11749 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11750 && reg_unused_after (operands[0], insn)"
11751 "fmov{.s|} @(%0,%1),%2")
11753 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11754 (define_insn "sp_switch_1"
11755 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11758 output_asm_insn ("mov.l r0,@-r15\;mov.l %0,r0", operands);
11759 output_asm_insn ("mov.l @r0,r0\;mov.l r15,@-r0", operands);
11760 return "mov r0,r15";
11762 [(set_attr "length" "10")])
11764 ;; Switch back to the original stack for interrupt functions with the
11765 ;; sp_switch attribute. */
11766 (define_insn "sp_switch_2"
11769 "mov.l @r15+,r15\;mov.l @r15+,r0"
11770 [(set_attr "length" "4")])
11772 ;; Integer vector moves
11774 (define_expand "movv8qi"
11775 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11776 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11779 if (prepare_move_operands (operands, V8QImode))
11783 (define_insn "movv8qi_i"
11784 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11785 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11787 && (register_operand (operands[0], V8QImode)
11788 || sh_register_operand (operands[1], V8QImode))"
11795 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11796 (set_attr "length" "4,4,16,4,4")])
11799 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11800 (subreg:V8QI (const_int 0) 0))]
11802 [(set (match_dup 0)
11803 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11804 (const_int 0) (const_int 0) (const_int 0)
11805 (const_int 0) (const_int 0)]))])
11808 [(set (match_operand 0 "arith_reg_dest" "")
11809 (match_operand 1 "sh_rep_vec" ""))]
11810 "TARGET_SHMEDIA && reload_completed
11811 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11812 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11813 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11814 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11815 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11816 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11817 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11818 [(set (match_dup 0) (match_dup 1))
11821 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11822 rtx elt1 = XVECEXP (operands[1], 0, 1);
11825 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11829 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11830 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11832 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11833 operands[1] = XVECEXP (operands[1], 0, 0);
11836 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11838 = GEN_INT (TARGET_LITTLE_ENDIAN
11839 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11840 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11843 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11845 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11851 [(set (match_operand 0 "arith_reg_dest" "")
11852 (match_operand 1 "sh_const_vec" ""))]
11853 "TARGET_SHMEDIA && reload_completed
11854 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11855 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11856 [(set (match_dup 0) (match_dup 1))]
11858 rtx v = operands[1];
11859 enum machine_mode new_mode
11860 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11862 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11864 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11867 (define_expand "movv2hi"
11868 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11869 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11872 if (prepare_move_operands (operands, V2HImode))
11876 (define_insn "movv2hi_i"
11877 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11878 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11880 && (register_operand (operands[0], V2HImode)
11881 || sh_register_operand (operands[1], V2HImode))"
11888 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11889 (set_attr "length" "4,4,16,4,4")
11890 (set (attr "highpart")
11891 (cond [(match_test "sh_contains_memref_p (insn)")
11892 (const_string "user")]
11893 (const_string "ignore")))])
11895 (define_expand "movv4hi"
11896 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11897 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11900 if (prepare_move_operands (operands, V4HImode))
11904 (define_insn "movv4hi_i"
11905 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11906 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11908 && (register_operand (operands[0], V4HImode)
11909 || sh_register_operand (operands[1], V4HImode))"
11916 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11917 (set_attr "length" "4,4,16,4,4")
11918 (set_attr "highpart" "depend")])
11920 (define_expand "movv2si"
11921 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11922 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11925 if (prepare_move_operands (operands, V2SImode))
11929 (define_insn "movv2si_i"
11930 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11931 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11933 && (register_operand (operands[0], V2SImode)
11934 || sh_register_operand (operands[1], V2SImode))"
11941 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11942 (set_attr "length" "4,4,16,4,4")
11943 (set_attr "highpart" "depend")])
11945 ;; Multimedia Intrinsics
11947 (define_insn "absv2si2"
11948 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11949 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11952 [(set_attr "type" "mcmp_media")
11953 (set_attr "highpart" "depend")])
11955 (define_insn "absv4hi2"
11956 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11957 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11960 [(set_attr "type" "mcmp_media")
11961 (set_attr "highpart" "depend")])
11963 (define_insn "addv2si3"
11964 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11965 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11966 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11968 "madd.l %1, %2, %0"
11969 [(set_attr "type" "arith_media")
11970 (set_attr "highpart" "depend")])
11972 (define_insn "addv4hi3"
11973 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11974 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11975 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11977 "madd.w %1, %2, %0"
11978 [(set_attr "type" "arith_media")
11979 (set_attr "highpart" "depend")])
11981 (define_insn_and_split "addv2hi3"
11982 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11983 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11984 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11990 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11991 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11992 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11993 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11994 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11996 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11997 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12000 [(set_attr "highpart" "must_split")])
12002 (define_insn "ssaddv2si3"
12003 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12004 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12005 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12007 "madds.l %1, %2, %0"
12008 [(set_attr "type" "mcmp_media")
12009 (set_attr "highpart" "depend")])
12011 (define_insn "usaddv8qi3"
12012 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12013 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12014 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12016 "madds.ub %1, %2, %0"
12017 [(set_attr "type" "mcmp_media")
12018 (set_attr "highpart" "depend")])
12020 (define_insn "ssaddv4hi3"
12021 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12022 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12023 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12025 "madds.w %1, %2, %0"
12026 [(set_attr "type" "mcmp_media")
12027 (set_attr "highpart" "depend")])
12029 (define_insn "negcmpeqv8qi"
12030 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12031 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12032 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12034 "mcmpeq.b %N1, %N2, %0"
12035 [(set_attr "type" "mcmp_media")
12036 (set_attr "highpart" "depend")])
12038 (define_insn "negcmpeqv2si"
12039 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12040 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12041 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12043 "mcmpeq.l %N1, %N2, %0"
12044 [(set_attr "type" "mcmp_media")
12045 (set_attr "highpart" "depend")])
12047 (define_insn "negcmpeqv4hi"
12048 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12049 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12050 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12052 "mcmpeq.w %N1, %N2, %0"
12053 [(set_attr "type" "mcmp_media")
12054 (set_attr "highpart" "depend")])
12056 (define_insn "negcmpgtuv8qi"
12057 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12058 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12059 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12061 "mcmpgt.ub %N1, %N2, %0"
12062 [(set_attr "type" "mcmp_media")
12063 (set_attr "highpart" "depend")])
12065 (define_insn "negcmpgtv2si"
12066 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12067 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12068 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12070 "mcmpgt.l %N1, %N2, %0"
12071 [(set_attr "type" "mcmp_media")
12072 (set_attr "highpart" "depend")])
12074 (define_insn "negcmpgtv4hi"
12075 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12076 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12077 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12079 "mcmpgt.w %N1, %N2, %0"
12080 [(set_attr "type" "mcmp_media")
12081 (set_attr "highpart" "depend")])
12083 (define_insn "mcmv"
12084 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12085 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12086 (match_operand:DI 2 "arith_reg_operand" "r"))
12087 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12088 (not:DI (match_dup 2)))))]
12091 [(set_attr "type" "arith_media")
12092 (set_attr "highpart" "depend")])
12094 (define_insn "mcnvs_lw"
12095 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12097 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12098 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12100 "mcnvs.lw %N1, %N2, %0"
12101 [(set_attr "type" "mcmp_media")])
12103 (define_insn "mcnvs_wb"
12104 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12106 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12107 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12109 "mcnvs.wb %N1, %N2, %0"
12110 [(set_attr "type" "mcmp_media")])
12112 (define_insn "mcnvs_wub"
12113 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12115 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12116 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12118 "mcnvs.wub %N1, %N2, %0"
12119 [(set_attr "type" "mcmp_media")])
12121 (define_insn "mextr_rl"
12122 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12123 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12124 (match_operand:HI 3 "mextr_bit_offset" "i"))
12125 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12126 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12127 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12129 static char templ[21];
12130 sprintf (templ, "mextr%d\\t%%N1, %%N2, %%0", (int) INTVAL (operands[3]) >> 3);
12133 [(set_attr "type" "arith_media")])
12135 (define_insn "*mextr_lr"
12136 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12137 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12138 (match_operand:HI 3 "mextr_bit_offset" "i"))
12139 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12140 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12141 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12143 static char templ[21];
12144 sprintf (templ, "mextr%d\\t%%N2, %%N1, %%0", (int) INTVAL (operands[4]) >> 3);
12147 [(set_attr "type" "arith_media")])
12149 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12150 ; vector then varies depending on endianness.
12151 (define_expand "mextr1"
12152 [(match_operand:DI 0 "arith_reg_dest" "")
12153 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12154 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12157 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12158 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12162 (define_expand "mextr2"
12163 [(match_operand:DI 0 "arith_reg_dest" "")
12164 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12165 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12168 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12169 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12173 (define_expand "mextr3"
12174 [(match_operand:DI 0 "arith_reg_dest" "")
12175 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12176 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12179 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12180 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12184 (define_expand "mextr4"
12185 [(match_operand:DI 0 "arith_reg_dest" "")
12186 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12187 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12190 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12191 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12195 (define_expand "mextr5"
12196 [(match_operand:DI 0 "arith_reg_dest" "")
12197 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12198 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12201 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12202 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12206 (define_expand "mextr6"
12207 [(match_operand:DI 0 "arith_reg_dest" "")
12208 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12209 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12212 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12213 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12217 (define_expand "mextr7"
12218 [(match_operand:DI 0 "arith_reg_dest" "")
12219 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12220 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12223 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12224 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12228 (define_expand "mmacfx_wl"
12229 [(match_operand:V2SI 0 "arith_reg_dest" "")
12230 (match_operand:V2HI 1 "extend_reg_operand" "")
12231 (match_operand:V2HI 2 "extend_reg_operand" "")
12232 (match_operand:V2SI 3 "arith_reg_operand" "")]
12235 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12236 operands[1], operands[2]));
12240 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12242 (define_insn "mmacfx_wl_i"
12243 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12245 (match_operand:V2SI 1 "arith_reg_operand" "0")
12250 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12251 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12254 "mmacfx.wl %2, %3, %0"
12255 [(set_attr "type" "mac_media")
12256 (set_attr "highpart" "depend")])
12258 (define_expand "mmacnfx_wl"
12259 [(match_operand:V2SI 0 "arith_reg_dest" "")
12260 (match_operand:V2HI 1 "extend_reg_operand" "")
12261 (match_operand:V2HI 2 "extend_reg_operand" "")
12262 (match_operand:V2SI 3 "arith_reg_operand" "")]
12265 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12266 operands[1], operands[2]));
12270 (define_insn "mmacnfx_wl_i"
12271 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12273 (match_operand:V2SI 1 "arith_reg_operand" "0")
12278 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12279 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12282 "mmacnfx.wl %2, %3, %0"
12283 [(set_attr "type" "mac_media")
12284 (set_attr "highpart" "depend")])
12286 (define_insn "mulv2si3"
12287 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12288 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12289 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12291 "mmul.l %1, %2, %0"
12292 [(set_attr "type" "d2mpy_media")
12293 (set_attr "highpart" "depend")])
12295 (define_insn "mulv4hi3"
12296 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12297 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12298 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12300 "mmul.w %1, %2, %0"
12301 [(set_attr "type" "dmpy_media")
12302 (set_attr "highpart" "depend")])
12304 (define_insn "mmulfx_l"
12305 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12309 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12310 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12313 "mmulfx.l %1, %2, %0"
12314 [(set_attr "type" "d2mpy_media")
12315 (set_attr "highpart" "depend")])
12317 (define_insn "mmulfx_w"
12318 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12322 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12323 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12326 "mmulfx.w %1, %2, %0"
12327 [(set_attr "type" "dmpy_media")
12328 (set_attr "highpart" "depend")])
12330 (define_insn "mmulfxrp_w"
12331 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12336 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12337 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12341 "mmulfxrp.w %1, %2, %0"
12342 [(set_attr "type" "dmpy_media")
12343 (set_attr "highpart" "depend")])
12346 (define_expand "mmulhi_wl"
12347 [(match_operand:V2SI 0 "arith_reg_dest" "")
12348 (match_operand:V4HI 1 "arith_reg_operand" "")
12349 (match_operand:V4HI 2 "arith_reg_operand" "")]
12352 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12353 (operands[0], operands[1], operands[2]));
12357 (define_expand "mmullo_wl"
12358 [(match_operand:V2SI 0 "arith_reg_dest" "")
12359 (match_operand:V4HI 1 "arith_reg_operand" "")
12360 (match_operand:V4HI 2 "arith_reg_operand" "")]
12363 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12364 (operands[0], operands[1], operands[2]));
12368 (define_insn "mmul23_wl"
12369 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12372 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12373 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12374 (parallel [(const_int 2) (const_int 3)])))]
12377 return (TARGET_LITTLE_ENDIAN
12378 ? "mmulhi.wl %1, %2, %0"
12379 : "mmullo.wl %1, %2, %0");
12381 [(set_attr "type" "dmpy_media")
12382 (set (attr "highpart")
12383 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12384 (const_string "user")))])
12386 (define_insn "mmul01_wl"
12387 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12390 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12391 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12392 (parallel [(const_int 0) (const_int 1)])))]
12395 return (TARGET_LITTLE_ENDIAN
12396 ? "mmullo.wl %1, %2, %0"
12397 : "mmulhi.wl %1, %2, %0");
12399 [(set_attr "type" "dmpy_media")
12400 (set (attr "highpart")
12401 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12402 (const_string "user")))])
12405 (define_expand "mmulsum_wq"
12406 [(match_operand:DI 0 "arith_reg_dest" "")
12407 (match_operand:V4HI 1 "arith_reg_operand" "")
12408 (match_operand:V4HI 2 "arith_reg_operand" "")
12409 (match_operand:DI 3 "arith_reg_operand" "")]
12412 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12413 operands[1], operands[2]));
12417 (define_insn "mmulsum_wq_i"
12418 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12419 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12424 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12425 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12426 (parallel [(const_int 0)]))
12427 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12428 (sign_extend:V4DI (match_dup 3)))
12429 (parallel [(const_int 1)])))
12431 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12432 (sign_extend:V4DI (match_dup 3)))
12433 (parallel [(const_int 2)]))
12434 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12435 (sign_extend:V4DI (match_dup 3)))
12436 (parallel [(const_int 3)]))))))]
12438 "mmulsum.wq %2, %3, %0"
12439 [(set_attr "type" "mac_media")])
12441 (define_expand "mperm_w"
12442 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12443 (match_operand:V4HI 1 "arith_reg_operand" "r")
12444 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12447 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12448 (operands[0], operands[1], operands[2]));
12452 ; This use of vec_select isn't exactly correct according to rtl.texi
12453 ; (because not constant), but it seems a straightforward extension.
12454 (define_insn "mperm_w_little"
12455 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12457 (match_operand:V4HI 1 "arith_reg_operand" "r")
12459 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12460 (const_int 2) (const_int 0))
12461 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12462 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12463 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12464 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12465 "mperm.w %1, %N2, %0"
12466 [(set_attr "type" "arith_media")])
12468 (define_insn "mperm_w_big"
12469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12471 (match_operand:V4HI 1 "arith_reg_operand" "r")
12473 [(zero_extract:QI (not:QI (match_operand:QI 2
12474 "extend_reg_or_0_operand" "rZ"))
12475 (const_int 2) (const_int 0))
12476 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12477 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12478 (zero_extract:QI (not:QI (match_dup 2))
12479 (const_int 2) (const_int 6))])))]
12480 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12481 "mperm.w %1, %N2, %0"
12482 [(set_attr "type" "arith_media")])
12484 (define_insn "mperm_w0"
12485 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12486 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12487 "trunc_hi_operand" "r"))))]
12489 "mperm.w %1, r63, %0"
12490 [(set_attr "type" "arith_media")
12491 (set_attr "highpart" "ignore")])
12493 (define_expand "msad_ubq"
12494 [(match_operand:DI 0 "arith_reg_dest" "")
12495 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12496 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12497 (match_operand:DI 3 "arith_reg_operand" "")]
12500 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12501 operands[1], operands[2]));
12505 (define_insn "msad_ubq_i"
12506 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12511 (match_operand:DI 1 "arith_reg_operand" "0")
12512 (abs:DI (vec_select:DI
12515 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12517 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12518 (parallel [(const_int 0)]))))
12519 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12520 (zero_extend:V8DI (match_dup 3)))
12521 (parallel [(const_int 1)]))))
12523 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12524 (zero_extend:V8DI (match_dup 3)))
12525 (parallel [(const_int 2)])))
12526 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12527 (zero_extend:V8DI (match_dup 3)))
12528 (parallel [(const_int 3)])))))
12531 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12532 (zero_extend:V8DI (match_dup 3)))
12533 (parallel [(const_int 4)])))
12534 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12535 (zero_extend:V8DI (match_dup 3)))
12536 (parallel [(const_int 5)]))))
12538 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12539 (zero_extend:V8DI (match_dup 3)))
12540 (parallel [(const_int 6)])))
12541 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12542 (zero_extend:V8DI (match_dup 3)))
12543 (parallel [(const_int 7)])))))))]
12545 "msad.ubq %N2, %N3, %0"
12546 [(set_attr "type" "mac_media")])
12548 (define_insn "mshalds_l"
12549 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12552 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12553 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12554 (const_int 31)))))]
12556 "mshalds.l %1, %2, %0"
12557 [(set_attr "type" "mcmp_media")
12558 (set_attr "highpart" "depend")])
12560 (define_insn "mshalds_w"
12561 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12564 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12565 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12566 (const_int 15)))))]
12568 "mshalds.w %1, %2, %0"
12569 [(set_attr "type" "mcmp_media")
12570 (set_attr "highpart" "depend")])
12572 (define_insn "ashrv2si3"
12573 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12574 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12575 (match_operand:DI 2 "arith_reg_operand" "r")))]
12577 "mshard.l %1, %2, %0"
12578 [(set_attr "type" "arith_media")
12579 (set_attr "highpart" "depend")])
12581 (define_insn "ashrv4hi3"
12582 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12583 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12584 (match_operand:DI 2 "arith_reg_operand" "r")))]
12586 "mshard.w %1, %2, %0"
12587 [(set_attr "type" "arith_media")
12588 (set_attr "highpart" "depend")])
12590 (define_insn "mshards_q"
12591 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12593 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12594 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12596 "mshards.q %1, %N2, %0"
12597 [(set_attr "type" "mcmp_media")])
12599 (define_expand "mshfhi_b"
12600 [(match_operand:V8QI 0 "arith_reg_dest" "")
12601 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12602 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12605 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12606 (operands[0], operands[1], operands[2]));
12610 (define_expand "mshflo_b"
12611 [(match_operand:V8QI 0 "arith_reg_dest" "")
12612 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12613 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12616 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12617 (operands[0], operands[1], operands[2]));
12621 (define_insn "mshf4_b"
12623 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12625 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12626 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12627 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12628 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12631 return (TARGET_LITTLE_ENDIAN
12632 ? "mshfhi.b %N1, %N2, %0"
12633 : "mshflo.b %N1, %N2, %0");
12635 [(set_attr "type" "arith_media")
12636 (set (attr "highpart")
12637 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12638 (const_string "user")))])
12640 (define_insn "mshf0_b"
12642 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12644 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12645 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12646 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12647 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12650 return (TARGET_LITTLE_ENDIAN
12651 ? "mshflo.b %N1, %N2, %0"
12652 : "mshfhi.b %N1, %N2, %0");
12654 [(set_attr "type" "arith_media")
12655 (set (attr "highpart")
12656 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12657 (const_string "user")))])
12659 (define_expand "mshfhi_l"
12660 [(match_operand:V2SI 0 "arith_reg_dest" "")
12661 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12662 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12665 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12666 (operands[0], operands[1], operands[2]));
12670 (define_expand "mshflo_l"
12671 [(match_operand:V2SI 0 "arith_reg_dest" "")
12672 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12673 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12676 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12677 (operands[0], operands[1], operands[2]));
12681 (define_insn "mshf4_l"
12682 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12684 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12685 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12686 (parallel [(const_int 1) (const_int 3)])))]
12689 return (TARGET_LITTLE_ENDIAN
12690 ? "mshfhi.l %N1, %N2, %0"
12691 : "mshflo.l %N1, %N2, %0");
12693 [(set_attr "type" "arith_media")
12694 (set (attr "highpart")
12695 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12696 (const_string "user")))])
12698 (define_insn "mshf0_l"
12699 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12701 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12702 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12703 (parallel [(const_int 0) (const_int 2)])))]
12706 return (TARGET_LITTLE_ENDIAN
12707 ? "mshflo.l %N1, %N2, %0"
12708 : "mshfhi.l %N1, %N2, %0");
12710 [(set_attr "type" "arith_media")
12711 (set (attr "highpart")
12712 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12713 (const_string "user")))])
12715 (define_expand "mshfhi_w"
12716 [(match_operand:V4HI 0 "arith_reg_dest" "")
12717 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12718 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12721 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12722 (operands[0], operands[1], operands[2]));
12726 (define_expand "mshflo_w"
12727 [(match_operand:V4HI 0 "arith_reg_dest" "")
12728 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12729 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12732 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12733 (operands[0], operands[1], operands[2]));
12737 (define_insn "mshf4_w"
12738 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12740 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12741 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12742 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12745 return (TARGET_LITTLE_ENDIAN
12746 ? "mshfhi.w %N1, %N2, %0"
12747 : "mshflo.w %N1, %N2, %0");
12749 [(set_attr "type" "arith_media")
12750 (set (attr "highpart")
12751 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12752 (const_string "user")))])
12754 (define_insn "mshf0_w"
12755 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12757 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12758 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12759 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12762 return (TARGET_LITTLE_ENDIAN
12763 ? "mshflo.w %N1, %N2, %0"
12764 : "mshfhi.w %N1, %N2, %0");
12766 [(set_attr "type" "arith_media")
12767 (set (attr "highpart")
12768 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12769 (const_string "user")))])
12771 (define_insn "mshflo_w_x"
12772 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12774 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12775 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12776 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12778 "mshflo.w %N1, %N2, %0"
12779 [(set_attr "type" "arith_media")
12780 (set_attr "highpart" "ignore")])
12782 ;; These are useful to expand ANDs and as combiner patterns.
12783 (define_insn_and_split "mshfhi_l_di"
12784 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12785 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12787 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12788 (const_int -4294967296))))]
12791 mshfhi.l %N1, %N2, %0
12793 "TARGET_SHMEDIA && reload_completed
12794 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12795 [(set (match_dup 3) (match_dup 4))
12796 (set (match_dup 5) (match_dup 6))]
12798 operands[3] = gen_lowpart (SImode, operands[0]);
12799 operands[4] = gen_highpart (SImode, operands[1]);
12800 operands[5] = gen_highpart (SImode, operands[0]);
12801 operands[6] = gen_highpart (SImode, operands[2]);
12803 [(set_attr "type" "arith_media")])
12805 (define_insn "*mshfhi_l_di_rev"
12806 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12807 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12808 (const_int -4294967296))
12809 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12812 "mshfhi.l %N2, %N1, %0"
12813 [(set_attr "type" "arith_media")])
12816 [(set (match_operand:DI 0 "arith_reg_dest" "")
12817 (ior:DI (zero_extend:DI (match_operand:SI 1
12818 "extend_reg_or_0_operand" ""))
12819 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12820 (const_int -4294967296))))
12821 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12825 emit_insn (gen_ashldi3_media (operands[3],
12826 simplify_gen_subreg (DImode, operands[1],
12829 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12833 (define_insn "mshflo_l_di"
12834 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12835 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12836 (const_int 4294967295))
12837 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12841 "mshflo.l %N1, %N2, %0"
12842 [(set_attr "type" "arith_media")
12843 (set_attr "highpart" "ignore")])
12845 (define_insn "*mshflo_l_di_rev"
12846 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12847 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12849 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12850 (const_int 4294967295))))]
12853 "mshflo.l %N2, %N1, %0"
12854 [(set_attr "type" "arith_media")
12855 (set_attr "highpart" "ignore")])
12857 ;; Combiner pattern for trampoline initialization.
12858 (define_insn_and_split "*double_shori"
12859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12860 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12862 (match_operand:DI 2 "const_int_operand" "n")))]
12864 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12866 "rtx_equal_p (operands[0], operands[1])"
12869 HOST_WIDE_INT v = INTVAL (operands[2]);
12871 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12872 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12875 [(set_attr "highpart" "ignore")])
12878 (define_insn "*mshflo_l_di_x"
12879 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12880 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12882 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12886 "mshflo.l %N1, %N2, %0"
12887 [(set_attr "type" "arith_media")
12888 (set_attr "highpart" "ignore")])
12890 (define_insn_and_split "concat_v2sf"
12891 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12892 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12893 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12894 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12898 mshflo.l %N1, %N2, %0
12901 "TARGET_SHMEDIA && reload_completed
12902 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12903 [(set (match_dup 3) (match_dup 1))
12904 (set (match_dup 4) (match_dup 2))]
12906 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12907 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12909 [(set_attr "type" "arith_media")
12910 (set_attr "highpart" "ignore")])
12912 (define_insn "*mshflo_l_di_x_rev"
12913 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12914 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12916 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12919 "mshflo.l %N2, %N1, %0"
12920 [(set_attr "type" "arith_media")
12921 (set_attr "highpart" "ignore")])
12923 (define_insn "ashlv2si3"
12924 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12925 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12926 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12928 "mshlld.l %1, %2, %0"
12929 [(set_attr "type" "arith_media")
12930 (set_attr "highpart" "depend")])
12933 [(set (match_operand 0 "any_register_operand" "")
12934 (match_operator 3 "shift_operator"
12935 [(match_operand 1 "any_register_operand" "")
12936 (match_operand 2 "shift_count_reg_operand" "")]))]
12937 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12938 [(set (match_dup 0) (match_dup 3))]
12940 rtx count = operands[2];
12941 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12943 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12944 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12945 || GET_CODE (count) == TRUNCATE)
12946 count = XEXP (count, 0);
12947 inner_mode = GET_MODE (count);
12948 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12949 subreg_lowpart_offset (outer_mode, inner_mode));
12950 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12951 operands[1], count);
12954 (define_insn "ashlv4hi3"
12955 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12956 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12957 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12959 "mshlld.w %1, %2, %0"
12960 [(set_attr "type" "arith_media")
12961 (set_attr "highpart" "depend")])
12963 (define_insn "lshrv2si3"
12964 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12965 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12966 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12968 "mshlrd.l %1, %2, %0"
12969 [(set_attr "type" "arith_media")
12970 (set_attr "highpart" "depend")])
12972 (define_insn "lshrv4hi3"
12973 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12974 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12975 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12977 "mshlrd.w %1, %2, %0"
12978 [(set_attr "type" "arith_media")
12979 (set_attr "highpart" "depend")])
12981 (define_insn "subv2si3"
12982 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12983 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12984 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12986 "msub.l %N1, %2, %0"
12987 [(set_attr "type" "arith_media")
12988 (set_attr "highpart" "depend")])
12990 (define_insn "subv4hi3"
12991 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12992 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12993 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12995 "msub.w %N1, %2, %0"
12996 [(set_attr "type" "arith_media")
12997 (set_attr "highpart" "depend")])
12999 (define_insn_and_split "subv2hi3"
13000 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13001 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13002 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13008 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13009 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13010 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13011 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13012 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13014 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13015 emit_insn (gen_truncdisi2 (si_dst, di_dst));
13018 [(set_attr "highpart" "must_split")])
13020 (define_insn "sssubv2si3"
13021 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13022 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13023 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13025 "msubs.l %N1, %2, %0"
13026 [(set_attr "type" "mcmp_media")
13027 (set_attr "highpart" "depend")])
13029 (define_insn "ussubv8qi3"
13030 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13031 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13032 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13034 "msubs.ub %N1, %2, %0"
13035 [(set_attr "type" "mcmp_media")
13036 (set_attr "highpart" "depend")])
13038 (define_insn "sssubv4hi3"
13039 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13040 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13041 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13043 "msubs.w %N1, %2, %0"
13044 [(set_attr "type" "mcmp_media")
13045 (set_attr "highpart" "depend")])
13047 ;; Floating Point Intrinsics
13049 (define_insn "fcosa_s"
13050 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13051 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13055 [(set_attr "type" "atrans_media")])
13057 (define_insn "fsina_s"
13058 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13059 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13063 [(set_attr "type" "atrans_media")])
13065 (define_insn "fipr"
13066 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13067 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13068 "fp_arith_reg_operand" "f")
13069 (match_operand:V4SF 2
13070 "fp_arith_reg_operand" "f"))
13071 (parallel [(const_int 0)]))
13072 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13073 (parallel [(const_int 1)])))
13074 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13075 (parallel [(const_int 2)]))
13076 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13077 (parallel [(const_int 3)])))))]
13079 "fipr.s %1, %2, %0"
13080 [(set_attr "type" "fparith_media")])
13082 (define_insn "fsrra_s"
13083 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13084 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13088 [(set_attr "type" "atrans_media")])
13090 (define_insn "ftrv"
13091 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13095 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13096 (parallel [(const_int 0) (const_int 5)
13097 (const_int 10) (const_int 15)]))
13098 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13100 (vec_select:V4SF (match_dup 1)
13101 (parallel [(const_int 4) (const_int 9)
13102 (const_int 14) (const_int 3)]))
13103 (vec_select:V4SF (match_dup 2)
13104 (parallel [(const_int 1) (const_int 2)
13105 (const_int 3) (const_int 0)]))))
13108 (vec_select:V4SF (match_dup 1)
13109 (parallel [(const_int 8) (const_int 13)
13110 (const_int 2) (const_int 7)]))
13111 (vec_select:V4SF (match_dup 2)
13112 (parallel [(const_int 2) (const_int 3)
13113 (const_int 0) (const_int 1)])))
13115 (vec_select:V4SF (match_dup 1)
13116 (parallel [(const_int 12) (const_int 1)
13117 (const_int 6) (const_int 11)]))
13118 (vec_select:V4SF (match_dup 2)
13119 (parallel [(const_int 3) (const_int 0)
13120 (const_int 1) (const_int 2)]))))))]
13122 "ftrv.s %1, %2, %0"
13123 [(set_attr "type" "fparith_media")])
13125 (define_insn "ldhi_l"
13126 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13128 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13131 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13135 [(set_attr "type" "load_media")])
13137 (define_insn "ldhi_q"
13138 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13140 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13143 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13147 [(set_attr "type" "load_media")])
13149 (define_insn_and_split "*ldhi_q_comb0"
13150 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13152 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13153 "register_operand" "r")
13154 (match_operand:SI 2
13155 "ua_offset" "I06"))
13158 (plus:SI (and:SI (match_dup 1) (const_int 7))
13161 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13166 emit_insn (gen_ldhi_q (operands[0],
13167 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13171 (define_insn_and_split "*ldhi_q_comb1"
13172 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13174 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13175 "register_operand" "r")
13176 (match_operand:SI 2
13177 "ua_offset" "I06"))
13180 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13181 "ua_offset" "I06"))
13185 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13186 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13191 emit_insn (gen_ldhi_q (operands[0],
13192 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13196 (define_insn "ldlo_l"
13197 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13199 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13201 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13202 (and:SI (match_dup 1) (const_int 3))))]
13205 [(set_attr "type" "load_media")])
13207 (define_insn "ldlo_q"
13208 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13210 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13212 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13213 (and:SI (match_dup 1) (const_int 7))))]
13216 [(set_attr "type" "load_media")])
13218 (define_insn_and_split "*ldlo_q_comb0"
13219 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13221 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13222 (match_operand:SI 2 "ua_offset" "I06"))
13224 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13225 (and:SI (match_dup 1) (const_int 7))))]
13226 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13231 emit_insn (gen_ldlo_q (operands[0],
13232 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13236 (define_insn_and_split "*ldlo_q_comb1"
13237 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13239 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13240 (match_operand:SI 2 "ua_offset" "I06"))
13242 (minus:SI (const_int 8)
13243 (and:SI (plus:SI (match_dup 1)
13244 (match_operand:SI 3 "ua_offset" "I06"))
13246 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13247 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13248 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13253 emit_insn (gen_ldlo_q (operands[0],
13254 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13258 (define_insn "sthi_l"
13259 [(set (zero_extract:SI
13260 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13263 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13265 (match_operand:SI 1 "arith_reg_operand" "r"))]
13268 [(set_attr "type" "ustore_media")])
13270 ;; All unaligned stores are considered to be 'narrow' because they typically
13271 ;; operate on less that a quadword, and when they operate on a full quadword,
13272 ;; the vanilla store high / store low sequence will cause a stall if not
13273 ;; scheduled apart.
13274 (define_insn "sthi_q"
13275 [(set (zero_extract:DI
13276 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13279 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13281 (match_operand:DI 1 "arith_reg_operand" "r"))]
13284 [(set_attr "type" "ustore_media")])
13286 (define_insn_and_split "*sthi_q_comb0"
13287 [(set (zero_extract:DI
13288 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13289 "register_operand" "r")
13290 (match_operand:SI 1 "ua_offset"
13294 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13296 (match_operand:DI 2 "arith_reg_operand" "r"))]
13297 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13302 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13307 (define_insn_and_split "*sthi_q_comb1"
13308 [(set (zero_extract:DI
13309 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13310 "register_operand" "r")
13311 (match_operand:SI 1 "ua_offset"
13315 (plus:SI (and:SI (plus:SI (match_dup 0)
13316 (match_operand:SI 2 "ua_offset" "I06"))
13320 (match_operand:DI 3 "arith_reg_operand" "r"))]
13321 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13322 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13327 emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13332 ;; This is highpart user because the address is used as full 64 bit.
13333 (define_insn "stlo_l"
13334 [(set (zero_extract:SI
13335 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13337 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13338 (and:SI (match_dup 0) (const_int 3)))
13339 (match_operand:SI 1 "arith_reg_operand" "r"))]
13342 [(set_attr "type" "ustore_media")])
13344 (define_insn "stlo_q"
13345 [(set (zero_extract:DI
13346 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13348 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13349 (and:SI (match_dup 0) (const_int 7)))
13350 (match_operand:DI 1 "arith_reg_operand" "r"))]
13353 [(set_attr "type" "ustore_media")])
13355 (define_insn_and_split "*stlo_q_comb0"
13356 [(set (zero_extract:DI
13357 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13358 (match_operand:SI 1 "ua_offset" "I06"))
13360 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13361 (and:SI (match_dup 0) (const_int 7)))
13362 (match_operand:DI 2 "arith_reg_operand" "r"))]
13363 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13368 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13373 (define_insn_and_split "*stlo_q_comb1"
13374 [(set (zero_extract:DI
13375 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13376 (match_operand:SI 1 "ua_offset" "I06"))
13378 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13379 (match_operand:SI 2
13380 "ua_offset" "I06"))
13382 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13383 (match_operand:DI 3 "arith_reg_operand" "r"))]
13384 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13389 emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13394 (define_insn "ldhi_l64"
13395 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13397 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13400 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13404 [(set_attr "type" "load_media")])
13406 (define_insn "ldhi_q64"
13407 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13409 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13412 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13416 [(set_attr "type" "load_media")])
13418 (define_insn "ldlo_l64"
13419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13421 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13423 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13424 (and:DI (match_dup 1) (const_int 3))))]
13427 [(set_attr "type" "load_media")])
13429 (define_insn "ldlo_q64"
13430 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13432 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13434 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13435 (and:DI (match_dup 1) (const_int 7))))]
13438 [(set_attr "type" "load_media")])
13440 (define_insn "sthi_l64"
13441 [(set (zero_extract:SI
13442 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13445 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13447 (match_operand:SI 1 "arith_reg_operand" "r"))]
13450 [(set_attr "type" "ustore_media")])
13452 (define_insn "sthi_q64"
13453 [(set (zero_extract:DI
13454 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13457 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13459 (match_operand:DI 1 "arith_reg_operand" "r"))]
13462 [(set_attr "type" "ustore_media")])
13464 (define_insn "stlo_l64"
13465 [(set (zero_extract:SI
13466 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13468 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13469 (and:DI (match_dup 0) (const_int 3)))
13470 (match_operand:SI 1 "arith_reg_operand" "r"))]
13473 [(set_attr "type" "ustore_media")])
13475 (define_insn "stlo_q64"
13476 [(set (zero_extract:DI
13477 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13479 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13480 (and:DI (match_dup 0) (const_int 7)))
13481 (match_operand:DI 1 "arith_reg_operand" "r"))]
13484 [(set_attr "type" "ustore_media")])
13487 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13488 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13492 [(set_attr "type" "arith_media")])
13494 (define_insn "nsbsi"
13495 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13497 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13501 [(set_attr "type" "arith_media")])
13503 (define_insn "nsbdi"
13504 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13506 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13510 [(set_attr "type" "arith_media")])
13512 (define_expand "ffsdi2"
13513 [(set (match_operand:DI 0 "arith_reg_dest" "")
13514 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13517 rtx scratch = gen_reg_rtx (DImode);
13520 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13521 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13522 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13523 emit_insn (gen_nsbdi (scratch, scratch));
13524 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13525 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13526 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13527 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13532 (define_expand "ffssi2"
13533 [(set (match_operand:SI 0 "arith_reg_dest" "")
13534 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13537 rtx scratch = gen_reg_rtx (SImode);
13538 rtx discratch = gen_reg_rtx (DImode);
13541 emit_insn (gen_adddi3 (discratch,
13542 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13544 emit_insn (gen_andcdi3 (discratch,
13545 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13547 emit_insn (gen_nsbsi (scratch, discratch));
13548 last = emit_insn (gen_subsi3 (operands[0],
13549 force_reg (SImode, GEN_INT (63)), scratch));
13550 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13555 (define_insn "byterev"
13556 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13557 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13558 (parallel [(const_int 7) (const_int 6) (const_int 5)
13559 (const_int 4) (const_int 3) (const_int 2)
13560 (const_int 1) (const_int 0)])))]
13563 [(set_attr "type" "arith_media")])
13565 (define_insn "*prefetch_media"
13566 [(prefetch (match_operand:QI 0 "address_operand" "p")
13567 (match_operand:SI 1 "const_int_operand" "n")
13568 (match_operand:SI 2 "const_int_operand" "n"))]
13571 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13572 output_asm_insn ("ld%M0.b %m0,r63", operands);
13575 [(set_attr "type" "other")])
13577 (define_insn "*prefetch_i4"
13578 [(prefetch (match_operand:SI 0 "register_operand" "r")
13579 (match_operand:SI 1 "const_int_operand" "n")
13580 (match_operand:SI 2 "const_int_operand" "n"))]
13581 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13583 [(set_attr "type" "other")])
13585 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13586 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13587 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13588 (define_expand "prefetch"
13589 [(prefetch (match_operand 0 "address_operand" "p")
13590 (match_operand:SI 1 "const_int_operand" "n")
13591 (match_operand:SI 2 "const_int_operand" "n"))]
13592 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13593 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13595 if (GET_MODE (operands[0]) != Pmode
13596 || !CONST_INT_P (operands[1])
13597 || !CONST_INT_P (operands[2]))
13599 if (! TARGET_SHMEDIA)
13600 operands[0] = force_reg (Pmode, operands[0]);
13603 (define_insn "prefetch_m2a"
13604 [(prefetch (match_operand:SI 0 "register_operand" "r")
13605 (match_operand:SI 1 "const_int_operand" "n")
13606 (match_operand:SI 2 "const_int_operand" "n"))]
13609 [(set_attr "type" "other")])
13611 (define_insn "alloco_i"
13612 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13613 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13618 if (GET_CODE (operands[0]) == PLUS)
13620 xops[0] = XEXP (operands[0], 0);
13621 xops[1] = XEXP (operands[0], 1);
13625 xops[0] = operands[0];
13626 xops[1] = const0_rtx;
13628 output_asm_insn ("alloco %0, %1", xops);
13631 [(set_attr "type" "other")])
13634 [(set (match_operand 0 "any_register_operand" "")
13635 (match_operand 1 "" ""))]
13636 "TARGET_SHMEDIA && reload_completed"
13637 [(set (match_dup 0) (match_dup 1))]
13641 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13646 ; Stack Protector Patterns
13648 (define_expand "stack_protect_set"
13649 [(set (match_operand 0 "memory_operand" "")
13650 (match_operand 1 "memory_operand" ""))]
13653 if (TARGET_SHMEDIA)
13655 if (TARGET_SHMEDIA64)
13656 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13658 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13661 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13666 (define_insn "stack_protect_set_si"
13667 [(set (match_operand:SI 0 "memory_operand" "=m")
13668 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13669 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13671 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13672 [(set_attr "type" "other")
13673 (set_attr "length" "6")])
13675 (define_insn "stack_protect_set_si_media"
13676 [(set (match_operand:SI 0 "memory_operand" "=m")
13677 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13678 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13680 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13681 [(set_attr "type" "other")
13682 (set_attr "length" "12")])
13684 (define_insn "stack_protect_set_di_media"
13685 [(set (match_operand:DI 0 "memory_operand" "=m")
13686 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13687 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13689 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13690 [(set_attr "type" "other")
13691 (set_attr "length" "12")])
13693 (define_expand "stack_protect_test"
13694 [(match_operand 0 "memory_operand" "")
13695 (match_operand 1 "memory_operand" "")
13696 (match_operand 2 "" "")]
13699 if (TARGET_SHMEDIA)
13701 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13704 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13705 if (TARGET_SHMEDIA64)
13707 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13709 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13713 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13715 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13720 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13721 emit_jump_insn (gen_branch_true (operands[2]));
13727 (define_insn "stack_protect_test_si"
13728 [(set (reg:SI T_REG)
13729 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13730 (match_operand:SI 1 "memory_operand" "m")]
13732 (set (match_scratch:SI 2 "=&r") (const_int 0))
13733 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13735 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13736 [(set_attr "type" "other")
13737 (set_attr "length" "10")])
13739 (define_insn "stack_protect_test_si_media"
13740 [(set (match_operand:SI 0 "register_operand" "=&r")
13741 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13742 (match_operand:SI 2 "memory_operand" "m")]
13744 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13746 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13747 [(set_attr "type" "other")
13748 (set_attr "length" "16")])
13750 (define_insn "stack_protect_test_di_media"
13751 [(set (match_operand:DI 0 "register_operand" "=&r")
13752 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13753 (match_operand:DI 2 "memory_operand" "m")]
13755 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13757 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13758 [(set_attr "type" "other")
13759 (set_attr "length" "16")])
13761 (include "sync.md")