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:SI 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))
687 if (GET_MODE (operands[0]) == QImode)
688 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
691 ;; Extract single bit, negate and store it in the T bit.
692 ;; Not used for SH4A.
694 (define_insn "tstsi_t_zero_extract_xor"
696 (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
697 (match_operand:SI 3 "const_int_operand"))
698 (match_operand:SI 1 "const_int_operand")
699 (match_operand:SI 2 "const_int_operand")))]
701 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
702 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
704 [(set_attr "type" "mt_group")])
706 ;; Extract single bit, negate and store it in the T bit.
707 ;; Used for SH4A little endian.
709 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
712 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
713 (match_operand:SI 3 "const_int_operand")) 0)
714 (match_operand:SI 1 "const_int_operand")
715 (match_operand:SI 2 "const_int_operand")))]
716 "TARGET_SH1 && TARGET_LITTLE_ENDIAN
717 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
718 == (INTVAL (operands[3]) & 255)
719 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
721 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
724 [(set_attr "type" "mt_group")])
726 ;; Extract single bit, negate and store it in the T bit.
727 ;; Used for SH4A big endian.
729 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
732 (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
733 (match_operand:SI 3 "const_int_operand")) 3)
734 (match_operand:SI 1 "const_int_operand")
735 (match_operand:SI 2 "const_int_operand")))]
736 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
737 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
738 == (INTVAL (operands[3]) & 255)
739 && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
741 operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
744 [(set_attr "type" "mt_group")])
746 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
747 ;; That would still allow reload to create cmpi instructions, but would
748 ;; perhaps allow forcing the constant into a register when that is better.
749 ;; Probably should use r0 for mem/imm compares, but force constant into a
750 ;; register for pseudo/imm compares.
752 (define_insn "cmpeqsi_t"
754 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
755 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
761 [(set_attr "type" "mt_group")])
763 (define_insn "cmpgtsi_t"
765 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
766 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
771 [(set_attr "type" "mt_group")])
773 (define_insn "cmpgesi_t"
775 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
781 [(set_attr "type" "mt_group")])
783 ;; -------------------------------------------------------------------------
784 ;; SImode compare and branch
785 ;; -------------------------------------------------------------------------
787 (define_expand "cbranchsi4"
789 (if_then_else (match_operator 0 "comparison_operator"
790 [(match_operand:SI 1 "arith_operand" "")
791 (match_operand:SI 2 "arith_operand" "")])
792 (label_ref (match_operand 3 "" ""))
794 (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);
805 ;; -------------------------------------------------------------------------
806 ;; SImode unsigned integer comparisons
807 ;; -------------------------------------------------------------------------
809 (define_insn_and_split "cmpgeusi_t"
811 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
812 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
815 "&& 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"
855 enum rtx_code comparison;
859 emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
860 operands[2], operands[3]));
864 else if (!TARGET_CBRANCHDI4)
866 sh_emit_compare_and_branch (operands, DImode);
872 if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
875 comparison = prepare_cbranch_operands (operands, DImode,
876 LAST_AND_UNUSED_RTX_CODE);
877 if (comparison != GET_CODE (operands[0]))
879 = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
880 operands[4] = gen_rtx_SCRATCH (SImode);
884 (define_insn_and_split "cbranchdi4_i"
886 (if_then_else (match_operator 0 "comparison_operator"
887 [(match_operand:DI 1 "arith_operand" "r,r")
888 (match_operand:DI 2 "arith_operand" "rN,I08")])
889 (label_ref (match_operand 3 "" ""))
891 (clobber (match_scratch:SI 4 "=X,&r"))
892 (clobber (reg:SI T_REG))]
895 "&& reload_completed"
899 if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
904 ;; -------------------------------------------------------------------------
905 ;; DImode signed integer comparisons
906 ;; -------------------------------------------------------------------------
910 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
911 (match_operand:DI 1 "arith_operand" "r"))
914 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
916 [(set_attr "length" "6")
917 (set_attr "type" "arith3b")])
919 (define_insn "cmpeqdi_t"
921 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
922 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
925 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
926 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
927 [(set_attr "length" "6")
928 (set_attr "type" "arith3b")])
932 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
933 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
934 ;; If we applied this split when not optimizing, it would only be
935 ;; applied during the machine-dependent reorg, when no new basic blocks
937 "TARGET_SH1 && reload_completed && optimize"
938 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
939 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
940 (label_ref (match_dup 6))
942 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
947 = gen_rtx_REG (SImode,
948 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
950 = (operands[1] == const0_rtx
952 : gen_rtx_REG (SImode,
953 true_regnum (operands[1])
954 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
955 operands[4] = gen_lowpart (SImode, operands[0]);
956 operands[5] = gen_lowpart (SImode, operands[1]);
957 operands[6] = gen_label_rtx ();
960 (define_insn "cmpgtdi_t"
962 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
963 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
966 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
967 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
968 [(set_attr "length" "8")
969 (set_attr "type" "arith3")])
971 (define_insn "cmpgedi_t"
973 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
974 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
977 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
979 [(set_attr "length" "8,2")
980 (set_attr "type" "arith3,mt_group")])
982 ;; -------------------------------------------------------------------------
983 ;; DImode unsigned integer comparisons
984 ;; -------------------------------------------------------------------------
986 (define_insn "cmpgeudi_t"
988 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
989 (match_operand:DI 1 "arith_reg_operand" "r")))]
991 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
992 [(set_attr "length" "8")
993 (set_attr "type" "arith3")])
995 (define_insn "cmpgtudi_t"
997 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
998 (match_operand:DI 1 "arith_reg_operand" "r")))]
1000 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
1001 [(set_attr "length" "8")
1002 (set_attr "type" "arith3")])
1004 (define_insn "cmpeqsi_media"
1005 [(set (match_operand:SI 0 "register_operand" "=r")
1006 (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1007 (match_operand:SI 2 "cmp_operand" "Nr")))]
1010 [(set_attr "type" "cmp_media")])
1012 (define_insn "cmpeqdi_media"
1013 [(set (match_operand:SI 0 "register_operand" "=r")
1014 (eq:SI (match_operand:DI 1 "register_operand" "%r")
1015 (match_operand:DI 2 "cmp_operand" "Nr")))]
1018 [(set_attr "type" "cmp_media")])
1020 (define_insn "cmpgtsi_media"
1021 [(set (match_operand:SI 0 "register_operand" "=r")
1022 (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1023 (match_operand:SI 2 "cmp_operand" "rN")))]
1025 "cmpgt %N1, %N2, %0"
1026 [(set_attr "type" "cmp_media")])
1028 (define_insn "cmpgtdi_media"
1029 [(set (match_operand:SI 0 "register_operand" "=r")
1030 (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1031 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1033 "cmpgt %N1, %N2, %0"
1034 [(set_attr "type" "cmp_media")])
1036 (define_insn "cmpgtusi_media"
1037 [(set (match_operand:SI 0 "register_operand" "=r")
1038 (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1039 (match_operand:SI 2 "cmp_operand" "rN")))]
1041 "cmpgtu %N1, %N2, %0"
1042 [(set_attr "type" "cmp_media")])
1044 (define_insn "cmpgtudi_media"
1045 [(set (match_operand:SI 0 "register_operand" "=r")
1046 (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1047 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1049 "cmpgtu %N1, %N2, %0"
1050 [(set_attr "type" "cmp_media")])
1052 ; These two patterns are for combine.
1053 (define_insn "*cmpne0sisi_media"
1054 [(set (match_operand:SI 0 "register_operand" "=r")
1055 (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1058 [(set_attr "type" "cmp_media")])
1060 ;; -------------------------------------------------------------------------
1061 ;; Conditional move instructions
1062 ;; -------------------------------------------------------------------------
1064 ;; The insn names may seem reversed, but note that cmveq performs the move
1065 ;; if op1 == 0, and cmvne does it if op1 != 0.
1067 (define_insn "movdicc_false"
1068 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1069 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1071 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1072 (match_operand:DI 3 "arith_reg_operand" "0")))]
1075 [(set_attr "type" "arith_media")])
1077 (define_insn "movdicc_true"
1078 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1079 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1081 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1082 (match_operand:DI 3 "arith_reg_operand" "0")))]
1085 [(set_attr "type" "arith_media")])
1088 [(set (match_operand:DI 0 "arith_reg_dest" "")
1089 (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1090 [(match_operand:DI 1 "arith_reg_operand" "")
1092 (match_operand:DI 2 "arith_reg_dest" "")
1094 (set (match_dup 2) (match_dup 0))]
1095 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1097 (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1100 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1101 VOIDmode, operands[1], CONST0_RTX (DImode));
1105 [(set (match_operand:DI 0 "general_movdst_operand" "")
1106 (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1107 (set (match_operand:DI 2 "arith_reg_dest" "")
1108 (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1109 [(match_operand:DI 3 "arith_reg_operand" "")
1113 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1115 (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1118 (define_expand "movdicc"
1119 [(set (match_operand:DI 0 "register_operand" "")
1120 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1121 (match_operand:DI 2 "register_operand" "")
1122 (match_operand:DI 3 "register_operand" "")))]
1126 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1127 && GET_MODE (XEXP (operands[1], 0)) == DImode
1128 && XEXP (operands[1], 1) == const0_rtx)
1132 if (!can_create_pseudo_p ())
1135 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1136 GET_CODE (operands[1]),
1137 XEXP (operands[1], 0),
1138 XEXP (operands[1], 1));
1144 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1145 ;; SImode to DImode.
1146 (define_insn "movsicc_false"
1147 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1148 (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1150 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1151 (match_operand:SI 3 "arith_reg_operand" "0")))]
1154 [(set_attr "type" "arith_media")])
1156 (define_insn "movsicc_true"
1157 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1158 (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1160 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1161 (match_operand:SI 3 "arith_reg_operand" "0")))]
1164 [(set_attr "type" "arith_media")])
1167 [(set (match_operand:SI 0 "arith_reg_dest" "")
1168 (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1169 [(match_operand:SI 1 "arith_reg_operand" "")
1171 (match_operand:SI 2 "arith_reg_dest" "")
1173 (set (match_dup 2) (match_dup 0))]
1174 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1176 (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1179 operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1180 VOIDmode, operands[1], CONST0_RTX (SImode));
1184 [(set (match_operand:SI 0 "general_movdst_operand" "")
1185 (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1186 (set (match_operand:SI 2 "arith_reg_dest" "")
1187 (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1188 [(match_operand:SI 3 "arith_reg_operand" "")
1192 "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1193 && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1195 (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1198 replace_rtx (operands[4], operands[0], operands[1]);
1202 [(set (match_operand 0 "any_register_operand" "")
1203 (match_operand 1 "any_register_operand" ""))
1204 (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1205 (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1206 "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1207 <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1208 && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1209 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1210 && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1211 && ! reg_overlap_mentioned_p (operands[0], operands[3])
1212 && ! reg_overlap_mentioned_p (operands[2], operands[0])
1213 && ! reg_overlap_mentioned_p (operands[0], operands[1])
1214 && (REGNO_REG_CLASS (REGNO (operands[0]))
1215 == REGNO_REG_CLASS (REGNO (operands[2])))
1216 && (REGNO_REG_CLASS (REGNO (operands[1]))
1217 == REGNO_REG_CLASS (REGNO (operands[0])))"
1218 [(set (match_dup 0) (match_dup 3))
1219 (set (match_dup 4) (match_dup 5))]
1222 rtx set1, set2, insn2;
1223 rtx replacements[4];
1225 /* We want to replace occurrences of operands[0] with operands[1] and
1226 operands[2] with operands[0] in operands[4]/operands[5].
1227 Doing just two replace_rtx calls naively would result in the second
1228 replacement undoing all that the first did if operands[1] and operands[2]
1229 are identical, so we must do this simultaneously. */
1230 replacements[0] = operands[0];
1231 replacements[1] = operands[1];
1232 replacements[2] = operands[2];
1233 replacements[3] = operands[0];
1234 if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1235 || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1236 || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1239 operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1240 replace_n_hard_rtx (operands[4], replacements, 2, 1);
1241 operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1242 /* The operands array is aliased to recog_data.operand, which gets
1243 clobbered by extract_insn, so finish with it now. */
1244 set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1245 set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1246 /* ??? The last insn might be a jump insn, but the generic peephole2 code
1247 always uses emit_insn. */
1248 /* Check that we don't violate matching constraints or earlyclobbers. */
1249 extract_insn (emit_insn (set1));
1250 if (! constrain_operands (1))
1252 insn2 = emit (set2);
1253 if (GET_CODE (insn2) == BARRIER)
1255 extract_insn (insn2);
1256 if (! constrain_operands (1))
1260 tmp = replacements[0];
1261 replacements[0] = replacements[1];
1262 replacements[1] = tmp;
1263 tmp = replacements[2];
1264 replacements[2] = replacements[3];
1265 replacements[3] = tmp;
1266 replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1267 replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1268 replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1274 ;; The register allocator is rather clumsy in handling multi-way conditional
1275 ;; moves, so allow the combiner to make them, and we split them up after
1277 (define_insn_and_split "*movsicc_umin"
1278 [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1279 (umin:SI (if_then_else:SI
1280 (eq (match_operand:SI 1 "arith_reg_operand" "r")
1282 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1283 (match_operand:SI 3 "register_operand" "0"))
1284 (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1285 (clobber (match_scratch:SI 5 "=&r"))]
1286 "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1288 "TARGET_SHMEDIA && reload_completed"
1292 emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1294 emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1295 emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1300 (define_insn "*movsicc_t_false"
1301 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1302 (if_then_else (eq (reg:SI T_REG) (const_int 0))
1303 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1304 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1305 "TARGET_PRETEND_CMOVE
1306 && (arith_reg_operand (operands[1], SImode)
1307 || (immediate_operand (operands[1], SImode)
1308 && satisfies_constraint_I08 (operands[1])))"
1309 "bt 0f\;mov %1,%0\\n0:"
1310 [(set_attr "type" "mt_group,arith") ;; poor approximation
1311 (set_attr "length" "4")])
1313 (define_insn "*movsicc_t_true"
1314 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1315 (if_then_else (ne (reg:SI T_REG) (const_int 0))
1316 (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1317 (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1318 "TARGET_PRETEND_CMOVE
1319 && (arith_reg_operand (operands[1], SImode)
1320 || (immediate_operand (operands[1], SImode)
1321 && satisfies_constraint_I08 (operands[1])))"
1322 "bf 0f\;mov %1,%0\\n0:"
1323 [(set_attr "type" "mt_group,arith") ;; poor approximation
1324 (set_attr "length" "4")])
1326 (define_expand "movsicc"
1327 [(set (match_operand:SI 0 "arith_reg_dest" "")
1328 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1329 (match_operand:SI 2 "arith_reg_or_0_operand" "")
1330 (match_operand:SI 3 "arith_reg_operand" "")))]
1331 "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1334 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1335 && GET_MODE (XEXP (operands[1], 0)) == SImode
1337 || (REG_P (XEXP (operands[1], 0))
1338 && REGNO (XEXP (operands[1], 0)) == T_REG))
1339 && XEXP (operands[1], 1) == const0_rtx)
1342 else if (TARGET_PRETEND_CMOVE)
1344 enum rtx_code code = GET_CODE (operands[1]);
1345 enum rtx_code new_code = code;
1346 rtx op0 = XEXP (operands[1], 0);
1347 rtx op1 = XEXP (operands[1], 1);
1349 if (! currently_expanding_to_rtl)
1353 case LT: case LE: case LEU: case LTU:
1354 if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1357 new_code = reverse_condition (code);
1359 case EQ: case GT: case GE: case GEU: case GTU:
1364 sh_emit_scc_to_t (new_code, op0, op1);
1365 operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1366 gen_rtx_REG (SImode, T_REG), const0_rtx);
1370 if (!can_create_pseudo_p ())
1373 operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1374 GET_CODE (operands[1]),
1375 XEXP (operands[1], 0),
1376 XEXP (operands[1], 1));
1382 (define_expand "movqicc"
1383 [(set (match_operand:QI 0 "register_operand" "")
1384 (if_then_else:QI (match_operand 1 "comparison_operator" "")
1385 (match_operand:QI 2 "register_operand" "")
1386 (match_operand:QI 3 "register_operand" "")))]
1390 operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1391 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1392 operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1393 emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1397 ;; -------------------------------------------------------------------------
1398 ;; Addition instructions
1399 ;; -------------------------------------------------------------------------
1401 (define_expand "adddi3"
1402 [(set (match_operand:DI 0 "arith_reg_operand" "")
1403 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1404 (match_operand:DI 2 "arith_operand" "")))]
1410 if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1412 operands[2] = force_reg (DImode, operands[2]);
1413 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1418 (define_insn "*adddi3_media"
1419 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1420 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1421 (match_operand:DI 2 "arith_operand" "r,I10")))]
1426 [(set_attr "type" "arith_media")])
1428 (define_insn "*adddisi3_media"
1429 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1430 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1431 (match_operand:DI 2 "arith_operand" "r,I10")))]
1436 [(set_attr "type" "arith_media")
1437 (set_attr "highpart" "ignore")])
1439 (define_insn "adddi3z_media"
1440 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1442 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1443 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1445 "addz.l %1, %N2, %0"
1446 [(set_attr "type" "arith_media")
1447 (set_attr "highpart" "ignore")])
1449 (define_insn "adddi3_compact"
1450 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1451 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1452 (match_operand:DI 2 "arith_reg_operand" "r")))
1453 (clobber (reg:SI T_REG))]
1456 [(set_attr "length" "6")])
1459 [(set (match_operand:DI 0 "arith_reg_dest" "")
1460 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1461 (match_operand:DI 2 "arith_reg_operand" "")))
1462 (clobber (reg:SI T_REG))]
1463 "TARGET_SH1 && reload_completed"
1467 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1468 high0 = gen_rtx_REG (SImode,
1469 true_regnum (operands[0])
1470 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1471 high2 = gen_rtx_REG (SImode,
1472 true_regnum (operands[2])
1473 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1474 emit_insn (gen_clrt ());
1475 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1476 emit_insn (gen_addc1 (high0, high0, high2));
1481 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1482 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1483 (match_operand:SI 2 "arith_reg_operand" "r"))
1486 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1489 [(set_attr "type" "arith")])
1491 (define_insn "addc1"
1492 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1493 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1494 (match_operand:SI 2 "arith_reg_operand" "r"))
1496 (clobber (reg:SI T_REG))]
1499 [(set_attr "type" "arith")])
1501 (define_expand "addsi3"
1502 [(set (match_operand:SI 0 "arith_reg_operand" "")
1503 (plus:SI (match_operand:SI 1 "arith_operand" "")
1504 (match_operand:SI 2 "arith_operand" "")))]
1509 operands[1] = force_reg (SImode, operands[1]);
1512 (define_insn "addsi3_media"
1513 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1514 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1515 (match_operand:SI 2 "arith_operand" "r,I10")))]
1520 [(set_attr "type" "arith_media")
1521 (set_attr "highpart" "ignore")])
1523 (define_insn "addsidi3_media"
1524 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1525 (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1527 (match_operand:SI 2 "arith_operand"
1533 [(set_attr "type" "arith_media")
1534 (set_attr "highpart" "ignore")])
1536 (define_insn "*addsi3_compact"
1537 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1538 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1539 (match_operand:SI 2 "arith_operand" "rI08")))]
1542 [(set_attr "type" "arith")])
1544 ;; -------------------------------------------------------------------------
1545 ;; Subtraction instructions
1546 ;; -------------------------------------------------------------------------
1548 (define_expand "subdi3"
1549 [(set (match_operand:DI 0 "arith_reg_operand" "")
1550 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1551 (match_operand:DI 2 "arith_reg_operand" "")))]
1557 operands[1] = force_reg (DImode, operands[1]);
1558 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1563 (define_insn "*subdi3_media"
1564 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1565 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1566 (match_operand:DI 2 "arith_reg_operand" "r")))]
1569 [(set_attr "type" "arith_media")])
1571 (define_insn "subdisi3_media"
1572 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1573 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1574 (match_operand:DI 2 "arith_reg_operand" "r")))]
1577 [(set_attr "type" "arith_media")
1578 (set_attr "highpart" "ignore")])
1580 (define_insn "subdi3_compact"
1581 [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1582 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1583 (match_operand:DI 2 "arith_reg_operand" "r")))
1584 (clobber (reg:SI T_REG))]
1587 [(set_attr "length" "6")])
1590 [(set (match_operand:DI 0 "arith_reg_dest" "")
1591 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1592 (match_operand:DI 2 "arith_reg_operand" "")))
1593 (clobber (reg:SI T_REG))]
1594 "TARGET_SH1 && reload_completed"
1598 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1599 high0 = gen_rtx_REG (SImode,
1600 true_regnum (operands[0])
1601 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1602 high2 = gen_rtx_REG (SImode,
1603 true_regnum (operands[2])
1604 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1605 emit_insn (gen_clrt ());
1606 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1607 emit_insn (gen_subc1 (high0, high0, high2));
1612 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1613 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1614 (match_operand:SI 2 "arith_reg_operand" "r"))
1617 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1622 [(set_attr "type" "arith")])
1624 (define_insn "subc1"
1625 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1626 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1627 (match_operand:SI 2 "arith_reg_operand" "r"))
1629 (clobber (reg:SI T_REG))]
1632 [(set_attr "type" "arith")])
1634 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1635 ;; pattern for this case. This helps multimedia applications that compute
1636 ;; the sum of absolute differences.
1637 (define_insn "mov_neg_si_t"
1638 [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1641 [(set_attr "type" "arith")])
1643 (define_insn "*subsi3_internal"
1644 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1645 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1646 (match_operand:SI 2 "arith_reg_operand" "r")))]
1649 [(set_attr "type" "arith")])
1651 (define_insn_and_split "*subsi3_media"
1652 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1653 (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1654 (match_operand:SI 2 "extend_reg_operand" "r")))]
1656 && (operands[1] != constm1_rtx
1657 || (GET_CODE (operands[2]) != TRUNCATE
1658 && GET_CODE (operands[2]) != SUBREG))"
1660 "operands[1] == constm1_rtx"
1661 [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1663 [(set_attr "type" "arith_media")
1664 (set_attr "highpart" "ignore")])
1667 [(set (match_operand:SI 0 "arith_reg_dest" "")
1668 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1669 "general_extend_operand"
1671 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1672 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1673 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1677 [(set (match_operand:SI 0 "arith_reg_dest" "")
1678 (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1679 "general_extend_operand"
1681 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1682 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1683 (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1685 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1686 ;; will sometimes save one instruction. Otherwise we might get
1687 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1690 (define_expand "subsi3"
1691 [(set (match_operand:SI 0 "arith_reg_operand" "")
1692 (minus:SI (match_operand:SI 1 "arith_operand" "")
1693 (match_operand:SI 2 "arith_reg_operand" "")))]
1697 if (TARGET_SH1 && CONST_INT_P (operands[1]))
1699 emit_insn (gen_negsi2 (operands[0], operands[2]));
1700 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1705 if (!can_create_pseudo_p ()
1706 && ! arith_reg_or_0_operand (operands[1], SImode))
1708 if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1709 operands[1] = force_reg (SImode, operands[1]);
1713 ;; -------------------------------------------------------------------------
1714 ;; Division instructions
1715 ;; -------------------------------------------------------------------------
1717 ;; We take advantage of the library routines which don't clobber as many
1718 ;; registers as a normal function call would.
1720 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1721 ;; also has an effect on the register that holds the address of the sfunc.
1722 ;; To make this work, we have an extra dummy insn that shows the use
1723 ;; of this register for reorg.
1725 (define_insn "use_sfunc_addr"
1726 [(set (reg:SI PR_REG)
1727 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1728 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1730 [(set_attr "length" "0")])
1732 (define_insn "udivsi3_sh2a"
1733 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1734 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1735 (match_operand:SI 2 "arith_reg_operand" "z")))]
1738 [(set_attr "type" "arith")
1739 (set_attr "in_delay_slot" "no")])
1741 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1742 ;; hard register 0. If we used hard register 0, then the next instruction
1743 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1744 ;; gets allocated to a stack slot that needs its address reloaded, then
1745 ;; there is nothing to prevent reload from using r0 to reload the address.
1746 ;; This reload would clobber the value in r0 we are trying to store.
1747 ;; If we let reload allocate r0, then this problem can never happen.
1749 (define_insn "udivsi3_i1"
1750 [(set (match_operand:SI 0 "register_operand" "=z")
1751 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1752 (clobber (reg:SI T_REG))
1753 (clobber (reg:SI PR_REG))
1754 (clobber (reg:SI R4_REG))
1755 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1756 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
1758 [(set_attr "type" "sfunc")
1759 (set_attr "needs_delay_slot" "yes")])
1761 ; Since shmedia-nofpu code could be linked against shcompact code, and
1762 ; the udivsi3 libcall has the same name, we must consider all registers
1763 ; clobbered that are in the union of the registers clobbered by the
1764 ; shmedia and the shcompact implementation. Note, if the shcompact
1765 ; implementation actually used shcompact code, we'd need to clobber
1766 ; also r23 and fr23.
1767 (define_insn "udivsi3_i1_media"
1768 [(set (match_operand:SI 0 "register_operand" "=z")
1769 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1770 (clobber (reg:SI T_MEDIA_REG))
1771 (clobber (reg:SI PR_MEDIA_REG))
1772 (clobber (reg:SI R20_REG))
1773 (clobber (reg:SI R21_REG))
1774 (clobber (reg:SI R22_REG))
1775 (clobber (reg:DI TR0_REG))
1776 (clobber (reg:DI TR1_REG))
1777 (clobber (reg:DI TR2_REG))
1778 (use (match_operand 1 "target_reg_operand" "b"))]
1779 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1781 [(set_attr "type" "sfunc")
1782 (set_attr "needs_delay_slot" "yes")])
1784 (define_expand "udivsi3_i4_media"
1786 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1788 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1789 (set (match_dup 5) (float:DF (match_dup 3)))
1790 (set (match_dup 6) (float:DF (match_dup 4)))
1791 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1792 (set (match_dup 8) (fix:DI (match_dup 7)))
1793 (set (match_operand:SI 0 "register_operand" "")
1794 (truncate:SI (match_dup 8)))]
1795 "TARGET_SHMEDIA_FPU"
1798 operands[3] = gen_reg_rtx (DImode);
1799 operands[4] = gen_reg_rtx (DImode);
1800 operands[5] = gen_reg_rtx (DFmode);
1801 operands[6] = gen_reg_rtx (DFmode);
1802 operands[7] = gen_reg_rtx (DFmode);
1803 operands[8] = gen_reg_rtx (DImode);
1806 (define_insn "udivsi3_i4"
1807 [(set (match_operand:SI 0 "register_operand" "=y")
1808 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1809 (clobber (reg:SI T_REG))
1810 (clobber (reg:SI PR_REG))
1811 (clobber (reg:DF DR0_REG))
1812 (clobber (reg:DF DR2_REG))
1813 (clobber (reg:DF DR4_REG))
1814 (clobber (reg:SI R0_REG))
1815 (clobber (reg:SI R1_REG))
1816 (clobber (reg:SI R4_REG))
1817 (clobber (reg:SI R5_REG))
1818 (use (reg:PSI FPSCR_REG))
1819 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1820 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
1822 [(set_attr "type" "sfunc")
1823 (set_attr "fp_mode" "double")
1824 (set_attr "needs_delay_slot" "yes")])
1826 (define_insn "udivsi3_i4_single"
1827 [(set (match_operand:SI 0 "register_operand" "=y")
1828 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829 (clobber (reg:SI T_REG))
1830 (clobber (reg:SI PR_REG))
1831 (clobber (reg:DF DR0_REG))
1832 (clobber (reg:DF DR2_REG))
1833 (clobber (reg:DF DR4_REG))
1834 (clobber (reg:SI R0_REG))
1835 (clobber (reg:SI R1_REG))
1836 (clobber (reg:SI R4_REG))
1837 (clobber (reg:SI R5_REG))
1838 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1839 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
1840 && TARGET_FPU_SINGLE"
1842 [(set_attr "type" "sfunc")
1843 (set_attr "needs_delay_slot" "yes")])
1845 (define_insn "udivsi3_i4_int"
1846 [(set (match_operand:SI 0 "register_operand" "=z")
1847 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1848 (clobber (reg:SI T_REG))
1849 (clobber (reg:SI R1_REG))
1850 (clobber (reg:SI PR_REG))
1851 (clobber (reg:SI MACH_REG))
1852 (clobber (reg:SI MACL_REG))
1853 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1856 [(set_attr "type" "sfunc")
1857 (set_attr "needs_delay_slot" "yes")])
1860 (define_expand "udivsi3"
1861 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1862 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1863 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1864 (parallel [(set (match_operand:SI 0 "register_operand" "")
1865 (udiv:SI (reg:SI R4_REG)
1867 (clobber (reg:SI T_REG))
1868 (clobber (reg:SI PR_REG))
1869 (clobber (reg:SI R4_REG))
1870 (use (match_dup 3))])]
1876 operands[3] = gen_reg_rtx (Pmode);
1877 /* Emit the move of the address to a pseudo outside of the libcall. */
1878 if (TARGET_DIVIDE_CALL_TABLE)
1880 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1881 that causes problems when the divide code is supposed to come from a
1882 separate library. Division by zero is undefined, so dividing 1 can be
1883 implemented by comparing with the divisor. */
1884 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1886 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1887 emit_insn (gen_cstoresi4 (operands[0], test,
1888 operands[1], operands[2]));
1891 else if (operands[2] == const0_rtx)
1893 emit_move_insn (operands[0], operands[2]);
1896 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1897 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1899 else if (TARGET_DIVIDE_CALL_FP)
1901 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1902 if (TARGET_FPU_SINGLE)
1903 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1905 last = gen_udivsi3_i4 (operands[0], operands[3]);
1907 else if (TARGET_SHMEDIA_FPU)
1909 operands[1] = force_reg (SImode, operands[1]);
1910 operands[2] = force_reg (SImode, operands[2]);
1911 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1914 else if (TARGET_SH2A)
1916 operands[1] = force_reg (SImode, operands[1]);
1917 operands[2] = force_reg (SImode, operands[2]);
1918 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1921 else if (TARGET_SH5)
1923 function_symbol (operands[3],
1924 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1928 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1929 else if (TARGET_FPU_ANY)
1930 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1932 last = gen_udivsi3_i1 (operands[0], operands[3]);
1936 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1937 last = gen_udivsi3_i1 (operands[0], operands[3]);
1939 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1940 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1945 (define_insn "divsi3_sh2a"
1946 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1947 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1948 (match_operand:SI 2 "arith_reg_operand" "z")))]
1951 [(set_attr "type" "arith")
1952 (set_attr "in_delay_slot" "no")])
1954 (define_insn "divsi3_i1"
1955 [(set (match_operand:SI 0 "register_operand" "=z")
1956 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1957 (clobber (reg:SI T_REG))
1958 (clobber (reg:SI PR_REG))
1959 (clobber (reg:SI R1_REG))
1960 (clobber (reg:SI R2_REG))
1961 (clobber (reg:SI R3_REG))
1962 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1963 "TARGET_SH1 && TARGET_DIVIDE_CALL_DIV1"
1965 [(set_attr "type" "sfunc")
1966 (set_attr "needs_delay_slot" "yes")])
1968 (define_insn "divsi3_i1_media"
1969 [(set (match_operand:SI 0 "register_operand" "=z")
1970 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1971 (clobber (reg:SI T_MEDIA_REG))
1972 (clobber (reg:SI PR_MEDIA_REG))
1973 (clobber (reg:SI R1_REG))
1974 (clobber (reg:SI R20_REG))
1975 (clobber (reg:SI R21_REG))
1976 (clobber (reg:SI TR0_REG))
1977 (use (match_operand 1 "target_reg_operand" "b"))]
1978 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1980 [(set_attr "type" "sfunc")])
1982 (define_insn "divsi3_media_2"
1983 [(set (match_operand:SI 0 "register_operand" "=z")
1984 (div:SI (reg:SI R4_REG) (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 (use (reg:SI R20_REG))
1991 (use (match_operand 1 "target_reg_operand" "b"))]
1992 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1994 [(set_attr "type" "sfunc")])
1996 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1997 ;; hard reg clobbers and data dependencies that we need when we want
1998 ;; to rematerialize the division into a call.
1999 (define_insn_and_split "divsi_inv_call"
2000 [(set (match_operand:SI 0 "register_operand" "=r")
2001 (div:SI (match_operand:SI 1 "register_operand" "r")
2002 (match_operand:SI 2 "register_operand" "r")))
2003 (clobber (reg:SI R4_REG))
2004 (clobber (reg:SI R5_REG))
2005 (clobber (reg:SI T_MEDIA_REG))
2006 (clobber (reg:SI PR_MEDIA_REG))
2007 (clobber (reg:SI R1_REG))
2008 (clobber (reg:SI R21_REG))
2009 (clobber (reg:SI TR0_REG))
2010 (clobber (reg:SI R20_REG))
2011 (use (match_operand:SI 3 "register_operand" "r"))]
2014 "&& (high_life_started || reload_completed)"
2015 [(set (match_dup 0) (match_dup 3))]
2017 [(set_attr "highpart" "must_split")])
2019 ;; This is the combiner pattern for -mdiv=inv:call .
2020 (define_insn_and_split "*divsi_inv_call_combine"
2021 [(set (match_operand:SI 0 "register_operand" "=z")
2022 (div:SI (match_operand:SI 1 "register_operand" "r")
2023 (match_operand:SI 2 "register_operand" "r")))
2024 (clobber (reg:SI R4_REG))
2025 (clobber (reg:SI R5_REG))
2026 (clobber (reg:SI T_MEDIA_REG))
2027 (clobber (reg:SI PR_MEDIA_REG))
2028 (clobber (reg:SI R1_REG))
2029 (clobber (reg:SI R21_REG))
2030 (clobber (reg:SI TR0_REG))
2031 (clobber (reg:SI R20_REG))
2032 (use (unspec:SI [(match_dup 1)
2033 (match_operand:SI 3 "" "")
2034 (unspec:SI [(match_operand:SI 4 "" "")
2036 (match_operand:DI 5 "" "")]
2038 (match_operand:DI 6 "" "")
2041 UNSPEC_DIV_INV_M3))]
2044 "&& (high_life_started || reload_completed)"
2048 const char *name = sh_divsi3_libfunc;
2049 enum sh_function_kind kind = SFUNC_GOT;
2052 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2053 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2054 while (TARGET_DIVIDE_INV_CALL2)
2056 rtx x = operands[3];
2058 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2060 x = XVECEXP (x, 0, 0);
2061 name = \"__sdivsi3_2\";
2062 kind = SFUNC_STATIC;
2063 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2066 sym = function_symbol (NULL, name, kind);
2067 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2070 [(set_attr "highpart" "must_split")])
2072 (define_expand "divsi3_i4_media"
2073 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2074 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2075 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2076 (set (match_operand:SI 0 "register_operand" "=r")
2077 (fix:SI (match_dup 5)))]
2078 "TARGET_SHMEDIA_FPU"
2081 operands[3] = gen_reg_rtx (DFmode);
2082 operands[4] = gen_reg_rtx (DFmode);
2083 operands[5] = gen_reg_rtx (DFmode);
2086 (define_insn "divsi3_i4"
2087 [(set (match_operand:SI 0 "register_operand" "=y")
2088 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2089 (clobber (reg:SI PR_REG))
2090 (clobber (reg:DF DR0_REG))
2091 (clobber (reg:DF DR2_REG))
2092 (use (reg:PSI FPSCR_REG))
2093 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2094 "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE"
2096 [(set_attr "type" "sfunc")
2097 (set_attr "fp_mode" "double")
2098 (set_attr "needs_delay_slot" "yes")])
2100 (define_insn "divsi3_i4_single"
2101 [(set (match_operand:SI 0 "register_operand" "=y")
2102 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2103 (clobber (reg:SI PR_REG))
2104 (clobber (reg:DF DR0_REG))
2105 (clobber (reg:DF DR2_REG))
2106 (clobber (reg:SI R2_REG))
2107 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2108 "(TARGET_FPU_SINGLE_ONLY || TARGET_FPU_DOUBLE || TARGET_SHCOMPACT)
2109 && TARGET_FPU_SINGLE"
2111 [(set_attr "type" "sfunc")
2112 (set_attr "needs_delay_slot" "yes")])
2114 (define_insn "divsi3_i4_int"
2115 [(set (match_operand:SI 0 "register_operand" "=z")
2116 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2117 (clobber (reg:SI T_REG))
2118 (clobber (reg:SI PR_REG))
2119 (clobber (reg:SI R1_REG))
2120 (clobber (reg:SI MACH_REG))
2121 (clobber (reg:SI MACL_REG))
2122 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2125 [(set_attr "type" "sfunc")
2126 (set_attr "needs_delay_slot" "yes")])
2128 (define_expand "divsi3"
2129 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2130 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2131 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2132 (parallel [(set (match_operand:SI 0 "register_operand" "")
2133 (div:SI (reg:SI R4_REG)
2135 (clobber (reg:SI T_REG))
2136 (clobber (reg:SI PR_REG))
2137 (clobber (reg:SI R1_REG))
2138 (clobber (reg:SI R2_REG))
2139 (clobber (reg:SI R3_REG))
2140 (use (match_dup 3))])]
2146 operands[3] = gen_reg_rtx (Pmode);
2147 /* Emit the move of the address to a pseudo outside of the libcall. */
2148 if (TARGET_DIVIDE_CALL_TABLE)
2150 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2151 last = gen_divsi3_i4_int (operands[0], operands[3]);
2153 else if (TARGET_DIVIDE_CALL_FP)
2155 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2156 if (TARGET_FPU_SINGLE)
2157 last = gen_divsi3_i4_single (operands[0], operands[3]);
2159 last = gen_divsi3_i4 (operands[0], operands[3]);
2161 else if (TARGET_SH2A)
2163 operands[1] = force_reg (SImode, operands[1]);
2164 operands[2] = force_reg (SImode, operands[2]);
2165 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2168 else if (TARGET_DIVIDE_INV)
2170 rtx dividend = operands[1];
2171 rtx divisor = operands[2];
2173 rtx nsb_res = gen_reg_rtx (DImode);
2174 rtx norm64 = gen_reg_rtx (DImode);
2175 rtx tab_ix = gen_reg_rtx (DImode);
2176 rtx norm32 = gen_reg_rtx (SImode);
2177 rtx i92 = force_reg (DImode, GEN_INT (92));
2178 rtx scratch0a = gen_reg_rtx (DImode);
2179 rtx scratch0b = gen_reg_rtx (DImode);
2180 rtx inv0 = gen_reg_rtx (SImode);
2181 rtx scratch1a = gen_reg_rtx (DImode);
2182 rtx scratch1b = gen_reg_rtx (DImode);
2183 rtx shift = gen_reg_rtx (DImode);
2185 rtx inv1 = gen_reg_rtx (SImode);
2186 rtx scratch2a = gen_reg_rtx (DImode);
2187 rtx scratch2b = gen_reg_rtx (SImode);
2188 rtx inv2 = gen_reg_rtx (SImode);
2189 rtx scratch3a = gen_reg_rtx (DImode);
2190 rtx scratch3b = gen_reg_rtx (DImode);
2191 rtx scratch3c = gen_reg_rtx (DImode);
2192 rtx scratch3d = gen_reg_rtx (SImode);
2193 rtx scratch3e = gen_reg_rtx (DImode);
2194 rtx result = gen_reg_rtx (SImode);
2196 if (! arith_reg_or_0_operand (dividend, SImode))
2197 dividend = force_reg (SImode, dividend);
2198 if (! arith_reg_operand (divisor, SImode))
2199 divisor = force_reg (SImode, divisor);
2200 if (flag_pic && Pmode != DImode)
2202 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2203 tab_base = gen_datalabel_ref (tab_base);
2204 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2208 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2209 tab_base = gen_datalabel_ref (tab_base);
2210 tab_base = force_reg (DImode, tab_base);
2212 if (TARGET_DIVIDE_INV20U)
2213 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2215 i2p27 = GEN_INT (0);
2216 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2217 i43 = force_reg (DImode, GEN_INT (43));
2220 emit_insn (gen_nsbdi (nsb_res,
2221 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2222 emit_insn (gen_ashldi3_media (norm64,
2223 gen_rtx_SUBREG (DImode, divisor, 0),
2225 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2226 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2227 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2228 inv0, scratch0a, scratch0b,
2229 scratch1a, scratch1b));
2230 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2231 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2233 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2235 scratch3a, scratch3b, scratch3c,
2236 scratch2a, scratch2b, scratch3d, scratch3e));
2237 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2238 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2239 else if (TARGET_DIVIDE_INV_FP)
2240 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2241 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2242 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2243 gen_reg_rtx (DFmode)));
2245 emit_move_insn (operands[0], result);
2248 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2250 operands[1] = force_reg (SImode, operands[1]);
2251 operands[2] = force_reg (SImode, operands[2]);
2252 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2255 else if (TARGET_SH5)
2257 if (TARGET_DIVIDE_CALL2)
2259 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2260 tab_base = gen_datalabel_ref (tab_base);
2261 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2263 if (TARGET_FPU_ANY && TARGET_SH1)
2264 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2265 else if (TARGET_DIVIDE_CALL2)
2266 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2268 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2271 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2272 (operands[0], operands[3]));
2273 else if (TARGET_FPU_ANY)
2274 last = gen_divsi3_i4_single (operands[0], operands[3]);
2276 last = gen_divsi3_i1 (operands[0], operands[3]);
2280 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2281 last = gen_divsi3_i1 (operands[0], operands[3]);
2283 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2284 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2289 ;; operands: scratch, tab_base, tab_ix
2290 ;; These are unspecs because we could generate an indexed addressing mode
2291 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2292 ;; confuse reload. See PR27117.
2294 (define_insn "divsi_inv_qitable"
2295 [(set (match_operand:DI 0 "register_operand" "=r")
2296 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2297 (match_operand:DI 2 "register_operand" "r")]
2298 UNSPEC_DIV_INV_TABLE)))]
2302 [(set_attr "type" "load_media")
2303 (set_attr "highpart" "user")])
2305 ;; operands: scratch, tab_base, tab_ix
2306 (define_insn "divsi_inv_hitable"
2307 [(set (match_operand:DI 0 "register_operand" "=r")
2308 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2309 (match_operand:DI 2 "register_operand" "r")]
2310 UNSPEC_DIV_INV_TABLE)))]
2314 [(set_attr "type" "load_media")
2315 (set_attr "highpart" "user")])
2317 ;; operands: inv0, tab_base, tab_ix, norm32
2318 ;; scratch equiv in sdivsi3_2: r19, r21
2319 (define_expand "divsi_inv_m0"
2320 [(set (match_operand:SI 0 "register_operand" "=r")
2321 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2322 (match_operand:DI 2 "register_operand" "r")
2323 (match_operand:SI 3 "register_operand" "r")]
2325 (clobber (match_operand:DI 4 "register_operand" "=r"))
2326 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2334 ldx.ub r20, r21, r19 // u0.8
2336 muls.l r25, r19, r19 // s2.38
2337 ldx.w r20, r21, r21 // s2.14
2338 shari r19, 24, r19 // truncate to s2.14
2339 sub r21, r19, r19 // some 11 bit inverse in s1.14
2342 rtx inv0 = operands[0];
2343 rtx tab_base = operands[1];
2344 rtx tab_ix = operands[2];
2345 rtx norm32 = operands[3];
2346 rtx scratch0 = operands[4];
2347 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2348 rtx scratch1 = operands[5];
2350 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2351 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2352 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2353 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2354 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2355 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2359 ;; operands: inv1, tab_base, tab_ix, norm32
2360 (define_insn_and_split "divsi_inv_m1"
2361 [(set (match_operand:SI 0 "register_operand" "=r")
2362 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2363 (match_operand:DI 2 "register_operand" "r")
2364 (match_operand:SI 3 "register_operand" "r")]
2366 (clobber (match_operand:SI 4 "register_operand" "=r"))
2367 (clobber (match_operand:DI 5 "register_operand" "=r"))
2368 (clobber (match_operand:DI 6 "register_operand" "=r"))
2369 (clobber (match_operand:DI 7 "register_operand" "=r"))
2370 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2373 "&& !can_create_pseudo_p ()"
2378 muls.l r19, r19, r18 // u0.28
2379 muls.l r25, r18, r18 // s2.58
2380 shlli r19, 45, r0 // multiply by two and convert to s2.58
2382 shari r18, 28, r18 // some 18 bit inverse in s1.30
2385 rtx inv1 = operands[0];
2386 rtx tab_base = operands[1];
2387 rtx tab_ix = operands[2];
2388 rtx norm32 = operands[3];
2389 rtx inv0 = operands[4];
2390 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2391 rtx scratch0a = operands[5];
2392 rtx scratch0b = operands[6];
2393 rtx scratch0 = operands[7];
2394 rtx scratch1 = operands[8];
2395 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2397 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2398 scratch0a, scratch0b));
2399 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2400 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2401 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2402 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2403 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2407 ;; operands: inv2, norm32, inv1, i92
2408 (define_insn_and_split "divsi_inv_m2"
2409 [(set (match_operand:SI 0 "register_operand" "=r")
2410 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2411 (match_operand:SI 2 "register_operand" "r")
2412 (match_operand:DI 3 "register_operand" "r")]
2414 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2417 "&& !can_create_pseudo_p ()"
2422 muls.l r18, r25, r0 // s2.60
2423 shari r0, 16, r0 // s-16.44
2425 muls.l r0, r18, r19 // s-16.74
2426 shari r19, 30, r19 // s-16.44
2428 rtx inv2 = operands[0];
2429 rtx norm32 = operands[1];
2430 rtx inv1 = operands[2];
2431 rtx i92 = operands[3];
2432 rtx scratch0 = operands[4];
2433 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2435 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2436 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2437 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2438 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2439 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2443 (define_insn_and_split "divsi_inv_m3"
2444 [(set (match_operand:SI 0 "register_operand" "=r")
2445 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2446 (match_operand:SI 2 "register_operand" "r")
2447 (match_operand:SI 3 "register_operand" "r")
2448 (match_operand:DI 4 "register_operand" "r")
2449 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2450 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2452 (clobber (match_operand:DI 7 "register_operand" "=r"))
2453 (clobber (match_operand:DI 8 "register_operand" "=r"))
2454 (clobber (match_operand:DI 9 "register_operand" "=r"))
2455 (clobber (match_operand:DI 10 "register_operand" "=r"))
2456 (clobber (match_operand:SI 11 "register_operand" "=r"))
2457 (clobber (match_operand:SI 12 "register_operand" "=r"))
2458 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2461 "&& !can_create_pseudo_p ()"
2466 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2467 r0: scratch0 r19: scratch1 r21: scratch2
2469 muls.l r18, r4, r25 // s32.30
2470 muls.l r19, r4, r19 // s15.30
2472 shari r19, 14, r19 // s18.-14
2478 rtx result = operands[0];
2479 rtx dividend = operands[1];
2480 rtx inv1 = operands[2];
2481 rtx inv2 = operands[3];
2482 rtx shift = operands[4];
2483 rtx scratch0 = operands[7];
2484 rtx scratch1 = operands[8];
2485 rtx scratch2 = operands[9];
2487 if (satisfies_constraint_N (dividend))
2489 emit_move_insn (result, dividend);
2493 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2494 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2495 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2496 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2497 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2498 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2499 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2503 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2504 ;; inv1: tab_base, tab_ix, norm32
2505 ;; inv2: norm32, inv1, i92
2506 (define_insn_and_split "divsi_inv_m1_3"
2507 [(set (match_operand:SI 0 "register_operand" "=r")
2508 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2509 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2510 (match_operand:DI 3 "register_operand" "r")
2511 (match_operand:SI 4 "register_operand" "r")]
2513 (unspec:SI [(match_dup 4)
2514 (unspec:SI [(match_dup 2)
2516 (match_dup 4)] UNSPEC_DIV_INV_M1)
2517 (match_operand:SI 5 "" "")]
2519 (match_operand:DI 6 "register_operand" "r")
2520 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2521 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2523 (clobber (match_operand:DI 9 "register_operand" "=r"))
2524 (clobber (match_operand:DI 10 "register_operand" "=r"))
2525 (clobber (match_operand:DI 11 "register_operand" "=r"))
2526 (clobber (match_operand:DI 12 "register_operand" "=r"))
2527 (clobber (match_operand:SI 13 "register_operand" "=r"))
2528 (clobber (match_operand:SI 14 "register_operand" "=r"))
2529 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2531 && (TARGET_DIVIDE_INV_MINLAT
2532 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2534 "&& !can_create_pseudo_p ()"
2538 rtx result = operands[0];
2539 rtx dividend = operands[1];
2540 rtx tab_base = operands[2];
2541 rtx tab_ix = operands[3];
2542 rtx norm32 = operands[4];
2543 /* rtx i92 = operands[5]; */
2544 rtx shift = operands[6];
2545 rtx i2p27 = operands[7];
2546 rtx i43 = operands[8];
2547 rtx scratch0 = operands[9];
2548 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2549 rtx scratch1 = operands[10];
2550 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2551 rtx scratch2 = operands[11];
2552 rtx scratch3 = operands[12];
2553 rtx scratch4 = operands[13];
2554 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2555 rtx scratch5 = operands[14];
2556 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2557 rtx scratch6 = operands[15];
2559 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2560 scratch0, scratch1));
2561 /* inv0 == scratch4 */
2562 if (! TARGET_DIVIDE_INV20U)
2564 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2566 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2570 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2571 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2573 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2574 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2575 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2576 /* inv1 == scratch4 */
2578 if (TARGET_DIVIDE_INV_MINLAT)
2580 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2581 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2582 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2583 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2584 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2585 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2586 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2587 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2588 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2589 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2590 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2594 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2595 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2596 emit_insn (gen_nsbdi (scratch6,
2597 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2598 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2599 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2600 emit_insn (gen_divsi_inv20 (scratch2,
2601 norm32, scratch4, dividend,
2602 scratch6, scratch3, i43,
2603 /* scratch0 may be shared with i2p27. */
2604 scratch0, scratch1, scratch5,
2605 label, label, i2p27));
2607 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2608 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2612 (define_insn "divsi_inv20"
2613 [(set (match_operand:DI 0 "register_operand" "=&r")
2614 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2615 (match_operand:SI 2 "register_operand" "r")
2616 (match_operand:SI 3 "register_operand" "r")
2617 (match_operand:DI 4 "register_operand" "r")
2618 (match_operand:DI 5 "register_operand" "r")
2619 (match_operand:DI 6 "register_operand" "r")
2620 (match_operand:DI 12 "register_operand" "r")
2621 (match_operand 10 "target_operand" "b")
2622 (match_operand 11 "immediate_operand" "i")]
2624 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2625 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2626 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2628 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2631 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2632 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2633 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2634 %10 label (tr), %11 label (imm)
2636 muls.l inv1, norm32, scratch0 // s2.60
2637 muls.l inv1, dividend, result // s32.30
2638 xor i2p27, result_sign, round_scratch
2639 bge/u dividend_nsb, i43, tr.. (label)
2640 shari scratch0, 16, scratch0 // s-16.44
2641 muls.l sratch0_si, inv1, scratch0 // s-16.74
2642 sub result, round_scratch, result
2643 shari dividend, 14, scratch1 // s19.-14
2644 shari scratch0, 30, scratch0 // s-16.44
2645 muls.l scratch0, scratch1, round_scratch // s15.30
2647 sub result, round_scratch, result */
2649 int likely = TARGET_DIVIDE_INV20L;
2651 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2652 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2653 output_asm_insn (likely
2654 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2655 : \"bge/u\t%4, %6, %10\", operands);
2656 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2657 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2658 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2660 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2661 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2664 (define_insn_and_split "divsi_inv_fp"
2665 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2666 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2667 (match_operand:SI 2 "register_operand" "rf")))
2668 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2669 (clobber (match_operand:SI 4 "register_operand" "=r"))
2670 (clobber (match_operand:SI 5 "register_operand" "=r"))
2671 (clobber (match_operand:DF 6 "register_operand" "=r"))
2672 (clobber (match_operand:DF 7 "register_operand" "=r"))
2673 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2674 "TARGET_SHMEDIA_FPU"
2676 "&& (high_life_started || reload_completed)"
2677 [(set (match_dup 0) (match_dup 3))]
2679 [(set_attr "highpart" "must_split")])
2681 ;; If a matching group of divide-by-inverse instructions is in the same
2682 ;; basic block after gcse & loop optimizations, we want to transform them
2683 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2684 (define_insn_and_split "*divsi_inv_fp_combine"
2685 [(set (match_operand:SI 0 "register_operand" "=f")
2686 (div:SI (match_operand:SI 1 "register_operand" "f")
2687 (match_operand:SI 2 "register_operand" "f")))
2688 (use (unspec:SI [(match_dup 1)
2689 (match_operand:SI 3 "" "")
2690 (unspec:SI [(match_operand:SI 4 "" "")
2692 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2693 (match_operand:DI 6 "" "")
2695 (const_int 0)] UNSPEC_DIV_INV_M3))
2696 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2697 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2698 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2699 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2700 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2701 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2704 [(set (match_dup 9) (float:DF (match_dup 1)))
2705 (set (match_dup 10) (float:DF (match_dup 2)))
2706 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2708 (fix:SI (match_dup 11)))
2709 (set (match_dup 0) (match_dup 8))]
2712 if (! fp_arith_reg_operand (operands[1], SImode))
2714 emit_move_insn (operands[7], operands[1]);
2715 operands[1] = operands[7];
2717 if (! fp_arith_reg_operand (operands[2], SImode))
2719 emit_move_insn (operands[8], operands[2]);
2720 operands[2] = operands[8];
2723 [(set_attr "highpart" "must_split")])
2725 ;; -------------------------------------------------------------------------
2726 ;; Multiplication instructions
2727 ;; -------------------------------------------------------------------------
2729 (define_insn "umulhisi3_i"
2730 [(set (reg:SI MACL_REG)
2731 (mult:SI (zero_extend:SI
2732 (match_operand:HI 0 "arith_reg_operand" "r"))
2734 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2737 [(set_attr "type" "smpy")])
2739 (define_insn "mulhisi3_i"
2740 [(set (reg:SI MACL_REG)
2741 (mult:SI (sign_extend:SI
2742 (match_operand:HI 0 "arith_reg_operand" "r"))
2744 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2747 [(set_attr "type" "smpy")])
2749 (define_expand "mulhisi3"
2750 [(set (reg:SI MACL_REG)
2751 (mult:SI (sign_extend:SI
2752 (match_operand:HI 1 "arith_reg_operand" ""))
2754 (match_operand:HI 2 "arith_reg_operand" ""))))
2755 (set (match_operand:SI 0 "arith_reg_operand" "")
2762 macl = gen_rtx_REG (SImode, MACL_REG);
2764 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2765 insn = get_insns ();
2767 /* expand_binop can't find a suitable code in umul_widen_optab to
2768 make a REG_EQUAL note from, so make one here.
2769 See also smulsi3_highpart.
2770 ??? Alternatively, we could put this at the calling site of expand_binop,
2771 i.e. expand_expr. */
2772 /* Use emit_libcall_block for loop invariant code motion and to make
2773 a REG_EQUAL note. */
2774 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2779 (define_expand "umulhisi3"
2780 [(set (reg:SI MACL_REG)
2781 (mult:SI (zero_extend:SI
2782 (match_operand:HI 1 "arith_reg_operand" ""))
2784 (match_operand:HI 2 "arith_reg_operand" ""))))
2785 (set (match_operand:SI 0 "arith_reg_operand" "")
2792 macl = gen_rtx_REG (SImode, MACL_REG);
2794 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2795 insn = get_insns ();
2797 /* expand_binop can't find a suitable code in umul_widen_optab to
2798 make a REG_EQUAL note from, so make one here.
2799 See also smulsi3_highpart.
2800 ??? Alternatively, we could put this at the calling site of expand_binop,
2801 i.e. expand_expr. */
2802 /* Use emit_libcall_block for loop invariant code motion and to make
2803 a REG_EQUAL note. */
2804 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2809 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2810 ;; a call to a routine which clobbers known registers.
2813 [(set (match_operand:SI 1 "register_operand" "=z")
2814 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2815 (clobber (reg:SI MACL_REG))
2816 (clobber (reg:SI T_REG))
2817 (clobber (reg:SI PR_REG))
2818 (clobber (reg:SI R3_REG))
2819 (clobber (reg:SI R2_REG))
2820 (clobber (reg:SI R1_REG))
2821 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2824 [(set_attr "type" "sfunc")
2825 (set_attr "needs_delay_slot" "yes")])
2827 (define_expand "mulsi3_call"
2828 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2829 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2830 (parallel[(set (match_operand:SI 0 "register_operand" "")
2831 (mult:SI (reg:SI R4_REG)
2833 (clobber (reg:SI MACL_REG))
2834 (clobber (reg:SI T_REG))
2835 (clobber (reg:SI PR_REG))
2836 (clobber (reg:SI R3_REG))
2837 (clobber (reg:SI R2_REG))
2838 (clobber (reg:SI R1_REG))
2839 (use (match_operand:SI 3 "register_operand" ""))])]
2843 (define_insn "mul_r"
2844 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2845 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2846 (match_operand:SI 2 "arith_reg_operand" "z")))]
2849 [(set_attr "type" "dmpy")])
2851 (define_insn "mul_l"
2852 [(set (reg:SI MACL_REG)
2853 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2854 (match_operand:SI 1 "arith_reg_operand" "r")))]
2857 [(set_attr "type" "dmpy")])
2859 (define_expand "mulsi3"
2860 [(set (reg:SI MACL_REG)
2861 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2862 (match_operand:SI 2 "arith_reg_operand" "")))
2863 (set (match_operand:SI 0 "arith_reg_operand" "")
2870 /* The address must be set outside the libcall,
2871 since it goes into a pseudo. */
2872 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2873 rtx addr = force_reg (SImode, sym);
2874 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2880 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2882 emit_insn (gen_mul_l (operands[1], operands[2]));
2883 /* consec_sets_giv can only recognize the first insn that sets a
2884 giv as the giv insn. So we must tag this also with a REG_EQUAL
2886 emit_insn (gen_movsi_i ((operands[0]), macl));
2891 (define_insn "mulsidi3_i"
2892 [(set (reg:SI MACH_REG)
2896 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2897 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2899 (set (reg:SI MACL_REG)
2900 (mult:SI (match_dup 0)
2904 [(set_attr "type" "dmpy")])
2906 (define_expand "mulsidi3"
2907 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2908 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2909 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2910 "TARGET_SH2 || TARGET_SHMEDIA"
2915 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2921 (define_insn "mulsidi3_media"
2922 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2923 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2924 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2927 [(set_attr "type" "dmpy_media")
2928 (set_attr "highpart" "ignore")])
2930 (define_insn "mulsidi3_compact"
2931 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2933 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2934 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2935 (clobber (reg:SI MACH_REG))
2936 (clobber (reg:SI MACL_REG))]
2941 [(set (match_operand:DI 0 "arith_reg_dest" "")
2943 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2944 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2945 (clobber (reg:SI MACH_REG))
2946 (clobber (reg:SI MACL_REG))]
2951 rtx low_dst = gen_lowpart (SImode, operands[0]);
2952 rtx high_dst = gen_highpart (SImode, operands[0]);
2954 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2956 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2957 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2958 /* We need something to tag the possible REG_EQUAL notes on to. */
2959 emit_move_insn (operands[0], operands[0]);
2963 (define_insn "umulsidi3_i"
2964 [(set (reg:SI MACH_REG)
2968 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2969 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2971 (set (reg:SI MACL_REG)
2972 (mult:SI (match_dup 0)
2976 [(set_attr "type" "dmpy")])
2978 (define_expand "umulsidi3"
2979 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2980 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2981 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2982 "TARGET_SH2 || TARGET_SHMEDIA"
2987 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2993 (define_insn "umulsidi3_media"
2994 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2995 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2996 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2999 [(set_attr "type" "dmpy_media")
3000 (set_attr "highpart" "ignore")])
3002 (define_insn "umulsidi3_compact"
3003 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3005 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3006 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3007 (clobber (reg:SI MACH_REG))
3008 (clobber (reg:SI MACL_REG))]
3013 [(set (match_operand:DI 0 "arith_reg_dest" "")
3014 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3015 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3016 (clobber (reg:SI MACH_REG))
3017 (clobber (reg:SI MACL_REG))]
3022 rtx low_dst = gen_lowpart (SImode, operands[0]);
3023 rtx high_dst = gen_highpart (SImode, operands[0]);
3025 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3027 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3028 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3029 /* We need something to tag the possible REG_EQUAL notes on to. */
3030 emit_move_insn (operands[0], operands[0]);
3034 (define_insn "smulsi3_highpart_i"
3035 [(set (reg:SI MACH_REG)
3039 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3040 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3042 (clobber (reg:SI MACL_REG))]
3045 [(set_attr "type" "dmpy")])
3047 (define_expand "smulsi3_highpart"
3049 [(set (reg:SI MACH_REG)
3053 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3054 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3056 (clobber (reg:SI MACL_REG))])
3057 (set (match_operand:SI 0 "arith_reg_operand" "")
3064 mach = gen_rtx_REG (SImode, MACH_REG);
3066 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3067 insn = get_insns ();
3069 /* expand_binop can't find a suitable code in mul_highpart_optab to
3070 make a REG_EQUAL note from, so make one here.
3071 See also {,u}mulhisi.
3072 ??? Alternatively, we could put this at the calling site of expand_binop,
3073 i.e. expand_mult_highpart. */
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 "umulsi3_highpart_i"
3082 [(set (reg:SI MACH_REG)
3086 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3087 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3089 (clobber (reg:SI MACL_REG))]
3092 [(set_attr "type" "dmpy")])
3094 (define_expand "umulsi3_highpart"
3096 [(set (reg:SI MACH_REG)
3100 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3101 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3103 (clobber (reg:SI MACL_REG))])
3104 (set (match_operand:SI 0 "arith_reg_operand" "")
3111 mach = gen_rtx_REG (SImode, MACH_REG);
3113 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3114 insn = get_insns ();
3116 /* Use emit_libcall_block for loop invariant code motion and to make
3117 a REG_EQUAL note. */
3118 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3123 (define_insn_and_split "muldi3"
3124 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3125 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3126 (match_operand:DI 2 "arith_reg_operand" "r")))
3127 (clobber (match_scratch:DI 3 "=&r"))
3128 (clobber (match_scratch:DI 4 "=r"))]
3135 rtx op3_v2si, op2_v2si;
3137 op3_v2si = operands[3];
3138 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3140 op3_v2si = XEXP (op3_v2si, 0);
3141 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3143 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3144 op2_v2si = operands[2];
3145 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3147 op2_v2si = XEXP (op2_v2si, 0);
3148 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3150 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3151 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3152 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3153 emit_insn (gen_umulsidi3_media (operands[4],
3154 sh_gen_truncate (SImode, operands[1], 0),
3155 sh_gen_truncate (SImode, operands[2], 0)));
3156 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3157 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3158 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3159 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3164 ;; -------------------------------------------------------------------------
3165 ;; Logical operations
3166 ;; -------------------------------------------------------------------------
3168 (define_insn "*andsi3_compact"
3169 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3170 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3171 (match_operand:SI 2 "logical_operand" "K08,r")))]
3174 [(set_attr "type" "arith")])
3176 (define_insn "*andsi3_media"
3177 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3178 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3179 (match_operand:SI 2 "logical_operand" "r,I10")))]
3184 [(set_attr "type" "arith_media")])
3186 (define_insn "*andsi3_bclr"
3187 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3188 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3189 (match_operand:SI 2 "const_int_operand" "Psz")))]
3190 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3192 [(set_attr "type" "arith")])
3194 ;; If the constant is 255, then emit an extu.b instruction instead of an
3195 ;; and, since that will give better code.
3197 (define_expand "andsi3"
3198 [(set (match_operand:SI 0 "arith_reg_operand" "")
3199 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3200 (match_operand:SI 2 "logical_operand" "")))]
3205 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3207 emit_insn (gen_zero_extendqisi2 (operands[0],
3208 gen_lowpart (QImode, operands[1])));
3213 (define_insn_and_split "anddi3"
3214 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3215 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3216 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3223 && ! logical_operand (operands[2], DImode)"
3227 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3228 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3230 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3233 [(set_attr "type" "arith_media")])
3235 (define_insn "andcsi3"
3236 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3237 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3238 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3241 [(set_attr "type" "arith_media")])
3243 (define_insn "andcdi3"
3244 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3245 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3246 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3249 [(set_attr "type" "arith_media")])
3251 (define_expand "iorsi3"
3252 [(set (match_operand:SI 0 "arith_reg_operand" "")
3253 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3254 (match_operand:SI 2 "logical_operand" "")))]
3258 (define_insn "*iorsi3_compact"
3259 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3260 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3261 (match_operand:SI 2 "logical_operand" "r,K08")))]
3263 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3265 [(set_attr "type" "arith")])
3267 (define_insn "*iorsi3_media"
3268 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3269 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3270 (match_operand:SI 2 "logical_operand" "r,I10")))]
3275 [(set_attr "type" "arith_media")])
3277 (define_insn "*iorsi3_bset"
3278 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3279 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3280 (match_operand:SI 2 "const_int_operand" "Pso")))]
3281 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3283 [(set_attr "type" "arith")])
3285 (define_insn "iordi3"
3286 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3287 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3288 (match_operand:DI 2 "logical_operand" "r,I10")))]
3293 [(set_attr "type" "arith_media")])
3295 (define_insn_and_split "*logical_sidi3"
3296 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3297 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3298 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3299 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3302 "&& reload_completed"
3303 [(set (match_dup 0) (match_dup 3))]
3307 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3308 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3309 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3312 (define_insn_and_split "*logical_sidisi3"
3313 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3314 (truncate:SI (sign_extend:DI
3315 (match_operator:SI 3 "logical_operator"
3316 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3317 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3321 [(set (match_dup 0) (match_dup 3))])
3323 (define_insn_and_split "*logical_sidi3_2"
3324 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3325 (sign_extend:DI (truncate:SI (sign_extend:DI
3326 (match_operator:SI 3 "logical_operator"
3327 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3328 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3332 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3334 (define_expand "xorsi3"
3335 [(set (match_operand:SI 0 "arith_reg_operand" "")
3336 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3337 (match_operand:SI 2 "xor_operand" "")))]
3341 (define_insn "*xorsi3_compact"
3342 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3343 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3344 (match_operand:SI 2 "logical_operand" "K08,r")))]
3347 [(set_attr "type" "arith")])
3349 (define_insn "*xorsi3_media"
3350 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3351 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3352 (match_operand:SI 2 "xor_operand" "r,I06")))]
3357 [(set_attr "type" "arith_media")])
3359 ;; Store the complements of the T bit in a register.
3360 (define_insn "xorsi3_movrt"
3361 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3362 (xor:SI (reg:SI T_REG)
3366 [(set_attr "type" "arith")])
3368 (define_insn "xordi3"
3369 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3370 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3371 (match_operand:DI 2 "xor_operand" "r,I06")))]
3376 [(set_attr "type" "arith_media")])
3378 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3379 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3381 [(set (match_operand:DI 0 "arith_reg_dest" "")
3382 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3383 [(match_operand 1 "any_register_operand" "")
3384 (match_operand 2 "any_register_operand" "")])))]
3386 [(set (match_dup 5) (match_dup 4))
3387 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3390 enum machine_mode inmode = GET_MODE (operands[1]);
3393 if (GET_CODE (operands[0]) == SUBREG)
3395 offset = SUBREG_BYTE (operands[0]);
3396 operands[0] = SUBREG_REG (operands[0]);
3398 gcc_assert (REG_P (operands[0]));
3399 if (! TARGET_LITTLE_ENDIAN)
3400 offset += 8 - GET_MODE_SIZE (inmode);
3401 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3404 ;; -------------------------------------------------------------------------
3405 ;; Shifts and rotates
3406 ;; -------------------------------------------------------------------------
3408 (define_expand "rotldi3"
3409 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3410 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3411 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3413 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3415 (define_insn "rotldi3_mextr"
3416 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3417 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3418 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3422 static char templ[16];
3424 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3425 8 - (int) (INTVAL (operands[2]) >> 3));
3428 [(set_attr "type" "arith_media")])
3430 (define_expand "rotrdi3"
3431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3432 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3433 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3435 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3437 (define_insn "rotrdi3_mextr"
3438 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3439 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3440 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3444 static char templ[16];
3446 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3449 [(set_attr "type" "arith_media")])
3452 [(set (match_operand:DI 0 "arith_reg_dest" "")
3453 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3454 "ua_address_operand" "")))
3455 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3457 (clobber (match_operand:DI 3 "register_operand" ""))]
3459 [(match_dup 4) (match_dup 5)]
3462 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3463 (operands[3], operands[1]));
3464 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3465 GEN_INT (56), GEN_INT (8));
3468 (define_insn "rotlsi3_1"
3469 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3473 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3476 [(set_attr "type" "arith")])
3478 (define_insn "rotlsi3_31"
3479 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3480 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3482 (clobber (reg:SI T_REG))]
3485 [(set_attr "type" "arith")])
3487 (define_insn "rotlsi3_16"
3488 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3489 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3493 [(set_attr "type" "arith")])
3495 (define_expand "rotlsi3"
3496 [(set (match_operand:SI 0 "arith_reg_dest" "")
3497 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3498 (match_operand:SI 2 "immediate_operand" "")))]
3502 static const char rot_tab[] = {
3503 000, 000, 000, 000, 000, 000, 010, 001,
3504 001, 001, 011, 013, 003, 003, 003, 003,
3505 003, 003, 003, 003, 003, 013, 012, 002,
3506 002, 002, 010, 000, 000, 000, 000, 000,
3511 if (!CONST_INT_P (operands[2]))
3513 count = INTVAL (operands[2]);
3514 choice = rot_tab[count];
3515 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3521 emit_move_insn (operands[0], operands[1]);
3522 count -= (count & 16) * 2;
3525 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3532 parts[0] = gen_reg_rtx (SImode);
3533 parts[1] = gen_reg_rtx (SImode);
3534 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3535 emit_move_insn (parts[choice-1], operands[1]);
3536 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3537 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3538 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3539 count = (count & ~16) - 8;
3543 for (; count > 0; count--)
3544 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3545 for (; count < 0; count++)
3546 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3551 (define_insn "*rotlhi3_8"
3552 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3553 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3557 [(set_attr "type" "arith")])
3559 (define_expand "rotlhi3"
3560 [(set (match_operand:HI 0 "arith_reg_operand" "")
3561 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3562 (match_operand:HI 2 "immediate_operand" "")))]
3566 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3573 ;; This pattern is used by init_expmed for computing the costs of shift
3576 (define_insn_and_split "ashlsi3_std"
3577 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3578 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3579 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3580 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3581 "(TARGET_SH3 || TARGET_SH2A)
3582 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3588 "(TARGET_SH3 || TARGET_SH2A)
3590 && CONST_INT_P (operands[2])
3591 && ! satisfies_constraint_P27 (operands[2])"
3592 [(set (match_dup 3) (match_dup 2))
3594 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3595 (clobber (match_dup 4))])]
3596 "operands[4] = gen_rtx_SCRATCH (SImode);"
3597 [(set_attr "length" "*,*,*,4")
3598 (set_attr "type" "dyn_shift,arith,arith,arith")])
3600 (define_insn "ashlhi3_k"
3601 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3602 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3603 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3604 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3608 [(set_attr "type" "arith")])
3610 (define_insn "ashlsi3_n"
3611 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3612 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3613 (match_operand:SI 2 "const_int_operand" "n")))
3614 (clobber (reg:SI T_REG))]
3615 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3617 [(set (attr "length")
3618 (cond [(match_test "shift_insns_rtx (insn)")
3620 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3622 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3624 (const_string "8")))
3625 (set_attr "type" "arith")])
3628 [(set (match_operand:SI 0 "arith_reg_dest" "")
3629 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3630 (match_operand:SI 2 "const_int_operand" "")))
3631 (clobber (reg:SI T_REG))]
3632 "TARGET_SH1 && reload_completed"
3633 [(use (reg:SI R0_REG))]
3636 gen_shifty_op (ASHIFT, operands);
3640 (define_insn "ashlsi3_media"
3641 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3642 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3643 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3648 [(set_attr "type" "arith_media")
3649 (set_attr "highpart" "ignore")])
3651 (define_expand "ashlsi3"
3652 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3653 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3654 (match_operand:SI 2 "nonmemory_operand" "")))
3655 (clobber (reg:SI T_REG))])]
3661 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3664 if (CONST_INT_P (operands[2])
3665 && sh_dynamicalize_shift_p (operands[2]))
3666 operands[2] = force_reg (SImode, operands[2]);
3667 if (TARGET_SH3 || TARGET_SH2A)
3669 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3672 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3676 (define_insn "*ashlhi3_n"
3677 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3678 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3679 (match_operand:HI 2 "const_int_operand" "n")))
3680 (clobber (reg:SI T_REG))]
3683 [(set (attr "length")
3684 (cond [(match_test "shift_insns_rtx (insn)")
3686 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3688 (const_string "6")))
3689 (set_attr "type" "arith")])
3691 (define_expand "ashlhi3"
3692 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3693 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3694 (match_operand:SI 2 "nonmemory_operand" "")))
3695 (clobber (reg:SI T_REG))])]
3699 if (!CONST_INT_P (operands[2]))
3701 /* It may be possible to call gen_ashlhi3 directly with more generic
3702 operands. Make sure operands[1] is a HImode register here. */
3703 if (!arith_reg_operand (operands[1], HImode))
3704 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3708 [(set (match_operand:HI 0 "arith_reg_dest" "")
3709 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3710 (match_operand:HI 2 "const_int_operand" "")))
3711 (clobber (reg:SI T_REG))]
3712 "TARGET_SH1 && reload_completed"
3713 [(use (reg:SI R0_REG))]
3716 gen_shifty_hi_op (ASHIFT, operands);
3721 ; arithmetic shift right
3724 (define_insn "ashrsi3_k"
3725 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3726 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3727 (match_operand:SI 2 "const_int_operand" "M")))
3728 (clobber (reg:SI T_REG))]
3729 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3731 [(set_attr "type" "arith")])
3733 ;; We can't do HImode right shifts correctly unless we start out with an
3734 ;; explicit zero / sign extension; doing that would result in worse overall
3735 ;; code, so just let the machine independent code widen the mode.
3736 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3739 ;; ??? This should be a define expand.
3741 (define_insn "ashrsi2_16"
3742 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3743 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3747 [(set_attr "length" "4")])
3750 [(set (match_operand:SI 0 "arith_reg_dest" "")
3751 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3754 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3755 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3756 "operands[2] = gen_lowpart (HImode, operands[0]);")
3758 ;; ??? This should be a define expand.
3760 (define_insn "ashrsi2_31"
3761 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3762 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3764 (clobber (reg:SI T_REG))]
3767 [(set_attr "length" "4")])
3770 [(set (match_operand:SI 0 "arith_reg_dest" "")
3771 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3773 (clobber (reg:SI T_REG))]
3778 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3779 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3784 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3786 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3788 && peep2_reg_dead_p (2, operands[0])
3789 && peep2_reg_dead_p (2, operands[1])"
3793 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3797 (define_insn "ashlsi_c"
3798 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3799 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3801 (lt:SI (match_dup 1) (const_int 0)))]
3804 [(set_attr "type" "arith")])
3806 (define_insn "*ashlsi_c_void"
3807 [(set (reg:SI T_REG)
3808 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3809 (clobber (match_scratch:SI 1 "=0"))]
3810 "TARGET_SH1 && cse_not_expected"
3812 [(set_attr "type" "arith")])
3814 (define_insn "ashrsi3_d"
3815 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3816 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3817 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3818 "TARGET_SH3 || TARGET_SH2A"
3820 [(set_attr "type" "dyn_shift")])
3822 (define_insn "ashrsi3_n"
3823 [(set (reg:SI R4_REG)
3824 (ashiftrt:SI (reg:SI R4_REG)
3825 (match_operand:SI 0 "const_int_operand" "i")))
3826 (clobber (reg:SI T_REG))
3827 (clobber (reg:SI PR_REG))
3828 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3831 [(set_attr "type" "sfunc")
3832 (set_attr "needs_delay_slot" "yes")])
3834 (define_insn "ashrsi3_media"
3835 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3836 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3837 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3842 [(set_attr "type" "arith_media")
3843 (set_attr "highpart" "ignore")])
3845 (define_expand "ashrsi3"
3846 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3847 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3848 (match_operand:SI 2 "nonmemory_operand" "")))
3849 (clobber (reg:SI T_REG))])]
3855 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3858 if (expand_ashiftrt (operands))
3864 ;; logical shift right
3866 (define_insn "lshrsi3_d"
3867 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3868 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3869 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3870 "TARGET_SH3 || TARGET_SH2A"
3872 [(set_attr "type" "dyn_shift")])
3874 ;; Only the single bit shift clobbers the T bit.
3876 (define_insn "lshrsi3_m"
3877 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3878 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3879 (match_operand:SI 2 "const_int_operand" "M")))
3880 (clobber (reg:SI T_REG))]
3881 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3883 [(set_attr "type" "arith")])
3885 (define_insn "lshrsi3_k"
3886 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3887 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3888 (match_operand:SI 2 "const_int_operand" "P27")))]
3889 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3890 && ! satisfies_constraint_M (operands[2])"
3892 [(set_attr "type" "arith")])
3894 (define_insn "lshrsi3_n"
3895 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3896 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3897 (match_operand:SI 2 "const_int_operand" "n")))
3898 (clobber (reg:SI T_REG))]
3899 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3901 [(set (attr "length")
3902 (cond [(match_test "shift_insns_rtx (insn)")
3904 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3906 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3908 (const_string "8")))
3909 (set_attr "type" "arith")])
3912 [(set (match_operand:SI 0 "arith_reg_dest" "")
3913 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3914 (match_operand:SI 2 "const_int_operand" "")))
3915 (clobber (reg:SI T_REG))]
3916 "TARGET_SH1 && reload_completed"
3917 [(use (reg:SI R0_REG))]
3920 gen_shifty_op (LSHIFTRT, operands);
3924 (define_insn "lshrsi3_media"
3925 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3926 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3927 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3932 [(set_attr "type" "arith_media")
3933 (set_attr "highpart" "ignore")])
3935 (define_expand "lshrsi3"
3936 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3937 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3938 (match_operand:SI 2 "nonmemory_operand" "")))
3939 (clobber (reg:SI T_REG))])]
3945 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3948 if (CONST_INT_P (operands[2])
3949 && sh_dynamicalize_shift_p (operands[2]))
3950 operands[2] = force_reg (SImode, operands[2]);
3951 if ((TARGET_SH3 || TARGET_SH2A)
3952 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3954 rtx count = copy_to_mode_reg (SImode, operands[2]);
3955 emit_insn (gen_negsi2 (count, count));
3956 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3959 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3963 ;; ??? This should be a define expand.
3965 (define_insn "ashldi3_k"
3966 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3967 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3969 (clobber (reg:SI T_REG))]
3971 "shll %R0\;rotcl %S0"
3972 [(set_attr "length" "4")
3973 (set_attr "type" "arith")])
3975 ;; Expander for DImode shift left with SImode operations.
3977 (define_expand "ashldi3_std"
3978 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3979 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3980 (match_operand:DI 2 "const_int_operand" "n")))]
3981 "TARGET_SH1 && INTVAL (operands[2]) < 32"
3984 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3985 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3986 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3987 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3988 rtx dst = gen_reg_rtx (DImode);
3989 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3990 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3993 tmp0 = gen_reg_rtx (SImode);
3994 tmp1 = gen_reg_rtx (SImode);
3995 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3996 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
3997 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
3998 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3999 emit_move_insn (operands[0], dst);
4003 (define_insn "ashldi3_media"
4004 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4005 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4006 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4011 [(set_attr "type" "arith_media")])
4013 (define_insn "*ashldisi3_media"
4014 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4015 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4016 (match_operand:DI 2 "const_int_operand" "n")))]
4017 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4018 "shlli.l %1, %2, %0"
4019 [(set_attr "type" "arith_media")
4020 (set_attr "highpart" "ignore")])
4022 (define_expand "ashldi3"
4023 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4024 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4025 (match_operand:DI 2 "immediate_operand" "")))
4026 (clobber (reg:SI T_REG))])]
4032 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4035 if (CONST_INT_P (operands[2])
4036 && INTVAL (operands[2]) == 1)
4038 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4041 else if (CONST_INT_P (operands[2])
4042 && INTVAL (operands[2]) < 32)
4044 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4051 ;; ??? This should be a define expand.
4053 (define_insn "lshrdi3_k"
4054 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4055 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4057 (clobber (reg:SI T_REG))]
4059 "shlr %S0\;rotcr %R0"
4060 [(set_attr "length" "4")
4061 (set_attr "type" "arith")])
4063 (define_insn "lshrdi3_media"
4064 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4065 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4066 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4068 && (arith_reg_dest (operands[0], DImode)
4069 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4073 [(set_attr "type" "arith_media")])
4075 (define_insn "*lshrdisi3_media"
4076 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4077 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4078 (match_operand:DI 2 "const_int_operand" "n")))]
4079 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4080 "shlri.l %1, %2, %0"
4081 [(set_attr "type" "arith_media")
4082 (set_attr "highpart" "ignore")])
4084 (define_expand "lshrdi3"
4085 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4086 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4087 (match_operand:DI 2 "immediate_operand" "")))
4088 (clobber (reg:SI T_REG))])]
4094 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4097 if (!CONST_INT_P (operands[2])
4098 || INTVAL (operands[2]) != 1)
4102 ;; ??? This should be a define expand.
4104 (define_insn "ashrdi3_k"
4105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4106 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4108 (clobber (reg:SI T_REG))]
4110 "shar %S0\;rotcr %R0"
4111 [(set_attr "length" "4")
4112 (set_attr "type" "arith")])
4114 (define_insn "ashrdi3_media"
4115 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4116 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4117 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4119 && (arith_reg_dest (operands[0], DImode)
4120 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4124 [(set_attr "type" "arith_media")])
4126 (define_insn "*ashrdisi3_media"
4127 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4128 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4129 (match_operand:DI 2 "const_int_operand" "n")))]
4130 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4131 "shari.l %1, %2, %0"
4132 [(set_attr "type" "arith_media")
4133 (set_attr "highpart" "ignore")])
4135 (define_insn "ashrdisi3_media_high"
4136 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4138 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4139 (match_operand:DI 2 "const_int_operand" "n"))))]
4140 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4142 [(set_attr "type" "arith_media")])
4144 (define_insn "ashrdisi3_media_opaque"
4145 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4146 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4147 (match_operand:DI 2 "const_int_operand" "n")]
4151 [(set_attr "type" "arith_media")])
4153 (define_expand "ashrdi3"
4154 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4155 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4156 (match_operand:DI 2 "immediate_operand" "")))
4157 (clobber (reg:SI T_REG))])]
4163 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4166 if (!CONST_INT_P (operands[2])
4167 || INTVAL (operands[2]) != 1)
4171 ;; combined left/right shift
4174 [(set (match_operand:SI 0 "register_operand" "")
4175 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4176 (match_operand:SI 2 "const_int_operand" ""))
4177 (match_operand:SI 3 "const_int_operand" "")))]
4178 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4179 [(use (reg:SI R0_REG))]
4180 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4184 [(set (match_operand:SI 0 "register_operand" "")
4185 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4186 (match_operand:SI 2 "const_int_operand" ""))
4187 (match_operand:SI 3 "const_int_operand" "")))
4188 (clobber (reg:SI T_REG))]
4189 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4190 [(use (reg:SI R0_REG))]
4191 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4195 [(set (match_operand:SI 0 "register_operand" "=r")
4196 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4197 (match_operand:SI 2 "const_int_operand" "n"))
4198 (match_operand:SI 3 "const_int_operand" "n")))
4199 (clobber (reg:SI T_REG))]
4200 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4202 [(set (attr "length")
4203 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4205 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4207 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4209 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4211 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4213 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4215 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4216 (const_string "16")]
4217 (const_string "18")))
4218 (set_attr "type" "arith")])
4221 [(set (match_operand:SI 0 "register_operand" "=z")
4222 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4223 (match_operand:SI 2 "const_int_operand" "n"))
4224 (match_operand:SI 3 "const_int_operand" "n")))
4225 (clobber (reg:SI T_REG))]
4226 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4228 [(set (attr "length")
4229 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4231 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4233 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4235 (const_string "10")))
4236 (set_attr "type" "arith")])
4238 ;; shift left / and combination with a scratch register: The combine pass
4239 ;; does not accept the individual instructions, even though they are
4240 ;; cheap. But it needs a precise description so that it is usable after
4242 (define_insn "and_shl_scratch"
4243 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4247 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4248 (match_operand:SI 2 "const_int_operand" "N,n"))
4249 (match_operand:SI 3 "" "0,r"))
4250 (match_operand:SI 4 "const_int_operand" "n,n"))
4251 (match_operand:SI 5 "const_int_operand" "n,n")))
4252 (clobber (reg:SI T_REG))]
4255 [(set (attr "length")
4256 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4258 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4260 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4262 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4263 (const_string "10")]
4264 (const_string "12")))
4265 (set_attr "type" "arith")])
4268 [(set (match_operand:SI 0 "register_operand" "")
4272 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4273 (match_operand:SI 2 "const_int_operand" ""))
4274 (match_operand:SI 3 "register_operand" ""))
4275 (match_operand:SI 4 "const_int_operand" ""))
4276 (match_operand:SI 5 "const_int_operand" "")))
4277 (clobber (reg:SI T_REG))]
4279 [(use (reg:SI R0_REG))]
4282 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4284 if (INTVAL (operands[2]))
4286 gen_shifty_op (LSHIFTRT, operands);
4288 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4289 operands[2] = operands[4];
4290 gen_shifty_op (ASHIFT, operands);
4291 if (INTVAL (operands[5]))
4293 operands[2] = operands[5];
4294 gen_shifty_op (LSHIFTRT, operands);
4299 ;; signed left/right shift combination.
4301 [(set (match_operand:SI 0 "register_operand" "")
4303 (ashift:SI (match_operand:SI 1 "register_operand" "")
4304 (match_operand:SI 2 "const_int_operand" ""))
4305 (match_operand:SI 3 "const_int_operand" "")
4307 (clobber (reg:SI T_REG))]
4309 [(use (reg:SI R0_REG))]
4310 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4313 (define_insn "shl_sext_ext"
4314 [(set (match_operand:SI 0 "register_operand" "=r")
4316 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4317 (match_operand:SI 2 "const_int_operand" "n"))
4318 (match_operand:SI 3 "const_int_operand" "n")
4320 (clobber (reg:SI T_REG))]
4321 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4323 [(set (attr "length")
4324 (cond [(match_test "shl_sext_length (insn)")
4326 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4328 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4330 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4332 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4334 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4336 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4338 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4339 (const_string "16")]
4340 (const_string "18")))
4341 (set_attr "type" "arith")])
4343 (define_insn "shl_sext_sub"
4344 [(set (match_operand:SI 0 "register_operand" "=z")
4346 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4347 (match_operand:SI 2 "const_int_operand" "n"))
4348 (match_operand:SI 3 "const_int_operand" "n")
4350 (clobber (reg:SI T_REG))]
4351 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4353 [(set (attr "length")
4354 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4356 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4358 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4360 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4361 (const_string "12")]
4362 (const_string "14")))
4363 (set_attr "type" "arith")])
4365 ;; These patterns are found in expansions of DImode shifts by 16, and
4366 ;; allow the xtrct instruction to be generated from C source.
4368 (define_insn "xtrct_left"
4369 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4370 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4372 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4376 [(set_attr "type" "arith")])
4378 (define_insn "xtrct_right"
4379 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4380 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4382 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4386 [(set_attr "type" "arith")])
4388 ;; -------------------------------------------------------------------------
4390 ;; -------------------------------------------------------------------------
4393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4394 (neg:SI (plus:SI (reg:SI T_REG)
4395 (match_operand:SI 1 "arith_reg_operand" "r"))))
4397 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4401 [(set_attr "type" "arith")])
4403 (define_insn "*negdi_media"
4404 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4405 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4408 [(set_attr "type" "arith_media")])
4410 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4412 (define_expand "negdi2"
4413 [(set (match_operand:DI 0 "arith_reg_dest" "")
4414 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4415 (clobber (reg:SI T_REG))]
4419 (define_insn_and_split "*negdi2"
4420 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4421 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4428 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4429 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4431 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4432 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4434 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4435 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4437 emit_insn (gen_clrt ());
4438 emit_insn (gen_negc (low_dst, low_src));
4439 emit_insn (gen_negc (high_dst, high_src));
4443 (define_insn "negsi2"
4444 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4445 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4448 [(set_attr "type" "arith")])
4450 (define_insn "one_cmplsi2"
4451 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4452 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4455 [(set_attr "type" "arith")])
4457 (define_expand "one_cmpldi2"
4458 [(set (match_operand:DI 0 "arith_reg_dest" "")
4459 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4461 "TARGET_SHMEDIA" "")
4463 (define_expand "abssi2"
4464 [(set (match_operand:SI 0 "arith_reg_dest" "")
4465 (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4466 (clobber (reg:SI T_REG))]
4470 (define_insn_and_split "*abssi2"
4471 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4472 (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4479 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4480 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4485 (define_insn_and_split "*negabssi2"
4486 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4487 (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4494 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4495 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4500 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4501 ;; This can be used as some kind of conditional execution, which is useful
4503 ;; Actually the instruction scheduling should decide whether to use a
4504 ;; zero-offset branch or not for any generic case involving a single
4505 ;; instruction on SH4 202.
4507 (define_insn_and_split "negsi_cond"
4508 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4509 (if_then_else:SI (eq:SI (reg:SI T_REG)
4510 (match_operand:SI 3 "const_int_operand" "M,N"))
4511 (match_operand:SI 1 "arith_reg_operand" "0,0")
4512 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4515 bt\\t0f\;neg\\t%2,%0\\n0:
4516 bf\\t0f\;neg\\t%2,%0\\n0:"
4521 rtx skip_neg_label = gen_label_rtx ();
4523 emit_insn (gen_movsi (operands[0], operands[1]));
4525 emit_jump_insn (INTVAL (operands[3])
4526 ? gen_branch_true (skip_neg_label)
4527 : gen_branch_false (skip_neg_label));
4529 emit_label_after (skip_neg_label,
4530 emit_insn (gen_negsi2 (operands[0], operands[1])));
4533 [(set_attr "type" "arith") ;; poor approximation
4534 (set_attr "length" "4")])
4537 ;; -------------------------------------------------------------------------
4538 ;; Zero extension instructions
4539 ;; -------------------------------------------------------------------------
4541 (define_insn "zero_extendsidi2"
4542 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4543 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4545 "addz.l %1, r63, %0"
4546 [(set_attr "type" "arith_media")
4547 (set_attr "highpart" "extend")])
4549 (define_insn "zero_extendhidi2"
4550 [(set (match_operand:DI 0 "register_operand" "=r,r")
4551 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4556 [(set_attr "type" "*,load_media")
4557 (set (attr "highpart")
4558 (cond [(match_test "sh_contains_memref_p (insn)")
4559 (const_string "user")]
4560 (const_string "ignore")))])
4563 [(set (match_operand:DI 0 "register_operand" "")
4564 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4565 "TARGET_SHMEDIA && reload_completed"
4566 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4567 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4570 if (GET_CODE (operands[1]) == TRUNCATE)
4571 operands[1] = XEXP (operands[1], 0);
4574 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4575 ;; reload the entire truncate expression.
4576 (define_insn_and_split "*loaddi_trunc"
4577 [(set (match_operand 0 "any_register_operand" "=r")
4578 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4579 "TARGET_SHMEDIA && reload_completed"
4581 "TARGET_SHMEDIA && reload_completed"
4582 [(set (match_dup 0) (match_dup 1))]
4583 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4585 (define_insn "zero_extendqidi2"
4586 [(set (match_operand:DI 0 "register_operand" "=r,r")
4587 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4592 [(set_attr "type" "arith_media,load_media")
4593 (set (attr "highpart")
4594 (cond [(match_test "sh_contains_memref_p (insn)")
4595 (const_string "user")]
4596 (const_string "ignore")))])
4598 (define_expand "zero_extendhisi2"
4599 [(set (match_operand:SI 0 "arith_reg_operand" "")
4600 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4604 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4605 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4608 (define_insn "*zero_extendhisi2_compact"
4609 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4610 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4613 [(set_attr "type" "arith")])
4615 (define_insn "*zero_extendhisi2_media"
4616 [(set (match_operand:SI 0 "register_operand" "=r,r")
4617 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4622 [(set_attr "type" "arith_media,load_media")
4623 (set (attr "highpart")
4624 (cond [(match_test "sh_contains_memref_p (insn)")
4625 (const_string "user")]
4626 (const_string "ignore")))])
4629 [(set (match_operand:SI 0 "register_operand" "")
4630 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4631 "TARGET_SHMEDIA && reload_completed"
4632 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4633 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4636 rtx op1 = operands[1];
4638 if (GET_CODE (op1) == TRUNCATE)
4639 op1 = XEXP (op1, 0);
4641 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4642 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4645 (define_expand "zero_extendqisi2"
4646 [(set (match_operand:SI 0 "arith_reg_operand" "")
4647 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4651 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4652 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4655 (define_insn "*zero_extendqisi2_compact"
4656 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4657 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4660 [(set_attr "type" "arith")])
4662 (define_insn "*zero_extendqisi2_media"
4663 [(set (match_operand:SI 0 "register_operand" "=r,r")
4664 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4669 [(set_attr "type" "arith_media,load_media")
4670 (set (attr "highpart")
4671 (cond [(match_test "sh_contains_memref_p (insn)")
4672 (const_string "user")]
4673 (const_string "ignore")))])
4675 (define_insn "zero_extendqihi2"
4676 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4677 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4680 [(set_attr "type" "arith")])
4682 ;; -------------------------------------------------------------------------
4683 ;; Sign extension instructions
4684 ;; -------------------------------------------------------------------------
4686 ;; ??? This should be a define expand.
4687 ;; ??? Or perhaps it should be dropped?
4689 ;; convert_move generates good code for SH[1-4].
4690 (define_insn "extendsidi2"
4691 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4692 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4698 [(set_attr "type" "arith_media,load_media,fpconv_media")
4699 (set (attr "highpart")
4700 (cond [(match_test "sh_contains_memref_p (insn)")
4701 (const_string "user")]
4702 (const_string "extend")))])
4704 (define_insn "extendhidi2"
4705 [(set (match_operand:DI 0 "register_operand" "=r,r")
4706 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4711 [(set_attr "type" "*,load_media")
4712 (set (attr "highpart")
4713 (cond [(match_test "sh_contains_memref_p (insn)")
4714 (const_string "user")]
4715 (const_string "ignore")))])
4718 [(set (match_operand:DI 0 "register_operand" "")
4719 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4720 "TARGET_SHMEDIA && reload_completed"
4721 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4722 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4725 if (GET_CODE (operands[1]) == TRUNCATE)
4726 operands[1] = XEXP (operands[1], 0);
4729 (define_insn "extendqidi2"
4730 [(set (match_operand:DI 0 "register_operand" "=r,r")
4731 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4736 [(set_attr "type" "*,load_media")
4737 (set (attr "highpart")
4738 (cond [(match_test "sh_contains_memref_p (insn)")
4739 (const_string "user")]
4740 (const_string "ignore")))])
4743 [(set (match_operand:DI 0 "register_operand" "")
4744 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4745 "TARGET_SHMEDIA && reload_completed"
4746 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4747 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4750 if (GET_CODE (operands[1]) == TRUNCATE)
4751 operands[1] = XEXP (operands[1], 0);
4754 (define_expand "extendhisi2"
4755 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4756 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4760 (define_insn "*extendhisi2_compact"
4761 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4762 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4767 [(set_attr "type" "arith,load")])
4769 (define_insn "*extendhisi2_media"
4770 [(set (match_operand:SI 0 "register_operand" "=r,r")
4771 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4776 [(set_attr "type" "arith_media,load_media")
4777 (set (attr "highpart")
4778 (cond [(match_test "sh_contains_memref_p (insn)")
4779 (const_string "user")]
4780 (const_string "ignore")))])
4783 [(set (match_operand:SI 0 "register_operand" "")
4784 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4785 "TARGET_SHMEDIA && reload_completed"
4786 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4787 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4790 rtx op1 = operands[1];
4791 if (GET_CODE (op1) == TRUNCATE)
4792 op1 = XEXP (op1, 0);
4794 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4795 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4798 (define_expand "extendqisi2"
4799 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4800 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4804 (define_insn "*extendqisi2_compact"
4805 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4806 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4811 [(set_attr "type" "arith,load")
4812 (set_attr_alternative "length"
4815 (match_test "TARGET_SH2A")
4816 (const_int 4) (const_int 2))])])
4818 (define_insn "*extendqisi2_media"
4819 [(set (match_operand:SI 0 "register_operand" "=r,r")
4820 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4825 [(set_attr "type" "arith_media,load_media")
4826 (set (attr "highpart")
4827 (cond [(match_test "sh_contains_memref_p (insn)")
4828 (const_string "user")]
4829 (const_string "ignore")))])
4832 [(set (match_operand:SI 0 "register_operand" "")
4833 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4834 "TARGET_SHMEDIA && reload_completed"
4835 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4836 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4839 rtx op1 = operands[1];
4840 if (GET_CODE (op1) == TRUNCATE)
4841 op1 = XEXP (op1, 0);
4843 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4844 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4847 (define_insn "extendqihi2"
4848 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4849 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4854 [(set_attr "type" "arith,load")
4855 (set_attr_alternative "length"
4858 (match_test "TARGET_SH2A")
4859 (const_int 4) (const_int 2))])])
4861 /* It would seem useful to combine the truncXi patterns into the movXi
4862 patterns, but unary operators are ignored when matching constraints,
4863 so we need separate patterns. */
4864 (define_insn "truncdisi2"
4865 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4866 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4875 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4876 (set (attr "highpart")
4877 (cond [(match_test "sh_contains_memref_p (insn)")
4878 (const_string "user")]
4879 (const_string "extend")))])
4881 (define_insn "truncdihi2"
4882 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4883 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4886 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4888 [(set_attr "type" "arith_media,store_media")
4889 (set_attr "length" "8,4")
4890 (set (attr "highpart")
4891 (cond [(match_test "sh_contains_memref_p (insn)")
4892 (const_string "user")]
4893 (const_string "extend")))])
4895 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4896 ; Because we use zero extension, we can't provide signed QImode compares
4897 ; using a simple compare or conditional branch insn.
4898 (define_insn "truncdiqi2"
4899 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4900 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4905 [(set_attr "type" "arith_media,store")
4906 (set (attr "highpart")
4907 (cond [(match_test "sh_contains_memref_p (insn)")
4908 (const_string "user")]
4909 (const_string "extend")))])
4910 ;; -------------------------------------------------------------------------
4911 ;; Move instructions
4912 ;; -------------------------------------------------------------------------
4914 ;; define push and pop so it is easy for sh.c
4915 ;; We can't use push and pop on SHcompact because the stack must always
4916 ;; be 8-byte aligned.
4918 (define_expand "push"
4919 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4920 (match_operand:SI 0 "register_operand" "r,l,x"))]
4921 "TARGET_SH1 && ! TARGET_SH5"
4924 (define_expand "pop"
4925 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4926 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4927 "TARGET_SH1 && ! TARGET_SH5"
4930 (define_expand "push_e"
4931 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4932 (match_operand:SF 0 "" ""))
4933 (use (reg:PSI FPSCR_REG))
4934 (clobber (scratch:SI))])]
4935 "TARGET_SH1 && ! TARGET_SH5"
4938 (define_insn "push_fpul"
4939 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4940 "TARGET_SH2E && ! TARGET_SH5"
4942 [(set_attr "type" "fstore")
4943 (set_attr "late_fp_use" "yes")
4944 (set_attr "hit_stack" "yes")])
4946 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4948 (define_expand "push_4"
4949 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4950 (match_operand:DF 0 "" ""))
4951 (use (reg:PSI FPSCR_REG))
4952 (clobber (scratch:SI))])]
4953 "TARGET_SH1 && ! TARGET_SH5"
4956 (define_expand "pop_e"
4957 [(parallel [(set (match_operand:SF 0 "" "")
4958 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4959 (use (reg:PSI FPSCR_REG))
4960 (clobber (scratch:SI))])]
4961 "TARGET_SH1 && ! TARGET_SH5"
4964 (define_insn "pop_fpul"
4965 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4966 "TARGET_SH2E && ! TARGET_SH5"
4968 [(set_attr "type" "load")
4969 (set_attr "hit_stack" "yes")])
4971 (define_expand "pop_4"
4972 [(parallel [(set (match_operand:DF 0 "" "")
4973 (mem:DF (post_inc:SI (reg:SI SP_REG))))
4974 (use (reg:PSI FPSCR_REG))
4975 (clobber (scratch:SI))])]
4976 "TARGET_SH1 && ! TARGET_SH5"
4979 (define_expand "push_fpscr"
4984 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4985 gen_rtx_PRE_DEC (Pmode,
4986 stack_pointer_rtx)),
4988 add_reg_note (insn, REG_INC, stack_pointer_rtx);
4992 (define_expand "pop_fpscr"
4997 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4998 gen_frame_mem (PSImode,
4999 gen_rtx_POST_INC (Pmode,
5000 stack_pointer_rtx))));
5001 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5005 ;; These two patterns can happen as the result of optimization, when
5006 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5007 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5010 [(set (reg:SI T_REG) (const_int 0))]
5015 [(set (reg:SI T_REG) (const_int 1))]
5019 ;; Define additional pop for SH1 and SH2 so it does not get
5020 ;; placed in the delay slot.
5021 (define_insn "*movsi_pop"
5022 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5023 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5024 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5030 [(set_attr "type" "load_si,mem_mac,pload")
5031 (set_attr "length" "2,2,2")
5032 (set_attr "in_delay_slot" "no,no,no")])
5034 ;; t/r must come after r/r, lest reload will try to reload stuff like
5035 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5036 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5037 (define_insn "movsi_i"
5038 [(set (match_operand:SI 0 "general_movdst_operand"
5039 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5040 (match_operand:SI 1 "general_movsrc_operand"
5041 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5045 && (register_operand (operands[0], SImode)
5046 || register_operand (operands[1], SImode))"
5064 [(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")
5065 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5067 ;; t/r must come after r/r, lest reload will try to reload stuff like
5068 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5069 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5070 ;; will require a reload.
5071 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5072 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5073 (define_insn "movsi_ie"
5074 [(set (match_operand:SI 0 "general_movdst_operand"
5075 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5076 (match_operand:SI 1 "general_movsrc_operand"
5077 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5078 "(TARGET_SH2E || TARGET_SH2A)
5079 && (register_operand (operands[0], SImode)
5080 || register_operand (operands[1], SImode))"
5107 ! move optimized away"
5108 [(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")
5109 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5110 (set_attr_alternative "length"
5118 (match_test "TARGET_SH2A")
5119 (const_int 4) (const_int 2))
5124 (match_test "TARGET_SH2A")
5125 (const_int 4) (const_int 2))
5142 (define_insn "movsi_i_lowpart"
5143 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5144 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5146 && (register_operand (operands[0], SImode)
5147 || register_operand (operands[1], SImode))"
5158 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5160 (define_insn_and_split "load_ra"
5161 [(set (match_operand:SI 0 "general_movdst_operand" "")
5162 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5165 "&& ! currently_expanding_to_rtl"
5166 [(set (match_dup 0) (match_dup 1))]
5169 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5170 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5173 ;; The '?'s in the following constraints may not reflect the time taken
5174 ;; to perform the move. They are there to discourage the use of floating-
5175 ;; point registers for storing integer values.
5176 (define_insn "*movsi_media"
5177 [(set (match_operand:SI 0 "general_movdst_operand"
5178 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5179 (match_operand:SI 1 "general_movsrc_operand"
5180 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5182 && (register_operand (operands[0], SImode)
5183 || sh_register_operand (operands[1], SImode)
5184 || GET_CODE (operands[1]) == TRUNCATE)"
5199 [(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")
5200 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5201 (set (attr "highpart")
5202 (cond [(match_test "sh_contains_memref_p (insn)")
5203 (const_string "user")]
5204 (const_string "ignore")))])
5206 (define_insn "*movsi_media_nofpu"
5207 [(set (match_operand:SI 0 "general_movdst_operand"
5208 "=r,r,r,r,m,*b,r,*b")
5209 (match_operand:SI 1 "general_movsrc_operand"
5210 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5212 && (register_operand (operands[0], SImode)
5213 || sh_register_operand (operands[1], SImode)
5214 || GET_CODE (operands[1]) == TRUNCATE)"
5224 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5225 (set_attr "length" "4,4,8,4,4,4,4,12")
5226 (set (attr "highpart")
5227 (cond [(match_test "sh_contains_memref_p (insn)")
5228 (const_string "user")]
5229 (const_string "ignore")))])
5231 (define_expand "movsi_const"
5232 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5233 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5234 (const_int 16)] UNSPEC_EXTRACT_S16)))
5236 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5237 (const:SI (unspec:SI [(match_dup 1)
5238 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5239 "TARGET_SHMEDIA && reload_completed
5240 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5243 if (GET_CODE (operands[1]) == LABEL_REF
5244 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5245 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5246 else if (GOTOFF_P (operands[1]))
5248 rtx unspec = XEXP (operands[1], 0);
5250 if (! UNSPEC_GOTOFF_P (unspec))
5252 unspec = XEXP (unspec, 0);
5253 if (! UNSPEC_GOTOFF_P (unspec))
5256 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5257 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5258 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5262 (define_expand "movsi_const_16bit"
5263 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5264 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5265 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5266 "TARGET_SHMEDIA && flag_pic && reload_completed
5267 && GET_CODE (operands[1]) == SYMBOL_REF"
5271 [(set (match_operand:SI 0 "arith_reg_dest" "")
5272 (match_operand:SI 1 "immediate_operand" ""))]
5273 "TARGET_SHMEDIA && reload_completed
5274 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5278 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5280 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5286 [(set (match_operand:SI 0 "register_operand" "")
5287 (match_operand:SI 1 "immediate_operand" ""))]
5288 "TARGET_SHMEDIA && reload_completed
5289 && ((CONST_INT_P (operands[1])
5290 && ! satisfies_constraint_I16 (operands[1]))
5291 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5292 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5294 (define_expand "movsi"
5295 [(set (match_operand:SI 0 "general_movdst_operand" "")
5296 (match_operand:SI 1 "general_movsrc_operand" ""))]
5298 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5300 (define_expand "ic_invalidate_line"
5301 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5302 (match_dup 1)] UNSPEC_ICACHE)
5303 (clobber (scratch:SI))])]
5304 "TARGET_HARD_SH4 || TARGET_SH5"
5309 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5312 else if (TARGET_SHCOMPACT)
5314 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5315 operands[1] = force_reg (Pmode, operands[1]);
5316 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5319 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5321 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5324 operands[0] = force_reg (Pmode, operands[0]);
5325 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5329 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5330 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5331 ;; the requirement *1*00 for associative address writes. The alignment of
5332 ;; %0 implies that its least significant bit is cleared,
5333 ;; thus we clear the V bit of a matching entry if there is one.
5334 (define_insn "ic_invalidate_line_i"
5335 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5336 (match_operand:SI 1 "register_operand" "r")]
5338 (clobber (match_scratch:SI 2 "=&r"))]
5340 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5341 [(set_attr "length" "8")
5342 (set_attr "type" "cwb")])
5344 (define_insn "ic_invalidate_line_sh4a"
5345 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5347 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5348 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5349 [(set_attr "length" "16")
5350 (set_attr "type" "cwb")])
5352 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5353 ;; an add in the code that calculates the address.
5354 (define_insn "ic_invalidate_line_media"
5355 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5358 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5359 [(set_attr "length" "16")
5360 (set_attr "type" "invalidate_line_media")])
5362 (define_insn "ic_invalidate_line_compact"
5363 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5364 (match_operand:SI 1 "register_operand" "r")]
5366 (clobber (reg:SI PR_REG))]
5369 [(set_attr "type" "sfunc")
5370 (set_attr "needs_delay_slot" "yes")])
5372 (define_expand "initialize_trampoline"
5373 [(match_operand:SI 0 "" "")
5374 (match_operand:SI 1 "" "")
5375 (match_operand:SI 2 "" "")]
5381 tramp = force_reg (Pmode, operands[0]);
5382 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5384 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5385 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5387 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5391 (define_insn "initialize_trampoline_compact"
5392 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5393 (match_operand:SI 1 "register_operand" "r")
5394 (reg:SI R2_REG) (reg:SI R3_REG)]
5397 (clobber (reg:SI PR_REG))]
5400 [(set_attr "type" "sfunc")
5401 (set_attr "needs_delay_slot" "yes")])
5403 (define_insn "movqi_i"
5404 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5405 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5407 && (arith_reg_operand (operands[0], QImode)
5408 || arith_reg_operand (operands[1], QImode))"
5417 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5418 (set_attr_alternative "length"
5422 (match_test "TARGET_SH2A")
5423 (const_int 4) (const_int 2))
5425 (match_test "TARGET_SH2A")
5426 (const_int 4) (const_int 2))
5431 (define_insn "*movqi_media"
5432 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5433 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5435 && (arith_reg_operand (operands[0], QImode)
5436 || extend_reg_or_0_operand (operands[1], QImode))"
5442 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5443 (set (attr "highpart")
5444 (cond [(match_test "sh_contains_memref_p (insn)")
5445 (const_string "user")]
5446 (const_string "ignore")))])
5448 (define_expand "movqi"
5449 [(set (match_operand:QI 0 "general_operand" "")
5450 (match_operand:QI 1 "general_operand" ""))]
5452 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5454 (define_expand "reload_inqi"
5455 [(set (match_operand:SI 2 "" "=&r")
5456 (match_operand:QI 1 "inqhi_operand" ""))
5457 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5458 (truncate:QI (match_dup 3)))]
5462 rtx inner = XEXP (operands[1], 0);
5463 int regno = REGNO (inner);
5465 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5466 operands[1] = gen_rtx_REG (SImode, regno);
5467 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5470 ;; When storing r0, we have to avoid reg+reg addressing.
5471 (define_insn "movhi_i"
5472 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5473 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5475 && (arith_reg_operand (operands[0], HImode)
5476 || arith_reg_operand (operands[1], HImode))
5477 && (!MEM_P (operands[0])
5478 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5479 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5480 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5490 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5492 (define_insn "*movhi_media"
5493 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5494 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5496 && (arith_reg_operand (operands[0], HImode)
5497 || arith_reg_or_0_operand (operands[1], HImode))"
5504 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5505 (set (attr "highpart")
5506 (cond [(match_test "sh_contains_memref_p (insn)")
5507 (const_string "user")]
5508 (const_string "ignore")))])
5511 [(set (match_operand:HI 0 "register_operand" "")
5512 (match_operand:HI 1 "immediate_operand" ""))]
5513 "TARGET_SHMEDIA && reload_completed
5514 && ! satisfies_constraint_I16 (operands[1])"
5515 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5517 (define_expand "movhi"
5518 [(set (match_operand:HI 0 "general_movdst_operand" "")
5519 (match_operand:HI 1 "general_movsrc_operand" ""))]
5521 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5523 (define_expand "reload_inhi"
5524 [(set (match_operand:SI 2 "" "=&r")
5525 (match_operand:HI 1 "inqhi_operand" ""))
5526 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5527 (truncate:HI (match_dup 3)))]
5531 rtx inner = XEXP (operands[1], 0);
5532 int regno = REGNO (inner);
5534 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5535 operands[1] = gen_rtx_REG (SImode, regno);
5536 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5539 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5540 ;; compiled with -m2 -ml -O3 -funroll-loops
5541 (define_insn "*movdi_i"
5542 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5543 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5545 && (arith_reg_operand (operands[0], DImode)
5546 || arith_reg_operand (operands[1], DImode))"
5547 "* return output_movedouble (insn, operands, DImode);"
5548 [(set_attr "length" "4")
5549 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5551 ;; If the output is a register and the input is memory or a register, we have
5552 ;; to be careful and see which word needs to be loaded first.
5555 [(set (match_operand:DI 0 "general_movdst_operand" "")
5556 (match_operand:DI 1 "general_movsrc_operand" ""))]
5557 "TARGET_SH1 && reload_completed"
5558 [(set (match_dup 2) (match_dup 3))
5559 (set (match_dup 4) (match_dup 5))]
5564 if ((MEM_P (operands[0])
5565 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5566 || (MEM_P (operands[1])
5567 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5570 switch (GET_CODE (operands[0]))
5573 regno = REGNO (operands[0]);
5576 regno = subreg_regno (operands[0]);
5586 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5588 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5589 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5590 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5591 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5595 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5596 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5597 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5598 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5601 if (operands[2] == 0 || operands[3] == 0
5602 || operands[4] == 0 || operands[5] == 0)
5606 ;; The '?'s in the following constraints may not reflect the time taken
5607 ;; to perform the move. They are there to discourage the use of floating-
5608 ;; point registers for storing integer values.
5609 (define_insn "*movdi_media"
5610 [(set (match_operand:DI 0 "general_movdst_operand"
5611 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5612 (match_operand:DI 1 "general_movsrc_operand"
5613 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5615 && (register_operand (operands[0], DImode)
5616 || sh_register_operand (operands[1], DImode))"
5631 [(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")
5632 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5634 (define_insn "*movdi_media_nofpu"
5635 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5636 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5638 && (register_operand (operands[0], DImode)
5639 || sh_register_operand (operands[1], DImode))"
5649 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5650 (set_attr "length" "4,4,16,4,4,4,4,*")])
5652 (define_insn "*movdi_media_I16"
5653 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5654 (match_operand:DI 1 "const_int_operand" "I16"))]
5655 "TARGET_SHMEDIA && reload_completed"
5657 [(set_attr "type" "arith_media")
5658 (set_attr "length" "4")])
5661 [(set (match_operand:DI 0 "arith_reg_dest" "")
5662 (match_operand:DI 1 "immediate_operand" ""))]
5663 "TARGET_SHMEDIA && reload_completed
5664 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5665 [(set (match_dup 0) (match_dup 1))]
5670 if (TARGET_SHMEDIA64)
5671 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5673 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5675 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5680 (define_expand "movdi_const"
5681 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5682 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5683 (const_int 48)] UNSPEC_EXTRACT_S16)))
5685 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5686 (const:DI (unspec:DI [(match_dup 1)
5687 (const_int 32)] UNSPEC_EXTRACT_U16))))
5689 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5690 (const:DI (unspec:DI [(match_dup 1)
5691 (const_int 16)] UNSPEC_EXTRACT_U16))))
5693 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5694 (const:DI (unspec:DI [(match_dup 1)
5695 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5696 "TARGET_SHMEDIA64 && reload_completed
5697 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5700 sh_mark_label (operands[1], 4);
5703 (define_expand "movdi_const_32bit"
5704 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5705 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5706 (const_int 16)] UNSPEC_EXTRACT_S16)))
5708 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5709 (const:DI (unspec:DI [(match_dup 1)
5710 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5711 "TARGET_SHMEDIA32 && reload_completed
5712 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5715 sh_mark_label (operands[1], 2);
5718 (define_expand "movdi_const_16bit"
5719 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5720 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5721 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5722 "TARGET_SHMEDIA && flag_pic && reload_completed
5723 && GET_CODE (operands[1]) == SYMBOL_REF"
5727 [(set (match_operand:DI 0 "ext_dest_operand" "")
5728 (match_operand:DI 1 "immediate_operand" ""))]
5729 "TARGET_SHMEDIA && reload_completed
5730 && CONST_INT_P (operands[1])
5731 && ! satisfies_constraint_I16 (operands[1])"
5732 [(set (match_dup 0) (match_dup 2))
5736 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5737 unsigned HOST_WIDE_INT low = val;
5738 unsigned HOST_WIDE_INT high = val;
5739 unsigned HOST_WIDE_INT sign;
5740 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5742 /* Zero-extend the 16 least-significant bits. */
5745 /* Arithmetic shift right the word by 16 bits. */
5747 if (GET_CODE (operands[0]) == SUBREG
5748 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5757 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5763 /* If we can't generate the constant with a two-insn movi / shori
5764 sequence, try some other strategies. */
5765 if (! CONST_OK_FOR_I16 (high))
5767 /* Try constant load / left shift. We know VAL != 0. */
5768 val2 = val ^ (val-1);
5771 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5773 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5774 || (! CONST_OK_FOR_I16 (high >> 16)
5775 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5777 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5778 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5779 GEN_INT (trailing_zeroes));
5783 /* Try constant load / right shift. */
5784 val2 = (val >> 15) + 1;
5785 if (val2 == (val2 & -val2))
5787 int shift = 49 - exact_log2 (val2);
5789 val2 = trunc_int_for_mode (val << shift, DImode);
5790 if (CONST_OK_FOR_I16 (val2))
5792 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5798 val2 = val & 0xffff;
5799 if ((val >> 16 & 0xffff) == val2
5800 && (val >> 32 & 0xffff) == val2
5801 && (val >> 48 & 0xffff) == val2)
5803 val2 = (HOST_WIDE_INT) val >> 48;
5804 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5805 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5808 /* Try movi / mshflo.l */
5809 val2 = (HOST_WIDE_INT) val >> 32;
5810 if (val2 == ((unsigned HOST_WIDE_INT)
5811 trunc_int_for_mode (val, SImode)))
5813 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5817 /* Try movi / mshflo.l w/ r63. */
5818 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5819 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5821 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5827 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5830 operands[2] = GEN_INT (val2);
5834 [(set (match_operand:DI 0 "ext_dest_operand" "")
5835 (match_operand:DI 1 "immediate_operand" ""))]
5836 "TARGET_SHMEDIA && reload_completed
5837 && GET_CODE (operands[1]) == CONST_DOUBLE"
5838 [(set (match_dup 0) (match_dup 2))
5840 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5843 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5844 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5845 unsigned HOST_WIDE_INT val = low;
5846 unsigned HOST_WIDE_INT sign;
5848 /* Zero-extend the 16 least-significant bits. */
5850 operands[1] = GEN_INT (val);
5852 /* Arithmetic shift right the double-word by 16 bits. */
5854 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5857 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5861 /* This will only be true if high is a sign-extension of low, i.e.,
5862 it must be either 0 or (unsigned)-1, and be zero iff the
5863 most-significant bit of low is set. */
5864 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5865 operands[2] = GEN_INT (low);
5867 operands[2] = immed_double_const (low, high, DImode);
5870 (define_insn "shori_media"
5871 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5872 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5874 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5875 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5879 [(set_attr "type" "arith_media,*")])
5881 (define_insn "*shori_media_si"
5882 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5883 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5885 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5889 (define_expand "movdi"
5890 [(set (match_operand:DI 0 "general_movdst_operand" "")
5891 (match_operand:DI 1 "general_movsrc_operand" ""))]
5893 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5895 (define_insn "movdf_media"
5896 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5897 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5899 && (register_operand (operands[0], DFmode)
5900 || sh_register_operand (operands[1], DFmode))"
5911 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5913 (define_insn "movdf_media_nofpu"
5914 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5915 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5917 && (register_operand (operands[0], DFmode)
5918 || sh_register_operand (operands[1], DFmode))"
5924 [(set_attr "type" "arith_media,*,load_media,store_media")])
5927 [(set (match_operand:DF 0 "arith_reg_dest" "")
5928 (match_operand:DF 1 "immediate_operand" ""))]
5929 "TARGET_SHMEDIA && reload_completed"
5930 [(set (match_dup 3) (match_dup 2))]
5933 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5935 REAL_VALUE_TYPE value;
5937 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5938 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5940 if (HOST_BITS_PER_WIDE_INT >= 64)
5941 operands[2] = immed_double_const ((unsigned long) values[endian]
5942 | ((HOST_WIDE_INT) values[1 - endian]
5946 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5947 operands[2] = immed_double_const (values[endian], values[1 - endian],
5951 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5954 ;; ??? This should be a define expand.
5956 (define_insn "movdf_k"
5957 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5958 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5960 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5961 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5962 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5963 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5964 && (arith_reg_operand (operands[0], DFmode)
5965 || arith_reg_operand (operands[1], DFmode))"
5966 "* return output_movedouble (insn, operands, DFmode);"
5967 [(set_attr "length" "4")
5968 (set_attr "type" "move,pcload,load,store")])
5970 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5971 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5972 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5973 ;; the d/m/c/X alternative, which is split later into single-precision
5974 ;; instructions. And when not optimizing, no splits are done before fixing
5975 ;; up pcloads, so we need usable length information for that.
5976 (define_insn "movdf_i4"
5977 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5978 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5979 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5980 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5981 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5982 && (arith_reg_operand (operands[0], DFmode)
5983 || arith_reg_operand (operands[1], DFmode))"
5985 switch (which_alternative)
5989 return "fmov %1,%0";
5990 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5991 return "fmov %R1,%R0\n\tfmov %S1,%S0";
5993 return "fmov %S1,%S0\n\tfmov %R1,%R0";
5996 return "fmov.d %1,%0";
6001 [(set_attr_alternative "length"
6002 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6004 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6005 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6006 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6008 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6009 ;; We can't use 4-byte push/pop on SHcompact, so we have to
6010 ;; increment or decrement r15 explicitly.
6012 (match_test "TARGET_SHCOMPACT")
6013 (const_int 10) (const_int 8))
6015 (match_test "TARGET_SHCOMPACT")
6016 (const_int 10) (const_int 8))])
6017 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6018 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6019 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6020 (const_string "double")
6021 (const_string "none")))])
6023 ;; Moving DFmode between fp/general registers through memory
6024 ;; (the top of the stack) is faster than moving through fpul even for
6025 ;; little endian. Because the type of an instruction is important for its
6026 ;; scheduling, it is beneficial to split these operations, rather than
6027 ;; emitting them in one single chunk, even if this will expose a stack
6028 ;; use that will prevent scheduling of other stack accesses beyond this
6031 [(set (match_operand:DF 0 "register_operand" "")
6032 (match_operand:DF 1 "register_operand" ""))
6033 (use (match_operand:PSI 2 "fpscr_operand" ""))
6034 (clobber (match_scratch:SI 3 "=X"))]
6035 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6036 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6042 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6044 emit_move_insn (stack_pointer_rtx,
6045 plus_constant (stack_pointer_rtx, -8));
6046 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6049 tos = gen_tmp_stack_mem (DFmode,
6050 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6051 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6052 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6053 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6054 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6055 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6057 tos = gen_tmp_stack_mem (DFmode,
6058 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6059 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6060 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6061 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6063 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6067 ;; local-alloc sometimes allocates scratch registers even when not required,
6068 ;; so we must be prepared to handle these.
6070 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6072 [(set (match_operand:DF 0 "general_movdst_operand" "")
6073 (match_operand:DF 1 "general_movsrc_operand" ""))
6074 (use (match_operand:PSI 2 "fpscr_operand" ""))
6075 (clobber (match_scratch:SI 3 ""))]
6076 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6078 && true_regnum (operands[0]) < 16
6079 && true_regnum (operands[1]) < 16"
6080 [(set (match_dup 0) (match_dup 1))]
6083 /* If this was a reg <-> mem operation with base + index reg addressing,
6084 we have to handle this in a special way. */
6085 rtx mem = operands[0];
6087 if (! memory_operand (mem, DFmode))
6092 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6093 mem = SUBREG_REG (mem);
6096 rtx addr = XEXP (mem, 0);
6097 if (GET_CODE (addr) == PLUS
6098 && REG_P (XEXP (addr, 0))
6099 && REG_P (XEXP (addr, 1)))
6102 rtx reg0 = gen_rtx_REG (Pmode, 0);
6103 rtx regop = operands[store_p], word0 ,word1;
6105 if (GET_CODE (regop) == SUBREG)
6106 alter_subreg (®op);
6107 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6111 mem = copy_rtx (mem);
6112 PUT_MODE (mem, SImode);
6113 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6114 alter_subreg (&word0);
6115 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6116 alter_subreg (&word1);
6117 if (store_p || ! refers_to_regno_p (REGNO (word0),
6118 REGNO (word0) + 1, addr, 0))
6121 ? gen_movsi_ie (mem, word0)
6122 : gen_movsi_ie (word0, mem));
6123 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6124 mem = copy_rtx (mem);
6126 ? gen_movsi_ie (mem, word1)
6127 : gen_movsi_ie (word1, mem));
6128 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6132 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6133 emit_insn (gen_movsi_ie (word1, mem));
6134 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6135 mem = copy_rtx (mem);
6136 emit_insn (gen_movsi_ie (word0, mem));
6143 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6145 [(set (match_operand:DF 0 "register_operand" "")
6146 (match_operand:DF 1 "memory_operand" ""))
6147 (use (match_operand:PSI 2 "fpscr_operand" ""))
6148 (clobber (reg:SI R0_REG))]
6149 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6150 [(parallel [(set (match_dup 0) (match_dup 1))
6152 (clobber (scratch:SI))])]
6155 (define_expand "reload_indf__frn"
6156 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6157 (match_operand:DF 1 "immediate_operand" "FQ"))
6158 (use (reg:PSI FPSCR_REG))
6159 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6163 (define_expand "reload_outdf__RnFRm"
6164 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6165 (match_operand:DF 1 "register_operand" "af,r"))
6166 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6170 ;; Simplify no-op moves.
6172 [(set (match_operand:SF 0 "register_operand" "")
6173 (match_operand:SF 1 "register_operand" ""))
6174 (use (match_operand:PSI 2 "fpscr_operand" ""))
6175 (clobber (match_scratch:SI 3 ""))]
6176 "TARGET_SH2E && reload_completed
6177 && true_regnum (operands[0]) == true_regnum (operands[1])"
6178 [(set (match_dup 0) (match_dup 0))]
6181 ;; fmovd substitute post-reload splits
6183 [(set (match_operand:DF 0 "register_operand" "")
6184 (match_operand:DF 1 "register_operand" ""))
6185 (use (match_operand:PSI 2 "fpscr_operand" ""))
6186 (clobber (match_scratch:SI 3 ""))]
6187 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6188 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6189 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6193 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6194 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6195 gen_rtx_REG (SFmode, src), operands[2]));
6196 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6197 gen_rtx_REG (SFmode, src + 1), operands[2]));
6202 [(set (match_operand:DF 0 "register_operand" "")
6203 (mem:DF (match_operand:SI 1 "register_operand" "")))
6204 (use (match_operand:PSI 2 "fpscr_operand" ""))
6205 (clobber (match_scratch:SI 3 ""))]
6206 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6207 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6208 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6212 int regno = true_regnum (operands[0]);
6214 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6216 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6217 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6218 regno + !! TARGET_LITTLE_ENDIAN),
6219 mem2, operands[2]));
6220 add_reg_note (insn, REG_INC, operands[1]);
6221 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6222 regno + ! TARGET_LITTLE_ENDIAN),
6223 change_address (mem, SFmode, NULL_RTX),
6229 [(set (match_operand:DF 0 "register_operand" "")
6230 (match_operand:DF 1 "memory_operand" ""))
6231 (use (match_operand:PSI 2 "fpscr_operand" ""))
6232 (clobber (match_scratch:SI 3 ""))]
6233 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6234 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6237 int regno = true_regnum (operands[0]);
6239 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6240 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6241 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6243 operands[1] = copy_rtx (mem2);
6244 addr = XEXP (mem2, 0);
6246 switch (GET_CODE (addr))
6249 /* This is complicated. If the register is an arithmetic register
6250 we can just fall through to the REG+DISP case below. Otherwise
6251 we have to use a combination of POST_INC and REG addressing... */
6252 if (! arith_reg_operand (operands[1], SFmode))
6254 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6255 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6256 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6258 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6260 /* If we have modified the stack pointer, the value that we have
6261 read with post-increment might be modified by an interrupt,
6262 so write it back. */
6263 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6264 emit_insn (gen_push_e (reg0));
6266 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6272 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6273 operands[1] = copy_rtx (operands[1]);
6274 XEXP (operands[1], 0) = plus_constant (addr, 4);
6275 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6279 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6280 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6282 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6283 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6295 [(set (match_operand:DF 0 "memory_operand" "")
6296 (match_operand:DF 1 "register_operand" ""))
6297 (use (match_operand:PSI 2 "fpscr_operand" ""))
6298 (clobber (match_scratch:SI 3 ""))]
6299 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6300 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6303 int regno = true_regnum (operands[1]);
6305 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6306 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6308 operands[0] = copy_rtx (operands[0]);
6309 PUT_MODE (operands[0], SFmode);
6310 addr = XEXP (operands[0], 0);
6312 switch (GET_CODE (addr))
6315 /* This is complicated. If the register is an arithmetic register
6316 we can just fall through to the REG+DISP case below. Otherwise
6317 we have to use a combination of REG and PRE_DEC addressing... */
6318 if (! arith_reg_operand (operands[0], SFmode))
6320 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6321 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6323 operands[0] = copy_rtx (operands[0]);
6324 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6326 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6327 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6333 /* Since REG+DISP addressing has already been decided upon by gcc
6334 we can rely upon it having chosen an arithmetic register as the
6335 register component of the address. Just emit the lower numbered
6336 register first, to the lower address, then the higher numbered
6337 register to the higher address. */
6338 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6340 operands[0] = copy_rtx (operands[0]);
6341 XEXP (operands[0], 0) = plus_constant (addr, 4);
6343 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6347 /* This is easy. Output the word to go to the higher address
6348 first (ie the word in the higher numbered register) then the
6349 word to go to the lower address. */
6351 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6352 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6354 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6355 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6367 ;; If the output is a register and the input is memory or a register, we have
6368 ;; to be careful and see which word needs to be loaded first.
6371 [(set (match_operand:DF 0 "general_movdst_operand" "")
6372 (match_operand:DF 1 "general_movsrc_operand" ""))]
6373 "TARGET_SH1 && reload_completed"
6374 [(set (match_dup 2) (match_dup 3))
6375 (set (match_dup 4) (match_dup 5))]
6380 if ((MEM_P (operands[0])
6381 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6382 || (MEM_P (operands[1])
6383 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6386 switch (GET_CODE (operands[0]))
6389 regno = REGNO (operands[0]);
6392 regno = subreg_regno (operands[0]);
6402 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6404 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6405 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6406 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6407 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6411 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6412 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6413 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6414 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6417 if (operands[2] == 0 || operands[3] == 0
6418 || operands[4] == 0 || operands[5] == 0)
6422 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6423 ;; used only once, let combine add in the index again.
6426 [(set (match_operand:SI 0 "register_operand" "")
6427 (match_operand:SI 1 "" ""))
6428 (clobber (match_operand 2 "register_operand" ""))]
6429 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6430 && ALLOW_INDEXED_ADDRESS"
6431 [(use (reg:SI R0_REG))]
6434 rtx addr, reg, const_int;
6436 if (!MEM_P (operands[1]))
6438 addr = XEXP (operands[1], 0);
6439 if (GET_CODE (addr) != PLUS)
6441 reg = XEXP (addr, 0);
6442 const_int = XEXP (addr, 1);
6443 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6444 && CONST_INT_P (const_int)))
6446 emit_move_insn (operands[2], const_int);
6447 emit_move_insn (operands[0],
6448 change_address (operands[1], VOIDmode,
6449 gen_rtx_PLUS (SImode, reg, operands[2])));
6454 [(set (match_operand:SI 1 "" "")
6455 (match_operand:SI 0 "register_operand" ""))
6456 (clobber (match_operand 2 "register_operand" ""))]
6457 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6458 && ALLOW_INDEXED_ADDRESS"
6459 [(use (reg:SI R0_REG))]
6462 rtx addr, reg, const_int;
6464 if (!MEM_P (operands[1]))
6466 addr = XEXP (operands[1], 0);
6467 if (GET_CODE (addr) != PLUS)
6469 reg = XEXP (addr, 0);
6470 const_int = XEXP (addr, 1);
6471 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6472 && CONST_INT_P (const_int)))
6474 emit_move_insn (operands[2], const_int);
6475 emit_move_insn (change_address (operands[1], VOIDmode,
6476 gen_rtx_PLUS (SImode, reg, operands[2])),
6481 (define_expand "movdf"
6482 [(set (match_operand:DF 0 "general_movdst_operand" "")
6483 (match_operand:DF 1 "general_movsrc_operand" ""))]
6487 if (prepare_move_operands (operands, DFmode)) DONE;
6490 if (TARGET_SHMEDIA_FPU)
6491 emit_insn (gen_movdf_media (operands[0], operands[1]));
6493 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6496 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6498 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6503 ;;This is incompatible with the way gcc uses subregs.
6504 ;;(define_insn "movv2sf_i"
6505 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6506 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6507 ;; "TARGET_SHMEDIA_FPU
6508 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6509 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6513 ;; fst%M0.p %m0, %1"
6514 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6516 (define_insn_and_split "movv2sf_i"
6517 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6518 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6519 "TARGET_SHMEDIA_FPU"
6521 "TARGET_SHMEDIA_FPU && reload_completed"
6522 [(set (match_dup 0) (match_dup 1))]
6525 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6526 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6529 (define_expand "movv2sf"
6530 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6531 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6532 "TARGET_SHMEDIA_FPU"
6535 if (prepare_move_operands (operands, V2SFmode))
6539 (define_expand "addv2sf3"
6540 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6541 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6542 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6543 "TARGET_SHMEDIA_FPU"
6546 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6550 (define_expand "subv2sf3"
6551 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6552 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6553 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6554 "TARGET_SHMEDIA_FPU"
6557 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6561 (define_expand "mulv2sf3"
6562 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6563 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6564 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6565 "TARGET_SHMEDIA_FPU"
6568 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6572 (define_expand "divv2sf3"
6573 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6574 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6575 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6576 "TARGET_SHMEDIA_FPU"
6579 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6583 (define_insn_and_split "*movv4sf_i"
6584 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6585 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6586 "TARGET_SHMEDIA_FPU"
6588 "&& reload_completed"
6594 for (i = 0; i < 4/2; i++)
6598 if (MEM_P (operands[0]))
6599 x = adjust_address (operands[0], V2SFmode,
6600 i * GET_MODE_SIZE (V2SFmode));
6602 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6604 if (MEM_P (operands[1]))
6605 y = adjust_address (operands[1], V2SFmode,
6606 i * GET_MODE_SIZE (V2SFmode));
6608 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6610 emit_insn (gen_movv2sf_i (x, y));
6615 [(set_attr "length" "8")])
6617 (define_expand "movv4sf"
6618 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6619 (match_operand:V4SF 1 "general_operand" ""))]
6620 "TARGET_SHMEDIA_FPU"
6623 if (prepare_move_operands (operands, V4SFmode))
6627 (define_insn_and_split "*movv16sf_i"
6628 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6629 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6630 "TARGET_SHMEDIA_FPU"
6632 "&& reload_completed"
6638 for (i = 0; i < 16/2; i++)
6642 if (MEM_P (operands[0]))
6643 x = adjust_address (operands[0], V2SFmode,
6644 i * GET_MODE_SIZE (V2SFmode));
6647 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6651 if (MEM_P (operands[1]))
6652 y = adjust_address (operands[1], V2SFmode,
6653 i * GET_MODE_SIZE (V2SFmode));
6656 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6660 emit_insn (gen_movv2sf_i (x, y));
6665 [(set_attr "length" "32")])
6667 (define_expand "movv16sf"
6668 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6669 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6670 "TARGET_SHMEDIA_FPU"
6673 if (prepare_move_operands (operands, V16SFmode))
6677 (define_insn "movsf_media"
6678 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6679 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6681 && (register_operand (operands[0], SFmode)
6682 || sh_register_operand (operands[1], SFmode))"
6693 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6694 (set (attr "highpart")
6695 (cond [(match_test "sh_contains_memref_p (insn)")
6696 (const_string "user")]
6697 (const_string "ignore")))])
6699 (define_insn "movsf_media_nofpu"
6700 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6701 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6703 && (register_operand (operands[0], SFmode)
6704 || sh_register_operand (operands[1], SFmode))"
6710 [(set_attr "type" "arith_media,*,load_media,store_media")
6711 (set (attr "highpart")
6712 (cond [(match_test "sh_contains_memref_p (insn)")
6713 (const_string "user")]
6714 (const_string "ignore")))])
6717 [(set (match_operand:SF 0 "arith_reg_dest" "")
6718 (match_operand:SF 1 "immediate_operand" ""))]
6719 "TARGET_SHMEDIA && reload_completed
6720 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6721 [(set (match_dup 3) (match_dup 2))]
6725 REAL_VALUE_TYPE value;
6727 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6728 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6729 operands[2] = GEN_INT (values);
6731 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6734 (define_insn "movsf_i"
6735 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6736 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6739 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6740 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6741 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6742 && (arith_reg_operand (operands[0], SFmode)
6743 || arith_reg_operand (operands[1], SFmode))"
6752 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6754 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6755 ;; update_flow_info would not know where to put REG_EQUAL notes
6756 ;; when the destination changes mode.
6757 (define_insn "movsf_ie"
6758 [(set (match_operand:SF 0 "general_movdst_operand"
6759 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6760 (match_operand:SF 1 "general_movsrc_operand"
6761 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6762 (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"))
6763 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6766 && (arith_reg_operand (operands[0], SFmode)
6767 || arith_reg_operand (operands[1], SFmode)
6768 || arith_reg_operand (operands[3], SImode)
6769 || (fpul_operand (operands[0], SFmode)
6770 && memory_operand (operands[1], SFmode)
6771 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6772 || (fpul_operand (operands[1], SFmode)
6773 && memory_operand (operands[0], SFmode)
6774 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6794 ! move optimized away"
6795 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6796 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6797 (set_attr_alternative "length"
6804 (match_test "TARGET_SH2A")
6805 (const_int 4) (const_int 2))
6807 (match_test "TARGET_SH2A")
6808 (const_int 4) (const_int 2))
6811 (match_test "TARGET_SH2A")
6812 (const_int 4) (const_int 2))
6814 (match_test "TARGET_SH2A")
6815 (const_int 4) (const_int 2))
6825 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6826 (const_string "single")
6827 (const_string "single")))])
6830 [(set (match_operand:SF 0 "register_operand" "")
6831 (match_operand:SF 1 "register_operand" ""))
6832 (use (match_operand:PSI 2 "fpscr_operand" ""))
6833 (clobber (reg:SI FPUL_REG))]
6835 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6837 (clobber (scratch:SI))])
6838 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6840 (clobber (scratch:SI))])]
6843 (define_expand "movsf"
6844 [(set (match_operand:SF 0 "general_movdst_operand" "")
6845 (match_operand:SF 1 "general_movsrc_operand" ""))]
6849 if (prepare_move_operands (operands, SFmode))
6853 if (TARGET_SHMEDIA_FPU)
6854 emit_insn (gen_movsf_media (operands[0], operands[1]));
6856 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6861 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6866 (define_insn "mov_nop"
6867 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6870 [(set_attr "length" "0")
6871 (set_attr "type" "nil")])
6873 (define_expand "reload_insf__frn"
6874 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6875 (match_operand:SF 1 "immediate_operand" "FQ"))
6876 (use (reg:PSI FPSCR_REG))
6877 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6881 (define_expand "reload_insi__i_fpul"
6882 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6883 (match_operand:SI 1 "immediate_operand" "i"))
6884 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6888 (define_expand "ptabs"
6889 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6893 if (!TARGET_PT_FIXED)
6895 rtx eq = operands[1];
6897 /* ??? For canonical RTL we really should remove any CONST from EQ
6898 before wrapping it in the AND, and finally wrap the EQ into a
6899 const if is constant. However, for reload we must expose the
6900 input register or symbolic constant, and we can't have
6901 different insn structures outside of the operands for different
6902 alternatives of the same pattern. */
6903 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6906 = (gen_rtx_IF_THEN_ELSE
6909 gen_rtx_MEM (PDImode, operands[1]),
6910 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6911 PDImode, operands[1])));
6915 ;; expanded by ptabs expander.
6916 (define_insn "*extendsipdi_media"
6917 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6918 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6922 (mem:PDI (match_dup 1))
6923 (sign_extend:PDI (match_dup 1))))]
6924 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6928 [(set_attr "type" "ptabs_media,pt_media")
6929 (set_attr "length" "4,*")])
6931 (define_insn "*truncdipdi_media"
6932 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6933 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6937 (mem:PDI (match_dup 1))
6938 (truncate:PDI (match_dup 1))))]
6939 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6943 [(set_attr "type" "ptabs_media,pt_media")
6944 (set_attr "length" "4,*")])
6946 (define_insn "*movsi_y"
6947 [(set (match_operand:SI 0 "register_operand" "=y,y")
6948 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6949 (clobber (match_scratch:SI 2 "=&z,r"))]
6951 && (reload_in_progress || reload_completed)"
6953 [(set_attr "length" "4")
6954 (set_attr "type" "pcload,move")])
6957 [(set (match_operand:SI 0 "register_operand" "")
6958 (match_operand:SI 1 "immediate_operand" ""))
6959 (clobber (match_operand:SI 2 "register_operand" ""))]
6961 [(set (match_dup 2) (match_dup 1))
6962 (set (match_dup 0) (match_dup 2))]
6966 [(set (match_operand:SI 0 "register_operand" "")
6967 (match_operand:SI 1 "memory_operand" ""))
6968 (clobber (reg:SI R0_REG))]
6970 [(set (match_dup 0) (match_dup 1))]
6973 ;; ------------------------------------------------------------------------
6974 ;; Define the real conditional branch instructions.
6975 ;; ------------------------------------------------------------------------
6977 (define_insn "branch_true"
6978 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6979 (label_ref (match_operand 0 "" ""))
6982 "* return output_branch (1, insn, operands);"
6983 [(set_attr "type" "cbranch")])
6985 (define_insn "branch_false"
6986 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6987 (label_ref (match_operand 0 "" ""))
6990 "* return output_branch (0, insn, operands);"
6991 [(set_attr "type" "cbranch")])
6993 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6994 ;; which destination is too far away.
6995 ;; The const_int_operand is distinct for each branch target; it avoids
6996 ;; unwanted matches with redundant_insn.
6997 (define_insn "block_branch_redirect"
6998 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7001 [(set_attr "length" "0")])
7003 ;; This one has the additional purpose to record a possible scratch register
7004 ;; for the following branch.
7005 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7006 ;; because the insn then might be deemed dead and deleted. And we can't
7007 ;; make the use in the jump insn explicit because that would disable
7008 ;; delay slot scheduling from the target.
7009 (define_insn "indirect_jump_scratch"
7010 [(set (match_operand:SI 0 "register_operand" "=r")
7011 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7012 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7015 [(set_attr "length" "0")])
7017 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7018 ;; being pulled into the delay slot of a condbranch that has been made to
7019 ;; jump around the unconditional jump because it was out of range.
7020 (define_insn "stuff_delay_slot"
7022 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7023 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7026 [(set_attr "length" "0")
7027 (set_attr "cond_delay_slot" "yes")])
7029 ;; Conditional branch insns
7031 (define_expand "cbranchint4_media"
7033 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7034 [(match_operand 1 "" "")
7035 (match_operand 2 "" "")])
7036 (match_operand 3 "" "")
7041 enum machine_mode mode = GET_MODE (operands[1]);
7042 if (mode == VOIDmode)
7043 mode = GET_MODE (operands[2]);
7044 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7046 operands[1] = force_reg (mode, operands[1]);
7047 if (CONSTANT_P (operands[2])
7048 && (! satisfies_constraint_I06 (operands[2])))
7049 operands[2] = force_reg (mode, operands[2]);
7053 if (operands[1] != const0_rtx)
7054 operands[1] = force_reg (mode, operands[1]);
7055 if (operands[2] != const0_rtx)
7056 operands[2] = force_reg (mode, operands[2]);
7058 switch (GET_CODE (operands[0]))
7064 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7065 VOIDmode, operands[2], operands[1]);
7066 operands[1] = XEXP (operands[0], 0);
7067 operands[2] = XEXP (operands[0], 1);
7070 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7071 VOIDmode, operands[1], operands[2]);
7074 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7077 (define_expand "cbranchfp4_media"
7079 (if_then_else (match_operator 0 "sh_float_comparison_operator"
7080 [(match_operand 1 "" "")
7081 (match_operand 2 "" "")])
7082 (match_operand 3 "" "")
7087 rtx tmp = gen_reg_rtx (SImode);
7089 if (GET_CODE (operands[0]) == NE)
7090 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7092 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7093 operands[1], operands[2]);
7095 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7097 if (GET_CODE (cmp) == GET_CODE (operands[0]))
7098 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7100 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7102 operands[2] = const0_rtx;
7103 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7106 (define_insn "*beq_media_i"
7108 (if_then_else (match_operator 3 "equality_comparison_operator"
7109 [(match_operand:DI 1 "arith_reg_operand" "r,r")
7110 (match_operand:DI 2 "arith_operand" "r,I06")])
7111 (match_operand 0 "target_operand" "b,b")
7116 b%o3i%' %1, %2, %0%>"
7117 [(set_attr "type" "cbranch_media")])
7119 (define_insn "*beq_media_i32"
7121 (if_then_else (match_operator 3 "equality_comparison_operator"
7122 [(match_operand:SI 1 "arith_reg_operand" "r,r")
7123 (match_operand:SI 2 "arith_operand" "r,I06")])
7124 (match_operand 0 "target_operand" "b,b")
7129 b%o3i%' %1, %2, %0%>"
7130 [(set_attr "type" "cbranch_media")])
7132 (define_insn "*bgt_media_i"
7134 (if_then_else (match_operator 3 "greater_comparison_operator"
7135 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7136 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7137 (match_operand 0 "target_operand" "b")
7140 "b%o3%' %N1, %N2, %0%>"
7141 [(set_attr "type" "cbranch_media")])
7143 (define_insn "*bgt_media_i32"
7145 (if_then_else (match_operator 3 "greater_comparison_operator"
7146 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7147 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7148 (match_operand 0 "target_operand" "b")
7151 "b%o3%' %N1, %N2, %0%>"
7152 [(set_attr "type" "cbranch_media")])
7154 ;; These are only needed to make invert_jump() happy - otherwise, jump
7155 ;; optimization will be silently disabled.
7156 (define_insn "*blt_media_i"
7158 (if_then_else (match_operator 3 "less_comparison_operator"
7159 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7160 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7161 (match_operand 0 "target_operand" "b")
7164 "b%o3%' %N2, %N1, %0%>"
7165 [(set_attr "type" "cbranch_media")])
7167 (define_insn "*blt_media_i32"
7169 (if_then_else (match_operator 3 "less_comparison_operator"
7170 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7171 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7172 (match_operand 0 "target_operand" "b")
7175 "b%o3%' %N2, %N1, %0%>"
7176 [(set_attr "type" "cbranch_media")])
7178 ;; combiner splitter for test-and-branch on single bit in register. This
7179 ;; is endian dependent because the non-paradoxical subreg looks different
7184 (match_operator 3 "equality_comparison_operator"
7185 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7186 "extend_reg_operand" "")
7190 "const_int_operand" "")) 0)
7192 (match_operand 0 "target_operand" "")
7194 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7195 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7196 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7197 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7201 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7202 operands[6] = (GET_CODE (operands[3]) == EQ
7203 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7204 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7207 ; operand 0 is the loop count pseudo register
7208 ; operand 1 is the number of loop iterations or 0 if it is unknown
7209 ; operand 2 is the maximum number of loop iterations
7210 ; operand 3 is the number of levels of enclosed loops
7211 ; operand 4 is the label to jump to at the top of the loop
7213 (define_expand "doloop_end"
7214 [(parallel [(set (pc) (if_then_else
7215 (ne:SI (match_operand:SI 0 "" "")
7217 (label_ref (match_operand 4 "" ""))
7220 (plus:SI (match_dup 0) (const_int -1)))
7221 (clobber (reg:SI T_REG))])]
7225 if (GET_MODE (operands[0]) != SImode)
7230 (define_insn_and_split "doloop_end_split"
7232 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7234 (label_ref (match_operand 1 "" ""))
7236 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7237 (plus (match_dup 2) (const_int -1)))
7238 (clobber (reg:SI T_REG))]
7242 [(parallel [(set (reg:SI T_REG)
7243 (eq:SI (match_dup 2) (const_int 1)))
7244 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7245 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7246 (label_ref (match_dup 1))
7249 [(set_attr "type" "cbranch")])
7252 ;; ------------------------------------------------------------------------
7253 ;; Jump and linkage insns
7254 ;; ------------------------------------------------------------------------
7256 (define_insn "jump_compact"
7258 (label_ref (match_operand 0 "" "")))]
7259 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7262 /* The length is 16 if the delay slot is unfilled. */
7263 if (get_attr_length(insn) > 4)
7264 return output_far_jump(insn, operands[0]);
7266 return \"bra %l0%#\";
7268 [(set_attr "type" "jump")
7269 (set_attr "needs_delay_slot" "yes")])
7271 ;; ??? It would be much saner to explicitly use the scratch register
7272 ;; in the jump insn, and have indirect_jump_scratch only set it,
7273 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7274 ;; from the target then, as it uses simplejump_p.
7275 ;;(define_insn "jump_compact_far"
7277 ;; (label_ref (match_operand 0 "" "")))
7278 ;; (use (match_operand 1 "register_operand" "r")]
7280 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7281 ;; [(set_attr "type" "jump")
7282 ;; (set_attr "needs_delay_slot" "yes")])
7284 (define_insn "jump_media"
7286 (match_operand 0 "target_operand" "b"))]
7289 [(set_attr "type" "jump_media")])
7291 (define_expand "jump"
7293 (label_ref (match_operand 0 "" "")))]
7298 emit_jump_insn (gen_jump_compact (operands[0]));
7299 else if (TARGET_SHMEDIA)
7301 if (reload_in_progress || reload_completed)
7303 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7309 (define_insn "force_mode_for_call"
7310 [(use (reg:PSI FPSCR_REG))]
7313 [(set_attr "length" "0")
7314 (set (attr "fp_mode")
7315 (if_then_else (eq_attr "fpu_single" "yes")
7316 (const_string "single") (const_string "double")))])
7318 (define_insn "calli"
7319 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7320 (match_operand 1 "" ""))
7321 (use (reg:PSI FPSCR_REG))
7322 (clobber (reg:SI PR_REG))]
7326 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7327 return \"jsr/n\\t@%0\";
7329 return \"jsr\\t@%0%#\";
7332 [(set_attr "type" "call")
7333 (set (attr "fp_mode")
7334 (if_then_else (eq_attr "fpu_single" "yes")
7335 (const_string "single") (const_string "double")))
7336 (set_attr "needs_delay_slot" "yes")
7337 (set_attr "fp_set" "unknown")])
7339 ;; This is TBR relative jump instruction for SH2A architecture.
7340 ;; Its use is enabled assigning an attribute "function_vector"
7341 ;; and the vector number to a function during its declaration.
7343 (define_insn "calli_tbr_rel"
7344 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7345 (match_operand 1 "" ""))
7346 (use (reg:PSI FPSCR_REG))
7347 (clobber (reg:SI PR_REG))]
7348 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7351 unsigned HOST_WIDE_INT vect_num;
7352 vect_num = sh2a_get_function_vector_number (operands[0]);
7353 operands[2] = GEN_INT (vect_num * 4);
7355 return \"jsr/n\\t@@(%O2,tbr)\";
7357 [(set_attr "type" "call")
7358 (set (attr "fp_mode")
7359 (if_then_else (eq_attr "fpu_single" "yes")
7360 (const_string "single") (const_string "double")))
7361 (set_attr "needs_delay_slot" "no")
7362 (set_attr "fp_set" "unknown")])
7364 ;; This is a pc-rel call, using bsrf, for use with PIC.
7366 (define_insn "calli_pcrel"
7367 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7368 (match_operand 1 "" ""))
7369 (use (reg:PSI FPSCR_REG))
7370 (use (reg:SI PIC_REG))
7371 (use (match_operand 2 "" ""))
7372 (clobber (reg:SI PR_REG))]
7375 [(set_attr "type" "call")
7376 (set (attr "fp_mode")
7377 (if_then_else (eq_attr "fpu_single" "yes")
7378 (const_string "single") (const_string "double")))
7379 (set_attr "needs_delay_slot" "yes")
7380 (set_attr "fp_set" "unknown")])
7382 (define_insn_and_split "call_pcrel"
7383 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7384 (match_operand 1 "" ""))
7385 (use (reg:PSI FPSCR_REG))
7386 (use (reg:SI PIC_REG))
7387 (clobber (reg:SI PR_REG))
7388 (clobber (match_scratch:SI 2 "=r"))]
7395 rtx lab = PATTERN (gen_call_site ());
7397 if (SYMBOL_REF_LOCAL_P (operands[0]))
7398 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7400 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7401 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7404 [(set_attr "type" "call")
7405 (set (attr "fp_mode")
7406 (if_then_else (eq_attr "fpu_single" "yes")
7407 (const_string "single") (const_string "double")))
7408 (set_attr "needs_delay_slot" "yes")
7409 (set_attr "fp_set" "unknown")])
7411 (define_insn "call_compact"
7412 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7413 (match_operand 1 "" ""))
7414 (match_operand 2 "immediate_operand" "n")
7415 (use (reg:SI R0_REG))
7416 (use (reg:SI R1_REG))
7417 (use (reg:PSI FPSCR_REG))
7418 (clobber (reg:SI PR_REG))]
7419 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7421 [(set_attr "type" "call")
7422 (set (attr "fp_mode")
7423 (if_then_else (eq_attr "fpu_single" "yes")
7424 (const_string "single") (const_string "double")))
7425 (set_attr "needs_delay_slot" "yes")])
7427 (define_insn "call_compact_rettramp"
7428 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7429 (match_operand 1 "" ""))
7430 (match_operand 2 "immediate_operand" "n")
7431 (use (reg:SI R0_REG))
7432 (use (reg:SI R1_REG))
7433 (use (reg:PSI FPSCR_REG))
7434 (clobber (reg:SI R10_REG))
7435 (clobber (reg:SI PR_REG))]
7436 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7438 [(set_attr "type" "call")
7439 (set (attr "fp_mode")
7440 (if_then_else (eq_attr "fpu_single" "yes")
7441 (const_string "single") (const_string "double")))
7442 (set_attr "needs_delay_slot" "yes")])
7444 (define_insn "call_media"
7445 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7446 (match_operand 1 "" ""))
7447 (clobber (reg:DI PR_MEDIA_REG))]
7450 [(set_attr "type" "jump_media")])
7452 (define_insn "call_valuei"
7453 [(set (match_operand 0 "" "=rf")
7454 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7455 (match_operand 2 "" "")))
7456 (use (reg:PSI FPSCR_REG))
7457 (clobber (reg:SI PR_REG))]
7461 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7462 return \"jsr/n\\t@%1\";
7464 return \"jsr\\t@%1%#\";
7466 [(set_attr "type" "call")
7467 (set (attr "fp_mode")
7468 (if_then_else (eq_attr "fpu_single" "yes")
7469 (const_string "single") (const_string "double")))
7470 (set_attr "needs_delay_slot" "yes")
7471 (set_attr "fp_set" "unknown")])
7473 ;; This is TBR relative jump instruction for SH2A architecture.
7474 ;; Its use is enabled by assigning an attribute "function_vector"
7475 ;; and the vector number to a function during its declaration.
7477 (define_insn "call_valuei_tbr_rel"
7478 [(set (match_operand 0 "" "=rf")
7479 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7480 (match_operand 2 "" "")))
7481 (use (reg:PSI FPSCR_REG))
7482 (clobber (reg:SI PR_REG))]
7483 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7486 unsigned HOST_WIDE_INT vect_num;
7487 vect_num = sh2a_get_function_vector_number (operands[1]);
7488 operands[3] = GEN_INT (vect_num * 4);
7490 return \"jsr/n\\t@@(%O3,tbr)\";
7492 [(set_attr "type" "call")
7493 (set (attr "fp_mode")
7494 (if_then_else (eq_attr "fpu_single" "yes")
7495 (const_string "single") (const_string "double")))
7496 (set_attr "needs_delay_slot" "no")
7497 (set_attr "fp_set" "unknown")])
7499 (define_insn "call_valuei_pcrel"
7500 [(set (match_operand 0 "" "=rf")
7501 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7502 (match_operand 2 "" "")))
7503 (use (reg:PSI FPSCR_REG))
7504 (use (reg:SI PIC_REG))
7505 (use (match_operand 3 "" ""))
7506 (clobber (reg:SI PR_REG))]
7509 [(set_attr "type" "call")
7510 (set (attr "fp_mode")
7511 (if_then_else (eq_attr "fpu_single" "yes")
7512 (const_string "single") (const_string "double")))
7513 (set_attr "needs_delay_slot" "yes")
7514 (set_attr "fp_set" "unknown")])
7516 (define_insn_and_split "call_value_pcrel"
7517 [(set (match_operand 0 "" "=rf")
7518 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7519 (match_operand 2 "" "")))
7520 (use (reg:PSI FPSCR_REG))
7521 (use (reg:SI PIC_REG))
7522 (clobber (reg:SI PR_REG))
7523 (clobber (match_scratch:SI 3 "=r"))]
7530 rtx lab = PATTERN (gen_call_site ());
7532 if (SYMBOL_REF_LOCAL_P (operands[1]))
7533 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7535 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7536 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7537 operands[2], copy_rtx (lab)));
7540 [(set_attr "type" "call")
7541 (set (attr "fp_mode")
7542 (if_then_else (eq_attr "fpu_single" "yes")
7543 (const_string "single") (const_string "double")))
7544 (set_attr "needs_delay_slot" "yes")
7545 (set_attr "fp_set" "unknown")])
7547 (define_insn "call_value_compact"
7548 [(set (match_operand 0 "" "=rf")
7549 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7550 (match_operand 2 "" "")))
7551 (match_operand 3 "immediate_operand" "n")
7552 (use (reg:SI R0_REG))
7553 (use (reg:SI R1_REG))
7554 (use (reg:PSI FPSCR_REG))
7555 (clobber (reg:SI PR_REG))]
7556 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7558 [(set_attr "type" "call")
7559 (set (attr "fp_mode")
7560 (if_then_else (eq_attr "fpu_single" "yes")
7561 (const_string "single") (const_string "double")))
7562 (set_attr "needs_delay_slot" "yes")])
7564 (define_insn "call_value_compact_rettramp"
7565 [(set (match_operand 0 "" "=rf")
7566 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7567 (match_operand 2 "" "")))
7568 (match_operand 3 "immediate_operand" "n")
7569 (use (reg:SI R0_REG))
7570 (use (reg:SI R1_REG))
7571 (use (reg:PSI FPSCR_REG))
7572 (clobber (reg:SI R10_REG))
7573 (clobber (reg:SI PR_REG))]
7574 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7576 [(set_attr "type" "call")
7577 (set (attr "fp_mode")
7578 (if_then_else (eq_attr "fpu_single" "yes")
7579 (const_string "single") (const_string "double")))
7580 (set_attr "needs_delay_slot" "yes")])
7582 (define_insn "call_value_media"
7583 [(set (match_operand 0 "" "=rf")
7584 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7585 (match_operand 2 "" "")))
7586 (clobber (reg:DI PR_MEDIA_REG))]
7589 [(set_attr "type" "jump_media")])
7591 (define_expand "call"
7592 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7593 (match_operand 1 "" ""))
7594 (match_operand 2 "" "")
7595 (use (reg:PSI FPSCR_REG))
7596 (clobber (reg:SI PR_REG))])]
7602 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7603 emit_call_insn (gen_call_media (operands[0], operands[1]));
7606 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7608 rtx cookie_rtx = operands[2];
7609 long cookie = INTVAL (cookie_rtx);
7610 rtx func = XEXP (operands[0], 0);
7615 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7617 rtx reg = gen_reg_rtx (Pmode);
7619 emit_insn (gen_symGOTPLT2reg (reg, func));
7623 func = legitimize_pic_address (func, Pmode, 0);
7626 r0 = gen_rtx_REG (SImode, R0_REG);
7627 r1 = gen_rtx_REG (SImode, R1_REG);
7629 /* Since such a call function may use all call-clobbered
7630 registers, we force a mode switch earlier, so that we don't
7631 run out of registers when adjusting fpscr for the call. */
7632 emit_insn (gen_force_mode_for_call ());
7635 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637 operands[0] = force_reg (SImode, operands[0]);
7639 emit_move_insn (r0, func);
7640 emit_move_insn (r1, cookie_rtx);
7642 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7643 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7646 emit_call_insn (gen_call_compact (operands[0], operands[1],
7651 else if (TARGET_SHCOMPACT && flag_pic
7652 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7653 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7655 rtx reg = gen_reg_rtx (Pmode);
7657 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7658 XEXP (operands[0], 0) = reg;
7660 if (!flag_pic && TARGET_SH2A
7661 && MEM_P (operands[0])
7662 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7664 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7666 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7671 if (flag_pic && TARGET_SH2
7672 && MEM_P (operands[0])
7673 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7675 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7680 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7681 operands[1] = operands[2];
7684 emit_call_insn (gen_calli (operands[0], operands[1]));
7688 (define_insn "call_pop_compact"
7689 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7690 (match_operand 1 "" ""))
7691 (match_operand 2 "immediate_operand" "n")
7692 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7693 (match_operand 3 "immediate_operand" "n")))
7694 (use (reg:SI R0_REG))
7695 (use (reg:SI R1_REG))
7696 (use (reg:PSI FPSCR_REG))
7697 (clobber (reg:SI PR_REG))]
7698 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7700 [(set_attr "type" "call")
7701 (set (attr "fp_mode")
7702 (if_then_else (eq_attr "fpu_single" "yes")
7703 (const_string "single") (const_string "double")))
7704 (set_attr "needs_delay_slot" "yes")])
7706 (define_insn "call_pop_compact_rettramp"
7707 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7708 (match_operand 1 "" ""))
7709 (match_operand 2 "immediate_operand" "n")
7710 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7711 (match_operand 3 "immediate_operand" "n")))
7712 (use (reg:SI R0_REG))
7713 (use (reg:SI R1_REG))
7714 (use (reg:PSI FPSCR_REG))
7715 (clobber (reg:SI R10_REG))
7716 (clobber (reg:SI PR_REG))]
7717 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7719 [(set_attr "type" "call")
7720 (set (attr "fp_mode")
7721 (if_then_else (eq_attr "fpu_single" "yes")
7722 (const_string "single") (const_string "double")))
7723 (set_attr "needs_delay_slot" "yes")])
7725 (define_expand "call_pop"
7726 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7727 (match_operand 1 "" ""))
7728 (match_operand 2 "" "")
7729 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7730 (match_operand 3 "" "")))])]
7739 gcc_assert (operands[2] && INTVAL (operands[2]));
7740 cookie_rtx = operands[2];
7741 cookie = INTVAL (cookie_rtx);
7742 func = XEXP (operands[0], 0);
7746 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7748 rtx reg = gen_reg_rtx (Pmode);
7749 emit_insn (gen_symGOTPLT2reg (reg, func));
7753 func = legitimize_pic_address (func, Pmode, 0);
7756 r0 = gen_rtx_REG (SImode, R0_REG);
7757 r1 = gen_rtx_REG (SImode, R1_REG);
7759 /* Since such a call function may use all call-clobbered
7760 registers, we force a mode switch earlier, so that we don't
7761 run out of registers when adjusting fpscr for the call. */
7762 emit_insn (gen_force_mode_for_call ());
7764 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7766 operands[0] = force_reg (SImode, operands[0]);
7768 emit_move_insn (r0, func);
7769 emit_move_insn (r1, cookie_rtx);
7771 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7772 emit_call_insn (gen_call_pop_compact_rettramp
7773 (operands[0], operands[1], operands[2], operands[3]));
7775 emit_call_insn (gen_call_pop_compact
7776 (operands[0], operands[1], operands[2], operands[3]));
7781 (define_expand "call_value"
7782 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7783 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7784 (match_operand 2 "" "")))
7785 (match_operand 3 "" "")
7786 (use (reg:PSI FPSCR_REG))
7787 (clobber (reg:SI PR_REG))])]
7793 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7794 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7798 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7800 rtx cookie_rtx = operands[3];
7801 long cookie = INTVAL (cookie_rtx);
7802 rtx func = XEXP (operands[1], 0);
7807 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7809 rtx reg = gen_reg_rtx (Pmode);
7811 emit_insn (gen_symGOTPLT2reg (reg, func));
7815 func = legitimize_pic_address (func, Pmode, 0);
7818 r0 = gen_rtx_REG (SImode, R0_REG);
7819 r1 = gen_rtx_REG (SImode, R1_REG);
7821 /* Since such a call function may use all call-clobbered
7822 registers, we force a mode switch earlier, so that we don't
7823 run out of registers when adjusting fpscr for the call. */
7824 emit_insn (gen_force_mode_for_call ());
7827 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7829 operands[1] = force_reg (SImode, operands[1]);
7831 emit_move_insn (r0, func);
7832 emit_move_insn (r1, cookie_rtx);
7834 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7835 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7840 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7841 operands[2], operands[3]));
7845 else if (TARGET_SHCOMPACT && flag_pic
7846 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7847 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7849 rtx reg = gen_reg_rtx (Pmode);
7851 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7852 XEXP (operands[1], 0) = reg;
7854 if (!flag_pic && TARGET_SH2A
7855 && MEM_P (operands[1])
7856 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7858 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7860 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7861 XEXP (operands[1], 0), operands[2]));
7865 if (flag_pic && TARGET_SH2
7866 && MEM_P (operands[1])
7867 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7869 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7874 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7876 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7880 (define_insn "sibcalli"
7881 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7882 (match_operand 1 "" ""))
7883 (use (reg:PSI FPSCR_REG))
7887 [(set_attr "needs_delay_slot" "yes")
7888 (set (attr "fp_mode")
7889 (if_then_else (eq_attr "fpu_single" "yes")
7890 (const_string "single") (const_string "double")))
7891 (set_attr "type" "jump_ind")])
7893 (define_insn "sibcalli_pcrel"
7894 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7895 (match_operand 1 "" ""))
7896 (use (match_operand 2 "" ""))
7897 (use (reg:PSI FPSCR_REG))
7901 [(set_attr "needs_delay_slot" "yes")
7902 (set (attr "fp_mode")
7903 (if_then_else (eq_attr "fpu_single" "yes")
7904 (const_string "single") (const_string "double")))
7905 (set_attr "type" "jump_ind")])
7907 ;; This uses an unspec to describe that the symbol_ref is very close.
7908 (define_insn "sibcalli_thunk"
7909 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7911 (match_operand 1 "" ""))
7912 (use (reg:PSI FPSCR_REG))
7916 [(set_attr "needs_delay_slot" "yes")
7917 (set (attr "fp_mode")
7918 (if_then_else (eq_attr "fpu_single" "yes")
7919 (const_string "single") (const_string "double")))
7920 (set_attr "type" "jump")
7921 (set_attr "length" "2")])
7923 (define_insn_and_split "sibcall_pcrel"
7924 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7925 (match_operand 1 "" ""))
7926 (use (reg:PSI FPSCR_REG))
7927 (clobber (match_scratch:SI 2 "=k"))
7935 rtx lab = PATTERN (gen_call_site ());
7938 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7939 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7941 SIBLING_CALL_P (call_insn) = 1;
7944 [(set_attr "needs_delay_slot" "yes")
7945 (set (attr "fp_mode")
7946 (if_then_else (eq_attr "fpu_single" "yes")
7947 (const_string "single") (const_string "double")))
7948 (set_attr "type" "jump_ind")])
7950 (define_insn "sibcall_compact"
7951 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7952 (match_operand 1 "" ""))
7954 (use (match_operand:SI 2 "register_operand" "z,x"))
7955 (use (reg:SI R1_REG))
7956 (use (reg:PSI FPSCR_REG))
7957 ;; We want to make sure the `x' above will only match MACH_REG
7958 ;; because sibcall_epilogue may clobber MACL_REG.
7959 (clobber (reg:SI MACL_REG))]
7963 jmp @%0\\n sts %2, r0"
7964 [(set_attr "needs_delay_slot" "yes,no")
7965 (set_attr "length" "2,4")
7966 (set (attr "fp_mode") (const_string "single"))
7967 (set_attr "type" "jump_ind")])
7969 (define_insn "sibcall_media"
7970 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7971 (match_operand 1 "" ""))
7972 (use (reg:SI PR_MEDIA_REG))
7976 [(set_attr "type" "jump_media")])
7978 (define_expand "sibcall"
7980 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7981 (match_operand 1 "" ""))
7982 (match_operand 2 "" "")
7983 (use (reg:PSI FPSCR_REG))
7990 operands[0] = shmedia_prepare_call_address (operands[0], 1);
7991 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7994 else if (TARGET_SHCOMPACT && operands[2]
7995 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7997 rtx cookie_rtx = operands[2];
7998 long cookie = INTVAL (cookie_rtx);
7999 rtx func = XEXP (operands[0], 0);
8004 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8006 rtx reg = gen_reg_rtx (Pmode);
8008 emit_insn (gen_symGOT2reg (reg, func));
8012 func = legitimize_pic_address (func, Pmode, 0);
8015 /* FIXME: if we could tell whether all argument registers are
8016 already taken, we could decide whether to force the use of
8017 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8018 simple way to tell. We could use the CALL_COOKIE, but we
8019 can't currently tell a register used for regular argument
8020 passing from one that is unused. If we leave it up to reload
8021 to decide which register to use, it seems to always choose
8022 R0_REG, which leaves no available registers in SIBCALL_REGS
8023 to hold the address of the trampoline. */
8024 mach = gen_rtx_REG (SImode, MACH_REG);
8025 r1 = gen_rtx_REG (SImode, R1_REG);
8027 /* Since such a call function may use all call-clobbered
8028 registers, we force a mode switch earlier, so that we don't
8029 run out of registers when adjusting fpscr for the call. */
8030 emit_insn (gen_force_mode_for_call ());
8033 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8035 operands[0] = force_reg (SImode, operands[0]);
8037 /* We don't need a return trampoline, since the callee will
8038 return directly to the upper caller. */
8039 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8041 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8042 cookie_rtx = GEN_INT (cookie);
8045 emit_move_insn (mach, func);
8046 emit_move_insn (r1, cookie_rtx);
8048 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8051 else if (TARGET_SHCOMPACT && flag_pic
8052 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8053 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8055 rtx reg = gen_reg_rtx (Pmode);
8057 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8058 XEXP (operands[0], 0) = reg;
8060 if (flag_pic && TARGET_SH2
8061 && MEM_P (operands[0])
8062 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8063 /* The PLT needs the PIC register, but the epilogue would have
8064 to restore it, so we can only use PC-relative PIC calls for
8065 static functions. */
8066 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8068 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8072 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8074 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8078 (define_insn "sibcall_valuei"
8079 [(set (match_operand 0 "" "=rf")
8080 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8081 (match_operand 2 "" "")))
8082 (use (reg:PSI FPSCR_REG))
8086 [(set_attr "needs_delay_slot" "yes")
8087 (set (attr "fp_mode")
8088 (if_then_else (eq_attr "fpu_single" "yes")
8089 (const_string "single") (const_string "double")))
8090 (set_attr "type" "jump_ind")])
8092 (define_insn "sibcall_valuei_pcrel"
8093 [(set (match_operand 0 "" "=rf")
8094 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8095 (match_operand 2 "" "")))
8096 (use (match_operand 3 "" ""))
8097 (use (reg:PSI FPSCR_REG))
8101 [(set_attr "needs_delay_slot" "yes")
8102 (set (attr "fp_mode")
8103 (if_then_else (eq_attr "fpu_single" "yes")
8104 (const_string "single") (const_string "double")))
8105 (set_attr "type" "jump_ind")])
8107 (define_insn_and_split "sibcall_value_pcrel"
8108 [(set (match_operand 0 "" "=rf")
8109 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8110 (match_operand 2 "" "")))
8111 (use (reg:PSI FPSCR_REG))
8112 (clobber (match_scratch:SI 3 "=k"))
8120 rtx lab = PATTERN (gen_call_site ());
8123 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8124 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8128 SIBLING_CALL_P (call_insn) = 1;
8131 [(set_attr "needs_delay_slot" "yes")
8132 (set (attr "fp_mode")
8133 (if_then_else (eq_attr "fpu_single" "yes")
8134 (const_string "single") (const_string "double")))
8135 (set_attr "type" "jump_ind")])
8137 (define_insn "sibcall_value_compact"
8138 [(set (match_operand 0 "" "=rf,rf")
8139 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8140 (match_operand 2 "" "")))
8142 (use (match_operand:SI 3 "register_operand" "z,x"))
8143 (use (reg:SI R1_REG))
8144 (use (reg:PSI FPSCR_REG))
8145 ;; We want to make sure the `x' above will only match MACH_REG
8146 ;; because sibcall_epilogue may clobber MACL_REG.
8147 (clobber (reg:SI MACL_REG))]
8151 jmp @%1\\n sts %3, r0"
8152 [(set_attr "needs_delay_slot" "yes,no")
8153 (set_attr "length" "2,4")
8154 (set (attr "fp_mode") (const_string "single"))
8155 (set_attr "type" "jump_ind")])
8157 (define_insn "sibcall_value_media"
8158 [(set (match_operand 0 "" "=rf")
8159 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8160 (match_operand 2 "" "")))
8161 (use (reg:SI PR_MEDIA_REG))
8165 [(set_attr "type" "jump_media")])
8167 (define_expand "sibcall_value"
8169 [(set (match_operand 0 "arith_reg_operand" "")
8170 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8171 (match_operand 2 "" "")))
8172 (match_operand 3 "" "")
8173 (use (reg:PSI FPSCR_REG))
8180 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8181 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8185 else if (TARGET_SHCOMPACT && operands[3]
8186 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8188 rtx cookie_rtx = operands[3];
8189 long cookie = INTVAL (cookie_rtx);
8190 rtx func = XEXP (operands[1], 0);
8195 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8197 rtx reg = gen_reg_rtx (Pmode);
8199 emit_insn (gen_symGOT2reg (reg, func));
8203 func = legitimize_pic_address (func, Pmode, 0);
8206 /* FIXME: if we could tell whether all argument registers are
8207 already taken, we could decide whether to force the use of
8208 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8209 simple way to tell. We could use the CALL_COOKIE, but we
8210 can't currently tell a register used for regular argument
8211 passing from one that is unused. If we leave it up to reload
8212 to decide which register to use, it seems to always choose
8213 R0_REG, which leaves no available registers in SIBCALL_REGS
8214 to hold the address of the trampoline. */
8215 mach = gen_rtx_REG (SImode, MACH_REG);
8216 r1 = gen_rtx_REG (SImode, R1_REG);
8218 /* Since such a call function may use all call-clobbered
8219 registers, we force a mode switch earlier, so that we don't
8220 run out of registers when adjusting fpscr for the call. */
8221 emit_insn (gen_force_mode_for_call ());
8224 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8226 operands[1] = force_reg (SImode, operands[1]);
8228 /* We don't need a return trampoline, since the callee will
8229 return directly to the upper caller. */
8230 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8232 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8233 cookie_rtx = GEN_INT (cookie);
8236 emit_move_insn (mach, func);
8237 emit_move_insn (r1, cookie_rtx);
8239 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8240 operands[2], mach));
8243 else if (TARGET_SHCOMPACT && flag_pic
8244 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8245 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8247 rtx reg = gen_reg_rtx (Pmode);
8249 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8250 XEXP (operands[1], 0) = reg;
8252 if (flag_pic && TARGET_SH2
8253 && MEM_P (operands[1])
8254 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8255 /* The PLT needs the PIC register, but the epilogue would have
8256 to restore it, so we can only use PC-relative PIC calls for
8257 static functions. */
8258 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8260 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8261 XEXP (operands[1], 0),
8266 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8268 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8272 (define_insn "call_value_pop_compact"
8273 [(set (match_operand 0 "" "=rf")
8274 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8275 (match_operand 2 "" "")))
8276 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8277 (match_operand 4 "immediate_operand" "n")))
8278 (match_operand 3 "immediate_operand" "n")
8279 (use (reg:SI R0_REG))
8280 (use (reg:SI R1_REG))
8281 (use (reg:PSI FPSCR_REG))
8282 (clobber (reg:SI PR_REG))]
8283 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8285 [(set_attr "type" "call")
8286 (set (attr "fp_mode")
8287 (if_then_else (eq_attr "fpu_single" "yes")
8288 (const_string "single") (const_string "double")))
8289 (set_attr "needs_delay_slot" "yes")])
8291 (define_insn "call_value_pop_compact_rettramp"
8292 [(set (match_operand 0 "" "=rf")
8293 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8294 (match_operand 2 "" "")))
8295 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8296 (match_operand 4 "immediate_operand" "n")))
8297 (match_operand 3 "immediate_operand" "n")
8298 (use (reg:SI R0_REG))
8299 (use (reg:SI R1_REG))
8300 (use (reg:PSI FPSCR_REG))
8301 (clobber (reg:SI R10_REG))
8302 (clobber (reg:SI PR_REG))]
8303 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8305 [(set_attr "type" "call")
8306 (set (attr "fp_mode")
8307 (if_then_else (eq_attr "fpu_single" "yes")
8308 (const_string "single") (const_string "double")))
8309 (set_attr "needs_delay_slot" "yes")])
8311 (define_expand "call_value_pop"
8312 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8313 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8314 (match_operand 2 "" "")))
8315 (match_operand 3 "" "")
8316 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8317 (match_operand 4 "" "")))])]
8326 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8327 cookie_rtx = operands[3];
8328 cookie = INTVAL (cookie_rtx);
8329 func = XEXP (operands[1], 0);
8333 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8335 rtx reg = gen_reg_rtx (Pmode);
8337 emit_insn (gen_symGOTPLT2reg (reg, func));
8341 func = legitimize_pic_address (func, Pmode, 0);
8344 r0 = gen_rtx_REG (SImode, R0_REG);
8345 r1 = gen_rtx_REG (SImode, R1_REG);
8347 /* Since such a call function may use all call-clobbered
8348 registers, we force a mode switch earlier, so that we don't
8349 run out of registers when adjusting fpscr for the call. */
8350 emit_insn (gen_force_mode_for_call ());
8352 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8354 operands[1] = force_reg (SImode, operands[1]);
8356 emit_move_insn (r0, func);
8357 emit_move_insn (r1, cookie_rtx);
8359 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8360 emit_call_insn (gen_call_value_pop_compact_rettramp
8361 (operands[0], operands[1], operands[2],
8362 operands[3], operands[4]));
8364 emit_call_insn (gen_call_value_pop_compact
8365 (operands[0], operands[1], operands[2],
8366 operands[3], operands[4]));
8371 (define_expand "sibcall_epilogue"
8376 sh_expand_epilogue (1);
8377 if (TARGET_SHCOMPACT)
8381 /* If epilogue clobbers r0, preserve it in macl. */
8382 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8383 if ((set = single_set (insn))
8384 && REG_P (SET_DEST (set))
8385 && REGNO (SET_DEST (set)) == R0_REG)
8387 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8388 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8390 /* We can't tell at this point whether the sibcall is a
8391 sibcall_compact and, if it is, whether it uses r0 or
8392 mach as operand 2, so let the instructions that
8393 preserve r0 be optimized away if r0 turns out to be
8395 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8396 emit_move_insn (r0, tmp);
8403 (define_insn "indirect_jump_compact"
8405 (match_operand:SI 0 "arith_reg_operand" "r"))]
8408 [(set_attr "needs_delay_slot" "yes")
8409 (set_attr "type" "jump_ind")])
8411 (define_expand "indirect_jump"
8413 (match_operand 0 "register_operand" ""))]
8417 if (GET_MODE (operands[0]) != Pmode)
8418 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8421 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8422 ;; which can be present in structured code from indirect jumps which can not
8423 ;; be present in structured code. This allows -fprofile-arcs to work.
8425 ;; For SH1 processors.
8426 (define_insn "casesi_jump_1"
8428 (match_operand:SI 0 "register_operand" "r"))
8429 (use (label_ref (match_operand 1 "" "")))]
8432 [(set_attr "needs_delay_slot" "yes")
8433 (set_attr "type" "jump_ind")])
8435 ;; For all later processors.
8436 (define_insn "casesi_jump_2"
8437 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8438 (label_ref (match_operand 1 "" ""))))
8439 (use (label_ref (match_operand 2 "" "")))]
8441 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8443 [(set_attr "needs_delay_slot" "yes")
8444 (set_attr "type" "jump_ind")])
8446 (define_insn "casesi_jump_media"
8447 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8448 (use (label_ref (match_operand 1 "" "")))]
8451 [(set_attr "type" "jump_media")])
8453 ;; Call subroutine returning any type.
8454 ;; ??? This probably doesn't work.
8456 (define_expand "untyped_call"
8457 [(parallel [(call (match_operand 0 "" "")
8459 (match_operand 1 "" "")
8460 (match_operand 2 "" "")])]
8461 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8466 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8468 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8470 rtx set = XVECEXP (operands[2], 0, i);
8471 emit_move_insn (SET_DEST (set), SET_SRC (set));
8474 /* The optimizer does not know that the call sets the function value
8475 registers we stored in the result block. We avoid problems by
8476 claiming that all hard registers are used and clobbered at this
8478 emit_insn (gen_blockage ());
8483 ;; ------------------------------------------------------------------------
8485 ;; ------------------------------------------------------------------------
8488 [(set (reg:SI T_REG)
8489 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8490 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8491 (plus:SI (match_dup 1) (const_int -1)))]
8494 [(set_attr "type" "arith")])
8501 ;; Load address of a label. This is only generated by the casesi expand,
8502 ;; and by machine_dependent_reorg (fixing up fp moves).
8503 ;; This must use unspec, because this only works for labels that are
8507 [(set (reg:SI R0_REG)
8508 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8511 [(set_attr "in_delay_slot" "no")
8512 (set_attr "type" "arith")])
8514 ;; machine_dependent_reorg will make this a `mova'.
8515 (define_insn "mova_const"
8516 [(set (reg:SI R0_REG)
8517 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8520 [(set_attr "in_delay_slot" "no")
8521 (set_attr "type" "arith")])
8523 (define_expand "GOTaddr2picreg"
8524 [(set (reg:SI R0_REG)
8525 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8527 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8528 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8531 if (TARGET_VXWORKS_RTP)
8533 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8534 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8535 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8539 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8540 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8544 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8545 rtx pic = operands[0];
8546 rtx lab = PATTERN (gen_call_site ());
8549 equiv = operands[1];
8550 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8551 UNSPEC_PCREL_SYMOFF);
8552 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8554 if (Pmode == SImode)
8556 emit_insn (gen_movsi_const (pic, operands[1]));
8557 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8561 emit_insn (gen_movdi_const (pic, operands[1]));
8562 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8565 insn = emit_move_insn (operands[0], tr);
8567 set_unique_reg_note (insn, REG_EQUAL, equiv);
8574 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8577 (define_expand "vxworks_picreg"
8578 [(set (reg:SI PIC_REG)
8579 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8580 (set (reg:SI R0_REG)
8581 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8582 (set (reg:SI PIC_REG)
8583 (mem:SI (reg:SI PIC_REG)))
8584 (set (reg:SI PIC_REG)
8585 (mem:SI (plus:SI (reg:SI PIC_REG)
8587 "TARGET_VXWORKS_RTP")
8590 [(set (match_operand 0 "target_reg_operand" "=b")
8591 (const (unspec [(match_operand 1 "" "Csy")]
8592 UNSPEC_DATALABEL)))]
8593 "TARGET_SHMEDIA && flag_pic
8594 && satisfies_constraint_Csy (operands[1])"
8595 "ptb/u datalabel %1, %0"
8596 [(set_attr "type" "ptabs_media")
8597 (set_attr "length" "*")])
8599 (define_insn "ptrel_si"
8600 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8601 (plus:SI (match_operand:SI 1 "register_operand" "r")
8603 (match_operand:SI 2 "" "")]
8605 "%O2: ptrel/u %1, %0"
8606 [(set_attr "type" "ptabs_media")])
8608 (define_insn "ptrel_di"
8609 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8610 (plus:DI (match_operand:DI 1 "register_operand" "r")
8612 (match_operand:DI 2 "" "")]
8614 "%O2: ptrel/u %1, %0"
8615 [(set_attr "type" "ptabs_media")])
8617 (define_expand "builtin_setjmp_receiver"
8618 [(match_operand 0 "" "")]
8622 emit_insn (gen_GOTaddr2picreg ());
8626 (define_expand "call_site"
8627 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8631 static HOST_WIDE_INT i = 0;
8632 operands[0] = GEN_INT (i);
8636 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8637 ;; in symGOT_load expand.
8639 (define_insn_and_split "chk_guard_add"
8640 [(set (match_operand:SI 0 "register_operand" "=&r")
8641 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8646 "TARGET_SH1 && reload_completed"
8647 [(set (match_dup 0) (reg:SI PIC_REG))
8648 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8650 [(set_attr "type" "arith")])
8652 (define_expand "sym_label2reg"
8653 [(set (match_operand:SI 0 "" "")
8654 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8655 (const (plus:SI (match_operand:SI 2 "" "")
8660 (define_expand "symGOT_load"
8661 [(set (match_dup 2) (match_operand 1 "" ""))
8662 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8663 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8669 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8670 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8674 rtx reg = operands[2];
8676 if (Pmode == DImode)
8679 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8681 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8686 emit_insn (gen_movsi_const (reg, operands[1]));
8688 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8692 emit_move_insn (operands[2], operands[1]);
8694 /* When stack protector inserts codes after the result is set to
8695 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8696 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8697 when rX is a GOT address for the guard symbol. Ugly but doesn't
8698 matter because this is a rare situation. */
8700 && flag_stack_protect
8701 && GET_CODE (operands[1]) == CONST
8702 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8703 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8704 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8705 \"__stack_chk_guard\") == 0)
8706 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8708 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8709 gen_rtx_REG (Pmode, PIC_REG)));
8711 /* N.B. This is not constant for a GOTPLT relocation. */
8712 mem = gen_rtx_MEM (Pmode, operands[3]);
8713 MEM_NOTRAP_P (mem) = 1;
8714 /* ??? Should we have a special alias set for the GOT? */
8715 emit_move_insn (operands[0], mem);
8720 (define_expand "sym2GOT"
8721 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8725 (define_expand "symGOT2reg"
8726 [(match_operand 0 "" "") (match_operand 1 "" "")]
8732 gotsym = gen_sym2GOT (operands[1]);
8733 PUT_MODE (gotsym, Pmode);
8734 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8736 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8741 (define_expand "symGOTPLT2reg"
8742 [(match_operand 0 "" "") (match_operand 1 "" "")]
8746 rtx pltsym = gen_rtx_CONST (Pmode,
8747 gen_rtx_UNSPEC (Pmode,
8748 gen_rtvec (1, operands[1]),
8750 emit_insn (gen_symGOT_load (operands[0], pltsym));
8754 (define_expand "sym2GOTOFF"
8755 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8759 (define_expand "symGOTOFF2reg"
8760 [(match_operand 0 "" "") (match_operand 1 "" "")]
8764 rtx gotoffsym, insn;
8765 rtx t = (!can_create_pseudo_p ()
8767 : gen_reg_rtx (GET_MODE (operands[0])));
8769 gotoffsym = gen_sym2GOTOFF (operands[1]);
8770 PUT_MODE (gotoffsym, Pmode);
8771 emit_move_insn (t, gotoffsym);
8772 insn = emit_move_insn (operands[0],
8773 gen_rtx_PLUS (Pmode, t,
8774 gen_rtx_REG (Pmode, PIC_REG)));
8776 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8781 (define_expand "symPLT_label2reg"
8782 [(set (match_operand:SI 0 "" "")
8785 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8786 (const:SI (plus:SI (match_operand:SI 2 "" "")
8787 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8788 ;; Even though the PIC register is not really used by the call
8789 ;; sequence in which this is expanded, the PLT code assumes the PIC
8790 ;; register is set, so we must not skip its initialization. Since
8791 ;; we only use this expand as part of calling sequences, and never
8792 ;; to take the address of a function, this is the best point to
8793 ;; insert the (use). Using the PLT to take the address of a
8794 ;; function would be wrong, not only because the PLT entry could
8795 ;; then be called from a function that doesn't initialize the PIC
8796 ;; register to the proper GOT, but also because pointers to the
8797 ;; same function might not compare equal, should they be set by
8798 ;; different shared libraries.
8799 (use (reg:SI PIC_REG))]
8803 (define_expand "sym2PIC"
8804 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8808 ;; TLS code generation.
8809 ;; ??? this should be a define_insn_and_split
8810 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8811 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8814 (define_insn "tls_global_dynamic"
8815 [(set (match_operand:SI 0 "register_operand" "=&z")
8816 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8819 (use (reg:PSI FPSCR_REG))
8820 (use (reg:SI PIC_REG))
8821 (clobber (reg:SI PR_REG))
8822 (clobber (scratch:SI))]
8828 \\tmova\\t2f,r0\\n\\
8829 \\tmov.l\\t2f,r1\\n\\
8832 \\tadd\\tr12,r4\\n\\
8836 1:\\t.long\\t%a1@TLSGD\\n\\
8837 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8840 [(set_attr "type" "tls_load")
8841 (set_attr "length" "26")])
8843 (define_insn "tls_local_dynamic"
8844 [(set (match_operand:SI 0 "register_operand" "=&z")
8845 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8848 (use (reg:PSI FPSCR_REG))
8849 (use (reg:SI PIC_REG))
8850 (clobber (reg:SI PR_REG))
8851 (clobber (scratch:SI))]
8857 \\tmova\\t2f,r0\\n\\
8858 \\tmov.l\\t2f,r1\\n\\
8861 \\tadd\\tr12,r4\\n\\
8865 1:\\t.long\\t%a1@TLSLDM\\n\\
8866 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8869 [(set_attr "type" "tls_load")
8870 (set_attr "length" "26")])
8872 (define_expand "sym2DTPOFF"
8873 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8877 (define_expand "symDTPOFF2reg"
8878 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8883 rtx t = (!can_create_pseudo_p ()
8885 : gen_reg_rtx (GET_MODE (operands[0])));
8887 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8888 PUT_MODE (dtpoffsym, Pmode);
8889 emit_move_insn (t, dtpoffsym);
8890 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8894 (define_expand "sym2GOTTPOFF"
8895 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8899 (define_insn "tls_initial_exec"
8900 [(set (match_operand:SI 0 "register_operand" "=&r")
8901 (unspec:SI [(match_operand:SI 1 "" "")]
8903 (use (reg:SI GBR_REG))
8904 (use (reg:SI PIC_REG))
8905 (clobber (reg:SI R0_REG))]
8911 \\tstc\\tgbr,%0\\n\\
8912 \\tmov.l\\t@(r0,r12),r0\\n\\
8916 1:\\t.long\\t%a1\\n\\
8919 [(set_attr "type" "tls_load")
8920 (set_attr "length" "16")])
8922 (define_expand "sym2TPOFF"
8923 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8927 (define_expand "symTPOFF2reg"
8928 [(match_operand 0 "" "") (match_operand 1 "" "")]
8934 tpoffsym = gen_sym2TPOFF (operands[1]);
8935 PUT_MODE (tpoffsym, Pmode);
8936 emit_move_insn (operands[0], tpoffsym);
8940 (define_insn "load_gbr"
8941 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8942 (use (reg:SI GBR_REG))]
8945 [(set_attr "type" "tls_load")])
8947 ;; case instruction for switch statements.
8949 ;; Operand 0 is index
8950 ;; operand 1 is the minimum bound
8951 ;; operand 2 is the maximum bound - minimum bound + 1
8952 ;; operand 3 is CODE_LABEL for the table;
8953 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8955 (define_expand "casesi"
8956 [(match_operand:SI 0 "arith_reg_operand" "")
8957 (match_operand:SI 1 "arith_reg_operand" "")
8958 (match_operand:SI 2 "arith_reg_operand" "")
8959 (match_operand 3 "" "") (match_operand 4 "" "")]
8963 rtx reg = gen_reg_rtx (SImode);
8964 rtx reg2 = gen_reg_rtx (SImode);
8967 rtx reg = gen_reg_rtx (DImode);
8968 rtx reg2 = gen_reg_rtx (DImode);
8969 rtx reg3 = gen_reg_rtx (Pmode);
8970 rtx reg4 = gen_reg_rtx (Pmode);
8971 rtx reg5 = gen_reg_rtx (Pmode);
8974 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8975 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8976 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8978 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8979 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8980 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8981 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8982 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8983 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8984 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8985 (Pmode, operands[3])));
8986 /* Messy: can we subreg to clean this up? */
8987 if (Pmode == DImode)
8988 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8990 load = gen_casesi_load_media (reg4,
8991 gen_rtx_SUBREG (DImode, reg3, 0),
8993 PUT_MODE (SET_SRC (load), Pmode);
8995 /* ??? The following add could be eliminated if we used ptrel. */
8996 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8997 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9001 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9002 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9003 /* If optimizing, casesi_worker depends on the mode of the instruction
9004 before label it 'uses' - operands[3]. */
9005 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9007 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9009 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9011 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9012 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9013 operands[3], but to lab. We will fix this up in
9014 machine_dependent_reorg. */
9019 (define_expand "casesi_0"
9020 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9021 (set (match_dup 4) (minus:SI (match_dup 4)
9022 (match_operand:SI 1 "arith_operand" "")))
9024 (gtu:SI (match_dup 4)
9025 (match_operand:SI 2 "arith_reg_operand" "")))
9027 (if_then_else (ne (reg:SI T_REG)
9029 (label_ref (match_operand 3 "" ""))
9034 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9035 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9036 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9038 (define_insn "casesi_worker_0"
9039 [(set (match_operand:SI 0 "register_operand" "=r,r")
9040 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9041 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9042 (clobber (match_scratch:SI 3 "=X,1"))
9043 (clobber (match_scratch:SI 4 "=&z,z"))]
9048 [(set (match_operand:SI 0 "register_operand" "")
9049 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9050 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9051 (clobber (match_scratch:SI 3 ""))
9052 (clobber (match_scratch:SI 4 ""))]
9053 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9054 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9055 (parallel [(set (match_dup 0)
9056 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9057 (label_ref (match_dup 2))] UNSPEC_CASESI))
9058 (clobber (match_dup 3))])
9059 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9060 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9063 [(set (match_operand:SI 0 "register_operand" "")
9064 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9065 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9066 (clobber (match_scratch:SI 3 ""))
9067 (clobber (match_scratch:SI 4 ""))]
9068 "TARGET_SH2 && reload_completed"
9069 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9070 (parallel [(set (match_dup 0)
9071 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9072 (label_ref (match_dup 2))] UNSPEC_CASESI))
9073 (clobber (match_dup 3))])]
9074 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9076 (define_insn "casesi_worker_1"
9077 [(set (match_operand:SI 0 "register_operand" "=r,r")
9078 (unspec:SI [(reg:SI R0_REG)
9079 (match_operand:SI 1 "register_operand" "0,r")
9080 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9081 (clobber (match_scratch:SI 3 "=X,1"))]
9085 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9087 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9089 switch (GET_MODE (diff_vec))
9092 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9094 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9096 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9097 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9098 return \"mov.b @(r0,%1),%0\";
9103 [(set_attr "length" "4")])
9105 (define_insn "casesi_worker_2"
9106 [(set (match_operand:SI 0 "register_operand" "=r,r")
9107 (unspec:SI [(reg:SI R0_REG)
9108 (match_operand:SI 1 "register_operand" "0,r")
9109 (label_ref (match_operand 2 "" ""))
9110 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9111 (clobber (match_operand:SI 4 "" "=X,1"))]
9112 "TARGET_SH2 && reload_completed && flag_pic"
9115 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9118 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9120 switch (GET_MODE (diff_vec))
9123 output_asm_insn (\"shll2 %1\", operands);
9124 load = \"mov.l @(r0,%1),%0\"; break;
9126 output_asm_insn (\"add %1,%1\", operands);
9127 load = \"mov.w @(r0,%1),%0\"; break;
9129 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9130 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9132 load = \"mov.b @(r0,%1),%0\";
9137 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9140 [(set_attr "length" "8")])
9142 (define_insn "casesi_shift_media"
9143 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9144 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9145 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9150 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9152 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9154 switch (GET_MODE (diff_vec))
9157 return \"shlli %1, 2, %0\";
9159 return \"shlli %1, 1, %0\";
9161 if (rtx_equal_p (operands[0], operands[1]))
9163 return \"add %1, r63, %0\";
9168 [(set_attr "type" "arith_media")])
9170 (define_insn "casesi_load_media"
9171 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9172 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9173 (match_operand:DI 2 "arith_reg_operand" "r")
9174 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9178 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9180 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9182 switch (GET_MODE (diff_vec))
9185 return \"ldx.l %1, %2, %0\";
9188 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9189 return \"ldx.uw %1, %2, %0\";
9191 return \"ldx.w %1, %2, %0\";
9193 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9194 return \"ldx.ub %1, %2, %0\";
9195 return \"ldx.b %1, %2, %0\";
9200 [(set_attr "type" "load_media")])
9202 (define_expand "return"
9204 "reload_completed && ! sh_need_epilogue ()"
9209 emit_jump_insn (gen_return_media ());
9213 if (TARGET_SHCOMPACT
9214 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9216 emit_jump_insn (gen_shcompact_return_tramp ());
9221 (define_insn "*return_i"
9223 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9224 && (crtl->args.info.call_cookie
9225 & CALL_COOKIE_RET_TRAMP (1)))
9227 && lookup_attribute (\"trap_exit\",
9228 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9231 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9232 && !current_function_interrupt)
9237 [(set_attr "type" "return")
9238 (set_attr "needs_delay_slot" "yes")])
9240 ;; trapa has no delay slot.
9241 (define_insn "*return_trapa"
9243 "TARGET_SH1 && !TARGET_SHCOMPACT
9244 && reload_completed"
9246 [(set_attr "type" "return")])
9248 (define_expand "shcompact_return_tramp"
9251 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9254 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9256 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9257 emit_jump_insn (gen_shcompact_return_tramp_i ());
9261 (define_insn "shcompact_return_tramp_i"
9262 [(parallel [(return) (use (reg:SI R0_REG))])]
9264 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9266 [(set_attr "type" "jump_ind")
9267 (set_attr "needs_delay_slot" "yes")])
9269 (define_insn "return_media_i"
9270 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9271 "TARGET_SHMEDIA && reload_completed"
9273 [(set_attr "type" "jump_media")])
9275 (define_insn "return_media_rte"
9277 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9279 [(set_attr "type" "jump_media")])
9281 (define_expand "return_media"
9283 "TARGET_SHMEDIA && reload_completed"
9286 int tr_regno = sh_media_register_for_return ();
9289 if (current_function_interrupt)
9291 emit_jump_insn (gen_return_media_rte ());
9296 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9298 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9300 tr = gen_rtx_REG (Pmode, tr_regno);
9301 emit_move_insn (tr, r18);
9304 tr = gen_rtx_REG (Pmode, tr_regno);
9306 emit_jump_insn (gen_return_media_i (tr));
9310 (define_insn "shcompact_preserve_incoming_args"
9311 [(set (match_operand:SI 0 "register_operand" "+r")
9312 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9315 [(set_attr "length" "0")])
9317 (define_insn "shcompact_incoming_args"
9318 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9319 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9320 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9321 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9322 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9323 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9324 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9325 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9326 (set (mem:BLK (reg:SI MACL_REG))
9327 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9328 (use (reg:SI R0_REG))
9329 (clobber (reg:SI R0_REG))
9330 (clobber (reg:SI MACL_REG))
9331 (clobber (reg:SI MACH_REG))
9332 (clobber (reg:SI PR_REG))]
9335 [(set_attr "needs_delay_slot" "yes")])
9337 (define_insn "shmedia_save_restore_regs_compact"
9338 [(set (reg:SI SP_REG)
9339 (plus:SI (reg:SI SP_REG)
9340 (match_operand:SI 0 "immediate_operand" "i")))
9341 (use (reg:SI R0_REG))
9342 (clobber (reg:SI PR_REG))]
9344 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9345 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9347 [(set_attr "needs_delay_slot" "yes")])
9349 (define_expand "prologue"
9352 "sh_expand_prologue (); DONE;")
9354 (define_expand "epilogue"
9359 sh_expand_epilogue (0);
9360 emit_jump_insn (gen_return ());
9364 (define_expand "eh_return"
9365 [(use (match_operand 0 "register_operand" ""))]
9368 rtx ra = operands[0];
9370 if (TARGET_SHMEDIA64)
9371 emit_insn (gen_eh_set_ra_di (ra));
9373 emit_insn (gen_eh_set_ra_si (ra));
9378 ;; Clobber the return address on the stack. We can't expand this
9379 ;; until we know where it will be put in the stack frame.
9381 (define_insn "eh_set_ra_si"
9382 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9384 (clobber (match_scratch:SI 1 "=&r"))]
9385 "! TARGET_SHMEDIA64"
9388 (define_insn "eh_set_ra_di"
9389 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9391 (clobber (match_scratch:DI 1 "=&r"))]
9396 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9398 (clobber (match_scratch 1 ""))]
9403 sh_set_return_address (operands[0], operands[1]);
9407 (define_insn "blockage"
9408 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9411 [(set_attr "length" "0")])
9413 ;; Define movml instructions for SH2A target. Currently they are
9414 ;; used to push and pop all banked registers only.
9416 (define_insn "movml_push_banked"
9417 [(set (match_operand:SI 0 "register_operand" "=r")
9418 (plus (match_dup 0) (const_int -32)))
9419 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9420 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9421 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9422 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9423 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9424 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9425 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9426 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9427 "TARGET_SH2A && REGNO (operands[0]) == 15"
9429 [(set_attr "in_delay_slot" "no")])
9431 (define_insn "movml_pop_banked"
9432 [(set (match_operand:SI 0 "register_operand" "=r")
9433 (plus (match_dup 0) (const_int 32)))
9434 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9435 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9436 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9437 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9438 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9439 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9440 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9441 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9442 "TARGET_SH2A && REGNO (operands[0]) == 15"
9444 [(set_attr "in_delay_slot" "no")])
9446 ;; ------------------------------------------------------------------------
9448 ;; ------------------------------------------------------------------------
9451 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9452 (eq:SI (reg:SI T_REG) (const_int 1)))]
9455 [(set_attr "type" "arith")])
9457 (define_expand "cstore4_media"
9458 [(set (match_operand:SI 0 "register_operand" "=r")
9459 (match_operator:SI 1 "sh_float_comparison_operator"
9460 [(match_operand 2 "logical_operand" "")
9461 (match_operand 3 "cmp_operand" "")]))]
9465 enum machine_mode mode = GET_MODE (operands[2]);
9466 enum rtx_code code = GET_CODE (operands[1]);
9468 if (mode == VOIDmode)
9469 mode = GET_MODE (operands[3]);
9470 if (operands[2] == const0_rtx)
9472 if (code == EQ || code == NE)
9473 operands[2] = operands[3], operands[3] = const0_rtx;
9476 operands[2] = force_reg (mode, operands[2]);
9477 if (operands[3] != const0_rtx)
9478 operands[3] = force_reg (mode, operands[3]);
9484 swap = invert = !FLOAT_MODE_P (mode);
9489 swap = FLOAT_MODE_P (mode), invert = !swap;
9494 swap = true, invert = false;
9501 swap = invert = false;
9505 swap = invert = true;
9514 rtx tem = operands[2];
9515 operands[2] = operands[3];
9517 code = swap_condition (code);
9522 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9523 code = reverse_condition (code);
9524 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9525 emit_insn (gen_cstore4_media (tem, operands[1],
9526 operands[2], operands[3]));
9529 operands[3] = const0_rtx;
9532 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9535 (define_expand "cstoresi4"
9536 [(set (match_operand:SI 0 "register_operand" "=r")
9537 (match_operator:SI 1 "comparison_operator"
9538 [(match_operand:SI 2 "cmpsi_operand" "")
9539 (match_operand:SI 3 "arith_operand" "")]))]
9540 "TARGET_SH1 || TARGET_SHMEDIA"
9541 "if (TARGET_SHMEDIA)
9543 emit_insn (gen_cstore4_media (operands[0], operands[1],
9544 operands[2], operands[3]));
9548 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9549 && sh_expand_t_scc (operands))
9552 if (! currently_expanding_to_rtl)
9555 sh_emit_compare_and_set (operands, SImode);
9559 (define_expand "cstoredi4"
9560 [(set (match_operand:SI 0 "register_operand" "=r")
9561 (match_operator:SI 1 "comparison_operator"
9562 [(match_operand:DI 2 "arith_operand" "")
9563 (match_operand:DI 3 "arith_operand" "")]))]
9564 "TARGET_SH2 || TARGET_SHMEDIA"
9565 "if (TARGET_SHMEDIA)
9567 emit_insn (gen_cstore4_media (operands[0], operands[1],
9568 operands[2], operands[3]));
9572 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9573 && sh_expand_t_scc (operands))
9576 if (! currently_expanding_to_rtl)
9579 sh_emit_compare_and_set (operands, DImode);
9583 ;; sne moves the complement of the T reg to DEST like this:
9587 ;; This is better than xoring compare result with 1 because it does
9588 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9591 (define_expand "movnegt"
9592 [(set (match_dup 1) (const_int -1))
9593 (parallel [(set (match_operand:SI 0 "" "")
9594 (neg:SI (plus:SI (reg:SI T_REG)
9597 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9602 operands[1] = gen_reg_rtx (SImode);
9605 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9606 ;; This prevents a regression that occurred when we switched from xor to
9610 [(set (match_operand:SI 0 "arith_reg_dest" "")
9611 (plus:SI (reg:SI T_REG)
9614 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9615 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9618 (define_expand "cstoresf4"
9619 [(set (match_operand:SI 0 "register_operand" "=r")
9620 (match_operator:SI 1 "sh_float_comparison_operator"
9621 [(match_operand:SF 2 "arith_operand" "")
9622 (match_operand:SF 3 "arith_operand" "")]))]
9623 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9624 "if (TARGET_SHMEDIA)
9626 emit_insn (gen_cstore4_media (operands[0], operands[1],
9627 operands[2], operands[3]));
9631 if (! currently_expanding_to_rtl)
9634 sh_emit_compare_and_set (operands, SFmode);
9638 (define_expand "cstoredf4"
9639 [(set (match_operand:SI 0 "register_operand" "=r")
9640 (match_operator:SI 1 "sh_float_comparison_operator"
9641 [(match_operand:DF 2 "arith_operand" "")
9642 (match_operand:DF 3 "arith_operand" "")]))]
9643 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9644 "if (TARGET_SHMEDIA)
9646 emit_insn (gen_cstore4_media (operands[0], operands[1],
9647 operands[2], operands[3]));
9651 if (! currently_expanding_to_rtl)
9654 sh_emit_compare_and_set (operands, DFmode);
9658 ;; -------------------------------------------------------------------------
9659 ;; Instructions to cope with inline literal tables
9660 ;; -------------------------------------------------------------------------
9662 ; 2 byte integer in line
9664 (define_insn "consttable_2"
9665 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9666 (match_operand 1 "" "")]
9671 if (operands[1] != const0_rtx)
9672 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9675 [(set_attr "length" "2")
9676 (set_attr "in_delay_slot" "no")])
9678 ; 4 byte integer in line
9680 (define_insn "consttable_4"
9681 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9682 (match_operand 1 "" "")]
9687 if (operands[1] != const0_rtx)
9689 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9690 mark_symbol_refs_as_used (operands[0]);
9694 [(set_attr "length" "4")
9695 (set_attr "in_delay_slot" "no")])
9697 ; 8 byte integer in line
9699 (define_insn "consttable_8"
9700 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9701 (match_operand 1 "" "")]
9706 if (operands[1] != const0_rtx)
9707 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9710 [(set_attr "length" "8")
9711 (set_attr "in_delay_slot" "no")])
9713 ; 4 byte floating point
9715 (define_insn "consttable_sf"
9716 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9717 (match_operand 1 "" "")]
9722 if (operands[1] != const0_rtx)
9725 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9726 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9730 [(set_attr "length" "4")
9731 (set_attr "in_delay_slot" "no")])
9733 ; 8 byte floating point
9735 (define_insn "consttable_df"
9736 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9737 (match_operand 1 "" "")]
9742 if (operands[1] != const0_rtx)
9745 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9746 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9750 [(set_attr "length" "8")
9751 (set_attr "in_delay_slot" "no")])
9753 ;; Alignment is needed for some constant tables; it may also be added for
9754 ;; Instructions at the start of loops, or after unconditional branches.
9755 ;; ??? We would get more accurate lengths if we did instruction
9756 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9757 ;; here is too conservative.
9759 ; align to a two byte boundary
9761 (define_expand "align_2"
9762 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9766 ; align to a four byte boundary
9767 ;; align_4 and align_log are instructions for the starts of loops, or
9768 ;; after unconditional branches, which may take up extra room.
9770 (define_expand "align_4"
9771 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9775 ; align to a cache line boundary
9777 (define_insn "align_log"
9778 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9781 [(set_attr "length" "0")
9782 (set_attr "in_delay_slot" "no")])
9784 ; emitted at the end of the literal table, used to emit the
9785 ; 32bit branch labels if needed.
9787 (define_insn "consttable_end"
9788 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9790 "* return output_jump_label_table ();"
9791 [(set_attr "in_delay_slot" "no")])
9793 ; emitted at the end of the window in the literal table.
9795 (define_insn "consttable_window_end"
9796 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9799 [(set_attr "length" "0")
9800 (set_attr "in_delay_slot" "no")])
9802 ;; -------------------------------------------------------------------------
9804 ;; -------------------------------------------------------------------------
9806 ;; String/block move insn.
9808 (define_expand "movmemsi"
9809 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9810 (mem:BLK (match_operand:BLK 1 "" "")))
9811 (use (match_operand:SI 2 "nonmemory_operand" ""))
9812 (use (match_operand:SI 3 "immediate_operand" ""))
9813 (clobber (reg:SI PR_REG))
9814 (clobber (reg:SI R4_REG))
9815 (clobber (reg:SI R5_REG))
9816 (clobber (reg:SI R0_REG))])]
9817 "TARGET_SH1 && ! TARGET_SH5"
9820 if(expand_block_move (operands))
9825 (define_insn "block_move_real"
9826 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9827 (mem:BLK (reg:SI R5_REG)))
9828 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9829 (clobber (reg:SI PR_REG))
9830 (clobber (reg:SI R0_REG))])]
9831 "TARGET_SH1 && ! TARGET_HARD_SH4"
9833 [(set_attr "type" "sfunc")
9834 (set_attr "needs_delay_slot" "yes")])
9836 (define_insn "block_lump_real"
9837 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9838 (mem:BLK (reg:SI R5_REG)))
9839 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9840 (use (reg:SI R6_REG))
9841 (clobber (reg:SI PR_REG))
9842 (clobber (reg:SI T_REG))
9843 (clobber (reg:SI R4_REG))
9844 (clobber (reg:SI R5_REG))
9845 (clobber (reg:SI R6_REG))
9846 (clobber (reg:SI R0_REG))])]
9847 "TARGET_SH1 && ! TARGET_HARD_SH4"
9849 [(set_attr "type" "sfunc")
9850 (set_attr "needs_delay_slot" "yes")])
9852 (define_insn "block_move_real_i4"
9853 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9854 (mem:BLK (reg:SI R5_REG)))
9855 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9856 (clobber (reg:SI PR_REG))
9857 (clobber (reg:SI R0_REG))
9858 (clobber (reg:SI R1_REG))
9859 (clobber (reg:SI R2_REG))])]
9862 [(set_attr "type" "sfunc")
9863 (set_attr "needs_delay_slot" "yes")])
9865 (define_insn "block_lump_real_i4"
9866 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9867 (mem:BLK (reg:SI R5_REG)))
9868 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9869 (use (reg:SI R6_REG))
9870 (clobber (reg:SI PR_REG))
9871 (clobber (reg:SI T_REG))
9872 (clobber (reg:SI R4_REG))
9873 (clobber (reg:SI R5_REG))
9874 (clobber (reg:SI R6_REG))
9875 (clobber (reg:SI R0_REG))
9876 (clobber (reg:SI R1_REG))
9877 (clobber (reg:SI R2_REG))
9878 (clobber (reg:SI R3_REG))])]
9881 [(set_attr "type" "sfunc")
9882 (set_attr "needs_delay_slot" "yes")])
9884 ;; -------------------------------------------------------------------------
9885 ;; Floating point instructions.
9886 ;; -------------------------------------------------------------------------
9888 ;; ??? All patterns should have a type attribute.
9890 (define_expand "movpsi"
9891 [(set (match_operand:PSI 0 "register_operand" "")
9892 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9893 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9896 ;; The c / m alternative is a fake to guide reload to load directly into
9897 ;; fpscr, since reload doesn't know how to use post-increment.
9898 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9899 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9900 ;; predicate after reload.
9901 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9902 ;; like a mac -> gpr move.
9903 (define_insn "fpu_switch"
9904 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9905 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9907 && (! reload_completed
9908 || true_regnum (operands[0]) != FPSCR_REG
9909 || !MEM_P (operands[1])
9910 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9912 ! precision stays the same
9921 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9922 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9925 [(set (reg:PSI FPSCR_REG)
9926 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9927 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9930 rtx fpscr, mem, new_insn;
9932 fpscr = SET_DEST (PATTERN (curr_insn));
9933 mem = SET_SRC (PATTERN (curr_insn));
9934 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9936 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9937 add_reg_note (new_insn, REG_INC, operands[0]);
9942 [(set (reg:PSI FPSCR_REG)
9943 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9944 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9945 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9948 rtx fpscr, mem, new_insn;
9950 fpscr = SET_DEST (PATTERN (curr_insn));
9951 mem = SET_SRC (PATTERN (curr_insn));
9952 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9954 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9955 add_reg_note (new_insn, REG_INC, operands[0]);
9957 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9958 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9962 ;; ??? This uses the fp unit, but has no type indicating that.
9963 ;; If we did that, this would either give a bogus latency or introduce
9964 ;; a bogus FIFO constraint.
9965 ;; Since this insn is currently only used for prologues/epilogues,
9966 ;; it is probably best to claim no function unit, which matches the
9968 (define_insn "toggle_sz"
9969 [(set (reg:PSI FPSCR_REG)
9970 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9971 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9973 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9975 ;; There's no way we can use it today, since optimize mode switching
9976 ;; doesn't enable us to know from which mode we're switching to the
9977 ;; mode it requests, to tell whether we can use a relative mode switch
9978 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9980 (define_insn "toggle_pr"
9981 [(set (reg:PSI FPSCR_REG)
9982 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9983 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9985 [(set_attr "type" "fpscr_toggle")])
9987 (define_expand "addsf3"
9988 [(set (match_operand:SF 0 "arith_reg_operand" "")
9989 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9990 (match_operand:SF 2 "arith_reg_operand" "")))]
9991 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9996 expand_sf_binop (&gen_addsf3_i, operands);
10001 (define_insn "*addsf3_media"
10002 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10003 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10004 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10005 "TARGET_SHMEDIA_FPU"
10006 "fadd.s %1, %2, %0"
10007 [(set_attr "type" "fparith_media")])
10009 (define_insn_and_split "unary_sf_op"
10010 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10015 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10016 (match_operator:SF 2 "unary_float_operator"
10017 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10018 (parallel [(match_operand 4
10019 "const_int_operand" "n")]))]))
10020 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10021 "TARGET_SHMEDIA_FPU"
10023 "TARGET_SHMEDIA_FPU && reload_completed"
10024 [(set (match_dup 5) (match_dup 6))]
10027 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10028 rtx op1 = gen_rtx_REG (SFmode,
10029 (true_regnum (operands[1])
10030 + (INTVAL (operands[4]) ^ endian)));
10032 operands[7] = gen_rtx_REG (SFmode,
10033 (true_regnum (operands[0])
10034 + (INTVAL (operands[3]) ^ endian)));
10035 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10037 [(set_attr "type" "fparith_media")])
10039 (define_insn_and_split "binary_sf_op0"
10040 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10042 (match_operator:SF 3 "binary_float_operator"
10043 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10044 (parallel [(const_int 0)]))
10045 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10046 (parallel [(const_int 0)]))])
10049 (parallel [(const_int 1)]))))]
10050 "TARGET_SHMEDIA_FPU"
10052 "&& reload_completed"
10053 [(set (match_dup 4) (match_dup 5))]
10056 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10057 rtx op1 = gen_rtx_REG (SFmode,
10058 true_regnum (operands[1]) + endian);
10059 rtx op2 = gen_rtx_REG (SFmode,
10060 true_regnum (operands[2]) + endian);
10062 operands[4] = gen_rtx_REG (SFmode,
10063 true_regnum (operands[0]) + endian);
10064 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10066 [(set_attr "type" "fparith_media")])
10068 (define_insn_and_split "binary_sf_op1"
10069 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10073 (parallel [(const_int 0)]))
10074 (match_operator:SF 3 "binary_float_operator"
10075 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10076 (parallel [(const_int 1)]))
10077 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10078 (parallel [(const_int 1)]))])))]
10079 "TARGET_SHMEDIA_FPU"
10081 "&& reload_completed"
10082 [(set (match_dup 4) (match_dup 5))]
10085 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10086 rtx op1 = gen_rtx_REG (SFmode,
10087 true_regnum (operands[1]) + (1 ^ endian));
10088 rtx op2 = gen_rtx_REG (SFmode,
10089 true_regnum (operands[2]) + (1 ^ endian));
10091 operands[4] = gen_rtx_REG (SFmode,
10092 true_regnum (operands[0]) + (1 ^ endian));
10093 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10095 [(set_attr "type" "fparith_media")])
10097 (define_insn "addsf3_i"
10098 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10099 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10100 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10101 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10104 [(set_attr "type" "fp")
10105 (set_attr "fp_mode" "single")])
10107 (define_expand "subsf3"
10108 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10109 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10110 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10111 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10116 expand_sf_binop (&gen_subsf3_i, operands);
10121 (define_insn "*subsf3_media"
10122 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10123 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10124 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10125 "TARGET_SHMEDIA_FPU"
10126 "fsub.s %1, %2, %0"
10127 [(set_attr "type" "fparith_media")])
10129 (define_insn "subsf3_i"
10130 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10131 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10132 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10133 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10136 [(set_attr "type" "fp")
10137 (set_attr "fp_mode" "single")])
10139 (define_expand "mulsf3"
10140 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10141 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10142 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10143 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10146 (define_insn "*mulsf3_media"
10147 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10148 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10149 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10150 "TARGET_SHMEDIA_FPU"
10151 "fmul.s %1, %2, %0"
10152 [(set_attr "type" "fparith_media")])
10154 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10155 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10156 ;; we start out with a mulsf pattern that does not depend on fpscr.
10157 ;; This is split after combine to introduce the dependency, in order to
10158 ;; get mode switching and scheduling right.
10159 (define_insn_and_split "mulsf3_ie"
10160 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10161 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10162 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10165 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10169 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10170 get_fpscr_rtx ()));
10173 [(set_attr "type" "fp")])
10175 (define_insn "mulsf3_i4"
10176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10177 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10178 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10179 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10182 [(set_attr "type" "fp")
10183 (set_attr "fp_mode" "single")])
10185 (define_insn "mac_media"
10186 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10187 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10188 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10189 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10190 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10191 "fmac.s %1, %2, %0"
10192 [(set_attr "type" "fparith_media")])
10194 (define_insn "*macsf3"
10195 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10196 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10197 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10198 (match_operand:SF 3 "arith_reg_operand" "0")))
10199 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10200 "TARGET_SH2E && TARGET_FMAC"
10202 [(set_attr "type" "fp")
10203 (set_attr "fp_mode" "single")])
10205 (define_expand "divsf3"
10206 [(set (match_operand:SF 0 "arith_reg_operand" "")
10207 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10208 (match_operand:SF 2 "arith_reg_operand" "")))]
10209 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10214 expand_sf_binop (&gen_divsf3_i, operands);
10219 (define_insn "*divsf3_media"
10220 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10221 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10222 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10223 "TARGET_SHMEDIA_FPU"
10224 "fdiv.s %1, %2, %0"
10225 [(set_attr "type" "fdiv_media")])
10227 (define_insn "divsf3_i"
10228 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10229 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10230 (match_operand:SF 2 "arith_reg_operand" "f")))
10231 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10234 [(set_attr "type" "fdiv")
10235 (set_attr "fp_mode" "single")])
10237 (define_insn "floatdisf2"
10238 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10239 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10240 "TARGET_SHMEDIA_FPU"
10242 [(set_attr "type" "fpconv_media")])
10244 (define_expand "floatsisf2"
10245 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10246 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10247 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10250 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10252 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10257 (define_insn "*floatsisf2_media"
10258 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10259 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10260 "TARGET_SHMEDIA_FPU"
10262 [(set_attr "type" "fpconv_media")])
10264 (define_insn "floatsisf2_i4"
10265 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10266 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10267 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10268 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10270 [(set_attr "type" "fp")
10271 (set_attr "fp_mode" "single")])
10273 (define_insn "*floatsisf2_ie"
10274 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10275 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10276 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10278 [(set_attr "type" "fp")])
10280 (define_insn "fix_truncsfdi2"
10281 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10282 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10283 "TARGET_SHMEDIA_FPU"
10285 [(set_attr "type" "fpconv_media")])
10287 (define_expand "fix_truncsfsi2"
10288 [(set (match_operand:SI 0 "fpul_operand" "=y")
10289 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10290 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10293 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10295 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10300 (define_insn "*fix_truncsfsi2_media"
10301 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10302 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10303 "TARGET_SHMEDIA_FPU"
10305 [(set_attr "type" "fpconv_media")])
10307 (define_insn "fix_truncsfsi2_i4"
10308 [(set (match_operand:SI 0 "fpul_operand" "=y")
10309 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10310 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10311 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10313 [(set_attr "type" "ftrc_s")
10314 (set_attr "fp_mode" "single")])
10316 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10317 ;; fix_truncsfsi2_i4.
10318 ;; (define_insn "fix_truncsfsi2_i4_2"
10319 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10320 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10321 ;; (use (reg:PSI FPSCR_REG))
10322 ;; (clobber (reg:SI FPUL_REG))]
10325 ;; [(set_attr "length" "4")
10326 ;; (set_attr "fp_mode" "single")])
10329 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10330 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10331 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10332 ;; (clobber (reg:SI FPUL_REG))]
10334 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10335 ;; (use (match_dup 2))])
10336 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10338 (define_insn "*fixsfsi"
10339 [(set (match_operand:SI 0 "fpul_operand" "=y")
10340 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10341 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10343 [(set_attr "type" "fp")])
10345 (define_insn "cmpgtsf_t"
10346 [(set (reg:SI T_REG)
10347 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10348 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10349 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10351 [(set_attr "type" "fp_cmp")
10352 (set_attr "fp_mode" "single")])
10354 (define_insn "cmpeqsf_t"
10355 [(set (reg:SI T_REG)
10356 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10357 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10358 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10360 [(set_attr "type" "fp_cmp")
10361 (set_attr "fp_mode" "single")])
10363 (define_insn "ieee_ccmpeqsf_t"
10364 [(set (reg:SI T_REG)
10365 (ior:SI (reg:SI T_REG)
10366 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10367 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10368 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10369 "* return output_ieee_ccmpeq (insn, operands);"
10370 [(set_attr "length" "4")])
10373 (define_insn "cmpgtsf_t_i4"
10374 [(set (reg:SI T_REG)
10375 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10376 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10377 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10378 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10380 [(set_attr "type" "fp_cmp")
10381 (set_attr "fp_mode" "single")])
10383 (define_insn "cmpeqsf_t_i4"
10384 [(set (reg:SI T_REG)
10385 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10386 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10387 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10388 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10390 [(set_attr "type" "fp_cmp")
10391 (set_attr "fp_mode" "single")])
10393 (define_insn "*ieee_ccmpeqsf_t_4"
10394 [(set (reg:SI T_REG)
10395 (ior:SI (reg:SI T_REG)
10396 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10397 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10398 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10399 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10400 "* return output_ieee_ccmpeq (insn, operands);"
10401 [(set_attr "length" "4")
10402 (set_attr "fp_mode" "single")])
10404 (define_insn "cmpeqsf_media"
10405 [(set (match_operand:SI 0 "register_operand" "=r")
10406 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10407 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10408 "TARGET_SHMEDIA_FPU"
10409 "fcmpeq.s %1, %2, %0"
10410 [(set_attr "type" "fcmp_media")])
10412 (define_insn "cmpgtsf_media"
10413 [(set (match_operand:SI 0 "register_operand" "=r")
10414 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10415 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10416 "TARGET_SHMEDIA_FPU"
10417 "fcmpgt.s %1, %2, %0"
10418 [(set_attr "type" "fcmp_media")])
10420 (define_insn "cmpgesf_media"
10421 [(set (match_operand:SI 0 "register_operand" "=r")
10422 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10423 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10424 "TARGET_SHMEDIA_FPU"
10425 "fcmpge.s %1, %2, %0"
10426 [(set_attr "type" "fcmp_media")])
10428 (define_insn "cmpunsf_media"
10429 [(set (match_operand:SI 0 "register_operand" "=r")
10430 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10431 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10432 "TARGET_SHMEDIA_FPU"
10433 "fcmpun.s %1, %2, %0"
10434 [(set_attr "type" "fcmp_media")])
10436 (define_expand "cbranchsf4"
10438 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10439 [(match_operand:SF 1 "arith_operand" "")
10440 (match_operand:SF 2 "arith_operand" "")])
10441 (match_operand 3 "" "")
10443 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10446 if (TARGET_SHMEDIA)
10447 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10450 sh_emit_compare_and_branch (operands, SFmode);
10454 (define_expand "negsf2"
10455 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10456 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10457 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10462 expand_sf_unop (&gen_negsf2_i, operands);
10467 (define_insn "*negsf2_media"
10468 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10469 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10470 "TARGET_SHMEDIA_FPU"
10472 [(set_attr "type" "fmove_media")])
10474 (define_insn "negsf2_i"
10475 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10476 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10477 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10480 [(set_attr "type" "fmove")
10481 (set_attr "fp_mode" "single")])
10483 (define_expand "sqrtsf2"
10484 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10485 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10486 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10491 expand_sf_unop (&gen_sqrtsf2_i, operands);
10496 (define_insn "*sqrtsf2_media"
10497 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10498 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10499 "TARGET_SHMEDIA_FPU"
10501 [(set_attr "type" "fdiv_media")])
10503 (define_insn "sqrtsf2_i"
10504 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10505 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10506 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10509 [(set_attr "type" "fdiv")
10510 (set_attr "fp_mode" "single")])
10512 (define_insn "rsqrtsf2"
10513 [(set (match_operand:SF 0 "register_operand" "=f")
10514 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10515 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10516 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10517 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10518 && operands[1] == CONST1_RTX (SFmode)"
10520 [(set_attr "type" "fsrra")
10521 (set_attr "fp_mode" "single")])
10523 (define_insn "fsca"
10524 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10526 (unspec:SF [(mult:SF
10527 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10528 (match_operand:SF 2 "immediate_operand" "i"))
10530 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10532 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10533 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10534 && operands[2] == sh_fsca_int2sf ()"
10536 [(set_attr "type" "fsca")
10537 (set_attr "fp_mode" "single")])
10539 (define_expand "sinsf2"
10540 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10541 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10543 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10546 rtx scaled = gen_reg_rtx (SFmode);
10547 rtx truncated = gen_reg_rtx (SImode);
10548 rtx fsca = gen_reg_rtx (V2SFmode);
10549 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10551 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10552 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10553 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10554 get_fpscr_rtx ()));
10555 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10559 (define_expand "cossf2"
10560 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10561 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10563 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10566 rtx scaled = gen_reg_rtx (SFmode);
10567 rtx truncated = gen_reg_rtx (SImode);
10568 rtx fsca = gen_reg_rtx (V2SFmode);
10569 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10571 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10572 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10573 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10574 get_fpscr_rtx ()));
10575 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10579 (define_expand "sindf2"
10580 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10581 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10583 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10586 rtx scaled = gen_reg_rtx (DFmode);
10587 rtx truncated = gen_reg_rtx (SImode);
10588 rtx fsca = gen_reg_rtx (V2SFmode);
10589 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10590 rtx sfresult = gen_reg_rtx (SFmode);
10592 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10593 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10594 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10595 get_fpscr_rtx ()));
10596 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10597 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10601 (define_expand "cosdf2"
10602 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10603 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10605 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10608 rtx scaled = gen_reg_rtx (DFmode);
10609 rtx truncated = gen_reg_rtx (SImode);
10610 rtx fsca = gen_reg_rtx (V2SFmode);
10611 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10612 rtx sfresult = gen_reg_rtx (SFmode);
10614 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10615 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10616 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10617 get_fpscr_rtx ()));
10618 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10619 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10623 (define_expand "abssf2"
10624 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10625 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10626 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10631 expand_sf_unop (&gen_abssf2_i, operands);
10636 (define_insn "*abssf2_media"
10637 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10638 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10639 "TARGET_SHMEDIA_FPU"
10641 [(set_attr "type" "fmove_media")])
10643 (define_insn "abssf2_i"
10644 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10645 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10646 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10649 [(set_attr "type" "fmove")
10650 (set_attr "fp_mode" "single")])
10652 (define_expand "adddf3"
10653 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10654 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10655 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10656 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10659 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10661 expand_df_binop (&gen_adddf3_i, operands);
10666 (define_insn "*adddf3_media"
10667 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10668 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10669 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10670 "TARGET_SHMEDIA_FPU"
10671 "fadd.d %1, %2, %0"
10672 [(set_attr "type" "dfparith_media")])
10674 (define_insn "adddf3_i"
10675 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10676 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10677 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10678 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10679 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10681 [(set_attr "type" "dfp_arith")
10682 (set_attr "fp_mode" "double")])
10684 (define_expand "subdf3"
10685 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10686 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10687 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10688 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10691 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10693 expand_df_binop (&gen_subdf3_i, operands);
10698 (define_insn "*subdf3_media"
10699 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10700 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10701 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10702 "TARGET_SHMEDIA_FPU"
10703 "fsub.d %1, %2, %0"
10704 [(set_attr "type" "dfparith_media")])
10706 (define_insn "subdf3_i"
10707 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10708 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10709 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10710 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10711 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10713 [(set_attr "type" "dfp_arith")
10714 (set_attr "fp_mode" "double")])
10716 (define_expand "muldf3"
10717 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10718 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10719 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10720 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10723 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10725 expand_df_binop (&gen_muldf3_i, operands);
10730 (define_insn "*muldf3_media"
10731 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10732 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10733 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10734 "TARGET_SHMEDIA_FPU"
10735 "fmul.d %1, %2, %0"
10736 [(set_attr "type" "dfmul_media")])
10738 (define_insn "muldf3_i"
10739 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10740 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10741 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10742 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10743 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10745 [(set_attr "type" "dfp_mul")
10746 (set_attr "fp_mode" "double")])
10748 (define_expand "divdf3"
10749 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10750 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10751 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10752 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10755 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10757 expand_df_binop (&gen_divdf3_i, operands);
10762 (define_insn "*divdf3_media"
10763 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10764 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10765 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10766 "TARGET_SHMEDIA_FPU"
10767 "fdiv.d %1, %2, %0"
10768 [(set_attr "type" "dfdiv_media")])
10770 (define_insn "divdf3_i"
10771 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10772 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10773 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10774 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10775 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10777 [(set_attr "type" "dfdiv")
10778 (set_attr "fp_mode" "double")])
10780 (define_insn "floatdidf2"
10781 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10782 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10783 "TARGET_SHMEDIA_FPU"
10785 [(set_attr "type" "dfpconv_media")])
10787 (define_expand "floatsidf2"
10788 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10789 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10790 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10793 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10795 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10796 get_fpscr_rtx ()));
10801 (define_insn "*floatsidf2_media"
10802 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10803 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10804 "TARGET_SHMEDIA_FPU"
10806 [(set_attr "type" "dfpconv_media")])
10808 (define_insn "floatsidf2_i"
10809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10810 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10811 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10812 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10814 [(set_attr "type" "dfp_conv")
10815 (set_attr "fp_mode" "double")])
10817 (define_insn "fix_truncdfdi2"
10818 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10819 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10820 "TARGET_SHMEDIA_FPU"
10822 [(set_attr "type" "dfpconv_media")])
10824 (define_expand "fix_truncdfsi2"
10825 [(set (match_operand:SI 0 "fpul_operand" "")
10826 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10827 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10830 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10832 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10833 get_fpscr_rtx ()));
10838 (define_insn "*fix_truncdfsi2_media"
10839 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10840 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10841 "TARGET_SHMEDIA_FPU"
10843 [(set_attr "type" "dfpconv_media")])
10845 (define_insn "fix_truncdfsi2_i"
10846 [(set (match_operand:SI 0 "fpul_operand" "=y")
10847 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10848 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10849 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10851 [(set_attr "type" "dfp_conv")
10852 (set_attr "dfp_comp" "no")
10853 (set_attr "fp_mode" "double")])
10855 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10856 ;; fix_truncdfsi2_i.
10857 ;; (define_insn "fix_truncdfsi2_i4"
10858 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10859 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10860 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10861 ;; (clobber (reg:SI FPUL_REG))]
10864 ;; [(set_attr "length" "4")
10865 ;; (set_attr "fp_mode" "double")])
10868 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10869 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10870 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10871 ;; (clobber (reg:SI FPUL_REG))]
10873 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10874 ;; (use (match_dup 2))])
10875 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10877 (define_insn "cmpgtdf_t"
10878 [(set (reg:SI T_REG)
10879 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10880 (match_operand:DF 1 "arith_reg_operand" "f")))
10881 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10882 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10884 [(set_attr "type" "dfp_cmp")
10885 (set_attr "fp_mode" "double")])
10887 (define_insn "cmpeqdf_t"
10888 [(set (reg:SI T_REG)
10889 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10890 (match_operand:DF 1 "arith_reg_operand" "f")))
10891 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10892 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10894 [(set_attr "type" "dfp_cmp")
10895 (set_attr "fp_mode" "double")])
10897 (define_insn "*ieee_ccmpeqdf_t"
10898 [(set (reg:SI T_REG)
10899 (ior:SI (reg:SI T_REG)
10900 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10901 (match_operand:DF 1 "arith_reg_operand" "f"))))
10902 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10903 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10904 "* return output_ieee_ccmpeq (insn, operands);"
10905 [(set_attr "length" "4")
10906 (set_attr "fp_mode" "double")])
10908 (define_insn "cmpeqdf_media"
10909 [(set (match_operand:SI 0 "register_operand" "=r")
10910 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10911 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10912 "TARGET_SHMEDIA_FPU"
10913 "fcmpeq.d %1,%2,%0"
10914 [(set_attr "type" "fcmp_media")])
10916 (define_insn "cmpgtdf_media"
10917 [(set (match_operand:SI 0 "register_operand" "=r")
10918 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10919 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10920 "TARGET_SHMEDIA_FPU"
10921 "fcmpgt.d %1,%2,%0"
10922 [(set_attr "type" "fcmp_media")])
10924 (define_insn "cmpgedf_media"
10925 [(set (match_operand:SI 0 "register_operand" "=r")
10926 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10927 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10928 "TARGET_SHMEDIA_FPU"
10929 "fcmpge.d %1,%2,%0"
10930 [(set_attr "type" "fcmp_media")])
10932 (define_insn "cmpundf_media"
10933 [(set (match_operand:SI 0 "register_operand" "=r")
10934 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10935 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10936 "TARGET_SHMEDIA_FPU"
10937 "fcmpun.d %1,%2,%0"
10938 [(set_attr "type" "fcmp_media")])
10940 (define_expand "cbranchdf4"
10942 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10943 [(match_operand:DF 1 "arith_operand" "")
10944 (match_operand:DF 2 "arith_operand" "")])
10945 (match_operand 3 "" "")
10947 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10950 if (TARGET_SHMEDIA)
10951 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10954 sh_emit_compare_and_branch (operands, DFmode);
10959 (define_expand "negdf2"
10960 [(set (match_operand:DF 0 "arith_reg_operand" "")
10961 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10962 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10965 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10967 expand_df_unop (&gen_negdf2_i, operands);
10972 (define_insn "*negdf2_media"
10973 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10974 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10975 "TARGET_SHMEDIA_FPU"
10977 [(set_attr "type" "fmove_media")])
10979 (define_insn "negdf2_i"
10980 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10981 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10982 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10983 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10985 [(set_attr "type" "fmove")
10986 (set_attr "fp_mode" "double")])
10988 (define_expand "sqrtdf2"
10989 [(set (match_operand:DF 0 "arith_reg_operand" "")
10990 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10991 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10994 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10996 expand_df_unop (&gen_sqrtdf2_i, operands);
11001 (define_insn "*sqrtdf2_media"
11002 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11003 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11004 "TARGET_SHMEDIA_FPU"
11006 [(set_attr "type" "dfdiv_media")])
11008 (define_insn "sqrtdf2_i"
11009 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11010 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11011 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11012 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11014 [(set_attr "type" "dfdiv")
11015 (set_attr "fp_mode" "double")])
11017 (define_expand "absdf2"
11018 [(set (match_operand:DF 0 "arith_reg_operand" "")
11019 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11020 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11023 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11025 expand_df_unop (&gen_absdf2_i, operands);
11030 (define_insn "*absdf2_media"
11031 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11032 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11033 "TARGET_SHMEDIA_FPU"
11035 [(set_attr "type" "fmove_media")])
11037 (define_insn "absdf2_i"
11038 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11039 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11040 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11041 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11043 [(set_attr "type" "fmove")
11044 (set_attr "fp_mode" "double")])
11046 (define_expand "extendsfdf2"
11047 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11048 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11049 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11052 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11054 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11055 get_fpscr_rtx ()));
11060 (define_insn "*extendsfdf2_media"
11061 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11062 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11063 "TARGET_SHMEDIA_FPU"
11065 [(set_attr "type" "dfpconv_media")])
11067 (define_insn "extendsfdf2_i4"
11068 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11069 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11070 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11071 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11073 [(set_attr "type" "fp")
11074 (set_attr "fp_mode" "double")])
11076 (define_expand "truncdfsf2"
11077 [(set (match_operand:SF 0 "fpul_operand" "")
11078 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11079 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11082 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11084 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11085 get_fpscr_rtx ()));
11090 (define_insn "*truncdfsf2_media"
11091 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11092 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11093 "TARGET_SHMEDIA_FPU"
11095 [(set_attr "type" "dfpconv_media")])
11097 (define_insn "truncdfsf2_i4"
11098 [(set (match_operand:SF 0 "fpul_operand" "=y")
11099 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11100 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11101 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11103 [(set_attr "type" "fp")
11104 (set_attr "fp_mode" "double")])
11106 ;; Bit field extract patterns. These give better code for packed bitfields,
11107 ;; because they allow auto-increment addresses to be generated.
11109 (define_expand "insv"
11110 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11111 (match_operand:SI 1 "immediate_operand" "")
11112 (match_operand:SI 2 "immediate_operand" ""))
11113 (match_operand:SI 3 "general_operand" ""))]
11114 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11117 rtx addr_target, orig_address, shift_reg, qi_val;
11118 HOST_WIDE_INT bitsize, size, v = 0;
11119 rtx x = operands[3];
11121 if (TARGET_SH2A && TARGET_BITOPS
11122 && (satisfies_constraint_Sbw (operands[0])
11123 || satisfies_constraint_Sbv (operands[0]))
11124 && satisfies_constraint_M (operands[1])
11125 && satisfies_constraint_K03 (operands[2]))
11127 if (satisfies_constraint_N (operands[3]))
11129 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11132 else if (satisfies_constraint_M (operands[3]))
11134 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11137 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11138 && satisfies_constraint_M (operands[1]))
11140 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11143 else if (REG_P (operands[3])
11144 && satisfies_constraint_M (operands[1]))
11146 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11147 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11151 /* ??? expmed doesn't care for non-register predicates. */
11152 if (! memory_operand (operands[0], VOIDmode)
11153 || ! immediate_operand (operands[1], VOIDmode)
11154 || ! immediate_operand (operands[2], VOIDmode)
11155 || ! general_operand (x, VOIDmode))
11157 /* If this isn't a 16 / 24 / 32 bit field, or if
11158 it doesn't start on a byte boundary, then fail. */
11159 bitsize = INTVAL (operands[1]);
11160 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11161 || (INTVAL (operands[2]) % 8) != 0)
11164 size = bitsize / 8;
11165 orig_address = XEXP (operands[0], 0);
11166 shift_reg = gen_reg_rtx (SImode);
11167 if (CONST_INT_P (x))
11170 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11174 emit_insn (gen_movsi (shift_reg, operands[3]));
11175 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11177 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11179 operands[0] = replace_equiv_address (operands[0], addr_target);
11180 emit_insn (gen_movqi (operands[0], qi_val));
11184 if (CONST_INT_P (x))
11186 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11189 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11190 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11192 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11193 emit_insn (gen_movqi (operands[0], qi_val));
11199 (define_insn "movua"
11200 [(set (match_operand:SI 0 "register_operand" "=z")
11201 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11205 [(set_attr "type" "movua")])
11207 ;; We shouldn't need this, but cse replaces increments with references
11208 ;; to other regs before flow has a chance to create post_inc
11209 ;; addressing modes, and only postreload's cse_move2add brings the
11210 ;; increments back to a usable form.
11212 [(set (match_operand:SI 0 "register_operand" "")
11213 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11214 (const_int 32) (const_int 0)))
11215 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11216 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11217 [(set (match_operand:SI 0 "register_operand" "")
11218 (sign_extract:SI (mem:SI (post_inc:SI
11219 (match_operand:SI 1 "register_operand" "")))
11220 (const_int 32) (const_int 0)))]
11223 (define_expand "extv"
11224 [(set (match_operand:SI 0 "register_operand" "")
11225 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11226 (match_operand 2 "const_int_operand" "")
11227 (match_operand 3 "const_int_operand" "")))]
11228 "TARGET_SH4A_ARCH || TARGET_SH2A"
11230 if (TARGET_SH2A && TARGET_BITOPS
11231 && (satisfies_constraint_Sbw (operands[1])
11232 || satisfies_constraint_Sbv (operands[1]))
11233 && satisfies_constraint_M (operands[2])
11234 && satisfies_constraint_K03 (operands[3]))
11236 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11237 if (REGNO (operands[0]) != T_REG)
11238 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11241 if (TARGET_SH4A_ARCH
11242 && INTVAL (operands[2]) == 32
11243 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11244 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11246 rtx src = adjust_address (operands[1], BLKmode, 0);
11247 set_mem_size (src, 4);
11248 emit_insn (gen_movua (operands[0], src));
11255 (define_expand "extzv"
11256 [(set (match_operand:SI 0 "register_operand" "")
11257 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11258 (match_operand 2 "const_int_operand" "")
11259 (match_operand 3 "const_int_operand" "")))]
11260 "TARGET_SH4A_ARCH || TARGET_SH2A"
11262 if (TARGET_SH2A && TARGET_BITOPS
11263 && (satisfies_constraint_Sbw (operands[1])
11264 || satisfies_constraint_Sbv (operands[1]))
11265 && satisfies_constraint_M (operands[2])
11266 && satisfies_constraint_K03 (operands[3]))
11268 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11269 if (REGNO (operands[0]) != T_REG)
11270 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11273 if (TARGET_SH4A_ARCH
11274 && INTVAL (operands[2]) == 32
11275 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11276 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11278 rtx src = adjust_address (operands[1], BLKmode, 0);
11279 set_mem_size (src, 4);
11280 emit_insn (gen_movua (operands[0], src));
11287 ;; SH2A instructions for bitwise operations.
11289 ;; Clear a bit in a memory location.
11290 (define_insn "bclr_m2a"
11291 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11293 (not:QI (ashift:QI (const_int 1)
11294 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11296 "TARGET_SH2A && TARGET_BITOPS"
11299 bclr.b\\t%1,@(0,%t0)"
11300 [(set_attr "length" "4,4")])
11302 (define_insn "bclrmem_m2a"
11303 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11304 (and:QI (match_dup 0)
11305 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11306 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11309 bclr.b\\t%W1,@(0,%t0)"
11310 [(set_attr "length" "4,4")])
11312 ;; Set a bit in a memory location.
11313 (define_insn "bset_m2a"
11314 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11316 (ashift:QI (const_int 1)
11317 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11319 "TARGET_SH2A && TARGET_BITOPS"
11322 bset.b\\t%1,@(0,%t0)"
11323 [(set_attr "length" "4,4")])
11325 (define_insn "bsetmem_m2a"
11326 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11327 (ior:QI (match_dup 0)
11328 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11329 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11332 bset.b\\t%V1,@(0,%t0)"
11333 [(set_attr "length" "4,4")])
11335 ;;; Transfer the contents of the T bit to a specified bit of memory.
11336 (define_insn "bst_m2a"
11337 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11338 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11340 (not:QI (ashift:QI (const_int 1)
11341 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11344 (ashift:QI (const_int 1) (match_dup 1))
11346 "TARGET_SH2A && TARGET_BITOPS"
11349 bst.b\\t%1,@(0,%t0)"
11350 [(set_attr "length" "4")])
11352 ;; Store a specified bit of memory in the T bit.
11353 (define_insn "bld_m2a"
11354 [(set (reg:SI T_REG)
11356 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11358 (match_operand 1 "const_int_operand" "K03,K03")))]
11359 "TARGET_SH2A && TARGET_BITOPS"
11362 bld.b\\t%1,@(0,%t0)"
11363 [(set_attr "length" "4,4")])
11365 ;; Store a specified bit of memory in the T bit.
11366 (define_insn "bldsign_m2a"
11367 [(set (reg:SI T_REG)
11369 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11371 (match_operand 1 "const_int_operand" "K03,K03")))]
11372 "TARGET_SH2A && TARGET_BITOPS"
11375 bld.b\\t%1,@(0,%t0)"
11376 [(set_attr "length" "4,4")])
11378 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11379 (define_insn "bld_reg"
11380 [(set (reg:SI T_REG)
11381 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11383 (match_operand 1 "const_int_operand" "K03")))]
11387 (define_insn "*bld_regqi"
11388 [(set (reg:SI T_REG)
11389 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11391 (match_operand 1 "const_int_operand" "K03")))]
11395 ;; Take logical and of a specified bit of memory with the T bit and
11396 ;; store its result in the T bit.
11397 (define_insn "band_m2a"
11398 [(set (reg:SI T_REG)
11399 (and:SI (reg:SI T_REG)
11401 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11403 (match_operand 1 "const_int_operand" "K03,K03"))))]
11404 "TARGET_SH2A && TARGET_BITOPS"
11407 band.b\\t%1,@(0,%t0)"
11408 [(set_attr "length" "4,4")])
11410 (define_insn "bandreg_m2a"
11411 [(set (match_operand:SI 0 "register_operand" "=r,r")
11412 (and:SI (zero_extract:SI
11413 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11415 (match_operand 2 "const_int_operand" "K03,K03"))
11416 (match_operand:SI 3 "register_operand" "r,r")))]
11417 "TARGET_SH2A && TARGET_BITOPS"
11419 band.b\\t%2,%1\;movt\\t%0
11420 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11421 [(set_attr "length" "6,6")])
11423 ;; Take logical or of a specified bit of memory with the T bit and
11424 ;; store its result in the T bit.
11425 (define_insn "bor_m2a"
11426 [(set (reg:SI T_REG)
11427 (ior:SI (reg:SI T_REG)
11429 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11431 (match_operand 1 "const_int_operand" "K03,K03"))))]
11432 "TARGET_SH2A && TARGET_BITOPS"
11435 bor.b\\t%1,@(0,%t0)"
11436 [(set_attr "length" "4,4")])
11438 (define_insn "borreg_m2a"
11439 [(set (match_operand:SI 0 "register_operand" "=r,r")
11440 (ior:SI (zero_extract:SI
11441 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11443 (match_operand 2 "const_int_operand" "K03,K03"))
11444 (match_operand:SI 3 "register_operand" "=r,r")))]
11445 "TARGET_SH2A && TARGET_BITOPS"
11447 bor.b\\t%2,%1\;movt\\t%0
11448 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11449 [(set_attr "length" "6,6")])
11451 ;; Take exclusive or of a specified bit of memory with the T bit and
11452 ;; store its result in the T bit.
11453 (define_insn "bxor_m2a"
11454 [(set (reg:SI T_REG)
11455 (xor:SI (reg:SI T_REG)
11457 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11459 (match_operand 1 "const_int_operand" "K03,K03"))))]
11460 "TARGET_SH2A && TARGET_BITOPS"
11463 bxor.b\\t%1,@(0,%t0)"
11464 [(set_attr "length" "4,4")])
11466 (define_insn "bxorreg_m2a"
11467 [(set (match_operand:SI 0 "register_operand" "=r,r")
11468 (xor:SI (zero_extract:SI
11469 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11471 (match_operand 2 "const_int_operand" "K03,K03"))
11472 (match_operand:SI 3 "register_operand" "=r,r")))]
11473 "TARGET_SH2A && TARGET_BITOPS"
11475 bxor.b\\t%2,%1\;movt\\t%0
11476 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11477 [(set_attr "length" "6,6")])
11480 ;; -------------------------------------------------------------------------
11482 ;; -------------------------------------------------------------------------
11483 ;; This matches cases where the bit in a memory location is set.
11485 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11486 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11488 (ior:SI (match_dup 0)
11489 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11491 (match_operand 3 "arith_reg_operand" "r,r"))]
11492 "TARGET_SH2A && TARGET_BITOPS
11493 && satisfies_constraint_Pso (operands[2])
11494 && REGNO (operands[0]) == REGNO (operands[3])"
11495 [(set (match_dup 1)
11496 (ior:QI (match_dup 1)
11500 ;; This matches cases where the bit in a memory location is cleared.
11502 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11503 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11505 (and:SI (match_dup 0)
11506 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11508 (match_operand 3 "arith_reg_operand" "r,r"))]
11509 "TARGET_SH2A && TARGET_BITOPS
11510 && satisfies_constraint_Psz (operands[2])
11511 && REGNO (operands[0]) == REGNO (operands[3])"
11512 [(set (match_dup 1)
11513 (and:QI (match_dup 1)
11517 ;; This matches cases where a stack pointer increment at the start of the
11518 ;; epilogue combines with a stack slot read loading the return value.
11521 [(set (match_operand:SI 0 "arith_reg_operand" "")
11522 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11523 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11524 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11527 ;; See the comment on the dt combiner pattern above.
11530 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11531 (plus:SI (match_dup 0)
11533 (set (reg:SI T_REG)
11534 (eq:SI (match_dup 0)
11539 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11540 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11541 ;; reload when the constant is too large for a reg+offset address.
11543 ;; ??? We would get much better code if this was done in reload. This would
11544 ;; require modifying find_reloads_address to recognize that if the constant
11545 ;; is out-of-range for an immediate add, then we get better code by reloading
11546 ;; the constant into a register than by reloading the sum into a register,
11547 ;; since the former is one instruction shorter if the address does not need
11548 ;; to be offsettable. Unfortunately this does not work, because there is
11549 ;; only one register, r0, that can be used as an index register. This register
11550 ;; is also the function return value register. So, if we try to force reload
11551 ;; to use double-reg addresses, then we end up with some instructions that
11552 ;; need to use r0 twice. The only way to fix this is to change the calling
11553 ;; convention so that r0 is not used to return values.
11556 [(set (match_operand:SI 0 "register_operand" "=r")
11557 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11558 (set (mem:SI (match_dup 0))
11559 (match_operand:SI 2 "general_movsrc_operand" ""))]
11560 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11561 "mov.l %2,@(%0,%1)")
11564 [(set (match_operand:SI 0 "register_operand" "=r")
11565 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11566 (set (match_operand:SI 2 "general_movdst_operand" "")
11567 (mem:SI (match_dup 0)))]
11568 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11569 "mov.l @(%0,%1),%2")
11572 [(set (match_operand:SI 0 "register_operand" "=r")
11573 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11574 (set (mem:HI (match_dup 0))
11575 (match_operand:HI 2 "general_movsrc_operand" ""))]
11576 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11577 "mov.w %2,@(%0,%1)")
11580 [(set (match_operand:SI 0 "register_operand" "=r")
11581 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11582 (set (match_operand:HI 2 "general_movdst_operand" "")
11583 (mem:HI (match_dup 0)))]
11584 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11585 "mov.w @(%0,%1),%2")
11588 [(set (match_operand:SI 0 "register_operand" "=r")
11589 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11590 (set (mem:QI (match_dup 0))
11591 (match_operand:QI 2 "general_movsrc_operand" ""))]
11592 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11593 "mov.b %2,@(%0,%1)")
11596 [(set (match_operand:SI 0 "register_operand" "=r")
11597 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11598 (set (match_operand:QI 2 "general_movdst_operand" "")
11599 (mem:QI (match_dup 0)))]
11600 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11601 "mov.b @(%0,%1),%2")
11604 [(set (match_operand:SI 0 "register_operand" "=r")
11605 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11606 (set (mem:SF (match_dup 0))
11607 (match_operand:SF 2 "general_movsrc_operand" ""))]
11608 "TARGET_SH1 && REGNO (operands[0]) == 0
11609 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11610 || (GET_CODE (operands[2]) == SUBREG
11611 && REGNO (SUBREG_REG (operands[2])) < 16))
11612 && reg_unused_after (operands[0], insn)"
11613 "mov.l %2,@(%0,%1)")
11616 [(set (match_operand:SI 0 "register_operand" "=r")
11617 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11618 (set (match_operand:SF 2 "general_movdst_operand" "")
11620 (mem:SF (match_dup 0)))]
11621 "TARGET_SH1 && REGNO (operands[0]) == 0
11622 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11623 || (GET_CODE (operands[2]) == SUBREG
11624 && REGNO (SUBREG_REG (operands[2])) < 16))
11625 && reg_unused_after (operands[0], insn)"
11626 "mov.l @(%0,%1),%2")
11629 [(set (match_operand:SI 0 "register_operand" "=r")
11630 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11631 (set (mem:SF (match_dup 0))
11632 (match_operand:SF 2 "general_movsrc_operand" ""))]
11633 "TARGET_SH2E && REGNO (operands[0]) == 0
11634 && ((REG_P (operands[2])
11635 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11636 || (GET_CODE (operands[2]) == SUBREG
11637 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11638 && reg_unused_after (operands[0], insn)"
11639 "fmov{.s|} %2,@(%0,%1)")
11642 [(set (match_operand:SI 0 "register_operand" "=r")
11643 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11644 (set (match_operand:SF 2 "general_movdst_operand" "")
11646 (mem:SF (match_dup 0)))]
11647 "TARGET_SH2E && REGNO (operands[0]) == 0
11648 && ((REG_P (operands[2])
11649 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11650 || (GET_CODE (operands[2]) == SUBREG
11651 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11652 && reg_unused_after (operands[0], insn)"
11653 "fmov{.s|} @(%0,%1),%2")
11655 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11656 (define_insn "sp_switch_1"
11657 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11661 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11662 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11663 return \"mov r0,r15\";
11665 [(set_attr "length" "10")])
11667 ;; Switch back to the original stack for interrupt functions with the
11668 ;; sp_switch attribute. */
11669 (define_insn "sp_switch_2"
11672 "mov.l @r15+,r15\;mov.l @r15+,r0"
11673 [(set_attr "length" "4")])
11675 ;; Integer vector moves
11677 (define_expand "movv8qi"
11678 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11679 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11681 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11683 (define_insn "movv8qi_i"
11684 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11685 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11687 && (register_operand (operands[0], V8QImode)
11688 || sh_register_operand (operands[1], V8QImode))"
11695 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11696 (set_attr "length" "4,4,16,4,4")])
11699 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11700 (subreg:V8QI (const_int 0) 0))]
11702 [(set (match_dup 0)
11703 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11704 (const_int 0) (const_int 0) (const_int 0)
11705 (const_int 0) (const_int 0)]))])
11708 [(set (match_operand 0 "arith_reg_dest" "")
11709 (match_operand 1 "sh_rep_vec" ""))]
11710 "TARGET_SHMEDIA && reload_completed
11711 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11712 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11713 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11714 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11715 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11716 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11717 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11718 [(set (match_dup 0) (match_dup 1))
11722 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11723 rtx elt1 = XVECEXP (operands[1], 0, 1);
11726 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11730 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11731 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11733 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11734 operands[1] = XVECEXP (operands[1], 0, 0);
11737 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11739 = GEN_INT (TARGET_LITTLE_ENDIAN
11740 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11741 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11744 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11746 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11752 [(set (match_operand 0 "arith_reg_dest" "")
11753 (match_operand 1 "sh_const_vec" ""))]
11754 "TARGET_SHMEDIA && reload_completed
11755 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11756 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11757 [(set (match_dup 0) (match_dup 1))]
11760 rtx v = operands[1];
11761 enum machine_mode new_mode
11762 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11764 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11766 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11769 (define_expand "movv2hi"
11770 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11771 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11773 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11775 (define_insn "movv2hi_i"
11776 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11777 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11779 && (register_operand (operands[0], V2HImode)
11780 || sh_register_operand (operands[1], V2HImode))"
11787 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11788 (set_attr "length" "4,4,16,4,4")
11789 (set (attr "highpart")
11790 (cond [(match_test "sh_contains_memref_p (insn)")
11791 (const_string "user")]
11792 (const_string "ignore")))])
11794 (define_expand "movv4hi"
11795 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11796 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11798 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11800 (define_insn "movv4hi_i"
11801 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11802 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11804 && (register_operand (operands[0], V4HImode)
11805 || sh_register_operand (operands[1], V4HImode))"
11812 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11813 (set_attr "length" "4,4,16,4,4")
11814 (set_attr "highpart" "depend")])
11816 (define_expand "movv2si"
11817 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11818 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11820 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11822 (define_insn "movv2si_i"
11823 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11824 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11826 && (register_operand (operands[0], V2SImode)
11827 || sh_register_operand (operands[1], V2SImode))"
11834 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11835 (set_attr "length" "4,4,16,4,4")
11836 (set_attr "highpart" "depend")])
11838 ;; Multimedia Intrinsics
11840 (define_insn "absv2si2"
11841 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11842 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11845 [(set_attr "type" "mcmp_media")
11846 (set_attr "highpart" "depend")])
11848 (define_insn "absv4hi2"
11849 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11850 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11853 [(set_attr "type" "mcmp_media")
11854 (set_attr "highpart" "depend")])
11856 (define_insn "addv2si3"
11857 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11858 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11859 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11861 "madd.l %1, %2, %0"
11862 [(set_attr "type" "arith_media")
11863 (set_attr "highpart" "depend")])
11865 (define_insn "addv4hi3"
11866 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11867 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11868 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11870 "madd.w %1, %2, %0"
11871 [(set_attr "type" "arith_media")
11872 (set_attr "highpart" "depend")])
11874 (define_insn_and_split "addv2hi3"
11875 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11876 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11877 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11884 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11885 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11886 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11887 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11888 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11890 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11891 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11894 [(set_attr "highpart" "must_split")])
11896 (define_insn "ssaddv2si3"
11897 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11898 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11899 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11901 "madds.l %1, %2, %0"
11902 [(set_attr "type" "mcmp_media")
11903 (set_attr "highpart" "depend")])
11905 (define_insn "usaddv8qi3"
11906 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11907 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11908 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11910 "madds.ub %1, %2, %0"
11911 [(set_attr "type" "mcmp_media")
11912 (set_attr "highpart" "depend")])
11914 (define_insn "ssaddv4hi3"
11915 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11916 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11917 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11919 "madds.w %1, %2, %0"
11920 [(set_attr "type" "mcmp_media")
11921 (set_attr "highpart" "depend")])
11923 (define_insn "negcmpeqv8qi"
11924 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11925 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11926 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11928 "mcmpeq.b %N1, %N2, %0"
11929 [(set_attr "type" "mcmp_media")
11930 (set_attr "highpart" "depend")])
11932 (define_insn "negcmpeqv2si"
11933 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11934 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11935 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11937 "mcmpeq.l %N1, %N2, %0"
11938 [(set_attr "type" "mcmp_media")
11939 (set_attr "highpart" "depend")])
11941 (define_insn "negcmpeqv4hi"
11942 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11943 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11944 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11946 "mcmpeq.w %N1, %N2, %0"
11947 [(set_attr "type" "mcmp_media")
11948 (set_attr "highpart" "depend")])
11950 (define_insn "negcmpgtuv8qi"
11951 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11952 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11953 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11955 "mcmpgt.ub %N1, %N2, %0"
11956 [(set_attr "type" "mcmp_media")
11957 (set_attr "highpart" "depend")])
11959 (define_insn "negcmpgtv2si"
11960 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11961 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11962 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11964 "mcmpgt.l %N1, %N2, %0"
11965 [(set_attr "type" "mcmp_media")
11966 (set_attr "highpart" "depend")])
11968 (define_insn "negcmpgtv4hi"
11969 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11970 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11971 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11973 "mcmpgt.w %N1, %N2, %0"
11974 [(set_attr "type" "mcmp_media")
11975 (set_attr "highpart" "depend")])
11977 (define_insn "mcmv"
11978 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11979 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11980 (match_operand:DI 2 "arith_reg_operand" "r"))
11981 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11982 (not:DI (match_dup 2)))))]
11985 [(set_attr "type" "arith_media")
11986 (set_attr "highpart" "depend")])
11988 (define_insn "mcnvs_lw"
11989 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11991 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11992 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11994 "mcnvs.lw %N1, %N2, %0"
11995 [(set_attr "type" "mcmp_media")])
11997 (define_insn "mcnvs_wb"
11998 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12000 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12001 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12003 "mcnvs.wb %N1, %N2, %0"
12004 [(set_attr "type" "mcmp_media")])
12006 (define_insn "mcnvs_wub"
12007 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12009 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12010 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12012 "mcnvs.wub %N1, %N2, %0"
12013 [(set_attr "type" "mcmp_media")])
12015 (define_insn "mextr_rl"
12016 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12017 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12018 (match_operand:HI 3 "mextr_bit_offset" "i"))
12019 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12020 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12021 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12024 static char templ[21];
12026 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12027 (int) INTVAL (operands[3]) >> 3);
12030 [(set_attr "type" "arith_media")])
12032 (define_insn "*mextr_lr"
12033 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12034 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12035 (match_operand:HI 3 "mextr_bit_offset" "i"))
12036 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12037 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12038 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12041 static char templ[21];
12043 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12044 (int) INTVAL (operands[4]) >> 3);
12047 [(set_attr "type" "arith_media")])
12049 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12050 ; vector then varies depending on endianness.
12051 (define_expand "mextr1"
12052 [(match_operand:DI 0 "arith_reg_dest" "")
12053 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12054 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12058 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12059 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12063 (define_expand "mextr2"
12064 [(match_operand:DI 0 "arith_reg_dest" "")
12065 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12066 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12070 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12071 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12075 (define_expand "mextr3"
12076 [(match_operand:DI 0 "arith_reg_dest" "")
12077 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12078 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12082 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12083 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12087 (define_expand "mextr4"
12088 [(match_operand:DI 0 "arith_reg_dest" "")
12089 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12090 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12094 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12095 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12099 (define_expand "mextr5"
12100 [(match_operand:DI 0 "arith_reg_dest" "")
12101 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12102 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12106 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12107 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12111 (define_expand "mextr6"
12112 [(match_operand:DI 0 "arith_reg_dest" "")
12113 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12114 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12118 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12119 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12123 (define_expand "mextr7"
12124 [(match_operand:DI 0 "arith_reg_dest" "")
12125 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12126 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12130 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12131 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12135 (define_expand "mmacfx_wl"
12136 [(match_operand:V2SI 0 "arith_reg_dest" "")
12137 (match_operand:V2HI 1 "extend_reg_operand" "")
12138 (match_operand:V2HI 2 "extend_reg_operand" "")
12139 (match_operand:V2SI 3 "arith_reg_operand" "")]
12143 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12144 operands[1], operands[2]));
12148 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12150 (define_insn "mmacfx_wl_i"
12151 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12153 (match_operand:V2SI 1 "arith_reg_operand" "0")
12158 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12159 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12162 "mmacfx.wl %2, %3, %0"
12163 [(set_attr "type" "mac_media")
12164 (set_attr "highpart" "depend")])
12166 (define_expand "mmacnfx_wl"
12167 [(match_operand:V2SI 0 "arith_reg_dest" "")
12168 (match_operand:V2HI 1 "extend_reg_operand" "")
12169 (match_operand:V2HI 2 "extend_reg_operand" "")
12170 (match_operand:V2SI 3 "arith_reg_operand" "")]
12174 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12175 operands[1], operands[2]));
12179 (define_insn "mmacnfx_wl_i"
12180 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12182 (match_operand:V2SI 1 "arith_reg_operand" "0")
12187 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12188 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12191 "mmacnfx.wl %2, %3, %0"
12192 [(set_attr "type" "mac_media")
12193 (set_attr "highpart" "depend")])
12195 (define_insn "mulv2si3"
12196 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12197 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12198 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12200 "mmul.l %1, %2, %0"
12201 [(set_attr "type" "d2mpy_media")
12202 (set_attr "highpart" "depend")])
12204 (define_insn "mulv4hi3"
12205 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12206 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12207 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12209 "mmul.w %1, %2, %0"
12210 [(set_attr "type" "dmpy_media")
12211 (set_attr "highpart" "depend")])
12213 (define_insn "mmulfx_l"
12214 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12218 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12219 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12222 "mmulfx.l %1, %2, %0"
12223 [(set_attr "type" "d2mpy_media")
12224 (set_attr "highpart" "depend")])
12226 (define_insn "mmulfx_w"
12227 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12231 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12232 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12235 "mmulfx.w %1, %2, %0"
12236 [(set_attr "type" "dmpy_media")
12237 (set_attr "highpart" "depend")])
12239 (define_insn "mmulfxrp_w"
12240 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12245 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12246 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12250 "mmulfxrp.w %1, %2, %0"
12251 [(set_attr "type" "dmpy_media")
12252 (set_attr "highpart" "depend")])
12255 (define_expand "mmulhi_wl"
12256 [(match_operand:V2SI 0 "arith_reg_dest" "")
12257 (match_operand:V4HI 1 "arith_reg_operand" "")
12258 (match_operand:V4HI 2 "arith_reg_operand" "")]
12262 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12263 (operands[0], operands[1], operands[2]));
12267 (define_expand "mmullo_wl"
12268 [(match_operand:V2SI 0 "arith_reg_dest" "")
12269 (match_operand:V4HI 1 "arith_reg_operand" "")
12270 (match_operand:V4HI 2 "arith_reg_operand" "")]
12274 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12275 (operands[0], operands[1], operands[2]));
12279 (define_insn "mmul23_wl"
12280 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12283 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12284 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12285 (parallel [(const_int 2) (const_int 3)])))]
12287 "* return (TARGET_LITTLE_ENDIAN
12288 ? \"mmulhi.wl %1, %2, %0\"
12289 : \"mmullo.wl %1, %2, %0\");"
12290 [(set_attr "type" "dmpy_media")
12291 (set (attr "highpart")
12292 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12293 (const_string "user")))])
12295 (define_insn "mmul01_wl"
12296 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12299 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12300 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12301 (parallel [(const_int 0) (const_int 1)])))]
12303 "* return (TARGET_LITTLE_ENDIAN
12304 ? \"mmullo.wl %1, %2, %0\"
12305 : \"mmulhi.wl %1, %2, %0\");"
12306 [(set_attr "type" "dmpy_media")
12307 (set (attr "highpart")
12308 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12309 (const_string "user")))])
12312 (define_expand "mmulsum_wq"
12313 [(match_operand:DI 0 "arith_reg_dest" "")
12314 (match_operand:V4HI 1 "arith_reg_operand" "")
12315 (match_operand:V4HI 2 "arith_reg_operand" "")
12316 (match_operand:DI 3 "arith_reg_operand" "")]
12320 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12321 operands[1], operands[2]));
12325 (define_insn "mmulsum_wq_i"
12326 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12327 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12332 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12333 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12334 (parallel [(const_int 0)]))
12335 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12336 (sign_extend:V4DI (match_dup 3)))
12337 (parallel [(const_int 1)])))
12339 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12340 (sign_extend:V4DI (match_dup 3)))
12341 (parallel [(const_int 2)]))
12342 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12343 (sign_extend:V4DI (match_dup 3)))
12344 (parallel [(const_int 3)]))))))]
12346 "mmulsum.wq %2, %3, %0"
12347 [(set_attr "type" "mac_media")])
12349 (define_expand "mperm_w"
12350 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12351 (match_operand:V4HI 1 "arith_reg_operand" "r")
12352 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12356 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12357 (operands[0], operands[1], operands[2]));
12361 ; This use of vec_select isn't exactly correct according to rtl.texi
12362 ; (because not constant), but it seems a straightforward extension.
12363 (define_insn "mperm_w_little"
12364 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12366 (match_operand:V4HI 1 "arith_reg_operand" "r")
12368 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12369 (const_int 2) (const_int 0))
12370 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12371 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12372 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12373 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12374 "mperm.w %1, %N2, %0"
12375 [(set_attr "type" "arith_media")])
12377 (define_insn "mperm_w_big"
12378 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12380 (match_operand:V4HI 1 "arith_reg_operand" "r")
12382 [(zero_extract:QI (not:QI (match_operand:QI 2
12383 "extend_reg_or_0_operand" "rZ"))
12384 (const_int 2) (const_int 0))
12385 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12386 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12387 (zero_extract:QI (not:QI (match_dup 2))
12388 (const_int 2) (const_int 6))])))]
12389 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12390 "mperm.w %1, %N2, %0"
12391 [(set_attr "type" "arith_media")])
12393 (define_insn "mperm_w0"
12394 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12395 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12396 "trunc_hi_operand" "r"))))]
12398 "mperm.w %1, r63, %0"
12399 [(set_attr "type" "arith_media")
12400 (set_attr "highpart" "ignore")])
12402 (define_expand "msad_ubq"
12403 [(match_operand:DI 0 "arith_reg_dest" "")
12404 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12405 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12406 (match_operand:DI 3 "arith_reg_operand" "")]
12410 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12411 operands[1], operands[2]));
12415 (define_insn "msad_ubq_i"
12416 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12421 (match_operand:DI 1 "arith_reg_operand" "0")
12422 (abs:DI (vec_select:DI
12425 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12427 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12428 (parallel [(const_int 0)]))))
12429 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12430 (zero_extend:V8DI (match_dup 3)))
12431 (parallel [(const_int 1)]))))
12433 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12434 (zero_extend:V8DI (match_dup 3)))
12435 (parallel [(const_int 2)])))
12436 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12437 (zero_extend:V8DI (match_dup 3)))
12438 (parallel [(const_int 3)])))))
12441 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12442 (zero_extend:V8DI (match_dup 3)))
12443 (parallel [(const_int 4)])))
12444 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12445 (zero_extend:V8DI (match_dup 3)))
12446 (parallel [(const_int 5)]))))
12448 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12449 (zero_extend:V8DI (match_dup 3)))
12450 (parallel [(const_int 6)])))
12451 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12452 (zero_extend:V8DI (match_dup 3)))
12453 (parallel [(const_int 7)])))))))]
12455 "msad.ubq %N2, %N3, %0"
12456 [(set_attr "type" "mac_media")])
12458 (define_insn "mshalds_l"
12459 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12462 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12463 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12464 (const_int 31)))))]
12466 "mshalds.l %1, %2, %0"
12467 [(set_attr "type" "mcmp_media")
12468 (set_attr "highpart" "depend")])
12470 (define_insn "mshalds_w"
12471 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12474 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12475 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12476 (const_int 15)))))]
12478 "mshalds.w %1, %2, %0"
12479 [(set_attr "type" "mcmp_media")
12480 (set_attr "highpart" "depend")])
12482 (define_insn "ashrv2si3"
12483 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12484 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12485 (match_operand:DI 2 "arith_reg_operand" "r")))]
12487 "mshard.l %1, %2, %0"
12488 [(set_attr "type" "arith_media")
12489 (set_attr "highpart" "depend")])
12491 (define_insn "ashrv4hi3"
12492 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12493 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12494 (match_operand:DI 2 "arith_reg_operand" "r")))]
12496 "mshard.w %1, %2, %0"
12497 [(set_attr "type" "arith_media")
12498 (set_attr "highpart" "depend")])
12500 (define_insn "mshards_q"
12501 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12503 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12504 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12506 "mshards.q %1, %N2, %0"
12507 [(set_attr "type" "mcmp_media")])
12509 (define_expand "mshfhi_b"
12510 [(match_operand:V8QI 0 "arith_reg_dest" "")
12511 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12512 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12516 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12517 (operands[0], operands[1], operands[2]));
12521 (define_expand "mshflo_b"
12522 [(match_operand:V8QI 0 "arith_reg_dest" "")
12523 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12524 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12528 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12529 (operands[0], operands[1], operands[2]));
12533 (define_insn "mshf4_b"
12535 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12537 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12538 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12539 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12540 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12542 "* return (TARGET_LITTLE_ENDIAN
12543 ? \"mshfhi.b %N1, %N2, %0\"
12544 : \"mshflo.b %N1, %N2, %0\");"
12545 [(set_attr "type" "arith_media")
12546 (set (attr "highpart")
12547 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12548 (const_string "user")))])
12550 (define_insn "mshf0_b"
12552 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12554 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12555 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12556 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12557 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12559 "* return (TARGET_LITTLE_ENDIAN
12560 ? \"mshflo.b %N1, %N2, %0\"
12561 : \"mshfhi.b %N1, %N2, %0\");"
12562 [(set_attr "type" "arith_media")
12563 (set (attr "highpart")
12564 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12565 (const_string "user")))])
12567 (define_expand "mshfhi_l"
12568 [(match_operand:V2SI 0 "arith_reg_dest" "")
12569 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12570 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12574 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12575 (operands[0], operands[1], operands[2]));
12579 (define_expand "mshflo_l"
12580 [(match_operand:V2SI 0 "arith_reg_dest" "")
12581 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12582 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12586 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12587 (operands[0], operands[1], operands[2]));
12591 (define_insn "mshf4_l"
12592 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12594 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12595 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12596 (parallel [(const_int 1) (const_int 3)])))]
12598 "* return (TARGET_LITTLE_ENDIAN
12599 ? \"mshfhi.l %N1, %N2, %0\"
12600 : \"mshflo.l %N1, %N2, %0\");"
12601 [(set_attr "type" "arith_media")
12602 (set (attr "highpart")
12603 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12604 (const_string "user")))])
12606 (define_insn "mshf0_l"
12607 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12609 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12610 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12611 (parallel [(const_int 0) (const_int 2)])))]
12613 "* return (TARGET_LITTLE_ENDIAN
12614 ? \"mshflo.l %N1, %N2, %0\"
12615 : \"mshfhi.l %N1, %N2, %0\");"
12616 [(set_attr "type" "arith_media")
12617 (set (attr "highpart")
12618 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12619 (const_string "user")))])
12621 (define_expand "mshfhi_w"
12622 [(match_operand:V4HI 0 "arith_reg_dest" "")
12623 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12624 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12628 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12629 (operands[0], operands[1], operands[2]));
12633 (define_expand "mshflo_w"
12634 [(match_operand:V4HI 0 "arith_reg_dest" "")
12635 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12636 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12640 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12641 (operands[0], operands[1], operands[2]));
12645 (define_insn "mshf4_w"
12646 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12648 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12649 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12650 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12652 "* return (TARGET_LITTLE_ENDIAN
12653 ? \"mshfhi.w %N1, %N2, %0\"
12654 : \"mshflo.w %N1, %N2, %0\");"
12655 [(set_attr "type" "arith_media")
12656 (set (attr "highpart")
12657 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12658 (const_string "user")))])
12660 (define_insn "mshf0_w"
12661 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12663 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12664 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12665 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12667 "* return (TARGET_LITTLE_ENDIAN
12668 ? \"mshflo.w %N1, %N2, %0\"
12669 : \"mshfhi.w %N1, %N2, %0\");"
12670 [(set_attr "type" "arith_media")
12671 (set (attr "highpart")
12672 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12673 (const_string "user")))])
12675 (define_insn "mshflo_w_x"
12676 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12678 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12679 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12680 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12682 "mshflo.w %N1, %N2, %0"
12683 [(set_attr "type" "arith_media")
12684 (set_attr "highpart" "ignore")])
12686 ;; These are useful to expand ANDs and as combiner patterns.
12687 (define_insn_and_split "mshfhi_l_di"
12688 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12689 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12691 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12692 (const_int -4294967296))))]
12695 mshfhi.l %N1, %N2, %0
12697 "TARGET_SHMEDIA && reload_completed
12698 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12699 [(set (match_dup 3) (match_dup 4))
12700 (set (match_dup 5) (match_dup 6))]
12703 operands[3] = gen_lowpart (SImode, operands[0]);
12704 operands[4] = gen_highpart (SImode, operands[1]);
12705 operands[5] = gen_highpart (SImode, operands[0]);
12706 operands[6] = gen_highpart (SImode, operands[2]);
12708 [(set_attr "type" "arith_media")])
12710 (define_insn "*mshfhi_l_di_rev"
12711 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12712 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12713 (const_int -4294967296))
12714 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12717 "mshfhi.l %N2, %N1, %0"
12718 [(set_attr "type" "arith_media")])
12721 [(set (match_operand:DI 0 "arith_reg_dest" "")
12722 (ior:DI (zero_extend:DI (match_operand:SI 1
12723 "extend_reg_or_0_operand" ""))
12724 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12725 (const_int -4294967296))))
12726 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12731 emit_insn (gen_ashldi3_media (operands[3],
12732 simplify_gen_subreg (DImode, operands[1],
12735 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12739 (define_insn "mshflo_l_di"
12740 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12741 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12742 (const_int 4294967295))
12743 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12747 "mshflo.l %N1, %N2, %0"
12748 [(set_attr "type" "arith_media")
12749 (set_attr "highpart" "ignore")])
12751 (define_insn "*mshflo_l_di_rev"
12752 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12753 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12755 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12756 (const_int 4294967295))))]
12759 "mshflo.l %N2, %N1, %0"
12760 [(set_attr "type" "arith_media")
12761 (set_attr "highpart" "ignore")])
12763 ;; Combiner pattern for trampoline initialization.
12764 (define_insn_and_split "*double_shori"
12765 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12766 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12768 (match_operand:DI 2 "const_int_operand" "n")))]
12770 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12772 "rtx_equal_p (operands[0], operands[1])"
12776 HOST_WIDE_INT v = INTVAL (operands[2]);
12778 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12779 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12782 [(set_attr "highpart" "ignore")])
12785 (define_insn "*mshflo_l_di_x"
12786 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12787 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12789 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12793 "mshflo.l %N1, %N2, %0"
12794 [(set_attr "type" "arith_media")
12795 (set_attr "highpart" "ignore")])
12797 (define_insn_and_split "concat_v2sf"
12798 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12799 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12800 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12801 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12805 mshflo.l %N1, %N2, %0
12808 "TARGET_SHMEDIA && reload_completed
12809 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12810 [(set (match_dup 3) (match_dup 1))
12811 (set (match_dup 4) (match_dup 2))]
12814 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12815 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12817 [(set_attr "type" "arith_media")
12818 (set_attr "highpart" "ignore")])
12820 (define_insn "*mshflo_l_di_x_rev"
12821 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12822 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12824 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12827 "mshflo.l %N2, %N1, %0"
12828 [(set_attr "type" "arith_media")
12829 (set_attr "highpart" "ignore")])
12831 (define_insn "ashlv2si3"
12832 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12833 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12834 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12836 "mshlld.l %1, %2, %0"
12837 [(set_attr "type" "arith_media")
12838 (set_attr "highpart" "depend")])
12841 [(set (match_operand 0 "any_register_operand" "")
12842 (match_operator 3 "shift_operator"
12843 [(match_operand 1 "any_register_operand" "")
12844 (match_operand 2 "shift_count_reg_operand" "")]))]
12845 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12846 [(set (match_dup 0) (match_dup 3))]
12849 rtx count = operands[2];
12850 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12852 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12853 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12854 || GET_CODE (count) == TRUNCATE)
12855 count = XEXP (count, 0);
12856 inner_mode = GET_MODE (count);
12857 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12858 subreg_lowpart_offset (outer_mode, inner_mode));
12859 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12860 operands[1], count);
12863 (define_insn "ashlv4hi3"
12864 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12865 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12866 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12868 "mshlld.w %1, %2, %0"
12869 [(set_attr "type" "arith_media")
12870 (set_attr "highpart" "depend")])
12872 (define_insn "lshrv2si3"
12873 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12874 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12875 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12877 "mshlrd.l %1, %2, %0"
12878 [(set_attr "type" "arith_media")
12879 (set_attr "highpart" "depend")])
12881 (define_insn "lshrv4hi3"
12882 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12883 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12884 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12886 "mshlrd.w %1, %2, %0"
12887 [(set_attr "type" "arith_media")
12888 (set_attr "highpart" "depend")])
12890 (define_insn "subv2si3"
12891 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12892 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12893 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12895 "msub.l %N1, %2, %0"
12896 [(set_attr "type" "arith_media")
12897 (set_attr "highpart" "depend")])
12899 (define_insn "subv4hi3"
12900 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12901 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12902 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12904 "msub.w %N1, %2, %0"
12905 [(set_attr "type" "arith_media")
12906 (set_attr "highpart" "depend")])
12908 (define_insn_and_split "subv2hi3"
12909 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12910 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12911 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12918 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12919 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12920 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12921 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12922 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12924 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12925 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12928 [(set_attr "highpart" "must_split")])
12930 (define_insn "sssubv2si3"
12931 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12932 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12933 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12935 "msubs.l %N1, %2, %0"
12936 [(set_attr "type" "mcmp_media")
12937 (set_attr "highpart" "depend")])
12939 (define_insn "ussubv8qi3"
12940 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12941 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12942 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12944 "msubs.ub %N1, %2, %0"
12945 [(set_attr "type" "mcmp_media")
12946 (set_attr "highpart" "depend")])
12948 (define_insn "sssubv4hi3"
12949 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12950 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12951 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12953 "msubs.w %N1, %2, %0"
12954 [(set_attr "type" "mcmp_media")
12955 (set_attr "highpart" "depend")])
12957 ;; Floating Point Intrinsics
12959 (define_insn "fcosa_s"
12960 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12961 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12965 [(set_attr "type" "atrans_media")])
12967 (define_insn "fsina_s"
12968 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12969 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12973 [(set_attr "type" "atrans_media")])
12975 (define_insn "fipr"
12976 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12977 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12978 "fp_arith_reg_operand" "f")
12979 (match_operand:V4SF 2
12980 "fp_arith_reg_operand" "f"))
12981 (parallel [(const_int 0)]))
12982 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12983 (parallel [(const_int 1)])))
12984 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12985 (parallel [(const_int 2)]))
12986 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12987 (parallel [(const_int 3)])))))]
12989 "fipr.s %1, %2, %0"
12990 [(set_attr "type" "fparith_media")])
12992 (define_insn "fsrra_s"
12993 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12994 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12998 [(set_attr "type" "atrans_media")])
13000 (define_insn "ftrv"
13001 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13005 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13006 (parallel [(const_int 0) (const_int 5)
13007 (const_int 10) (const_int 15)]))
13008 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13010 (vec_select:V4SF (match_dup 1)
13011 (parallel [(const_int 4) (const_int 9)
13012 (const_int 14) (const_int 3)]))
13013 (vec_select:V4SF (match_dup 2)
13014 (parallel [(const_int 1) (const_int 2)
13015 (const_int 3) (const_int 0)]))))
13018 (vec_select:V4SF (match_dup 1)
13019 (parallel [(const_int 8) (const_int 13)
13020 (const_int 2) (const_int 7)]))
13021 (vec_select:V4SF (match_dup 2)
13022 (parallel [(const_int 2) (const_int 3)
13023 (const_int 0) (const_int 1)])))
13025 (vec_select:V4SF (match_dup 1)
13026 (parallel [(const_int 12) (const_int 1)
13027 (const_int 6) (const_int 11)]))
13028 (vec_select:V4SF (match_dup 2)
13029 (parallel [(const_int 3) (const_int 0)
13030 (const_int 1) (const_int 2)]))))))]
13032 "ftrv.s %1, %2, %0"
13033 [(set_attr "type" "fparith_media")])
13035 (define_insn "ldhi_l"
13036 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13038 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13041 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13045 [(set_attr "type" "load_media")])
13047 (define_insn "ldhi_q"
13048 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13050 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13053 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13057 [(set_attr "type" "load_media")])
13059 (define_insn_and_split "*ldhi_q_comb0"
13060 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13062 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13063 "register_operand" "r")
13064 (match_operand:SI 2
13065 "ua_offset" "I06"))
13068 (plus:SI (and:SI (match_dup 1) (const_int 7))
13071 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13075 "emit_insn (gen_ldhi_q (operands[0],
13076 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13080 (define_insn_and_split "*ldhi_q_comb1"
13081 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13083 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13084 "register_operand" "r")
13085 (match_operand:SI 2
13086 "ua_offset" "I06"))
13089 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13090 "ua_offset" "I06"))
13094 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13095 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13099 "emit_insn (gen_ldhi_q (operands[0],
13100 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13104 (define_insn "ldlo_l"
13105 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13107 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13109 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13110 (and:SI (match_dup 1) (const_int 3))))]
13113 [(set_attr "type" "load_media")])
13115 (define_insn "ldlo_q"
13116 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13118 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13120 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13121 (and:SI (match_dup 1) (const_int 7))))]
13124 [(set_attr "type" "load_media")])
13126 (define_insn_and_split "*ldlo_q_comb0"
13127 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13129 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13130 (match_operand:SI 2 "ua_offset" "I06"))
13132 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13133 (and:SI (match_dup 1) (const_int 7))))]
13134 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13138 "emit_insn (gen_ldlo_q (operands[0],
13139 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13142 (define_insn_and_split "*ldlo_q_comb1"
13143 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13145 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13146 (match_operand:SI 2 "ua_offset" "I06"))
13148 (minus:SI (const_int 8)
13149 (and:SI (plus:SI (match_dup 1)
13150 (match_operand:SI 3 "ua_offset" "I06"))
13152 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13153 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13154 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13158 "emit_insn (gen_ldlo_q (operands[0],
13159 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13162 (define_insn "sthi_l"
13163 [(set (zero_extract:SI
13164 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13167 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13169 (match_operand:SI 1 "arith_reg_operand" "r"))]
13172 [(set_attr "type" "ustore_media")])
13174 ;; All unaligned stores are considered to be 'narrow' because they typically
13175 ;; operate on less that a quadword, and when they operate on a full quadword,
13176 ;; the vanilla store high / store low sequence will cause a stall if not
13177 ;; scheduled apart.
13178 (define_insn "sthi_q"
13179 [(set (zero_extract:DI
13180 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13183 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13185 (match_operand:DI 1 "arith_reg_operand" "r"))]
13188 [(set_attr "type" "ustore_media")])
13190 (define_insn_and_split "*sthi_q_comb0"
13191 [(set (zero_extract:DI
13192 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13193 "register_operand" "r")
13194 (match_operand:SI 1 "ua_offset"
13198 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13200 (match_operand:DI 2 "arith_reg_operand" "r"))]
13201 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13205 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13209 (define_insn_and_split "*sthi_q_comb1"
13210 [(set (zero_extract:DI
13211 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13212 "register_operand" "r")
13213 (match_operand:SI 1 "ua_offset"
13217 (plus:SI (and:SI (plus:SI (match_dup 0)
13218 (match_operand:SI 2 "ua_offset" "I06"))
13222 (match_operand:DI 3 "arith_reg_operand" "r"))]
13223 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13224 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13228 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13232 ;; This is highpart user because the address is used as full 64 bit.
13233 (define_insn "stlo_l"
13234 [(set (zero_extract:SI
13235 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13237 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13238 (and:SI (match_dup 0) (const_int 3)))
13239 (match_operand:SI 1 "arith_reg_operand" "r"))]
13242 [(set_attr "type" "ustore_media")])
13244 (define_insn "stlo_q"
13245 [(set (zero_extract:DI
13246 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13248 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13249 (and:SI (match_dup 0) (const_int 7)))
13250 (match_operand:DI 1 "arith_reg_operand" "r"))]
13253 [(set_attr "type" "ustore_media")])
13255 (define_insn_and_split "*stlo_q_comb0"
13256 [(set (zero_extract:DI
13257 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13258 (match_operand:SI 1 "ua_offset" "I06"))
13260 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13261 (and:SI (match_dup 0) (const_int 7)))
13262 (match_operand:DI 2 "arith_reg_operand" "r"))]
13263 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13267 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13271 (define_insn_and_split "*stlo_q_comb1"
13272 [(set (zero_extract:DI
13273 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13274 (match_operand:SI 1 "ua_offset" "I06"))
13276 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13277 (match_operand:SI 2
13278 "ua_offset" "I06"))
13280 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13281 (match_operand:DI 3 "arith_reg_operand" "r"))]
13282 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13286 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13290 (define_insn "ldhi_l64"
13291 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13293 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13296 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13300 [(set_attr "type" "load_media")])
13302 (define_insn "ldhi_q64"
13303 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13305 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13308 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13312 [(set_attr "type" "load_media")])
13314 (define_insn "ldlo_l64"
13315 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13317 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13319 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13320 (and:DI (match_dup 1) (const_int 3))))]
13323 [(set_attr "type" "load_media")])
13325 (define_insn "ldlo_q64"
13326 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13328 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13330 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13331 (and:DI (match_dup 1) (const_int 7))))]
13334 [(set_attr "type" "load_media")])
13336 (define_insn "sthi_l64"
13337 [(set (zero_extract:SI
13338 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13341 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13343 (match_operand:SI 1 "arith_reg_operand" "r"))]
13346 [(set_attr "type" "ustore_media")])
13348 (define_insn "sthi_q64"
13349 [(set (zero_extract:DI
13350 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13353 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13355 (match_operand:DI 1 "arith_reg_operand" "r"))]
13358 [(set_attr "type" "ustore_media")])
13360 (define_insn "stlo_l64"
13361 [(set (zero_extract:SI
13362 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13364 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13365 (and:DI (match_dup 0) (const_int 3)))
13366 (match_operand:SI 1 "arith_reg_operand" "r"))]
13369 [(set_attr "type" "ustore_media")])
13371 (define_insn "stlo_q64"
13372 [(set (zero_extract:DI
13373 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13375 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13376 (and:DI (match_dup 0) (const_int 7)))
13377 (match_operand:DI 1 "arith_reg_operand" "r"))]
13380 [(set_attr "type" "ustore_media")])
13383 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13384 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13388 [(set_attr "type" "arith_media")])
13390 (define_insn "nsbsi"
13391 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13393 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13397 [(set_attr "type" "arith_media")])
13399 (define_insn "nsbdi"
13400 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13402 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13406 [(set_attr "type" "arith_media")])
13408 (define_expand "ffsdi2"
13409 [(set (match_operand:DI 0 "arith_reg_dest" "")
13410 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13414 rtx scratch = gen_reg_rtx (DImode);
13417 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13418 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13419 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13420 emit_insn (gen_nsbdi (scratch, scratch));
13421 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13422 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13423 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13424 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13429 (define_expand "ffssi2"
13430 [(set (match_operand:SI 0 "arith_reg_dest" "")
13431 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13435 rtx scratch = gen_reg_rtx (SImode);
13436 rtx discratch = gen_reg_rtx (DImode);
13439 emit_insn (gen_adddi3 (discratch,
13440 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13442 emit_insn (gen_andcdi3 (discratch,
13443 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13445 emit_insn (gen_nsbsi (scratch, discratch));
13446 last = emit_insn (gen_subsi3 (operands[0],
13447 force_reg (SImode, GEN_INT (63)), scratch));
13448 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13453 (define_insn "byterev"
13454 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13455 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13456 (parallel [(const_int 7) (const_int 6) (const_int 5)
13457 (const_int 4) (const_int 3) (const_int 2)
13458 (const_int 1) (const_int 0)])))]
13461 [(set_attr "type" "arith_media")])
13463 (define_insn "*prefetch_media"
13464 [(prefetch (match_operand:QI 0 "address_operand" "p")
13465 (match_operand:SI 1 "const_int_operand" "n")
13466 (match_operand:SI 2 "const_int_operand" "n"))]
13470 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13471 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13474 [(set_attr "type" "other")])
13476 (define_insn "*prefetch_i4"
13477 [(prefetch (match_operand:SI 0 "register_operand" "r")
13478 (match_operand:SI 1 "const_int_operand" "n")
13479 (match_operand:SI 2 "const_int_operand" "n"))]
13480 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13483 return \"pref @%0\";
13485 [(set_attr "type" "other")])
13487 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13488 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13489 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13490 (define_expand "prefetch"
13491 [(prefetch (match_operand 0 "address_operand" "p")
13492 (match_operand:SI 1 "const_int_operand" "n")
13493 (match_operand:SI 2 "const_int_operand" "n"))]
13494 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13495 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13498 if (GET_MODE (operands[0]) != Pmode
13499 || !CONST_INT_P (operands[1])
13500 || !CONST_INT_P (operands[2]))
13502 if (! TARGET_SHMEDIA)
13503 operands[0] = force_reg (Pmode, operands[0]);
13506 (define_insn "prefetch_m2a"
13507 [(prefetch (match_operand:SI 0 "register_operand" "r")
13508 (match_operand:SI 1 "const_int_operand" "n")
13509 (match_operand:SI 2 "const_int_operand" "n"))]
13512 [(set_attr "type" "other")])
13514 (define_insn "alloco_i"
13515 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13516 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13522 if (GET_CODE (operands[0]) == PLUS)
13524 xops[0] = XEXP (operands[0], 0);
13525 xops[1] = XEXP (operands[0], 1);
13529 xops[0] = operands[0];
13530 xops[1] = const0_rtx;
13532 output_asm_insn (\"alloco %0, %1\", xops);
13535 [(set_attr "type" "other")])
13538 [(set (match_operand 0 "any_register_operand" "")
13539 (match_operand 1 "" ""))]
13540 "TARGET_SHMEDIA && reload_completed"
13541 [(set (match_dup 0) (match_dup 1))]
13546 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13551 ; Stack Protector Patterns
13553 (define_expand "stack_protect_set"
13554 [(set (match_operand 0 "memory_operand" "")
13555 (match_operand 1 "memory_operand" ""))]
13558 if (TARGET_SHMEDIA)
13560 if (TARGET_SHMEDIA64)
13561 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13563 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13566 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13571 (define_insn "stack_protect_set_si"
13572 [(set (match_operand:SI 0 "memory_operand" "=m")
13573 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13574 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13576 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13577 [(set_attr "type" "other")
13578 (set_attr "length" "6")])
13580 (define_insn "stack_protect_set_si_media"
13581 [(set (match_operand:SI 0 "memory_operand" "=m")
13582 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13583 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13585 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13586 [(set_attr "type" "other")
13587 (set_attr "length" "12")])
13589 (define_insn "stack_protect_set_di_media"
13590 [(set (match_operand:DI 0 "memory_operand" "=m")
13591 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13592 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13594 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13595 [(set_attr "type" "other")
13596 (set_attr "length" "12")])
13598 (define_expand "stack_protect_test"
13599 [(match_operand 0 "memory_operand" "")
13600 (match_operand 1 "memory_operand" "")
13601 (match_operand 2 "" "")]
13604 if (TARGET_SHMEDIA)
13606 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13609 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13610 if (TARGET_SHMEDIA64)
13612 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13614 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13618 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13620 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13625 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13626 emit_jump_insn (gen_branch_true (operands[2]));
13632 (define_insn "stack_protect_test_si"
13633 [(set (reg:SI T_REG)
13634 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13635 (match_operand:SI 1 "memory_operand" "m")]
13637 (set (match_scratch:SI 2 "=&r") (const_int 0))
13638 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13640 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13641 [(set_attr "type" "other")
13642 (set_attr "length" "10")])
13644 (define_insn "stack_protect_test_si_media"
13645 [(set (match_operand:SI 0 "register_operand" "=&r")
13646 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13647 (match_operand:SI 2 "memory_operand" "m")]
13649 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13651 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13652 [(set_attr "type" "other")
13653 (set_attr "length" "16")])
13655 (define_insn "stack_protect_test_di_media"
13656 [(set (match_operand:DI 0 "register_operand" "=&r")
13657 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13658 (match_operand:DI 2 "memory_operand" "m")]
13660 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13662 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13663 [(set_attr "type" "other")
13664 (set_attr "length" "16")])
13666 (include "sync.md")