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
4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;; Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
145 (UNSPEC_DIV_INV_M0 30)
146 (UNSPEC_DIV_INV_M1 31)
147 (UNSPEC_DIV_INV_M2 32)
148 (UNSPEC_DIV_INV_M3 33)
149 (UNSPEC_DIV_INV20 34)
150 (UNSPEC_DIV_INV_TABLE 37)
158 ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159 ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160 (UNSPEC_EXTRACT_S16 43)
161 (UNSPEC_EXTRACT_U16 44)
163 ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
166 ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167 (UNSPEC_PCREL_SYMOFF 46)
169 ;; These are used with unspec_volatile.
175 (UNSPECV_WINDOW_END 10)
176 (UNSPECV_CONST_END 11)
177 (UNSPECV_EH_RETURN 12)
180 ;; -------------------------------------------------------------------------
182 ;; -------------------------------------------------------------------------
187 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188 (const (symbol_ref "sh_cpu_attr")))
190 (define_attr "endian" "big,little"
191 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192 (const_string "little") (const_string "big"))))
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197 (const_string "yes") (const_string "no"))))
199 (define_attr "fmovd" "yes,no"
200 (const (if_then_else (symbol_ref "TARGET_FMOVD")
201 (const_string "yes") (const_string "no"))))
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
205 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207 (const_string "sh1"))))
209 ;; cbranch conditional branch instructions
210 ;; jump unconditional jumps
211 ;; arith ordinary arithmetic
212 ;; arith3 a compound insn that behaves similarly to a sequence of
213 ;; three insns of type arith
214 ;; arith3b like above, but might end with a redirected branch
216 ;; load_si Likewise, SImode variant for general register.
217 ;; fload Likewise, but load to fp register.
219 ;; fstore floating point register to memory
220 ;; move general purpose register to register
221 ;; movi8 8-bit immediate to general purpose register
222 ;; mt_group other sh4 mt instructions
223 ;; fmove register to register, floating point
224 ;; smpy word precision integer multiply
225 ;; dmpy longword or doublelongword precision integer multiply
227 ;; pload load of pr reg, which can't be put into delay slot of rts
228 ;; prset copy register to pr reg, ditto
229 ;; pstore store of pr reg, which can't be put into delay slot of jsr
230 ;; prget copy pr to register, ditto
231 ;; pcload pc relative load of constant value
232 ;; pcfload Likewise, but load to fp register.
233 ;; pcload_si Likewise, SImode variant for general register.
234 ;; rte return from exception
235 ;; sfunc special function call with known used registers
236 ;; call function call
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv floating point divide (or square root)
240 ;; gp_fpul move from general purpose register to fpul
241 ;; fpul_gp move from fpul to general purpose register
242 ;; mac_gp move from mac[lh] to general purpose register
243 ;; gp_mac move from general purpose register to mac[lh]
244 ;; mac_mem move from mac[lh] to memory
245 ;; mem_mac move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s fix_truncsfsi2_i4
248 ;; dfdiv double precision floating point divide (or square root)
249 ;; cwb ic_invalidate_line_i
250 ;; movua SH4a unaligned load
251 ;; fsrra square root reciprocal approximate
252 ;; fsca sine and cosine approximate
253 ;; tls_load load TLS related address
254 ;; arith_media SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media SHmedia compare instructions
257 ;; dfdiv_media SHmedia double precision divide and square root
258 ;; dfmul_media SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media SHmedia longword multiply
262 ;; fcmp_media SHmedia floating point compare instructions
263 ;; fdiv_media SHmedia single precision divide and square root
264 ;; fload_media SHmedia floating point register load instructions
265 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media SHmedia unconditional branch instructions
272 ;; load_media SHmedia general register load instructions
273 ;; pt_media SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media SHmedia ptabs instruction
275 ;; store_media SHmedia general register store instructions
276 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media SHmedia mac-style fixed point operations
278 ;; d2mpy_media SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil no-op move, will be deleted.
284 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
285 (const_string "other"))
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
290 ;; mt_group SH4 "mt" group instructions.
292 ;; ex_group SH4 "ex" group instructions.
294 ;; ls_group SH4 "ls" group instructions.
297 (define_attr "insn_class"
298 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300 (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302 (eq_attr "type" "cbranch,jump") (const_string "br_group")
303 (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304 (const_string "fe_group")
305 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306 (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long. Something in the
325 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
330 ;; The maximum range used for SImode constant pool entries is 1018. A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table. That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
348 (define_attr "short_cbranch_p" "no,yes"
349 (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
351 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
353 (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
357 ] (const_string "no")))
359 (define_attr "med_branch_p" "no,yes"
360 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
363 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
368 ] (const_string "no")))
370 (define_attr "med_cbranch_p" "no,yes"
371 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
374 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
376 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
379 ] (const_string "no")))
381 (define_attr "braf_branch_p" "no,yes"
382 (cond [(match_test "! TARGET_SH2")
384 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
387 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
389 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
392 ] (const_string "no")))
394 (define_attr "braf_cbranch_p" "no,yes"
395 (cond [(match_test "! TARGET_SH2")
397 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
400 (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
402 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
405 ] (const_string "no")))
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
414 ; All other instructions are two bytes long by default.
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419 (cond [(eq_attr "type" "cbranch")
420 (cond [(eq_attr "short_cbranch_p" "yes")
422 (eq_attr "med_cbranch_p" "yes")
424 (eq_attr "braf_cbranch_p" "yes")
426 ;; ??? using pc is not computed transitively.
427 (ne (match_dup 0) (match_dup 0))
429 (match_test "flag_pic")
432 (eq_attr "type" "jump")
433 (cond [(eq_attr "med_branch_p" "yes")
435 (and (match_test "prev_nonnote_insn (insn)")
436 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))") (symbol_ref "INSN"))
437 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))") (symbol_ref "code_for_indirect_jump_scratch"))))
438 (cond [(eq_attr "braf_branch_p" "yes")
440 (not (match_test "flag_pic"))
442 (match_test "TARGET_SH2")
443 (const_int 10)] (const_int 18))
444 (eq_attr "braf_branch_p" "yes")
446 ;; ??? using pc is not computed transitively.
447 (ne (match_dup 0) (match_dup 0))
449 (match_test "flag_pic")
452 (eq_attr "type" "pt_media")
453 (if_then_else (match_test "TARGET_SHMEDIA64")
454 (const_int 20) (const_int 12))
455 (and (eq_attr "type" "jump_media")
456 (match_test "TARGET_SH5_CUT2_WORKAROUND"))
458 ] (if_then_else (match_test "TARGET_SHMEDIA")
462 ;; DFA descriptions for the pipelines
465 (include "shmedia.md")
468 (include "predicates.md")
469 (include "constraints.md")
471 ;; Definitions for filling delay slots
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475 (define_attr "banked" "yes,no"
476 (cond [(match_test "sh_loads_bankedreg_p (insn)")
477 (const_string "yes")]
478 (const_string "no")))
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482 (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
484 (const_string "yes")))
486 (define_attr "interrupt_function" "no,yes"
487 (const (symbol_ref "current_function_interrupt")))
489 (define_attr "in_delay_slot" "yes,no"
490 (cond [(eq_attr "type" "cbranch") (const_string "no")
491 (eq_attr "type" "pcload,pcload_si") (const_string "no")
492 (eq_attr "needs_delay_slot" "yes") (const_string "no")
493 (eq_attr "length" "2") (const_string "yes")
494 ] (const_string "no")))
496 (define_attr "cond_delay_slot" "yes,no"
497 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498 ] (const_string "no")))
500 (define_attr "is_sfunc" ""
501 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
503 (define_attr "is_mac_media" ""
504 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
506 (define_attr "branch_zero" "yes,no"
507 (cond [(eq_attr "type" "!cbranch") (const_string "no")
508 (ne (symbol_ref "(next_active_insn (insn)\
509 == (prev_active_insn\
510 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511 && get_attr_length (next_active_insn (insn)) == 2")
513 (const_string "yes")]
514 (const_string "no")))
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519 (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520 (const_string "no")))
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527 (const_string "yes")]
528 (const_string "no")))
530 (define_attr "any_int_load" "yes,no"
531 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532 (const_string "yes")]
533 (const_string "no")))
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536 (const_string "user"))
539 (eq_attr "needs_delay_slot" "yes")
540 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
551 (eq_attr "type" "return")
552 [(and (eq_attr "in_delay_slot" "yes")
553 (ior (and (eq_attr "interrupt_function" "no")
554 (eq_attr "type" "!pload,prset"))
555 (and (eq_attr "interrupt_function" "yes")
557 (not (match_test "TARGET_SH3"))
558 (eq_attr "hit_stack" "no")
559 (eq_attr "banked" "no"))))) (nil) (nil)])
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
565 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566 [(and (eq_attr "in_delay_slot" "yes")
567 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
577 (and (eq_attr "type" "cbranch")
578 (match_test "TARGET_SH2"))
579 ;; SH2e has a hardware bug that pretty much prohibits the use of
580 ;; annuled delay slots.
581 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582 (not (eq_attr "cpu" "sh2e"))) (nil)])
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group
592 ;; instructions and thus will be executed in parallel. On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits
600 (define_insn "tstsi_t"
602 (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603 (match_operand:SI 1 "logical_operand" "K08,r"))
607 [(set_attr "type" "mt_group")])
609 (define_insn "tsthi_t"
611 (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612 (match_operand 1 "const_int_operand")) 0)
615 && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
617 [(set_attr "type" "mt_group")])
619 (define_insn "tstqi_t"
621 (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622 (match_operand 1 "const_int_operand")) 0)
625 && (CONST_OK_FOR_K08 (INTVAL (operands[1]))
626 || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
628 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
631 [(set_attr "type" "mt_group")])
633 ;; Test low QI subreg against zero.
634 ;; This avoids unecessary zero extension before the test.
636 (define_insn "tstqi_t_zero"
638 (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
641 [(set_attr "type" "mt_group")])
643 ;; Extract LSB, negate and store in T bit.
645 (define_insn "tstsi_t_and_not"
647 (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
651 [(set_attr "type" "mt_group")])
653 ;; Extract contiguous bits and compare them against zero.
655 (define_insn "tstsi_t_zero_extract_eq"
657 (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658 (match_operand:SI 1 "const_int_operand")
659 (match_operand:SI 2 "const_int_operand"))
662 && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
664 operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
667 [(set_attr "type" "mt_group")])
669 ;; This split is required when testing bits in a QI subreg.
673 (eq:SI (if_then_else:SI (zero_extract:SI
674 (match_operand 0 "logical_operand" "")
675 (match_operand 1 "const_int_operand")
676 (match_operand 2 "const_int_operand"))
677 (match_operand 3 "const_int_operand")
681 && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682 && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683 [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
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_SH4 || 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_SH4 && ! 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_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1841 [(set_attr "type" "sfunc")
1842 (set_attr "needs_delay_slot" "yes")])
1844 (define_insn "udivsi3_i4_int"
1845 [(set (match_operand:SI 0 "register_operand" "=z")
1846 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1847 (clobber (reg:SI T_REG))
1848 (clobber (reg:SI R1_REG))
1849 (clobber (reg:SI PR_REG))
1850 (clobber (reg:SI MACH_REG))
1851 (clobber (reg:SI MACL_REG))
1852 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1855 [(set_attr "type" "sfunc")
1856 (set_attr "needs_delay_slot" "yes")])
1859 (define_expand "udivsi3"
1860 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1861 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1862 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1863 (parallel [(set (match_operand:SI 0 "register_operand" "")
1864 (udiv:SI (reg:SI R4_REG)
1866 (clobber (reg:SI T_REG))
1867 (clobber (reg:SI PR_REG))
1868 (clobber (reg:SI R4_REG))
1869 (use (match_dup 3))])]
1875 operands[3] = gen_reg_rtx (Pmode);
1876 /* Emit the move of the address to a pseudo outside of the libcall. */
1877 if (TARGET_DIVIDE_CALL_TABLE)
1879 /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1880 that causes problems when the divide code is supposed to come from a
1881 separate library. Division by zero is undefined, so dividing 1 can be
1882 implemented by comparing with the divisor. */
1883 if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1885 rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1886 emit_insn (gen_cstoresi4 (operands[0], test,
1887 operands[1], operands[2]));
1890 else if (operands[2] == const0_rtx)
1892 emit_move_insn (operands[0], operands[2]);
1895 function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1896 last = gen_udivsi3_i4_int (operands[0], operands[3]);
1898 else if (TARGET_DIVIDE_CALL_FP)
1900 function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1901 if (TARGET_FPU_SINGLE)
1902 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1904 last = gen_udivsi3_i4 (operands[0], operands[3]);
1906 else if (TARGET_SHMEDIA_FPU)
1908 operands[1] = force_reg (SImode, operands[1]);
1909 operands[2] = force_reg (SImode, operands[2]);
1910 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1913 else if (TARGET_SH2A)
1915 operands[1] = force_reg (SImode, operands[1]);
1916 operands[2] = force_reg (SImode, operands[2]);
1917 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1920 else if (TARGET_SH5)
1922 function_symbol (operands[3],
1923 TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1927 last = gen_udivsi3_i1_media (operands[0], operands[3]);
1928 else if (TARGET_FPU_ANY)
1929 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1931 last = gen_udivsi3_i1 (operands[0], operands[3]);
1935 function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1936 last = gen_udivsi3_i1 (operands[0], operands[3]);
1938 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1939 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1944 (define_insn "divsi3_sh2a"
1945 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1946 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1947 (match_operand:SI 2 "arith_reg_operand" "z")))]
1950 [(set_attr "type" "arith")
1951 (set_attr "in_delay_slot" "no")])
1953 (define_insn "divsi3_i1"
1954 [(set (match_operand:SI 0 "register_operand" "=z")
1955 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956 (clobber (reg:SI T_REG))
1957 (clobber (reg:SI PR_REG))
1958 (clobber (reg:SI R1_REG))
1959 (clobber (reg:SI R2_REG))
1960 (clobber (reg:SI R3_REG))
1961 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962 "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1964 [(set_attr "type" "sfunc")
1965 (set_attr "needs_delay_slot" "yes")])
1967 (define_insn "divsi3_i1_media"
1968 [(set (match_operand:SI 0 "register_operand" "=z")
1969 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970 (clobber (reg:SI T_MEDIA_REG))
1971 (clobber (reg:SI PR_MEDIA_REG))
1972 (clobber (reg:SI R1_REG))
1973 (clobber (reg:SI R20_REG))
1974 (clobber (reg:SI R21_REG))
1975 (clobber (reg:SI TR0_REG))
1976 (use (match_operand 1 "target_reg_operand" "b"))]
1977 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1979 [(set_attr "type" "sfunc")])
1981 (define_insn "divsi3_media_2"
1982 [(set (match_operand:SI 0 "register_operand" "=z")
1983 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1984 (clobber (reg:SI T_MEDIA_REG))
1985 (clobber (reg:SI PR_MEDIA_REG))
1986 (clobber (reg:SI R1_REG))
1987 (clobber (reg:SI R21_REG))
1988 (clobber (reg:SI TR0_REG))
1989 (use (reg:SI R20_REG))
1990 (use (match_operand 1 "target_reg_operand" "b"))]
1991 "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1993 [(set_attr "type" "sfunc")])
1995 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1996 ;; hard reg clobbers and data dependencies that we need when we want
1997 ;; to rematerialize the division into a call.
1998 (define_insn_and_split "divsi_inv_call"
1999 [(set (match_operand:SI 0 "register_operand" "=r")
2000 (div:SI (match_operand:SI 1 "register_operand" "r")
2001 (match_operand:SI 2 "register_operand" "r")))
2002 (clobber (reg:SI R4_REG))
2003 (clobber (reg:SI R5_REG))
2004 (clobber (reg:SI T_MEDIA_REG))
2005 (clobber (reg:SI PR_MEDIA_REG))
2006 (clobber (reg:SI R1_REG))
2007 (clobber (reg:SI R21_REG))
2008 (clobber (reg:SI TR0_REG))
2009 (clobber (reg:SI R20_REG))
2010 (use (match_operand:SI 3 "register_operand" "r"))]
2013 "&& (high_life_started || reload_completed)"
2014 [(set (match_dup 0) (match_dup 3))]
2016 [(set_attr "highpart" "must_split")])
2018 ;; This is the combiner pattern for -mdiv=inv:call .
2019 (define_insn_and_split "*divsi_inv_call_combine"
2020 [(set (match_operand:SI 0 "register_operand" "=z")
2021 (div:SI (match_operand:SI 1 "register_operand" "r")
2022 (match_operand:SI 2 "register_operand" "r")))
2023 (clobber (reg:SI R4_REG))
2024 (clobber (reg:SI R5_REG))
2025 (clobber (reg:SI T_MEDIA_REG))
2026 (clobber (reg:SI PR_MEDIA_REG))
2027 (clobber (reg:SI R1_REG))
2028 (clobber (reg:SI R21_REG))
2029 (clobber (reg:SI TR0_REG))
2030 (clobber (reg:SI R20_REG))
2031 (use (unspec:SI [(match_dup 1)
2032 (match_operand:SI 3 "" "")
2033 (unspec:SI [(match_operand:SI 4 "" "")
2035 (match_operand:DI 5 "" "")]
2037 (match_operand:DI 6 "" "")
2040 UNSPEC_DIV_INV_M3))]
2043 "&& (high_life_started || reload_completed)"
2047 const char *name = sh_divsi3_libfunc;
2048 enum sh_function_kind kind = SFUNC_GOT;
2051 emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2052 emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2053 while (TARGET_DIVIDE_INV_CALL2)
2055 rtx x = operands[3];
2057 if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2059 x = XVECEXP (x, 0, 0);
2060 name = \"__sdivsi3_2\";
2061 kind = SFUNC_STATIC;
2062 emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2065 sym = function_symbol (NULL, name, kind);
2066 emit_insn (gen_divsi3_media_2 (operands[0], sym));
2069 [(set_attr "highpart" "must_split")])
2071 (define_expand "divsi3_i4_media"
2072 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2073 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2074 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2075 (set (match_operand:SI 0 "register_operand" "=r")
2076 (fix:SI (match_dup 5)))]
2077 "TARGET_SHMEDIA_FPU"
2080 operands[3] = gen_reg_rtx (DFmode);
2081 operands[4] = gen_reg_rtx (DFmode);
2082 operands[5] = gen_reg_rtx (DFmode);
2085 (define_insn "divsi3_i4"
2086 [(set (match_operand:SI 0 "register_operand" "=y")
2087 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2088 (clobber (reg:SI PR_REG))
2089 (clobber (reg:DF DR0_REG))
2090 (clobber (reg:DF DR2_REG))
2091 (use (reg:PSI FPSCR_REG))
2092 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2093 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2095 [(set_attr "type" "sfunc")
2096 (set_attr "fp_mode" "double")
2097 (set_attr "needs_delay_slot" "yes")])
2099 (define_insn "divsi3_i4_single"
2100 [(set (match_operand:SI 0 "register_operand" "=y")
2101 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2102 (clobber (reg:SI PR_REG))
2103 (clobber (reg:DF DR0_REG))
2104 (clobber (reg:DF DR2_REG))
2105 (clobber (reg:SI R2_REG))
2106 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2107 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2109 [(set_attr "type" "sfunc")
2110 (set_attr "needs_delay_slot" "yes")])
2112 (define_insn "divsi3_i4_int"
2113 [(set (match_operand:SI 0 "register_operand" "=z")
2114 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2115 (clobber (reg:SI T_REG))
2116 (clobber (reg:SI PR_REG))
2117 (clobber (reg:SI R1_REG))
2118 (clobber (reg:SI MACH_REG))
2119 (clobber (reg:SI MACL_REG))
2120 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2123 [(set_attr "type" "sfunc")
2124 (set_attr "needs_delay_slot" "yes")])
2126 (define_expand "divsi3"
2127 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2128 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2129 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2130 (parallel [(set (match_operand:SI 0 "register_operand" "")
2131 (div:SI (reg:SI R4_REG)
2133 (clobber (reg:SI T_REG))
2134 (clobber (reg:SI PR_REG))
2135 (clobber (reg:SI R1_REG))
2136 (clobber (reg:SI R2_REG))
2137 (clobber (reg:SI R3_REG))
2138 (use (match_dup 3))])]
2144 operands[3] = gen_reg_rtx (Pmode);
2145 /* Emit the move of the address to a pseudo outside of the libcall. */
2146 if (TARGET_DIVIDE_CALL_TABLE)
2148 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2149 last = gen_divsi3_i4_int (operands[0], operands[3]);
2151 else if (TARGET_DIVIDE_CALL_FP)
2153 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2154 if (TARGET_FPU_SINGLE)
2155 last = gen_divsi3_i4_single (operands[0], operands[3]);
2157 last = gen_divsi3_i4 (operands[0], operands[3]);
2159 else if (TARGET_SH2A)
2161 operands[1] = force_reg (SImode, operands[1]);
2162 operands[2] = force_reg (SImode, operands[2]);
2163 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2166 else if (TARGET_DIVIDE_INV)
2168 rtx dividend = operands[1];
2169 rtx divisor = operands[2];
2171 rtx nsb_res = gen_reg_rtx (DImode);
2172 rtx norm64 = gen_reg_rtx (DImode);
2173 rtx tab_ix = gen_reg_rtx (DImode);
2174 rtx norm32 = gen_reg_rtx (SImode);
2175 rtx i92 = force_reg (DImode, GEN_INT (92));
2176 rtx scratch0a = gen_reg_rtx (DImode);
2177 rtx scratch0b = gen_reg_rtx (DImode);
2178 rtx inv0 = gen_reg_rtx (SImode);
2179 rtx scratch1a = gen_reg_rtx (DImode);
2180 rtx scratch1b = gen_reg_rtx (DImode);
2181 rtx shift = gen_reg_rtx (DImode);
2183 rtx inv1 = gen_reg_rtx (SImode);
2184 rtx scratch2a = gen_reg_rtx (DImode);
2185 rtx scratch2b = gen_reg_rtx (SImode);
2186 rtx inv2 = gen_reg_rtx (SImode);
2187 rtx scratch3a = gen_reg_rtx (DImode);
2188 rtx scratch3b = gen_reg_rtx (DImode);
2189 rtx scratch3c = gen_reg_rtx (DImode);
2190 rtx scratch3d = gen_reg_rtx (SImode);
2191 rtx scratch3e = gen_reg_rtx (DImode);
2192 rtx result = gen_reg_rtx (SImode);
2194 if (! arith_reg_or_0_operand (dividend, SImode))
2195 dividend = force_reg (SImode, dividend);
2196 if (! arith_reg_operand (divisor, SImode))
2197 divisor = force_reg (SImode, divisor);
2198 if (flag_pic && Pmode != DImode)
2200 tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2201 tab_base = gen_datalabel_ref (tab_base);
2202 tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2206 tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2207 tab_base = gen_datalabel_ref (tab_base);
2208 tab_base = force_reg (DImode, tab_base);
2210 if (TARGET_DIVIDE_INV20U)
2211 i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2213 i2p27 = GEN_INT (0);
2214 if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2215 i43 = force_reg (DImode, GEN_INT (43));
2218 emit_insn (gen_nsbdi (nsb_res,
2219 simplify_gen_subreg (DImode, divisor, SImode, 0)));
2220 emit_insn (gen_ashldi3_media (norm64,
2221 gen_rtx_SUBREG (DImode, divisor, 0),
2223 emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2224 emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2225 emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2226 inv0, scratch0a, scratch0b,
2227 scratch1a, scratch1b));
2228 emit_insn (gen_subdi3 (shift, i92, nsb_res));
2229 emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2231 emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2233 scratch3a, scratch3b, scratch3c,
2234 scratch2a, scratch2b, scratch3d, scratch3e));
2235 if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2236 emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2237 else if (TARGET_DIVIDE_INV_FP)
2238 emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2239 gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2240 gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2241 gen_reg_rtx (DFmode)));
2243 emit_move_insn (operands[0], result);
2246 else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2248 operands[1] = force_reg (SImode, operands[1]);
2249 operands[2] = force_reg (SImode, operands[2]);
2250 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2253 else if (TARGET_SH5)
2255 if (TARGET_DIVIDE_CALL2)
2257 rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2258 tab_base = gen_datalabel_ref (tab_base);
2259 emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2261 if (TARGET_FPU_ANY && TARGET_SH1)
2262 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2263 else if (TARGET_DIVIDE_CALL2)
2264 function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2266 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2269 last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2270 (operands[0], operands[3]));
2271 else if (TARGET_FPU_ANY)
2272 last = gen_divsi3_i4_single (operands[0], operands[3]);
2274 last = gen_divsi3_i1 (operands[0], operands[3]);
2278 function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2279 last = gen_divsi3_i1 (operands[0], operands[3]);
2281 emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2282 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2287 ;; operands: scratch, tab_base, tab_ix
2288 ;; These are unspecs because we could generate an indexed addressing mode
2289 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2290 ;; confuse reload. See PR27117.
2292 (define_insn "divsi_inv_qitable"
2293 [(set (match_operand:DI 0 "register_operand" "=r")
2294 (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2295 (match_operand:DI 2 "register_operand" "r")]
2296 UNSPEC_DIV_INV_TABLE)))]
2300 [(set_attr "type" "load_media")
2301 (set_attr "highpart" "user")])
2303 ;; operands: scratch, tab_base, tab_ix
2304 (define_insn "divsi_inv_hitable"
2305 [(set (match_operand:DI 0 "register_operand" "=r")
2306 (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2307 (match_operand:DI 2 "register_operand" "r")]
2308 UNSPEC_DIV_INV_TABLE)))]
2312 [(set_attr "type" "load_media")
2313 (set_attr "highpart" "user")])
2315 ;; operands: inv0, tab_base, tab_ix, norm32
2316 ;; scratch equiv in sdivsi3_2: r19, r21
2317 (define_expand "divsi_inv_m0"
2318 [(set (match_operand:SI 0 "register_operand" "=r")
2319 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2320 (match_operand:DI 2 "register_operand" "r")
2321 (match_operand:SI 3 "register_operand" "r")]
2323 (clobber (match_operand:DI 4 "register_operand" "=r"))
2324 (clobber (match_operand:DI 5 "register_operand" "=r"))]
2332 ldx.ub r20, r21, r19 // u0.8
2334 muls.l r25, r19, r19 // s2.38
2335 ldx.w r20, r21, r21 // s2.14
2336 shari r19, 24, r19 // truncate to s2.14
2337 sub r21, r19, r19 // some 11 bit inverse in s1.14
2340 rtx inv0 = operands[0];
2341 rtx tab_base = operands[1];
2342 rtx tab_ix = operands[2];
2343 rtx norm32 = operands[3];
2344 rtx scratch0 = operands[4];
2345 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2346 rtx scratch1 = operands[5];
2348 emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2349 emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2350 emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2351 emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2352 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2353 emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2357 ;; operands: inv1, tab_base, tab_ix, norm32
2358 (define_insn_and_split "divsi_inv_m1"
2359 [(set (match_operand:SI 0 "register_operand" "=r")
2360 (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2361 (match_operand:DI 2 "register_operand" "r")
2362 (match_operand:SI 3 "register_operand" "r")]
2364 (clobber (match_operand:SI 4 "register_operand" "=r"))
2365 (clobber (match_operand:DI 5 "register_operand" "=r"))
2366 (clobber (match_operand:DI 6 "register_operand" "=r"))
2367 (clobber (match_operand:DI 7 "register_operand" "=r"))
2368 (clobber (match_operand:DI 8 "register_operand" "=r"))]
2371 "&& !can_create_pseudo_p ()"
2376 muls.l r19, r19, r18 // u0.28
2377 muls.l r25, r18, r18 // s2.58
2378 shlli r19, 45, r0 // multiply by two and convert to s2.58
2380 shari r18, 28, r18 // some 18 bit inverse in s1.30
2383 rtx inv1 = operands[0];
2384 rtx tab_base = operands[1];
2385 rtx tab_ix = operands[2];
2386 rtx norm32 = operands[3];
2387 rtx inv0 = operands[4];
2388 rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2389 rtx scratch0a = operands[5];
2390 rtx scratch0b = operands[6];
2391 rtx scratch0 = operands[7];
2392 rtx scratch1 = operands[8];
2393 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2395 emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2396 scratch0a, scratch0b));
2397 emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2398 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2399 emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2400 emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2401 emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2405 ;; operands: inv2, norm32, inv1, i92
2406 (define_insn_and_split "divsi_inv_m2"
2407 [(set (match_operand:SI 0 "register_operand" "=r")
2408 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2409 (match_operand:SI 2 "register_operand" "r")
2410 (match_operand:DI 3 "register_operand" "r")]
2412 (clobber (match_operand:DI 4 "register_operand" "=r"))]
2415 "&& !can_create_pseudo_p ()"
2420 muls.l r18, r25, r0 // s2.60
2421 shari r0, 16, r0 // s-16.44
2423 muls.l r0, r18, r19 // s-16.74
2424 shari r19, 30, r19 // s-16.44
2426 rtx inv2 = operands[0];
2427 rtx norm32 = operands[1];
2428 rtx inv1 = operands[2];
2429 rtx i92 = operands[3];
2430 rtx scratch0 = operands[4];
2431 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2433 emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2434 emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2435 emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2436 emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2437 emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2441 (define_insn_and_split "divsi_inv_m3"
2442 [(set (match_operand:SI 0 "register_operand" "=r")
2443 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2444 (match_operand:SI 2 "register_operand" "r")
2445 (match_operand:SI 3 "register_operand" "r")
2446 (match_operand:DI 4 "register_operand" "r")
2447 (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2448 (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2450 (clobber (match_operand:DI 7 "register_operand" "=r"))
2451 (clobber (match_operand:DI 8 "register_operand" "=r"))
2452 (clobber (match_operand:DI 9 "register_operand" "=r"))
2453 (clobber (match_operand:DI 10 "register_operand" "=r"))
2454 (clobber (match_operand:SI 11 "register_operand" "=r"))
2455 (clobber (match_operand:SI 12 "register_operand" "=r"))
2456 (clobber (match_operand:DI 13 "register_operand" "=r"))]
2459 "&& !can_create_pseudo_p ()"
2464 r0: result r1: shift r4: dividend r18: inv1 r19: inv2
2465 r0: scratch0 r19: scratch1 r21: scratch2
2467 muls.l r18, r4, r25 // s32.30
2468 muls.l r19, r4, r19 // s15.30
2470 shari r19, 14, r19 // s18.-14
2476 rtx result = operands[0];
2477 rtx dividend = operands[1];
2478 rtx inv1 = operands[2];
2479 rtx inv2 = operands[3];
2480 rtx shift = operands[4];
2481 rtx scratch0 = operands[7];
2482 rtx scratch1 = operands[8];
2483 rtx scratch2 = operands[9];
2485 if (satisfies_constraint_N (dividend))
2487 emit_move_insn (result, dividend);
2491 emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2492 emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2493 emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2494 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2495 emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2496 emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2497 emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2501 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2502 ;; inv1: tab_base, tab_ix, norm32
2503 ;; inv2: norm32, inv1, i92
2504 (define_insn_and_split "divsi_inv_m1_3"
2505 [(set (match_operand:SI 0 "register_operand" "=r")
2506 (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2507 (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2508 (match_operand:DI 3 "register_operand" "r")
2509 (match_operand:SI 4 "register_operand" "r")]
2511 (unspec:SI [(match_dup 4)
2512 (unspec:SI [(match_dup 2)
2514 (match_dup 4)] UNSPEC_DIV_INV_M1)
2515 (match_operand:SI 5 "" "")]
2517 (match_operand:DI 6 "register_operand" "r")
2518 (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2519 (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2521 (clobber (match_operand:DI 9 "register_operand" "=r"))
2522 (clobber (match_operand:DI 10 "register_operand" "=r"))
2523 (clobber (match_operand:DI 11 "register_operand" "=r"))
2524 (clobber (match_operand:DI 12 "register_operand" "=r"))
2525 (clobber (match_operand:SI 13 "register_operand" "=r"))
2526 (clobber (match_operand:SI 14 "register_operand" "=r"))
2527 (clobber (match_operand:DI 15 "register_operand" "=r"))]
2529 && (TARGET_DIVIDE_INV_MINLAT
2530 || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2532 "&& !can_create_pseudo_p ()"
2536 rtx result = operands[0];
2537 rtx dividend = operands[1];
2538 rtx tab_base = operands[2];
2539 rtx tab_ix = operands[3];
2540 rtx norm32 = operands[4];
2541 /* rtx i92 = operands[5]; */
2542 rtx shift = operands[6];
2543 rtx i2p27 = operands[7];
2544 rtx i43 = operands[8];
2545 rtx scratch0 = operands[9];
2546 rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2547 rtx scratch1 = operands[10];
2548 rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2549 rtx scratch2 = operands[11];
2550 rtx scratch3 = operands[12];
2551 rtx scratch4 = operands[13];
2552 rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2553 rtx scratch5 = operands[14];
2554 rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2555 rtx scratch6 = operands[15];
2557 emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2558 scratch0, scratch1));
2559 /* inv0 == scratch4 */
2560 if (! TARGET_DIVIDE_INV20U)
2562 emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2564 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2568 emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2569 emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2571 emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2572 emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2573 emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2574 /* inv1 == scratch4 */
2576 if (TARGET_DIVIDE_INV_MINLAT)
2578 emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2579 emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2580 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2581 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2582 emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2583 emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2584 emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2585 emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2586 emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2587 emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2588 emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2592 rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2593 /* Use separate scratch regs for nsb and sign to allow scheduling. */
2594 emit_insn (gen_nsbdi (scratch6,
2595 simplify_gen_subreg (DImode, dividend, SImode, 0)));
2596 emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2597 emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2598 emit_insn (gen_divsi_inv20 (scratch2,
2599 norm32, scratch4, dividend,
2600 scratch6, scratch3, i43,
2601 /* scratch0 may be shared with i2p27. */
2602 scratch0, scratch1, scratch5,
2603 label, label, i2p27));
2605 emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2606 emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2610 (define_insn "divsi_inv20"
2611 [(set (match_operand:DI 0 "register_operand" "=&r")
2612 (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2613 (match_operand:SI 2 "register_operand" "r")
2614 (match_operand:SI 3 "register_operand" "r")
2615 (match_operand:DI 4 "register_operand" "r")
2616 (match_operand:DI 5 "register_operand" "r")
2617 (match_operand:DI 6 "register_operand" "r")
2618 (match_operand:DI 12 "register_operand" "r")
2619 (match_operand 10 "target_operand" "b")
2620 (match_operand 11 "immediate_operand" "i")]
2622 (clobber (match_operand:DI 7 "register_operand" "=&r"))
2623 (clobber (match_operand:DI 8 "register_operand" "=&r"))
2624 (clobber (match_operand:SI 9 "register_operand" "=r"))]
2626 && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2629 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2630 %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2631 %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2632 %10 label (tr), %11 label (imm)
2634 muls.l inv1, norm32, scratch0 // s2.60
2635 muls.l inv1, dividend, result // s32.30
2636 xor i2p27, result_sign, round_scratch
2637 bge/u dividend_nsb, i43, tr.. (label)
2638 shari scratch0, 16, scratch0 // s-16.44
2639 muls.l sratch0_si, inv1, scratch0 // s-16.74
2640 sub result, round_scratch, result
2641 shari dividend, 14, scratch1 // s19.-14
2642 shari scratch0, 30, scratch0 // s-16.44
2643 muls.l scratch0, scratch1, round_scratch // s15.30
2645 sub result, round_scratch, result */
2647 int likely = TARGET_DIVIDE_INV20L;
2649 if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2650 output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2651 output_asm_insn (likely
2652 ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2653 : \"bge/u\t%4, %6, %10\", operands);
2654 output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2655 if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2656 output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2658 ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2659 : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2662 (define_insn_and_split "divsi_inv_fp"
2663 [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2664 (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2665 (match_operand:SI 2 "register_operand" "rf")))
2666 (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2667 (clobber (match_operand:SI 4 "register_operand" "=r"))
2668 (clobber (match_operand:SI 5 "register_operand" "=r"))
2669 (clobber (match_operand:DF 6 "register_operand" "=r"))
2670 (clobber (match_operand:DF 7 "register_operand" "=r"))
2671 (clobber (match_operand:DF 8 "register_operand" "=r"))]
2672 "TARGET_SHMEDIA_FPU"
2674 "&& (high_life_started || reload_completed)"
2675 [(set (match_dup 0) (match_dup 3))]
2677 [(set_attr "highpart" "must_split")])
2679 ;; If a matching group of divide-by-inverse instructions is in the same
2680 ;; basic block after gcse & loop optimizations, we want to transform them
2681 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2682 (define_insn_and_split "*divsi_inv_fp_combine"
2683 [(set (match_operand:SI 0 "register_operand" "=f")
2684 (div:SI (match_operand:SI 1 "register_operand" "f")
2685 (match_operand:SI 2 "register_operand" "f")))
2686 (use (unspec:SI [(match_dup 1)
2687 (match_operand:SI 3 "" "")
2688 (unspec:SI [(match_operand:SI 4 "" "")
2690 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2691 (match_operand:DI 6 "" "")
2693 (const_int 0)] UNSPEC_DIV_INV_M3))
2694 (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2695 (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2696 (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2697 (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2698 (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2699 "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2702 [(set (match_dup 9) (float:DF (match_dup 1)))
2703 (set (match_dup 10) (float:DF (match_dup 2)))
2704 (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2706 (fix:SI (match_dup 11)))
2707 (set (match_dup 0) (match_dup 8))]
2710 if (! fp_arith_reg_operand (operands[1], SImode))
2712 emit_move_insn (operands[7], operands[1]);
2713 operands[1] = operands[7];
2715 if (! fp_arith_reg_operand (operands[2], SImode))
2717 emit_move_insn (operands[8], operands[2]);
2718 operands[2] = operands[8];
2721 [(set_attr "highpart" "must_split")])
2723 ;; -------------------------------------------------------------------------
2724 ;; Multiplication instructions
2725 ;; -------------------------------------------------------------------------
2727 (define_insn "umulhisi3_i"
2728 [(set (reg:SI MACL_REG)
2729 (mult:SI (zero_extend:SI
2730 (match_operand:HI 0 "arith_reg_operand" "r"))
2732 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2735 [(set_attr "type" "smpy")])
2737 (define_insn "mulhisi3_i"
2738 [(set (reg:SI MACL_REG)
2739 (mult:SI (sign_extend:SI
2740 (match_operand:HI 0 "arith_reg_operand" "r"))
2742 (match_operand:HI 1 "arith_reg_operand" "r"))))]
2745 [(set_attr "type" "smpy")])
2747 (define_expand "mulhisi3"
2748 [(set (reg:SI MACL_REG)
2749 (mult:SI (sign_extend:SI
2750 (match_operand:HI 1 "arith_reg_operand" ""))
2752 (match_operand:HI 2 "arith_reg_operand" ""))))
2753 (set (match_operand:SI 0 "arith_reg_operand" "")
2760 macl = gen_rtx_REG (SImode, MACL_REG);
2762 emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2763 insn = get_insns ();
2765 /* expand_binop can't find a suitable code in umul_widen_optab to
2766 make a REG_EQUAL note from, so make one here.
2767 See also smulsi3_highpart.
2768 ??? Alternatively, we could put this at the calling site of expand_binop,
2769 i.e. expand_expr. */
2770 /* Use emit_libcall_block for loop invariant code motion and to make
2771 a REG_EQUAL note. */
2772 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2777 (define_expand "umulhisi3"
2778 [(set (reg:SI MACL_REG)
2779 (mult:SI (zero_extend:SI
2780 (match_operand:HI 1 "arith_reg_operand" ""))
2782 (match_operand:HI 2 "arith_reg_operand" ""))))
2783 (set (match_operand:SI 0 "arith_reg_operand" "")
2790 macl = gen_rtx_REG (SImode, MACL_REG);
2792 emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2793 insn = get_insns ();
2795 /* expand_binop can't find a suitable code in umul_widen_optab to
2796 make a REG_EQUAL note from, so make one here.
2797 See also smulsi3_highpart.
2798 ??? Alternatively, we could put this at the calling site of expand_binop,
2799 i.e. expand_expr. */
2800 /* Use emit_libcall_block for loop invariant code motion and to make
2801 a REG_EQUAL note. */
2802 emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2807 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2808 ;; a call to a routine which clobbers known registers.
2811 [(set (match_operand:SI 1 "register_operand" "=z")
2812 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2813 (clobber (reg:SI MACL_REG))
2814 (clobber (reg:SI T_REG))
2815 (clobber (reg:SI PR_REG))
2816 (clobber (reg:SI R3_REG))
2817 (clobber (reg:SI R2_REG))
2818 (clobber (reg:SI R1_REG))
2819 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2822 [(set_attr "type" "sfunc")
2823 (set_attr "needs_delay_slot" "yes")])
2825 (define_expand "mulsi3_call"
2826 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2827 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2828 (parallel[(set (match_operand:SI 0 "register_operand" "")
2829 (mult:SI (reg:SI R4_REG)
2831 (clobber (reg:SI MACL_REG))
2832 (clobber (reg:SI T_REG))
2833 (clobber (reg:SI PR_REG))
2834 (clobber (reg:SI R3_REG))
2835 (clobber (reg:SI R2_REG))
2836 (clobber (reg:SI R1_REG))
2837 (use (match_operand:SI 3 "register_operand" ""))])]
2841 (define_insn "mul_r"
2842 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2843 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2844 (match_operand:SI 2 "arith_reg_operand" "z")))]
2847 [(set_attr "type" "dmpy")])
2849 (define_insn "mul_l"
2850 [(set (reg:SI MACL_REG)
2851 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2852 (match_operand:SI 1 "arith_reg_operand" "r")))]
2855 [(set_attr "type" "dmpy")])
2857 (define_expand "mulsi3"
2858 [(set (reg:SI MACL_REG)
2859 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
2860 (match_operand:SI 2 "arith_reg_operand" "")))
2861 (set (match_operand:SI 0 "arith_reg_operand" "")
2868 /* The address must be set outside the libcall,
2869 since it goes into a pseudo. */
2870 rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2871 rtx addr = force_reg (SImode, sym);
2872 rtx insns = gen_mulsi3_call (operands[0], operands[1],
2878 rtx macl = gen_rtx_REG (SImode, MACL_REG);
2880 emit_insn (gen_mul_l (operands[1], operands[2]));
2881 /* consec_sets_giv can only recognize the first insn that sets a
2882 giv as the giv insn. So we must tag this also with a REG_EQUAL
2884 emit_insn (gen_movsi_i ((operands[0]), macl));
2889 (define_insn "mulsidi3_i"
2890 [(set (reg:SI MACH_REG)
2894 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2895 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2897 (set (reg:SI MACL_REG)
2898 (mult:SI (match_dup 0)
2902 [(set_attr "type" "dmpy")])
2904 (define_expand "mulsidi3"
2905 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2906 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2907 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2908 "TARGET_SH2 || TARGET_SHMEDIA"
2913 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2919 (define_insn "mulsidi3_media"
2920 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2922 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2925 [(set_attr "type" "dmpy_media")
2926 (set_attr "highpart" "ignore")])
2928 (define_insn "mulsidi3_compact"
2929 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2931 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2932 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2933 (clobber (reg:SI MACH_REG))
2934 (clobber (reg:SI MACL_REG))]
2939 [(set (match_operand:DI 0 "arith_reg_dest" "")
2941 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2942 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2943 (clobber (reg:SI MACH_REG))
2944 (clobber (reg:SI MACL_REG))]
2949 rtx low_dst = gen_lowpart (SImode, operands[0]);
2950 rtx high_dst = gen_highpart (SImode, operands[0]);
2952 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2954 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2955 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2956 /* We need something to tag the possible REG_EQUAL notes on to. */
2957 emit_move_insn (operands[0], operands[0]);
2961 (define_insn "umulsidi3_i"
2962 [(set (reg:SI MACH_REG)
2966 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2967 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2969 (set (reg:SI MACL_REG)
2970 (mult:SI (match_dup 0)
2974 [(set_attr "type" "dmpy")])
2976 (define_expand "umulsidi3"
2977 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2978 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2979 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2980 "TARGET_SH2 || TARGET_SHMEDIA"
2985 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2991 (define_insn "umulsidi3_media"
2992 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2993 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2994 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2997 [(set_attr "type" "dmpy_media")
2998 (set_attr "highpart" "ignore")])
3000 (define_insn "umulsidi3_compact"
3001 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3003 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
3004 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
3005 (clobber (reg:SI MACH_REG))
3006 (clobber (reg:SI MACL_REG))]
3011 [(set (match_operand:DI 0 "arith_reg_dest" "")
3012 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3013 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3014 (clobber (reg:SI MACH_REG))
3015 (clobber (reg:SI MACL_REG))]
3020 rtx low_dst = gen_lowpart (SImode, operands[0]);
3021 rtx high_dst = gen_highpart (SImode, operands[0]);
3023 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3025 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3026 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3027 /* We need something to tag the possible REG_EQUAL notes on to. */
3028 emit_move_insn (operands[0], operands[0]);
3032 (define_insn "smulsi3_highpart_i"
3033 [(set (reg:SI MACH_REG)
3037 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3038 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3040 (clobber (reg:SI MACL_REG))]
3043 [(set_attr "type" "dmpy")])
3045 (define_expand "smulsi3_highpart"
3047 [(set (reg:SI MACH_REG)
3051 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3052 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3054 (clobber (reg:SI MACL_REG))])
3055 (set (match_operand:SI 0 "arith_reg_operand" "")
3062 mach = gen_rtx_REG (SImode, MACH_REG);
3064 emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3065 insn = get_insns ();
3067 /* expand_binop can't find a suitable code in mul_highpart_optab to
3068 make a REG_EQUAL note from, so make one here.
3069 See also {,u}mulhisi.
3070 ??? Alternatively, we could put this at the calling site of expand_binop,
3071 i.e. expand_mult_highpart. */
3072 /* Use emit_libcall_block for loop invariant code motion and to make
3073 a REG_EQUAL note. */
3074 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3079 (define_insn "umulsi3_highpart_i"
3080 [(set (reg:SI MACH_REG)
3084 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3085 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3087 (clobber (reg:SI MACL_REG))]
3090 [(set_attr "type" "dmpy")])
3092 (define_expand "umulsi3_highpart"
3094 [(set (reg:SI MACH_REG)
3098 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3099 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3101 (clobber (reg:SI MACL_REG))])
3102 (set (match_operand:SI 0 "arith_reg_operand" "")
3109 mach = gen_rtx_REG (SImode, MACH_REG);
3111 emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3112 insn = get_insns ();
3114 /* Use emit_libcall_block for loop invariant code motion and to make
3115 a REG_EQUAL note. */
3116 emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3121 (define_insn_and_split "muldi3"
3122 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3123 (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3124 (match_operand:DI 2 "arith_reg_operand" "r")))
3125 (clobber (match_scratch:DI 3 "=&r"))
3126 (clobber (match_scratch:DI 4 "=r"))]
3133 rtx op3_v2si, op2_v2si;
3135 op3_v2si = operands[3];
3136 if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3138 op3_v2si = XEXP (op3_v2si, 0);
3139 op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3141 op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3142 op2_v2si = operands[2];
3143 if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3145 op2_v2si = XEXP (op2_v2si, 0);
3146 op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3148 op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3149 emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3150 emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3151 emit_insn (gen_umulsidi3_media (operands[4],
3152 sh_gen_truncate (SImode, operands[1], 0),
3153 sh_gen_truncate (SImode, operands[2], 0)));
3154 emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3155 emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3156 emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3157 emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3162 ;; -------------------------------------------------------------------------
3163 ;; Logical operations
3164 ;; -------------------------------------------------------------------------
3166 (define_insn "*andsi3_compact"
3167 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3168 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3169 (match_operand:SI 2 "logical_operand" "K08,r")))]
3172 [(set_attr "type" "arith")])
3174 (define_insn "*andsi3_media"
3175 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3176 (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3177 (match_operand:SI 2 "logical_operand" "r,I10")))]
3182 [(set_attr "type" "arith_media")])
3184 (define_insn "*andsi3_bclr"
3185 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3186 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3187 (match_operand:SI 2 "const_int_operand" "Psz")))]
3188 "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3190 [(set_attr "type" "arith")])
3192 ;; If the constant is 255, then emit an extu.b instruction instead of an
3193 ;; and, since that will give better code.
3195 (define_expand "andsi3"
3196 [(set (match_operand:SI 0 "arith_reg_operand" "")
3197 (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3198 (match_operand:SI 2 "logical_operand" "")))]
3203 && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3205 emit_insn (gen_zero_extendqisi2 (operands[0],
3206 gen_lowpart (QImode, operands[1])));
3211 (define_insn_and_split "anddi3"
3212 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3213 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3214 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3221 && ! logical_operand (operands[2], DImode)"
3225 if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3226 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3228 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3231 [(set_attr "type" "arith_media")])
3233 (define_insn "andcsi3"
3234 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3235 (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3236 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3239 [(set_attr "type" "arith_media")])
3241 (define_insn "andcdi3"
3242 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3243 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3244 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3247 [(set_attr "type" "arith_media")])
3249 (define_expand "iorsi3"
3250 [(set (match_operand:SI 0 "arith_reg_operand" "")
3251 (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3252 (match_operand:SI 2 "logical_operand" "")))]
3256 (define_insn "*iorsi3_compact"
3257 [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3258 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3259 (match_operand:SI 2 "logical_operand" "r,K08")))]
3261 && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3263 [(set_attr "type" "arith")])
3265 (define_insn "*iorsi3_media"
3266 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3267 (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3268 (match_operand:SI 2 "logical_operand" "r,I10")))]
3273 [(set_attr "type" "arith_media")])
3275 (define_insn "*iorsi3_bset"
3276 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3277 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3278 (match_operand:SI 2 "const_int_operand" "Pso")))]
3279 "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3281 [(set_attr "type" "arith")])
3283 (define_insn "iordi3"
3284 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3285 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3286 (match_operand:DI 2 "logical_operand" "r,I10")))]
3291 [(set_attr "type" "arith_media")])
3293 (define_insn_and_split "*logical_sidi3"
3294 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3295 (sign_extend:DI (match_operator:SI 3 "logical_operator"
3296 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3297 (match_operand:SI 2 "logical_operand" "r,I10")])))]
3300 "&& reload_completed"
3301 [(set (match_dup 0) (match_dup 3))]
3305 = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3306 simplify_gen_subreg (DImode, operands[1], SImode, 0),
3307 simplify_gen_subreg (DImode, operands[2], SImode, 0));
3310 (define_insn_and_split "*logical_sidisi3"
3311 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3312 (truncate:SI (sign_extend:DI
3313 (match_operator:SI 3 "logical_operator"
3314 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3315 (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3319 [(set (match_dup 0) (match_dup 3))])
3321 (define_insn_and_split "*logical_sidi3_2"
3322 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3323 (sign_extend:DI (truncate:SI (sign_extend:DI
3324 (match_operator:SI 3 "logical_operator"
3325 [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3326 (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3330 [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3332 (define_expand "xorsi3"
3333 [(set (match_operand:SI 0 "arith_reg_operand" "")
3334 (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3335 (match_operand:SI 2 "xor_operand" "")))]
3339 (define_insn "*xorsi3_compact"
3340 [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3341 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3342 (match_operand:SI 2 "logical_operand" "K08,r")))]
3345 [(set_attr "type" "arith")])
3347 (define_insn "*xorsi3_media"
3348 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3349 (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3350 (match_operand:SI 2 "xor_operand" "r,I06")))]
3355 [(set_attr "type" "arith_media")])
3357 ;; Store the complements of the T bit in a register.
3358 (define_insn "xorsi3_movrt"
3359 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3360 (xor:SI (reg:SI T_REG)
3364 [(set_attr "type" "arith")])
3366 (define_insn "xordi3"
3367 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3368 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3369 (match_operand:DI 2 "xor_operand" "r,I06")))]
3374 [(set_attr "type" "arith_media")])
3376 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3377 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3379 [(set (match_operand:DI 0 "arith_reg_dest" "")
3380 (sign_extend:DI (match_operator 4 "binary_logical_operator"
3381 [(match_operand 1 "any_register_operand" "")
3382 (match_operand 2 "any_register_operand" "")])))]
3384 [(set (match_dup 5) (match_dup 4))
3385 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3388 enum machine_mode inmode = GET_MODE (operands[1]);
3391 if (GET_CODE (operands[0]) == SUBREG)
3393 offset = SUBREG_BYTE (operands[0]);
3394 operands[0] = SUBREG_REG (operands[0]);
3396 gcc_assert (REG_P (operands[0]));
3397 if (! TARGET_LITTLE_ENDIAN)
3398 offset += 8 - GET_MODE_SIZE (inmode);
3399 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3402 ;; -------------------------------------------------------------------------
3403 ;; Shifts and rotates
3404 ;; -------------------------------------------------------------------------
3406 (define_expand "rotldi3"
3407 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3408 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3409 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3411 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3413 (define_insn "rotldi3_mextr"
3414 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3415 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3416 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3420 static char templ[16];
3422 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3423 8 - (int) (INTVAL (operands[2]) >> 3));
3426 [(set_attr "type" "arith_media")])
3428 (define_expand "rotrdi3"
3429 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3430 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3431 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3433 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3435 (define_insn "rotrdi3_mextr"
3436 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3437 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3438 (match_operand:HI 2 "mextr_bit_offset" "i")))]
3442 static char templ[16];
3444 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3447 [(set_attr "type" "arith_media")])
3450 [(set (match_operand:DI 0 "arith_reg_dest" "")
3451 (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3452 "ua_address_operand" "")))
3453 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3455 (clobber (match_operand:DI 3 "register_operand" ""))]
3457 [(match_dup 4) (match_dup 5)]
3460 operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3461 (operands[3], operands[1]));
3462 operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3463 GEN_INT (56), GEN_INT (8));
3466 (define_insn "rotlsi3_1"
3467 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3468 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3471 (lshiftrt:SI (match_dup 1) (const_int 31)))]
3474 [(set_attr "type" "arith")])
3476 (define_insn "rotlsi3_31"
3477 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3478 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3480 (clobber (reg:SI T_REG))]
3483 [(set_attr "type" "arith")])
3485 (define_insn "rotlsi3_16"
3486 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3487 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3491 [(set_attr "type" "arith")])
3493 (define_expand "rotlsi3"
3494 [(set (match_operand:SI 0 "arith_reg_dest" "")
3495 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3496 (match_operand:SI 2 "immediate_operand" "")))]
3500 static const char rot_tab[] = {
3501 000, 000, 000, 000, 000, 000, 010, 001,
3502 001, 001, 011, 013, 003, 003, 003, 003,
3503 003, 003, 003, 003, 003, 013, 012, 002,
3504 002, 002, 010, 000, 000, 000, 000, 000,
3509 if (!CONST_INT_P (operands[2]))
3511 count = INTVAL (operands[2]);
3512 choice = rot_tab[count];
3513 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3519 emit_move_insn (operands[0], operands[1]);
3520 count -= (count & 16) * 2;
3523 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3530 parts[0] = gen_reg_rtx (SImode);
3531 parts[1] = gen_reg_rtx (SImode);
3532 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3533 emit_move_insn (parts[choice-1], operands[1]);
3534 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3535 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3536 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3537 count = (count & ~16) - 8;
3541 for (; count > 0; count--)
3542 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3543 for (; count < 0; count++)
3544 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3549 (define_insn "*rotlhi3_8"
3550 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3551 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3555 [(set_attr "type" "arith")])
3557 (define_expand "rotlhi3"
3558 [(set (match_operand:HI 0 "arith_reg_operand" "")
3559 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3560 (match_operand:HI 2 "immediate_operand" "")))]
3564 if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3571 (define_insn "ashlsi3_sh2a"
3572 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3573 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3574 (match_operand:SI 2 "arith_reg_operand" "r")))]
3577 [(set_attr "type" "arith")
3578 (set_attr "length" "4")])
3580 ;; This pattern is used by init_expmed for computing the costs of shift
3583 (define_insn_and_split "ashlsi3_std"
3584 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3585 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3586 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3587 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3589 || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3597 && CONST_INT_P (operands[2])
3598 && ! satisfies_constraint_P27 (operands[2])"
3599 [(set (match_dup 3) (match_dup 2))
3601 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3602 (clobber (match_dup 4))])]
3603 "operands[4] = gen_rtx_SCRATCH (SImode);"
3604 [(set_attr "length" "*,*,*,4")
3605 (set_attr "type" "dyn_shift,arith,arith,arith")])
3607 (define_insn "ashlhi3_k"
3608 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3609 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3610 (match_operand:HI 2 "const_int_operand" "M,P27")))]
3611 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3615 [(set_attr "type" "arith")])
3617 (define_insn "ashlsi3_n"
3618 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3619 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3620 (match_operand:SI 2 "const_int_operand" "n")))
3621 (clobber (reg:SI T_REG))]
3622 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3624 [(set (attr "length")
3625 (cond [(match_test "shift_insns_rtx (insn)")
3627 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3629 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3631 (const_string "8")))
3632 (set_attr "type" "arith")])
3635 [(set (match_operand:SI 0 "arith_reg_dest" "")
3636 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3637 (match_operand:SI 2 "const_int_operand" "")))
3638 (clobber (reg:SI T_REG))]
3639 "TARGET_SH1 && reload_completed"
3640 [(use (reg:SI R0_REG))]
3643 gen_shifty_op (ASHIFT, operands);
3647 (define_insn "ashlsi3_media"
3648 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3649 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3650 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3655 [(set_attr "type" "arith_media")
3656 (set_attr "highpart" "ignore")])
3658 (define_expand "ashlsi3"
3659 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3660 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3661 (match_operand:SI 2 "nonmemory_operand" "")))
3662 (clobber (reg:SI T_REG))])]
3668 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3671 if (CONST_INT_P (operands[2])
3672 && sh_dynamicalize_shift_p (operands[2]))
3673 operands[2] = force_reg (SImode, operands[2]);
3676 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3679 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3683 (define_insn "*ashlhi3_n"
3684 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3685 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3686 (match_operand:HI 2 "const_int_operand" "n")))
3687 (clobber (reg:SI T_REG))]
3690 [(set (attr "length")
3691 (cond [(match_test "shift_insns_rtx (insn)")
3693 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3695 (const_string "6")))
3696 (set_attr "type" "arith")])
3698 (define_expand "ashlhi3"
3699 [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3700 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3701 (match_operand:SI 2 "nonmemory_operand" "")))
3702 (clobber (reg:SI T_REG))])]
3706 if (!CONST_INT_P (operands[2]))
3708 /* It may be possible to call gen_ashlhi3 directly with more generic
3709 operands. Make sure operands[1] is a HImode register here. */
3710 if (!arith_reg_operand (operands[1], HImode))
3711 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3715 [(set (match_operand:HI 0 "arith_reg_dest" "")
3716 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3717 (match_operand:HI 2 "const_int_operand" "")))
3718 (clobber (reg:SI T_REG))]
3719 "TARGET_SH1 && reload_completed"
3720 [(use (reg:SI R0_REG))]
3723 gen_shifty_hi_op (ASHIFT, operands);
3728 ; arithmetic shift right
3731 (define_insn "ashrsi3_sh2a"
3732 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3733 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3734 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3737 [(set_attr "type" "dyn_shift")
3738 (set_attr "length" "4")])
3740 (define_insn "ashrsi3_k"
3741 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3742 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3743 (match_operand:SI 2 "const_int_operand" "M")))
3744 (clobber (reg:SI T_REG))]
3745 "TARGET_SH1 && INTVAL (operands[2]) == 1"
3747 [(set_attr "type" "arith")])
3749 ;; We can't do HImode right shifts correctly unless we start out with an
3750 ;; explicit zero / sign extension; doing that would result in worse overall
3751 ;; code, so just let the machine independent code widen the mode.
3752 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3755 ;; ??? This should be a define expand.
3757 (define_insn "ashrsi2_16"
3758 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3759 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3763 [(set_attr "length" "4")])
3766 [(set (match_operand:SI 0 "arith_reg_dest" "")
3767 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3770 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3771 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3772 "operands[2] = gen_lowpart (HImode, operands[0]);")
3774 ;; ??? This should be a define expand.
3776 (define_insn "ashrsi2_31"
3777 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3778 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3780 (clobber (reg:SI T_REG))]
3783 [(set_attr "length" "4")])
3786 [(set (match_operand:SI 0 "arith_reg_dest" "")
3787 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3789 (clobber (reg:SI T_REG))]
3794 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3795 emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3800 [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3802 (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3804 && peep2_reg_dead_p (2, operands[0])
3805 && peep2_reg_dead_p (2, operands[1])"
3809 emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3813 (define_insn "ashlsi_c"
3814 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3815 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3817 (lt:SI (match_dup 1) (const_int 0)))]
3820 [(set_attr "type" "arith")])
3822 (define_insn "*ashlsi_c_void"
3823 [(set (reg:SI T_REG)
3824 (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3825 (clobber (match_scratch:SI 1 "=0"))]
3826 "TARGET_SH1 && cse_not_expected"
3828 [(set_attr "type" "arith")])
3830 (define_insn "ashrsi3_d"
3831 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3832 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3833 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3836 [(set_attr "type" "dyn_shift")])
3838 (define_insn "ashrsi3_n"
3839 [(set (reg:SI R4_REG)
3840 (ashiftrt:SI (reg:SI R4_REG)
3841 (match_operand:SI 0 "const_int_operand" "i")))
3842 (clobber (reg:SI T_REG))
3843 (clobber (reg:SI PR_REG))
3844 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3847 [(set_attr "type" "sfunc")
3848 (set_attr "needs_delay_slot" "yes")])
3850 (define_insn "ashrsi3_media"
3851 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3852 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3853 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3858 [(set_attr "type" "arith_media")
3859 (set_attr "highpart" "ignore")])
3861 (define_expand "ashrsi3"
3862 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3863 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3864 (match_operand:SI 2 "nonmemory_operand" "")))
3865 (clobber (reg:SI T_REG))])]
3871 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3874 if (expand_ashiftrt (operands))
3880 ;; logical shift right
3882 (define_insn "lshrsi3_sh2a"
3883 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3884 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3885 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3888 [(set_attr "type" "dyn_shift")
3889 (set_attr "length" "4")])
3891 (define_insn "lshrsi3_d"
3892 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3893 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3894 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3897 [(set_attr "type" "dyn_shift")])
3899 ;; Only the single bit shift clobbers the T bit.
3901 (define_insn "lshrsi3_m"
3902 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3903 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3904 (match_operand:SI 2 "const_int_operand" "M")))
3905 (clobber (reg:SI T_REG))]
3906 "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3908 [(set_attr "type" "arith")])
3910 (define_insn "lshrsi3_k"
3911 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3912 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3913 (match_operand:SI 2 "const_int_operand" "P27")))]
3914 "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3915 && ! satisfies_constraint_M (operands[2])"
3917 [(set_attr "type" "arith")])
3919 (define_insn "lshrsi3_n"
3920 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3922 (match_operand:SI 2 "const_int_operand" "n")))
3923 (clobber (reg:SI T_REG))]
3924 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3926 [(set (attr "length")
3927 (cond [(match_test "shift_insns_rtx (insn)")
3929 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3931 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3933 (const_string "8")))
3934 (set_attr "type" "arith")])
3937 [(set (match_operand:SI 0 "arith_reg_dest" "")
3938 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3939 (match_operand:SI 2 "const_int_operand" "")))
3940 (clobber (reg:SI T_REG))]
3941 "TARGET_SH1 && reload_completed"
3942 [(use (reg:SI R0_REG))]
3945 gen_shifty_op (LSHIFTRT, operands);
3949 (define_insn "lshrsi3_media"
3950 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3951 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3952 (match_operand:SI 2 "shift_count_operand" "r,n")))]
3957 [(set_attr "type" "arith_media")
3958 (set_attr "highpart" "ignore")])
3960 (define_expand "lshrsi3"
3961 [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3962 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3963 (match_operand:SI 2 "nonmemory_operand" "")))
3964 (clobber (reg:SI T_REG))])]
3970 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3973 if (CONST_INT_P (operands[2])
3974 && sh_dynamicalize_shift_p (operands[2]))
3975 operands[2] = force_reg (SImode, operands[2]);
3976 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3978 rtx count = copy_to_mode_reg (SImode, operands[2]);
3979 emit_insn (gen_negsi2 (count, count));
3980 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3983 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3987 ;; ??? This should be a define expand.
3989 (define_insn "ashldi3_k"
3990 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3991 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3993 (clobber (reg:SI T_REG))]
3995 "shll %R0\;rotcl %S0"
3996 [(set_attr "length" "4")
3997 (set_attr "type" "arith")])
3999 ;; Expander for DImode shift left with SImode operations.
4001 (define_expand "ashldi3_std"
4002 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4003 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004 (match_operand:DI 2 "const_int_operand" "n")))]
4005 "TARGET_SH1 && INTVAL (operands[2]) < 32"
4008 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4009 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4010 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4011 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4012 rtx dst = gen_reg_rtx (DImode);
4013 rtx low_dst = operand_subword (dst, low_word, 1, DImode);
4014 rtx high_dst = operand_subword (dst, high_word, 1, DImode);
4017 tmp0 = gen_reg_rtx (SImode);
4018 tmp1 = gen_reg_rtx (SImode);
4019 emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
4020 emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
4021 emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
4022 emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
4023 emit_move_insn (operands[0], dst);
4027 (define_insn "ashldi3_media"
4028 [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4029 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4030 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4035 [(set_attr "type" "arith_media")])
4037 (define_insn "*ashldisi3_media"
4038 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4039 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4040 (match_operand:DI 2 "const_int_operand" "n")))]
4041 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4042 "shlli.l %1, %2, %0"
4043 [(set_attr "type" "arith_media")
4044 (set_attr "highpart" "ignore")])
4046 (define_expand "ashldi3"
4047 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4048 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4049 (match_operand:DI 2 "immediate_operand" "")))
4050 (clobber (reg:SI T_REG))])]
4056 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4059 if (CONST_INT_P (operands[2])
4060 && INTVAL (operands[2]) == 1)
4062 emit_insn (gen_ashldi3_k (operands[0], operands[1]));
4065 else if (CONST_INT_P (operands[2])
4066 && INTVAL (operands[2]) < 32)
4068 emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
4075 ;; ??? This should be a define expand.
4077 (define_insn "lshrdi3_k"
4078 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4079 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4081 (clobber (reg:SI T_REG))]
4083 "shlr %S0\;rotcr %R0"
4084 [(set_attr "length" "4")
4085 (set_attr "type" "arith")])
4087 (define_insn "lshrdi3_media"
4088 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4089 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4090 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4092 && (arith_reg_dest (operands[0], DImode)
4093 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4097 [(set_attr "type" "arith_media")])
4099 (define_insn "*lshrdisi3_media"
4100 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4101 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4102 (match_operand:DI 2 "const_int_operand" "n")))]
4103 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4104 "shlri.l %1, %2, %0"
4105 [(set_attr "type" "arith_media")
4106 (set_attr "highpart" "ignore")])
4108 (define_expand "lshrdi3"
4109 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4110 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4111 (match_operand:DI 2 "immediate_operand" "")))
4112 (clobber (reg:SI T_REG))])]
4118 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4121 if (!CONST_INT_P (operands[2])
4122 || INTVAL (operands[2]) != 1)
4126 ;; ??? This should be a define expand.
4128 (define_insn "ashrdi3_k"
4129 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4130 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4132 (clobber (reg:SI T_REG))]
4134 "shar %S0\;rotcr %R0"
4135 [(set_attr "length" "4")
4136 (set_attr "type" "arith")])
4138 (define_insn "ashrdi3_media"
4139 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4140 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4141 (match_operand:DI 2 "shift_count_operand" "r,n")))]
4143 && (arith_reg_dest (operands[0], DImode)
4144 || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4148 [(set_attr "type" "arith_media")])
4150 (define_insn "*ashrdisi3_media"
4151 [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4152 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4153 (match_operand:DI 2 "const_int_operand" "n")))]
4154 "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4155 "shari.l %1, %2, %0"
4156 [(set_attr "type" "arith_media")
4157 (set_attr "highpart" "ignore")])
4159 (define_insn "ashrdisi3_media_high"
4160 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4162 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4163 (match_operand:DI 2 "const_int_operand" "n"))))]
4164 "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4166 [(set_attr "type" "arith_media")])
4168 (define_insn "ashrdisi3_media_opaque"
4169 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4170 (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4171 (match_operand:DI 2 "const_int_operand" "n")]
4175 [(set_attr "type" "arith_media")])
4177 (define_expand "ashrdi3"
4178 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4179 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4180 (match_operand:DI 2 "immediate_operand" "")))
4181 (clobber (reg:SI T_REG))])]
4187 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4190 if (!CONST_INT_P (operands[2])
4191 || INTVAL (operands[2]) != 1)
4195 ;; combined left/right shift
4198 [(set (match_operand:SI 0 "register_operand" "")
4199 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4200 (match_operand:SI 2 "const_int_operand" ""))
4201 (match_operand:SI 3 "const_int_operand" "")))]
4202 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4203 [(use (reg:SI R0_REG))]
4204 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4208 [(set (match_operand:SI 0 "register_operand" "")
4209 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4210 (match_operand:SI 2 "const_int_operand" ""))
4211 (match_operand:SI 3 "const_int_operand" "")))
4212 (clobber (reg:SI T_REG))]
4213 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4214 [(use (reg:SI R0_REG))]
4215 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4219 [(set (match_operand:SI 0 "register_operand" "=r")
4220 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4221 (match_operand:SI 2 "const_int_operand" "n"))
4222 (match_operand:SI 3 "const_int_operand" "n")))
4223 (clobber (reg:SI T_REG))]
4224 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4226 [(set (attr "length")
4227 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4229 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4231 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4233 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4235 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4237 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4239 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4240 (const_string "16")]
4241 (const_string "18")))
4242 (set_attr "type" "arith")])
4245 [(set (match_operand:SI 0 "register_operand" "=z")
4246 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4247 (match_operand:SI 2 "const_int_operand" "n"))
4248 (match_operand:SI 3 "const_int_operand" "n")))
4249 (clobber (reg:SI T_REG))]
4250 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4252 [(set (attr "length")
4253 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4255 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4257 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4259 (const_string "10")))
4260 (set_attr "type" "arith")])
4262 ;; shift left / and combination with a scratch register: The combine pass
4263 ;; does not accept the individual instructions, even though they are
4264 ;; cheap. But it needs a precise description so that it is usable after
4266 (define_insn "and_shl_scratch"
4267 [(set (match_operand:SI 0 "register_operand" "=r,&r")
4271 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4272 (match_operand:SI 2 "const_int_operand" "N,n"))
4273 (match_operand:SI 3 "" "0,r"))
4274 (match_operand:SI 4 "const_int_operand" "n,n"))
4275 (match_operand:SI 5 "const_int_operand" "n,n")))
4276 (clobber (reg:SI T_REG))]
4279 [(set (attr "length")
4280 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4282 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4284 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4286 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4287 (const_string "10")]
4288 (const_string "12")))
4289 (set_attr "type" "arith")])
4292 [(set (match_operand:SI 0 "register_operand" "")
4296 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4297 (match_operand:SI 2 "const_int_operand" ""))
4298 (match_operand:SI 3 "register_operand" ""))
4299 (match_operand:SI 4 "const_int_operand" ""))
4300 (match_operand:SI 5 "const_int_operand" "")))
4301 (clobber (reg:SI T_REG))]
4303 [(use (reg:SI R0_REG))]
4306 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4308 if (INTVAL (operands[2]))
4310 gen_shifty_op (LSHIFTRT, operands);
4312 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4313 operands[2] = operands[4];
4314 gen_shifty_op (ASHIFT, operands);
4315 if (INTVAL (operands[5]))
4317 operands[2] = operands[5];
4318 gen_shifty_op (LSHIFTRT, operands);
4323 ;; signed left/right shift combination.
4325 [(set (match_operand:SI 0 "register_operand" "")
4327 (ashift:SI (match_operand:SI 1 "register_operand" "")
4328 (match_operand:SI 2 "const_int_operand" ""))
4329 (match_operand:SI 3 "const_int_operand" "")
4331 (clobber (reg:SI T_REG))]
4333 [(use (reg:SI R0_REG))]
4334 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4337 (define_insn "shl_sext_ext"
4338 [(set (match_operand:SI 0 "register_operand" "=r")
4340 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4341 (match_operand:SI 2 "const_int_operand" "n"))
4342 (match_operand:SI 3 "const_int_operand" "n")
4344 (clobber (reg:SI T_REG))]
4345 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4347 [(set (attr "length")
4348 (cond [(match_test "shl_sext_length (insn)")
4350 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4352 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4354 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4356 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4358 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4360 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4362 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4363 (const_string "16")]
4364 (const_string "18")))
4365 (set_attr "type" "arith")])
4367 (define_insn "shl_sext_sub"
4368 [(set (match_operand:SI 0 "register_operand" "=z")
4370 (ashift:SI (match_operand:SI 1 "register_operand" "0")
4371 (match_operand:SI 2 "const_int_operand" "n"))
4372 (match_operand:SI 3 "const_int_operand" "n")
4374 (clobber (reg:SI T_REG))]
4375 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4377 [(set (attr "length")
4378 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4380 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4382 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4384 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4385 (const_string "12")]
4386 (const_string "14")))
4387 (set_attr "type" "arith")])
4389 ;; These patterns are found in expansions of DImode shifts by 16, and
4390 ;; allow the xtrct instruction to be generated from C source.
4392 (define_insn "xtrct_left"
4393 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4394 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4396 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4400 [(set_attr "type" "arith")])
4402 (define_insn "xtrct_right"
4403 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4404 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4406 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4410 [(set_attr "type" "arith")])
4412 ;; -------------------------------------------------------------------------
4414 ;; -------------------------------------------------------------------------
4417 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4418 (neg:SI (plus:SI (reg:SI T_REG)
4419 (match_operand:SI 1 "arith_reg_operand" "r"))))
4421 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4425 [(set_attr "type" "arith")])
4427 (define_insn "*negdi_media"
4428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4429 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4432 [(set_attr "type" "arith_media")])
4436 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4438 (define_expand "negdi2"
4439 [(set (match_operand:DI 0 "arith_reg_dest" "")
4440 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4441 (clobber (reg:SI T_REG))]
4445 (define_insn_and_split "*negdi2"
4446 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4447 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4454 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4455 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4457 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4458 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4460 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4461 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4463 emit_insn (gen_clrt ());
4464 emit_insn (gen_negc (low_dst, low_src));
4465 emit_insn (gen_negc (high_dst, high_src));
4469 (define_insn "negsi2"
4470 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4471 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4474 [(set_attr "type" "arith")])
4476 (define_insn "one_cmplsi2"
4477 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4478 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4481 [(set_attr "type" "arith")])
4483 (define_expand "one_cmpldi2"
4484 [(set (match_operand:DI 0 "arith_reg_dest" "")
4485 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4487 "TARGET_SHMEDIA" "")
4489 (define_expand "abssi2"
4490 [(set (match_operand:SI 0 "arith_reg_dest" "")
4491 (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4492 (clobber (reg:SI T_REG))]
4496 (define_insn_and_split "*abssi2"
4497 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4498 (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4505 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4506 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4511 (define_insn_and_split "*negabssi2"
4512 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4513 (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4520 emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4521 emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4527 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4528 ;; This can be used as some kind of conditional execution, which is useful
4530 ;; Actually the instruction scheduling should decide whether to use a
4531 ;; zero-offset branch or not for any generic case involving a single
4532 ;; instruction on SH4 202.
4534 (define_insn_and_split "negsi_cond"
4535 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4536 (if_then_else:SI (eq:SI (reg:SI T_REG)
4537 (match_operand:SI 3 "const_int_operand" "M,N"))
4538 (match_operand:SI 1 "arith_reg_operand" "0,0")
4539 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4542 bt\\t0f\;neg\\t%2,%0\\n0:
4543 bf\\t0f\;neg\\t%2,%0\\n0:"
4548 rtx skip_neg_label = gen_label_rtx ();
4550 emit_insn (gen_movsi (operands[0], operands[1]));
4552 emit_jump_insn (INTVAL (operands[3])
4553 ? gen_branch_true (skip_neg_label)
4554 : gen_branch_false (skip_neg_label));
4556 emit_label_after (skip_neg_label,
4557 emit_insn (gen_negsi2 (operands[0], operands[1])));
4560 [(set_attr "type" "arith") ;; poor approximation
4561 (set_attr "length" "4")])
4564 ;; -------------------------------------------------------------------------
4565 ;; Zero extension instructions
4566 ;; -------------------------------------------------------------------------
4568 (define_insn "zero_extendsidi2"
4569 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4570 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4572 "addz.l %1, r63, %0"
4573 [(set_attr "type" "arith_media")
4574 (set_attr "highpart" "extend")])
4576 (define_insn "zero_extendhidi2"
4577 [(set (match_operand:DI 0 "register_operand" "=r,r")
4578 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4583 [(set_attr "type" "*,load_media")
4584 (set (attr "highpart")
4585 (cond [(match_test "sh_contains_memref_p (insn)")
4586 (const_string "user")]
4587 (const_string "ignore")))])
4590 [(set (match_operand:DI 0 "register_operand" "")
4591 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4592 "TARGET_SHMEDIA && reload_completed"
4593 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4594 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4597 if (GET_CODE (operands[1]) == TRUNCATE)
4598 operands[1] = XEXP (operands[1], 0);
4601 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4602 ;; reload the entire truncate expression.
4603 (define_insn_and_split "*loaddi_trunc"
4604 [(set (match_operand 0 "any_register_operand" "=r")
4605 (truncate (match_operand:DI 1 "memory_operand" "m")))]
4606 "TARGET_SHMEDIA && reload_completed"
4608 "TARGET_SHMEDIA && reload_completed"
4609 [(set (match_dup 0) (match_dup 1))]
4610 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4612 (define_insn "zero_extendqidi2"
4613 [(set (match_operand:DI 0 "register_operand" "=r,r")
4614 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4619 [(set_attr "type" "arith_media,load_media")
4620 (set (attr "highpart")
4621 (cond [(match_test "sh_contains_memref_p (insn)")
4622 (const_string "user")]
4623 (const_string "ignore")))])
4625 (define_expand "zero_extendhisi2"
4626 [(set (match_operand:SI 0 "arith_reg_operand" "")
4627 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4631 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4632 operands[1] = copy_to_mode_reg (HImode, operands[1]);
4635 (define_insn "*zero_extendhisi2_compact"
4636 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4637 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4640 [(set_attr "type" "arith")])
4642 (define_insn "*zero_extendhisi2_media"
4643 [(set (match_operand:SI 0 "register_operand" "=r,r")
4644 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4649 [(set_attr "type" "arith_media,load_media")
4650 (set (attr "highpart")
4651 (cond [(match_test "sh_contains_memref_p (insn)")
4652 (const_string "user")]
4653 (const_string "ignore")))])
4656 [(set (match_operand:SI 0 "register_operand" "")
4657 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4658 "TARGET_SHMEDIA && reload_completed"
4659 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4660 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4663 rtx op1 = operands[1];
4665 if (GET_CODE (op1) == TRUNCATE)
4666 op1 = XEXP (op1, 0);
4668 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4669 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4672 (define_expand "zero_extendqisi2"
4673 [(set (match_operand:SI 0 "arith_reg_operand" "")
4674 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4678 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4679 operands[1] = copy_to_mode_reg (QImode, operands[1]);
4682 (define_insn "*zero_extendqisi2_compact"
4683 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4684 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4687 [(set_attr "type" "arith")])
4689 (define_insn "*zero_extendqisi2_media"
4690 [(set (match_operand:SI 0 "register_operand" "=r,r")
4691 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4696 [(set_attr "type" "arith_media,load_media")
4697 (set (attr "highpart")
4698 (cond [(match_test "sh_contains_memref_p (insn)")
4699 (const_string "user")]
4700 (const_string "ignore")))])
4702 (define_insn "zero_extendqihi2"
4703 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4704 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4707 [(set_attr "type" "arith")])
4709 ;; -------------------------------------------------------------------------
4710 ;; Sign extension instructions
4711 ;; -------------------------------------------------------------------------
4713 ;; ??? This should be a define expand.
4714 ;; ??? Or perhaps it should be dropped?
4716 ;; convert_move generates good code for SH[1-4].
4717 (define_insn "extendsidi2"
4718 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4719 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4725 [(set_attr "type" "arith_media,load_media,fpconv_media")
4726 (set (attr "highpart")
4727 (cond [(match_test "sh_contains_memref_p (insn)")
4728 (const_string "user")]
4729 (const_string "extend")))])
4731 (define_insn "extendhidi2"
4732 [(set (match_operand:DI 0 "register_operand" "=r,r")
4733 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4738 [(set_attr "type" "*,load_media")
4739 (set (attr "highpart")
4740 (cond [(match_test "sh_contains_memref_p (insn)")
4741 (const_string "user")]
4742 (const_string "ignore")))])
4745 [(set (match_operand:DI 0 "register_operand" "")
4746 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4747 "TARGET_SHMEDIA && reload_completed"
4748 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4749 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4752 if (GET_CODE (operands[1]) == TRUNCATE)
4753 operands[1] = XEXP (operands[1], 0);
4756 (define_insn "extendqidi2"
4757 [(set (match_operand:DI 0 "register_operand" "=r,r")
4758 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4763 [(set_attr "type" "*,load_media")
4764 (set (attr "highpart")
4765 (cond [(match_test "sh_contains_memref_p (insn)")
4766 (const_string "user")]
4767 (const_string "ignore")))])
4770 [(set (match_operand:DI 0 "register_operand" "")
4771 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4772 "TARGET_SHMEDIA && reload_completed"
4773 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4774 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4777 if (GET_CODE (operands[1]) == TRUNCATE)
4778 operands[1] = XEXP (operands[1], 0);
4781 (define_expand "extendhisi2"
4782 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4783 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4787 (define_insn "*extendhisi2_compact"
4788 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4789 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4794 [(set_attr "type" "arith,load")])
4796 (define_insn "*extendhisi2_media"
4797 [(set (match_operand:SI 0 "register_operand" "=r,r")
4798 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4803 [(set_attr "type" "arith_media,load_media")
4804 (set (attr "highpart")
4805 (cond [(match_test "sh_contains_memref_p (insn)")
4806 (const_string "user")]
4807 (const_string "ignore")))])
4810 [(set (match_operand:SI 0 "register_operand" "")
4811 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4812 "TARGET_SHMEDIA && reload_completed"
4813 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4814 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4817 rtx op1 = operands[1];
4818 if (GET_CODE (op1) == TRUNCATE)
4819 op1 = XEXP (op1, 0);
4821 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4822 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4825 (define_expand "extendqisi2"
4826 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4827 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4831 (define_insn "*extendqisi2_compact"
4832 [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4833 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4838 [(set_attr "type" "arith,load")
4839 (set_attr_alternative "length"
4842 (match_test "TARGET_SH2A")
4843 (const_int 4) (const_int 2))])])
4845 (define_insn "*extendqisi2_media"
4846 [(set (match_operand:SI 0 "register_operand" "=r,r")
4847 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4852 [(set_attr "type" "arith_media,load_media")
4853 (set (attr "highpart")
4854 (cond [(match_test "sh_contains_memref_p (insn)")
4855 (const_string "user")]
4856 (const_string "ignore")))])
4859 [(set (match_operand:SI 0 "register_operand" "")
4860 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4861 "TARGET_SHMEDIA && reload_completed"
4862 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4863 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4866 rtx op1 = operands[1];
4867 if (GET_CODE (op1) == TRUNCATE)
4868 op1 = XEXP (op1, 0);
4870 = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4871 subreg_lowpart_offset (SImode, GET_MODE (op1)));
4874 (define_insn "extendqihi2"
4875 [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4876 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4881 [(set_attr "type" "arith,load")
4882 (set_attr_alternative "length"
4885 (match_test "TARGET_SH2A")
4886 (const_int 4) (const_int 2))])])
4888 /* It would seem useful to combine the truncXi patterns into the movXi
4889 patterns, but unary operators are ignored when matching constraints,
4890 so we need separate patterns. */
4891 (define_insn "truncdisi2"
4892 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4893 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4902 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4903 (set (attr "highpart")
4904 (cond [(match_test "sh_contains_memref_p (insn)")
4905 (const_string "user")]
4906 (const_string "extend")))])
4908 (define_insn "truncdihi2"
4909 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4910 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4913 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4915 [(set_attr "type" "arith_media,store_media")
4916 (set_attr "length" "8,4")
4917 (set (attr "highpart")
4918 (cond [(match_test "sh_contains_memref_p (insn)")
4919 (const_string "user")]
4920 (const_string "extend")))])
4922 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4923 ; Because we use zero extension, we can't provide signed QImode compares
4924 ; using a simple compare or conditional branch insn.
4925 (define_insn "truncdiqi2"
4926 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4927 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4932 [(set_attr "type" "arith_media,store")
4933 (set (attr "highpart")
4934 (cond [(match_test "sh_contains_memref_p (insn)")
4935 (const_string "user")]
4936 (const_string "extend")))])
4937 ;; -------------------------------------------------------------------------
4938 ;; Move instructions
4939 ;; -------------------------------------------------------------------------
4941 ;; define push and pop so it is easy for sh.c
4942 ;; We can't use push and pop on SHcompact because the stack must always
4943 ;; be 8-byte aligned.
4945 (define_expand "push"
4946 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4947 (match_operand:SI 0 "register_operand" "r,l,x"))]
4948 "TARGET_SH1 && ! TARGET_SH5"
4951 (define_expand "pop"
4952 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4953 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4954 "TARGET_SH1 && ! TARGET_SH5"
4957 (define_expand "push_e"
4958 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4959 (match_operand:SF 0 "" ""))
4960 (use (reg:PSI FPSCR_REG))
4961 (clobber (scratch:SI))])]
4962 "TARGET_SH1 && ! TARGET_SH5"
4965 (define_insn "push_fpul"
4966 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4967 "TARGET_SH2E && ! TARGET_SH5"
4969 [(set_attr "type" "fstore")
4970 (set_attr "late_fp_use" "yes")
4971 (set_attr "hit_stack" "yes")])
4973 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4975 (define_expand "push_4"
4976 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4977 (match_operand:DF 0 "" ""))
4978 (use (reg:PSI FPSCR_REG))
4979 (clobber (scratch:SI))])]
4980 "TARGET_SH1 && ! TARGET_SH5"
4983 (define_expand "pop_e"
4984 [(parallel [(set (match_operand:SF 0 "" "")
4985 (mem:SF (post_inc:SI (reg:SI SP_REG))))
4986 (use (reg:PSI FPSCR_REG))
4987 (clobber (scratch:SI))])]
4988 "TARGET_SH1 && ! TARGET_SH5"
4991 (define_insn "pop_fpul"
4992 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4993 "TARGET_SH2E && ! TARGET_SH5"
4995 [(set_attr "type" "load")
4996 (set_attr "hit_stack" "yes")])
4998 (define_expand "pop_4"
4999 [(parallel [(set (match_operand:DF 0 "" "")
5000 (mem:DF (post_inc:SI (reg:SI SP_REG))))
5001 (use (reg:PSI FPSCR_REG))
5002 (clobber (scratch:SI))])]
5003 "TARGET_SH1 && ! TARGET_SH5"
5006 (define_expand "push_fpscr"
5011 rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
5012 gen_rtx_PRE_DEC (Pmode,
5013 stack_pointer_rtx)),
5015 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5019 (define_expand "pop_fpscr"
5024 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
5025 gen_frame_mem (PSImode,
5026 gen_rtx_POST_INC (Pmode,
5027 stack_pointer_rtx))));
5028 add_reg_note (insn, REG_INC, stack_pointer_rtx);
5032 ;; These two patterns can happen as the result of optimization, when
5033 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5034 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5037 [(set (reg:SI T_REG) (const_int 0))]
5042 [(set (reg:SI T_REG) (const_int 1))]
5046 ;; Define additional pop for SH1 and SH2 so it does not get
5047 ;; placed in the delay slot.
5048 (define_insn "*movsi_pop"
5049 [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5050 (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5051 "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5057 [(set_attr "type" "load_si,mem_mac,pload")
5058 (set_attr "length" "2,2,2")
5059 (set_attr "in_delay_slot" "no,no,no")])
5061 ;; t/r must come after r/r, lest reload will try to reload stuff like
5062 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5063 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5064 (define_insn "movsi_i"
5065 [(set (match_operand:SI 0 "general_movdst_operand"
5066 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5067 (match_operand:SI 1 "general_movsrc_operand"
5068 "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5072 && (register_operand (operands[0], SImode)
5073 || register_operand (operands[1], SImode))"
5091 [(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")
5092 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5094 ;; t/r must come after r/r, lest reload will try to reload stuff like
5095 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5096 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5097 ;; will require a reload.
5098 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5099 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5100 (define_insn "movsi_ie"
5101 [(set (match_operand:SI 0 "general_movdst_operand"
5102 "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5103 (match_operand:SI 1 "general_movsrc_operand"
5104 "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5105 "(TARGET_SH2E || TARGET_SH2A)
5106 && (register_operand (operands[0], SImode)
5107 || register_operand (operands[1], SImode))"
5134 ! move optimized away"
5135 [(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")
5136 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5137 (set_attr_alternative "length"
5145 (match_test "TARGET_SH2A")
5146 (const_int 4) (const_int 2))
5151 (match_test "TARGET_SH2A")
5152 (const_int 4) (const_int 2))
5169 (define_insn "movsi_i_lowpart"
5170 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5171 (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5173 && (register_operand (operands[0], SImode)
5174 || register_operand (operands[1], SImode))"
5185 [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5187 (define_insn_and_split "load_ra"
5188 [(set (match_operand:SI 0 "general_movdst_operand" "")
5189 (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5192 "&& ! currently_expanding_to_rtl"
5193 [(set (match_dup 0) (match_dup 1))]
5196 if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5197 operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5200 ;; The '?'s in the following constraints may not reflect the time taken
5201 ;; to perform the move. They are there to discourage the use of floating-
5202 ;; point registers for storing integer values.
5203 (define_insn "*movsi_media"
5204 [(set (match_operand:SI 0 "general_movdst_operand"
5205 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5206 (match_operand:SI 1 "general_movsrc_operand"
5207 "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5209 && (register_operand (operands[0], SImode)
5210 || sh_register_operand (operands[1], SImode)
5211 || GET_CODE (operands[1]) == TRUNCATE)"
5226 [(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")
5227 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5228 (set (attr "highpart")
5229 (cond [(match_test "sh_contains_memref_p (insn)")
5230 (const_string "user")]
5231 (const_string "ignore")))])
5233 (define_insn "*movsi_media_nofpu"
5234 [(set (match_operand:SI 0 "general_movdst_operand"
5235 "=r,r,r,r,m,*b,r,*b")
5236 (match_operand:SI 1 "general_movsrc_operand"
5237 "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5239 && (register_operand (operands[0], SImode)
5240 || sh_register_operand (operands[1], SImode)
5241 || GET_CODE (operands[1]) == TRUNCATE)"
5251 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5252 (set_attr "length" "4,4,8,4,4,4,4,12")
5253 (set (attr "highpart")
5254 (cond [(match_test "sh_contains_memref_p (insn)")
5255 (const_string "user")]
5256 (const_string "ignore")))])
5258 (define_expand "movsi_const"
5259 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5260 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5261 (const_int 16)] UNSPEC_EXTRACT_S16)))
5263 (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5264 (const:SI (unspec:SI [(match_dup 1)
5265 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5266 "TARGET_SHMEDIA && reload_completed
5267 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5270 if (GET_CODE (operands[1]) == LABEL_REF
5271 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5272 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5273 else if (GOTOFF_P (operands[1]))
5275 rtx unspec = XEXP (operands[1], 0);
5277 if (! UNSPEC_GOTOFF_P (unspec))
5279 unspec = XEXP (unspec, 0);
5280 if (! UNSPEC_GOTOFF_P (unspec))
5283 if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5284 && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5285 LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5289 (define_expand "movsi_const_16bit"
5290 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5291 (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5292 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5293 "TARGET_SHMEDIA && flag_pic && reload_completed
5294 && GET_CODE (operands[1]) == SYMBOL_REF"
5298 [(set (match_operand:SI 0 "arith_reg_dest" "")
5299 (match_operand:SI 1 "immediate_operand" ""))]
5300 "TARGET_SHMEDIA && reload_completed
5301 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5305 rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5307 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5313 [(set (match_operand:SI 0 "register_operand" "")
5314 (match_operand:SI 1 "immediate_operand" ""))]
5315 "TARGET_SHMEDIA && reload_completed
5316 && ((CONST_INT_P (operands[1])
5317 && ! satisfies_constraint_I16 (operands[1]))
5318 || GET_CODE (operands[1]) == CONST_DOUBLE)"
5319 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5321 (define_expand "movsi"
5322 [(set (match_operand:SI 0 "general_movdst_operand" "")
5323 (match_operand:SI 1 "general_movsrc_operand" ""))]
5325 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5327 (define_expand "ic_invalidate_line"
5328 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5329 (match_dup 1)] UNSPEC_ICACHE)
5330 (clobber (scratch:SI))])]
5331 "TARGET_HARD_SH4 || TARGET_SH5"
5336 emit_insn (gen_ic_invalidate_line_media (operands[0]));
5339 else if (TARGET_SHCOMPACT)
5341 operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5342 operands[1] = force_reg (Pmode, operands[1]);
5343 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5346 else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5348 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5351 operands[0] = force_reg (Pmode, operands[0]);
5352 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5356 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
5357 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5358 ;; the requirement *1*00 for associative address writes. The alignment of
5359 ;; %0 implies that its least significant bit is cleared,
5360 ;; thus we clear the V bit of a matching entry if there is one.
5361 (define_insn "ic_invalidate_line_i"
5362 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5363 (match_operand:SI 1 "register_operand" "r")]
5365 (clobber (match_scratch:SI 2 "=&r"))]
5367 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5368 [(set_attr "length" "8")
5369 (set_attr "type" "cwb")])
5371 (define_insn "ic_invalidate_line_sh4a"
5372 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5374 "TARGET_SH4A_ARCH || TARGET_SH4_300"
5375 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5376 [(set_attr "length" "16")
5377 (set_attr "type" "cwb")])
5379 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5380 ;; an add in the code that calculates the address.
5381 (define_insn "ic_invalidate_line_media"
5382 [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5385 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
5386 [(set_attr "length" "16")
5387 (set_attr "type" "invalidate_line_media")])
5389 (define_insn "ic_invalidate_line_compact"
5390 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5391 (match_operand:SI 1 "register_operand" "r")]
5393 (clobber (reg:SI PR_REG))]
5396 [(set_attr "type" "sfunc")
5397 (set_attr "needs_delay_slot" "yes")])
5399 (define_expand "initialize_trampoline"
5400 [(match_operand:SI 0 "" "")
5401 (match_operand:SI 1 "" "")
5402 (match_operand:SI 2 "" "")]
5408 tramp = force_reg (Pmode, operands[0]);
5409 sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5411 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5412 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5414 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5418 (define_insn "initialize_trampoline_compact"
5419 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5420 (match_operand:SI 1 "register_operand" "r")
5421 (reg:SI R2_REG) (reg:SI R3_REG)]
5424 (clobber (reg:SI PR_REG))]
5427 [(set_attr "type" "sfunc")
5428 (set_attr "needs_delay_slot" "yes")])
5430 (define_insn "movqi_i"
5431 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5432 (match_operand:QI 1 "general_movsrc_operand" "r,i,m,r,t,l,r"))]
5434 && (arith_reg_operand (operands[0], QImode)
5435 || arith_reg_operand (operands[1], QImode))"
5444 [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5445 (set_attr_alternative "length"
5449 (match_test "TARGET_SH2A")
5450 (const_int 4) (const_int 2))
5452 (match_test "TARGET_SH2A")
5453 (const_int 4) (const_int 2))
5458 (define_insn "*movqi_media"
5459 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5460 (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5462 && (arith_reg_operand (operands[0], QImode)
5463 || extend_reg_or_0_operand (operands[1], QImode))"
5469 [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5470 (set (attr "highpart")
5471 (cond [(match_test "sh_contains_memref_p (insn)")
5472 (const_string "user")]
5473 (const_string "ignore")))])
5475 (define_expand "movqi"
5476 [(set (match_operand:QI 0 "general_operand" "")
5477 (match_operand:QI 1 "general_operand" ""))]
5479 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5481 (define_expand "reload_inqi"
5482 [(set (match_operand:SI 2 "" "=&r")
5483 (match_operand:QI 1 "inqhi_operand" ""))
5484 (set (match_operand:QI 0 "arith_reg_operand" "=r")
5485 (truncate:QI (match_dup 3)))]
5489 rtx inner = XEXP (operands[1], 0);
5490 int regno = REGNO (inner);
5492 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5493 operands[1] = gen_rtx_REG (SImode, regno);
5494 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5497 /* When storing r0, we have to avoid reg+reg addressing. */
5498 (define_insn "movhi_i"
5499 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
5500 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5502 && (arith_reg_operand (operands[0], HImode)
5503 || arith_reg_operand (operands[1], HImode))
5504 && (!MEM_P (operands[0])
5505 || GET_CODE (XEXP (operands[0], 0)) != PLUS
5506 || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5507 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5517 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5519 (define_insn "*movhi_media"
5520 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
5521 (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5523 && (arith_reg_operand (operands[0], HImode)
5524 || arith_reg_or_0_operand (operands[1], HImode))"
5531 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5532 (set (attr "highpart")
5533 (cond [(match_test "sh_contains_memref_p (insn)")
5534 (const_string "user")]
5535 (const_string "ignore")))])
5538 [(set (match_operand:HI 0 "register_operand" "")
5539 (match_operand:HI 1 "immediate_operand" ""))]
5540 "TARGET_SHMEDIA && reload_completed
5541 && ! satisfies_constraint_I16 (operands[1])"
5542 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5544 (define_expand "movhi"
5545 [(set (match_operand:HI 0 "general_movdst_operand" "")
5546 (match_operand:HI 1 "general_movsrc_operand" ""))]
5548 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5550 (define_expand "reload_inhi"
5551 [(set (match_operand:SI 2 "" "=&r")
5552 (match_operand:HI 1 "inqhi_operand" ""))
5553 (set (match_operand:HI 0 "arith_reg_operand" "=r")
5554 (truncate:HI (match_dup 3)))]
5558 rtx inner = XEXP (operands[1], 0);
5559 int regno = REGNO (inner);
5561 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5562 operands[1] = gen_rtx_REG (SImode, regno);
5563 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5566 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5567 ;; compiled with -m2 -ml -O3 -funroll-loops
5568 (define_insn "*movdi_i"
5569 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5570 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5572 && (arith_reg_operand (operands[0], DImode)
5573 || arith_reg_operand (operands[1], DImode))"
5574 "* return output_movedouble (insn, operands, DImode);"
5575 [(set_attr "length" "4")
5576 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5578 ;; If the output is a register and the input is memory or a register, we have
5579 ;; to be careful and see which word needs to be loaded first.
5582 [(set (match_operand:DI 0 "general_movdst_operand" "")
5583 (match_operand:DI 1 "general_movsrc_operand" ""))]
5584 "TARGET_SH1 && reload_completed"
5585 [(set (match_dup 2) (match_dup 3))
5586 (set (match_dup 4) (match_dup 5))]
5591 if ((MEM_P (operands[0])
5592 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5593 || (MEM_P (operands[1])
5594 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5597 switch (GET_CODE (operands[0]))
5600 regno = REGNO (operands[0]);
5603 regno = subreg_regno (operands[0]);
5613 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5615 operands[2] = operand_subword (operands[0], 0, 0, DImode);
5616 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5617 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5618 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5622 operands[2] = operand_subword (operands[0], 1, 0, DImode);
5623 operands[3] = operand_subword (operands[1], 1, 0, DImode);
5624 operands[4] = operand_subword (operands[0], 0, 0, DImode);
5625 operands[5] = operand_subword (operands[1], 0, 0, DImode);
5628 if (operands[2] == 0 || operands[3] == 0
5629 || operands[4] == 0 || operands[5] == 0)
5633 ;; The '?'s in the following constraints may not reflect the time taken
5634 ;; to perform the move. They are there to discourage the use of floating-
5635 ;; point registers for storing integer values.
5636 (define_insn "*movdi_media"
5637 [(set (match_operand:DI 0 "general_movdst_operand"
5638 "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5639 (match_operand:DI 1 "general_movsrc_operand"
5640 "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5642 && (register_operand (operands[0], DImode)
5643 || sh_register_operand (operands[1], DImode))"
5658 [(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")
5659 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5661 (define_insn "*movdi_media_nofpu"
5662 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5663 (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5665 && (register_operand (operands[0], DImode)
5666 || sh_register_operand (operands[1], DImode))"
5676 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5677 (set_attr "length" "4,4,16,4,4,4,4,*")])
5679 (define_insn "*movdi_media_I16"
5680 [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5681 (match_operand:DI 1 "const_int_operand" "I16"))]
5682 "TARGET_SHMEDIA && reload_completed"
5684 [(set_attr "type" "arith_media")
5685 (set_attr "length" "4")])
5688 [(set (match_operand:DI 0 "arith_reg_dest" "")
5689 (match_operand:DI 1 "immediate_operand" ""))]
5690 "TARGET_SHMEDIA && reload_completed
5691 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5692 [(set (match_dup 0) (match_dup 1))]
5697 if (TARGET_SHMEDIA64)
5698 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5700 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5702 set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5707 (define_expand "movdi_const"
5708 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5709 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5710 (const_int 48)] UNSPEC_EXTRACT_S16)))
5712 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5713 (const:DI (unspec:DI [(match_dup 1)
5714 (const_int 32)] UNSPEC_EXTRACT_U16))))
5716 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5717 (const:DI (unspec:DI [(match_dup 1)
5718 (const_int 16)] UNSPEC_EXTRACT_U16))))
5720 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5721 (const:DI (unspec:DI [(match_dup 1)
5722 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5723 "TARGET_SHMEDIA64 && reload_completed
5724 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5727 sh_mark_label (operands[1], 4);
5730 (define_expand "movdi_const_32bit"
5731 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5732 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5733 (const_int 16)] UNSPEC_EXTRACT_S16)))
5735 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5736 (const:DI (unspec:DI [(match_dup 1)
5737 (const_int 0)] UNSPEC_EXTRACT_U16))))]
5738 "TARGET_SHMEDIA32 && reload_completed
5739 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5742 sh_mark_label (operands[1], 2);
5745 (define_expand "movdi_const_16bit"
5746 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5747 (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5748 (const_int 0)] UNSPEC_EXTRACT_S16)))]
5749 "TARGET_SHMEDIA && flag_pic && reload_completed
5750 && GET_CODE (operands[1]) == SYMBOL_REF"
5754 [(set (match_operand:DI 0 "ext_dest_operand" "")
5755 (match_operand:DI 1 "immediate_operand" ""))]
5756 "TARGET_SHMEDIA && reload_completed
5757 && CONST_INT_P (operands[1])
5758 && ! satisfies_constraint_I16 (operands[1])"
5759 [(set (match_dup 0) (match_dup 2))
5763 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5764 unsigned HOST_WIDE_INT low = val;
5765 unsigned HOST_WIDE_INT high = val;
5766 unsigned HOST_WIDE_INT sign;
5767 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5769 /* Zero-extend the 16 least-significant bits. */
5772 /* Arithmetic shift right the word by 16 bits. */
5774 if (GET_CODE (operands[0]) == SUBREG
5775 && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5784 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5790 /* If we can't generate the constant with a two-insn movi / shori
5791 sequence, try some other strategies. */
5792 if (! CONST_OK_FOR_I16 (high))
5794 /* Try constant load / left shift. We know VAL != 0. */
5795 val2 = val ^ (val-1);
5798 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5800 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5801 || (! CONST_OK_FOR_I16 (high >> 16)
5802 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5804 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5805 operands[1] = gen_ashldi3_media (operands[0], operands[0],
5806 GEN_INT (trailing_zeroes));
5810 /* Try constant load / right shift. */
5811 val2 = (val >> 15) + 1;
5812 if (val2 == (val2 & -val2))
5814 int shift = 49 - exact_log2 (val2);
5816 val2 = trunc_int_for_mode (val << shift, DImode);
5817 if (CONST_OK_FOR_I16 (val2))
5819 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5825 val2 = val & 0xffff;
5826 if ((val >> 16 & 0xffff) == val2
5827 && (val >> 32 & 0xffff) == val2
5828 && (val >> 48 & 0xffff) == val2)
5830 val2 = (HOST_WIDE_INT) val >> 48;
5831 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5832 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5835 /* Try movi / mshflo.l */
5836 val2 = (HOST_WIDE_INT) val >> 32;
5837 if (val2 == ((unsigned HOST_WIDE_INT)
5838 trunc_int_for_mode (val, SImode)))
5840 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5844 /* Try movi / mshflo.l w/ r63. */
5845 val2 = val + ((HOST_WIDE_INT) -1 << 32);
5846 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5848 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5854 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5857 operands[2] = GEN_INT (val2);
5861 [(set (match_operand:DI 0 "ext_dest_operand" "")
5862 (match_operand:DI 1 "immediate_operand" ""))]
5863 "TARGET_SHMEDIA && reload_completed
5864 && GET_CODE (operands[1]) == CONST_DOUBLE"
5865 [(set (match_dup 0) (match_dup 2))
5867 (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5870 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5871 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5872 unsigned HOST_WIDE_INT val = low;
5873 unsigned HOST_WIDE_INT sign;
5875 /* Zero-extend the 16 least-significant bits. */
5877 operands[1] = GEN_INT (val);
5879 /* Arithmetic shift right the double-word by 16 bits. */
5881 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5884 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5888 /* This will only be true if high is a sign-extension of low, i.e.,
5889 it must be either 0 or (unsigned)-1, and be zero iff the
5890 most-significant bit of low is set. */
5891 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5892 operands[2] = GEN_INT (low);
5894 operands[2] = immed_double_const (low, high, DImode);
5897 (define_insn "shori_media"
5898 [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5899 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5901 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5902 "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5906 [(set_attr "type" "arith_media,*")])
5908 (define_insn "*shori_media_si"
5909 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5910 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5912 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5916 (define_expand "movdi"
5917 [(set (match_operand:DI 0 "general_movdst_operand" "")
5918 (match_operand:DI 1 "general_movsrc_operand" ""))]
5920 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5922 (define_insn "movdf_media"
5923 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5924 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5926 && (register_operand (operands[0], DFmode)
5927 || sh_register_operand (operands[1], DFmode))"
5938 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5940 (define_insn "movdf_media_nofpu"
5941 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5942 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5944 && (register_operand (operands[0], DFmode)
5945 || sh_register_operand (operands[1], DFmode))"
5951 [(set_attr "type" "arith_media,*,load_media,store_media")])
5954 [(set (match_operand:DF 0 "arith_reg_dest" "")
5955 (match_operand:DF 1 "immediate_operand" ""))]
5956 "TARGET_SHMEDIA && reload_completed"
5957 [(set (match_dup 3) (match_dup 2))]
5960 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5962 REAL_VALUE_TYPE value;
5964 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5965 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5967 if (HOST_BITS_PER_WIDE_INT >= 64)
5968 operands[2] = immed_double_const ((unsigned long) values[endian]
5969 | ((HOST_WIDE_INT) values[1 - endian]
5973 gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5974 operands[2] = immed_double_const (values[endian], values[1 - endian],
5978 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5981 ;; ??? This should be a define expand.
5983 (define_insn "movdf_k"
5984 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5985 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5987 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5988 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5989 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5990 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5991 && (arith_reg_operand (operands[0], DFmode)
5992 || arith_reg_operand (operands[1], DFmode))"
5993 "* return output_movedouble (insn, operands, DFmode);"
5994 [(set_attr "length" "4")
5995 (set_attr "type" "move,pcload,load,store")])
5997 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5998 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5999 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
6000 ;; the d/m/c/X alternative, which is split later into single-precision
6001 ;; instructions. And when not optimizing, no splits are done before fixing
6002 ;; up pcloads, so we need usable length information for that.
6003 (define_insn "movdf_i4"
6004 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
6005 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
6006 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
6007 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
6008 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6009 && (arith_reg_operand (operands[0], DFmode)
6010 || arith_reg_operand (operands[1], DFmode))"
6012 switch (which_alternative)
6016 return "fmov %1,%0";
6017 else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
6018 return "fmov %R1,%R0\n\tfmov %S1,%S0";
6020 return "fmov %S1,%S0\n\tfmov %R1,%R0";
6023 return "fmov.d %1,%0";
6028 [(set_attr_alternative "length"
6029 [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6031 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6032 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6033 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6035 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6036 ;; We can't use 4-byte push/pop on SHcompact, so we have to
6037 ;; increment or decrement r15 explicitly.
6039 (match_test "TARGET_SHCOMPACT")
6040 (const_int 10) (const_int 8))
6042 (match_test "TARGET_SHCOMPACT")
6043 (const_int 10) (const_int 8))])
6044 (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6045 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6046 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6047 (const_string "double")
6048 (const_string "none")))])
6050 ;; Moving DFmode between fp/general registers through memory
6051 ;; (the top of the stack) is faster than moving through fpul even for
6052 ;; little endian. Because the type of an instruction is important for its
6053 ;; scheduling, it is beneficial to split these operations, rather than
6054 ;; emitting them in one single chunk, even if this will expose a stack
6055 ;; use that will prevent scheduling of other stack accesses beyond this
6058 [(set (match_operand:DF 0 "register_operand" "")
6059 (match_operand:DF 1 "register_operand" ""))
6060 (use (match_operand:PSI 2 "fpscr_operand" ""))
6061 (clobber (match_scratch:SI 3 "=X"))]
6062 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6063 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6069 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6071 emit_move_insn (stack_pointer_rtx,
6072 plus_constant (stack_pointer_rtx, -8));
6073 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6076 tos = gen_tmp_stack_mem (DFmode,
6077 gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6078 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6079 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6080 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6081 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6082 tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6084 tos = gen_tmp_stack_mem (DFmode,
6085 gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6086 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6087 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6088 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6090 add_reg_note (insn, REG_INC, stack_pointer_rtx);
6094 ;; local-alloc sometimes allocates scratch registers even when not required,
6095 ;; so we must be prepared to handle these.
6097 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6099 [(set (match_operand:DF 0 "general_movdst_operand" "")
6100 (match_operand:DF 1 "general_movsrc_operand" ""))
6101 (use (match_operand:PSI 2 "fpscr_operand" ""))
6102 (clobber (match_scratch:SI 3 ""))]
6103 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6105 && true_regnum (operands[0]) < 16
6106 && true_regnum (operands[1]) < 16"
6107 [(set (match_dup 0) (match_dup 1))]
6110 /* If this was a reg <-> mem operation with base + index reg addressing,
6111 we have to handle this in a special way. */
6112 rtx mem = operands[0];
6114 if (! memory_operand (mem, DFmode))
6119 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6120 mem = SUBREG_REG (mem);
6123 rtx addr = XEXP (mem, 0);
6124 if (GET_CODE (addr) == PLUS
6125 && REG_P (XEXP (addr, 0))
6126 && REG_P (XEXP (addr, 1)))
6129 rtx reg0 = gen_rtx_REG (Pmode, 0);
6130 rtx regop = operands[store_p], word0 ,word1;
6132 if (GET_CODE (regop) == SUBREG)
6133 alter_subreg (®op);
6134 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6138 mem = copy_rtx (mem);
6139 PUT_MODE (mem, SImode);
6140 word0 = gen_rtx_SUBREG (SImode, regop, 0);
6141 alter_subreg (&word0);
6142 word1 = gen_rtx_SUBREG (SImode, regop, 4);
6143 alter_subreg (&word1);
6144 if (store_p || ! refers_to_regno_p (REGNO (word0),
6145 REGNO (word0) + 1, addr, 0))
6148 ? gen_movsi_ie (mem, word0)
6149 : gen_movsi_ie (word0, mem));
6150 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6151 mem = copy_rtx (mem);
6153 ? gen_movsi_ie (mem, word1)
6154 : gen_movsi_ie (word1, mem));
6155 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6159 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6160 emit_insn (gen_movsi_ie (word1, mem));
6161 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6162 mem = copy_rtx (mem);
6163 emit_insn (gen_movsi_ie (word0, mem));
6170 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6172 [(set (match_operand:DF 0 "register_operand" "")
6173 (match_operand:DF 1 "memory_operand" ""))
6174 (use (match_operand:PSI 2 "fpscr_operand" ""))
6175 (clobber (reg:SI R0_REG))]
6176 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6177 [(parallel [(set (match_dup 0) (match_dup 1))
6179 (clobber (scratch:SI))])]
6182 (define_expand "reload_indf__frn"
6183 [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6184 (match_operand:DF 1 "immediate_operand" "FQ"))
6185 (use (reg:PSI FPSCR_REG))
6186 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6190 (define_expand "reload_outdf__RnFRm"
6191 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6192 (match_operand:DF 1 "register_operand" "af,r"))
6193 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6197 ;; Simplify no-op moves.
6199 [(set (match_operand:SF 0 "register_operand" "")
6200 (match_operand:SF 1 "register_operand" ""))
6201 (use (match_operand:PSI 2 "fpscr_operand" ""))
6202 (clobber (match_scratch:SI 3 ""))]
6203 "TARGET_SH2E && reload_completed
6204 && true_regnum (operands[0]) == true_regnum (operands[1])"
6205 [(set (match_dup 0) (match_dup 0))]
6208 ;; fmovd substitute post-reload splits
6210 [(set (match_operand:DF 0 "register_operand" "")
6211 (match_operand:DF 1 "register_operand" ""))
6212 (use (match_operand:PSI 2 "fpscr_operand" ""))
6213 (clobber (match_scratch:SI 3 ""))]
6214 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6215 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6216 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6220 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6221 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6222 gen_rtx_REG (SFmode, src), operands[2]));
6223 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6224 gen_rtx_REG (SFmode, src + 1), operands[2]));
6229 [(set (match_operand:DF 0 "register_operand" "")
6230 (mem:DF (match_operand:SI 1 "register_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]))
6235 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6239 int regno = true_regnum (operands[0]);
6241 rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6243 = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6244 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6245 regno + !! TARGET_LITTLE_ENDIAN),
6246 mem2, operands[2]));
6247 add_reg_note (insn, REG_INC, operands[1]);
6248 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6249 regno + ! TARGET_LITTLE_ENDIAN),
6250 change_address (mem, SFmode, NULL_RTX),
6256 [(set (match_operand:DF 0 "register_operand" "")
6257 (match_operand:DF 1 "memory_operand" ""))
6258 (use (match_operand:PSI 2 "fpscr_operand" ""))
6259 (clobber (match_scratch:SI 3 ""))]
6260 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6261 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6264 int regno = true_regnum (operands[0]);
6266 rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6267 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6268 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6270 operands[1] = copy_rtx (mem2);
6271 addr = XEXP (mem2, 0);
6273 switch (GET_CODE (addr))
6276 /* This is complicated. If the register is an arithmetic register
6277 we can just fall through to the REG+DISP case below. Otherwise
6278 we have to use a combination of POST_INC and REG addressing... */
6279 if (! arith_reg_operand (operands[1], SFmode))
6281 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6282 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6283 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6285 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6287 /* If we have modified the stack pointer, the value that we have
6288 read with post-increment might be modified by an interrupt,
6289 so write it back. */
6290 if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6291 emit_insn (gen_push_e (reg0));
6293 emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6299 emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6300 operands[1] = copy_rtx (operands[1]);
6301 XEXP (operands[1], 0) = plus_constant (addr, 4);
6302 emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6306 insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6307 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6309 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6310 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6322 [(set (match_operand:DF 0 "memory_operand" "")
6323 (match_operand:DF 1 "register_operand" ""))
6324 (use (match_operand:PSI 2 "fpscr_operand" ""))
6325 (clobber (match_scratch:SI 3 ""))]
6326 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6327 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6330 int regno = true_regnum (operands[1]);
6332 rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6333 rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6335 operands[0] = copy_rtx (operands[0]);
6336 PUT_MODE (operands[0], SFmode);
6337 addr = XEXP (operands[0], 0);
6339 switch (GET_CODE (addr))
6342 /* This is complicated. If the register is an arithmetic register
6343 we can just fall through to the REG+DISP case below. Otherwise
6344 we have to use a combination of REG and PRE_DEC addressing... */
6345 if (! arith_reg_operand (operands[0], SFmode))
6347 emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6348 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6350 operands[0] = copy_rtx (operands[0]);
6351 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6353 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6354 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6360 /* Since REG+DISP addressing has already been decided upon by gcc
6361 we can rely upon it having chosen an arithmetic register as the
6362 register component of the address. Just emit the lower numbered
6363 register first, to the lower address, then the higher numbered
6364 register to the higher address. */
6365 emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6367 operands[0] = copy_rtx (operands[0]);
6368 XEXP (operands[0], 0) = plus_constant (addr, 4);
6370 emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6374 /* This is easy. Output the word to go to the higher address
6375 first (ie the word in the higher numbered register) then the
6376 word to go to the lower address. */
6378 insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6379 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6381 insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6382 add_reg_note (insn, REG_INC, XEXP (addr, 0));
6394 ;; If the output is a register and the input is memory or a register, we have
6395 ;; to be careful and see which word needs to be loaded first.
6398 [(set (match_operand:DF 0 "general_movdst_operand" "")
6399 (match_operand:DF 1 "general_movsrc_operand" ""))]
6400 "TARGET_SH1 && reload_completed"
6401 [(set (match_dup 2) (match_dup 3))
6402 (set (match_dup 4) (match_dup 5))]
6407 if ((MEM_P (operands[0])
6408 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6409 || (MEM_P (operands[1])
6410 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6413 switch (GET_CODE (operands[0]))
6416 regno = REGNO (operands[0]);
6419 regno = subreg_regno (operands[0]);
6429 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6431 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6432 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6433 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6434 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6438 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6439 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6440 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6441 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6444 if (operands[2] == 0 || operands[3] == 0
6445 || operands[4] == 0 || operands[5] == 0)
6449 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6450 ;; used only once, let combine add in the index again.
6453 [(set (match_operand:SI 0 "register_operand" "")
6454 (match_operand:SI 1 "" ""))
6455 (clobber (match_operand 2 "register_operand" ""))]
6456 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6457 && ALLOW_INDEXED_ADDRESS"
6458 [(use (reg:SI R0_REG))]
6461 rtx addr, reg, const_int;
6463 if (!MEM_P (operands[1]))
6465 addr = XEXP (operands[1], 0);
6466 if (GET_CODE (addr) != PLUS)
6468 reg = XEXP (addr, 0);
6469 const_int = XEXP (addr, 1);
6470 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6471 && CONST_INT_P (const_int)))
6473 emit_move_insn (operands[2], const_int);
6474 emit_move_insn (operands[0],
6475 change_address (operands[1], VOIDmode,
6476 gen_rtx_PLUS (SImode, reg, operands[2])));
6481 [(set (match_operand:SI 1 "" "")
6482 (match_operand:SI 0 "register_operand" ""))
6483 (clobber (match_operand 2 "register_operand" ""))]
6484 "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6485 && ALLOW_INDEXED_ADDRESS"
6486 [(use (reg:SI R0_REG))]
6489 rtx addr, reg, const_int;
6491 if (!MEM_P (operands[1]))
6493 addr = XEXP (operands[1], 0);
6494 if (GET_CODE (addr) != PLUS)
6496 reg = XEXP (addr, 0);
6497 const_int = XEXP (addr, 1);
6498 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6499 && CONST_INT_P (const_int)))
6501 emit_move_insn (operands[2], const_int);
6502 emit_move_insn (change_address (operands[1], VOIDmode,
6503 gen_rtx_PLUS (SImode, reg, operands[2])),
6508 (define_expand "movdf"
6509 [(set (match_operand:DF 0 "general_movdst_operand" "")
6510 (match_operand:DF 1 "general_movsrc_operand" ""))]
6514 if (prepare_move_operands (operands, DFmode)) DONE;
6517 if (TARGET_SHMEDIA_FPU)
6518 emit_insn (gen_movdf_media (operands[0], operands[1]));
6520 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6523 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6525 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6530 ;;This is incompatible with the way gcc uses subregs.
6531 ;;(define_insn "movv2sf_i"
6532 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6533 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6534 ;; "TARGET_SHMEDIA_FPU
6535 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
6536 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
6540 ;; fst%M0.p %m0, %1"
6541 ;; [(set_attr "type" "*,fload_media,fstore_media")])
6543 (define_insn_and_split "movv2sf_i"
6544 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6545 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6546 "TARGET_SHMEDIA_FPU"
6548 "TARGET_SHMEDIA_FPU && reload_completed"
6549 [(set (match_dup 0) (match_dup 1))]
6552 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6553 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6556 (define_expand "movv2sf"
6557 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6558 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6559 "TARGET_SHMEDIA_FPU"
6562 if (prepare_move_operands (operands, V2SFmode))
6566 (define_expand "addv2sf3"
6567 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6568 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6569 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6570 "TARGET_SHMEDIA_FPU"
6573 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6577 (define_expand "subv2sf3"
6578 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6579 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6580 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6581 "TARGET_SHMEDIA_FPU"
6584 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6588 (define_expand "mulv2sf3"
6589 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6590 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6591 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6592 "TARGET_SHMEDIA_FPU"
6595 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6599 (define_expand "divv2sf3"
6600 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6601 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6602 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6603 "TARGET_SHMEDIA_FPU"
6606 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6610 (define_insn_and_split "*movv4sf_i"
6611 [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6612 (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6613 "TARGET_SHMEDIA_FPU"
6615 "&& reload_completed"
6621 for (i = 0; i < 4/2; i++)
6625 if (MEM_P (operands[0]))
6626 x = adjust_address (operands[0], V2SFmode,
6627 i * GET_MODE_SIZE (V2SFmode));
6629 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6631 if (MEM_P (operands[1]))
6632 y = adjust_address (operands[1], V2SFmode,
6633 i * GET_MODE_SIZE (V2SFmode));
6635 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6637 emit_insn (gen_movv2sf_i (x, y));
6642 [(set_attr "length" "8")])
6644 (define_expand "movv4sf"
6645 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6646 (match_operand:V4SF 1 "general_operand" ""))]
6647 "TARGET_SHMEDIA_FPU"
6650 if (prepare_move_operands (operands, V4SFmode))
6654 (define_insn_and_split "*movv16sf_i"
6655 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6656 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6657 "TARGET_SHMEDIA_FPU"
6659 "&& reload_completed"
6665 for (i = 0; i < 16/2; i++)
6669 if (MEM_P (operands[0]))
6670 x = adjust_address (operands[0], V2SFmode,
6671 i * GET_MODE_SIZE (V2SFmode));
6674 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6678 if (MEM_P (operands[1]))
6679 y = adjust_address (operands[1], V2SFmode,
6680 i * GET_MODE_SIZE (V2SFmode));
6683 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6687 emit_insn (gen_movv2sf_i (x, y));
6692 [(set_attr "length" "32")])
6694 (define_expand "movv16sf"
6695 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6696 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6697 "TARGET_SHMEDIA_FPU"
6700 if (prepare_move_operands (operands, V16SFmode))
6704 (define_insn "movsf_media"
6705 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6706 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6708 && (register_operand (operands[0], SFmode)
6709 || sh_register_operand (operands[1], SFmode))"
6720 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6721 (set (attr "highpart")
6722 (cond [(match_test "sh_contains_memref_p (insn)")
6723 (const_string "user")]
6724 (const_string "ignore")))])
6726 (define_insn "movsf_media_nofpu"
6727 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6728 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6730 && (register_operand (operands[0], SFmode)
6731 || sh_register_operand (operands[1], SFmode))"
6737 [(set_attr "type" "arith_media,*,load_media,store_media")
6738 (set (attr "highpart")
6739 (cond [(match_test "sh_contains_memref_p (insn)")
6740 (const_string "user")]
6741 (const_string "ignore")))])
6744 [(set (match_operand:SF 0 "arith_reg_dest" "")
6745 (match_operand:SF 1 "immediate_operand" ""))]
6746 "TARGET_SHMEDIA && reload_completed
6747 && ! FP_REGISTER_P (true_regnum (operands[0]))"
6748 [(set (match_dup 3) (match_dup 2))]
6752 REAL_VALUE_TYPE value;
6754 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6755 REAL_VALUE_TO_TARGET_SINGLE (value, values);
6756 operands[2] = GEN_INT (values);
6758 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6761 (define_insn "movsf_i"
6762 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6763 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
6766 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6767 || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6768 || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6769 && (arith_reg_operand (operands[0], SFmode)
6770 || arith_reg_operand (operands[1], SFmode))"
6779 [(set_attr "type" "move,move,pcload,load,store,move,move")])
6781 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6782 ;; update_flow_info would not know where to put REG_EQUAL notes
6783 ;; when the destination changes mode.
6784 (define_insn "movsf_ie"
6785 [(set (match_operand:SF 0 "general_movdst_operand"
6786 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6787 (match_operand:SF 1 "general_movsrc_operand"
6788 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6789 (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"))
6790 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6793 && (arith_reg_operand (operands[0], SFmode)
6794 || arith_reg_operand (operands[1], SFmode)
6795 || arith_reg_operand (operands[3], SImode)
6796 || (fpul_operand (operands[0], SFmode)
6797 && memory_operand (operands[1], SFmode)
6798 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6799 || (fpul_operand (operands[1], SFmode)
6800 && memory_operand (operands[0], SFmode)
6801 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6821 ! move optimized away"
6822 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6823 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6824 (set_attr_alternative "length"
6831 (match_test "TARGET_SH2A")
6832 (const_int 4) (const_int 2))
6834 (match_test "TARGET_SH2A")
6835 (const_int 4) (const_int 2))
6838 (match_test "TARGET_SH2A")
6839 (const_int 4) (const_int 2))
6841 (match_test "TARGET_SH2A")
6842 (const_int 4) (const_int 2))
6852 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6853 (const_string "single")
6854 (const_string "single")))])
6857 [(set (match_operand:SF 0 "register_operand" "")
6858 (match_operand:SF 1 "register_operand" ""))
6859 (use (match_operand:PSI 2 "fpscr_operand" ""))
6860 (clobber (reg:SI FPUL_REG))]
6862 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6864 (clobber (scratch:SI))])
6865 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6867 (clobber (scratch:SI))])]
6870 (define_expand "movsf"
6871 [(set (match_operand:SF 0 "general_movdst_operand" "")
6872 (match_operand:SF 1 "general_movsrc_operand" ""))]
6876 if (prepare_move_operands (operands, SFmode))
6880 if (TARGET_SHMEDIA_FPU)
6881 emit_insn (gen_movsf_media (operands[0], operands[1]));
6883 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6888 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6893 (define_insn "mov_nop"
6894 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6897 [(set_attr "length" "0")
6898 (set_attr "type" "nil")])
6900 (define_expand "reload_insf__frn"
6901 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6902 (match_operand:SF 1 "immediate_operand" "FQ"))
6903 (use (reg:PSI FPSCR_REG))
6904 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6908 (define_expand "reload_insi__i_fpul"
6909 [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6910 (match_operand:SI 1 "immediate_operand" "i"))
6911 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6915 (define_expand "ptabs"
6916 [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6920 if (!TARGET_PT_FIXED)
6922 rtx eq = operands[1];
6924 /* ??? For canonical RTL we really should remove any CONST from EQ
6925 before wrapping it in the AND, and finally wrap the EQ into a
6926 const if is constant. However, for reload we must expose the
6927 input register or symbolic constant, and we can't have
6928 different insn structures outside of the operands for different
6929 alternatives of the same pattern. */
6930 eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6933 = (gen_rtx_IF_THEN_ELSE
6936 gen_rtx_MEM (PDImode, operands[1]),
6937 gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6938 PDImode, operands[1])));
6942 ;; expanded by ptabs expander.
6943 (define_insn "*extendsipdi_media"
6944 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6945 (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6949 (mem:PDI (match_dup 1))
6950 (sign_extend:PDI (match_dup 1))))]
6951 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6955 [(set_attr "type" "ptabs_media,pt_media")
6956 (set_attr "length" "4,*")])
6958 (define_insn "*truncdipdi_media"
6959 [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6960 (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6964 (mem:PDI (match_dup 1))
6965 (truncate:PDI (match_dup 1))))]
6966 "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6970 [(set_attr "type" "ptabs_media,pt_media")
6971 (set_attr "length" "4,*")])
6973 (define_insn "*movsi_y"
6974 [(set (match_operand:SI 0 "register_operand" "=y,y")
6975 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6976 (clobber (match_scratch:SI 2 "=&z,r"))]
6978 && (reload_in_progress || reload_completed)"
6980 [(set_attr "length" "4")
6981 (set_attr "type" "pcload,move")])
6984 [(set (match_operand:SI 0 "register_operand" "")
6985 (match_operand:SI 1 "immediate_operand" ""))
6986 (clobber (match_operand:SI 2 "register_operand" ""))]
6988 [(set (match_dup 2) (match_dup 1))
6989 (set (match_dup 0) (match_dup 2))]
6993 [(set (match_operand:SI 0 "register_operand" "")
6994 (match_operand:SI 1 "memory_operand" ""))
6995 (clobber (reg:SI R0_REG))]
6997 [(set (match_dup 0) (match_dup 1))]
7000 ;; ------------------------------------------------------------------------
7001 ;; Define the real conditional branch instructions.
7002 ;; ------------------------------------------------------------------------
7004 (define_insn "branch_true"
7005 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
7006 (label_ref (match_operand 0 "" ""))
7009 "* return output_branch (1, insn, operands);"
7010 [(set_attr "type" "cbranch")])
7012 (define_insn "branch_false"
7013 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7014 (label_ref (match_operand 0 "" ""))
7017 "* return output_branch (0, insn, operands);"
7018 [(set_attr "type" "cbranch")])
7020 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
7021 ;; which destination is too far away.
7022 ;; The const_int_operand is distinct for each branch target; it avoids
7023 ;; unwanted matches with redundant_insn.
7024 (define_insn "block_branch_redirect"
7025 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7028 [(set_attr "length" "0")])
7030 ;; This one has the additional purpose to record a possible scratch register
7031 ;; for the following branch.
7032 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7033 ;; because the insn then might be deemed dead and deleted. And we can't
7034 ;; make the use in the jump insn explicit because that would disable
7035 ;; delay slot scheduling from the target.
7036 (define_insn "indirect_jump_scratch"
7037 [(set (match_operand:SI 0 "register_operand" "=r")
7038 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7039 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7042 [(set_attr "length" "0")])
7044 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7045 ;; being pulled into the delay slot of a condbranch that has been made to
7046 ;; jump around the unconditional jump because it was out of range.
7047 (define_insn "stuff_delay_slot"
7049 (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7050 (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7053 [(set_attr "length" "0")
7054 (set_attr "cond_delay_slot" "yes")])
7056 ;; Conditional branch insns
7058 (define_expand "cbranchint4_media"
7060 (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7061 [(match_operand 1 "" "")
7062 (match_operand 2 "" "")])
7063 (match_operand 3 "" "")
7068 enum machine_mode mode = GET_MODE (operands[1]);
7069 if (mode == VOIDmode)
7070 mode = GET_MODE (operands[2]);
7071 if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7073 operands[1] = force_reg (mode, operands[1]);
7074 if (CONSTANT_P (operands[2])
7075 && (! satisfies_constraint_I06 (operands[2])))
7076 operands[2] = force_reg (mode, operands[2]);
7080 if (operands[1] != const0_rtx)
7081 operands[1] = force_reg (mode, operands[1]);
7082 if (operands[2] != const0_rtx)
7083 operands[2] = force_reg (mode, operands[2]);
7085 switch (GET_CODE (operands[0]))
7091 operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7092 VOIDmode, operands[2], operands[1]);
7093 operands[1] = XEXP (operands[0], 0);
7094 operands[2] = XEXP (operands[0], 1);
7097 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7098 VOIDmode, operands[1], operands[2]);
7101 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7104 (define_expand "cbranchfp4_media"
7106 (if_then_else (match_operator 0 "sh_float_comparison_operator"
7107 [(match_operand 1 "" "")
7108 (match_operand 2 "" "")])
7109 (match_operand 3 "" "")
7114 rtx tmp = gen_reg_rtx (SImode);
7116 if (GET_CODE (operands[0]) == NE)
7117 cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7119 cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7120 operands[1], operands[2]);
7122 emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7124 if (GET_CODE (cmp) == GET_CODE (operands[0]))
7125 operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7127 operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7129 operands[2] = const0_rtx;
7130 operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7133 (define_insn "*beq_media_i"
7135 (if_then_else (match_operator 3 "equality_comparison_operator"
7136 [(match_operand:DI 1 "arith_reg_operand" "r,r")
7137 (match_operand:DI 2 "arith_operand" "r,I06")])
7138 (match_operand 0 "target_operand" "b,b")
7143 b%o3i%' %1, %2, %0%>"
7144 [(set_attr "type" "cbranch_media")])
7146 (define_insn "*beq_media_i32"
7148 (if_then_else (match_operator 3 "equality_comparison_operator"
7149 [(match_operand:SI 1 "arith_reg_operand" "r,r")
7150 (match_operand:SI 2 "arith_operand" "r,I06")])
7151 (match_operand 0 "target_operand" "b,b")
7156 b%o3i%' %1, %2, %0%>"
7157 [(set_attr "type" "cbranch_media")])
7159 (define_insn "*bgt_media_i"
7161 (if_then_else (match_operator 3 "greater_comparison_operator"
7162 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7163 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7164 (match_operand 0 "target_operand" "b")
7167 "b%o3%' %N1, %N2, %0%>"
7168 [(set_attr "type" "cbranch_media")])
7170 (define_insn "*bgt_media_i32"
7172 (if_then_else (match_operator 3 "greater_comparison_operator"
7173 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7174 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7175 (match_operand 0 "target_operand" "b")
7178 "b%o3%' %N1, %N2, %0%>"
7179 [(set_attr "type" "cbranch_media")])
7181 ;; These are only needed to make invert_jump() happy - otherwise, jump
7182 ;; optimization will be silently disabled.
7183 (define_insn "*blt_media_i"
7185 (if_then_else (match_operator 3 "less_comparison_operator"
7186 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7187 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7188 (match_operand 0 "target_operand" "b")
7191 "b%o3%' %N2, %N1, %0%>"
7192 [(set_attr "type" "cbranch_media")])
7194 (define_insn "*blt_media_i32"
7196 (if_then_else (match_operator 3 "less_comparison_operator"
7197 [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7198 (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7199 (match_operand 0 "target_operand" "b")
7202 "b%o3%' %N2, %N1, %0%>"
7203 [(set_attr "type" "cbranch_media")])
7205 ;; combiner splitter for test-and-branch on single bit in register. This
7206 ;; is endian dependent because the non-paradoxical subreg looks different
7211 (match_operator 3 "equality_comparison_operator"
7212 [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7213 "extend_reg_operand" "")
7217 "const_int_operand" "")) 0)
7219 (match_operand 0 "target_operand" "")
7221 (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7222 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7223 [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7224 (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7228 operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7229 operands[6] = (GET_CODE (operands[3]) == EQ
7230 ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7231 : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7234 ; operand 0 is the loop count pseudo register
7235 ; operand 1 is the number of loop iterations or 0 if it is unknown
7236 ; operand 2 is the maximum number of loop iterations
7237 ; operand 3 is the number of levels of enclosed loops
7238 ; operand 4 is the label to jump to at the top of the loop
7240 (define_expand "doloop_end"
7241 [(parallel [(set (pc) (if_then_else
7242 (ne:SI (match_operand:SI 0 "" "")
7244 (label_ref (match_operand 4 "" ""))
7247 (plus:SI (match_dup 0) (const_int -1)))
7248 (clobber (reg:SI T_REG))])]
7252 if (GET_MODE (operands[0]) != SImode)
7257 (define_insn_and_split "doloop_end_split"
7259 (if_then_else (ne:SI (match_operand:SI 2 "arith_reg_dest" "0")
7261 (label_ref (match_operand 1 "" ""))
7263 (set (match_operand:SI 0 "arith_reg_dest" "=r")
7264 (plus (match_dup 2) (const_int -1)))
7265 (clobber (reg:SI T_REG))]
7269 [(parallel [(set (reg:SI T_REG)
7270 (eq:SI (match_dup 2) (const_int 1)))
7271 (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7272 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7273 (label_ref (match_dup 1))
7276 [(set_attr "type" "cbranch")])
7279 ;; ------------------------------------------------------------------------
7280 ;; Jump and linkage insns
7281 ;; ------------------------------------------------------------------------
7283 (define_insn "jump_compact"
7285 (label_ref (match_operand 0 "" "")))]
7286 "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7289 /* The length is 16 if the delay slot is unfilled. */
7290 if (get_attr_length(insn) > 4)
7291 return output_far_jump(insn, operands[0]);
7293 return \"bra %l0%#\";
7295 [(set_attr "type" "jump")
7296 (set_attr "needs_delay_slot" "yes")])
7298 ;; ??? It would be much saner to explicitly use the scratch register
7299 ;; in the jump insn, and have indirect_jump_scratch only set it,
7300 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7301 ;; from the target then, as it uses simplejump_p.
7302 ;;(define_insn "jump_compact_far"
7304 ;; (label_ref (match_operand 0 "" "")))
7305 ;; (use (match_operand 1 "register_operand" "r")]
7307 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
7308 ;; [(set_attr "type" "jump")
7309 ;; (set_attr "needs_delay_slot" "yes")])
7311 (define_insn "jump_media"
7313 (match_operand 0 "target_operand" "b"))]
7316 [(set_attr "type" "jump_media")])
7318 (define_expand "jump"
7320 (label_ref (match_operand 0 "" "")))]
7325 emit_jump_insn (gen_jump_compact (operands[0]));
7326 else if (TARGET_SHMEDIA)
7328 if (reload_in_progress || reload_completed)
7330 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7336 (define_insn "force_mode_for_call"
7337 [(use (reg:PSI FPSCR_REG))]
7340 [(set_attr "length" "0")
7341 (set (attr "fp_mode")
7342 (if_then_else (eq_attr "fpu_single" "yes")
7343 (const_string "single") (const_string "double")))])
7345 (define_insn "calli"
7346 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7347 (match_operand 1 "" ""))
7348 (use (reg:PSI FPSCR_REG))
7349 (clobber (reg:SI PR_REG))]
7353 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7354 return \"jsr/n\\t@%0\";
7356 return \"jsr\\t@%0%#\";
7359 [(set_attr "type" "call")
7360 (set (attr "fp_mode")
7361 (if_then_else (eq_attr "fpu_single" "yes")
7362 (const_string "single") (const_string "double")))
7363 (set_attr "needs_delay_slot" "yes")
7364 (set_attr "fp_set" "unknown")])
7366 ;; This is TBR relative jump instruction for SH2A architecture.
7367 ;; Its use is enabled assigning an attribute "function_vector"
7368 ;; and the vector number to a function during its declaration.
7370 (define_insn "calli_tbr_rel"
7371 [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7372 (match_operand 1 "" ""))
7373 (use (reg:PSI FPSCR_REG))
7374 (clobber (reg:SI PR_REG))]
7375 "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7378 unsigned HOST_WIDE_INT vect_num;
7379 vect_num = sh2a_get_function_vector_number (operands[0]);
7380 operands[2] = GEN_INT (vect_num * 4);
7382 return \"jsr/n\\t@@(%O2,tbr)\";
7384 [(set_attr "type" "call")
7385 (set (attr "fp_mode")
7386 (if_then_else (eq_attr "fpu_single" "yes")
7387 (const_string "single") (const_string "double")))
7388 (set_attr "needs_delay_slot" "no")
7389 (set_attr "fp_set" "unknown")])
7391 ;; This is a pc-rel call, using bsrf, for use with PIC.
7393 (define_insn "calli_pcrel"
7394 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7395 (match_operand 1 "" ""))
7396 (use (reg:PSI FPSCR_REG))
7397 (use (reg:SI PIC_REG))
7398 (use (match_operand 2 "" ""))
7399 (clobber (reg:SI PR_REG))]
7402 [(set_attr "type" "call")
7403 (set (attr "fp_mode")
7404 (if_then_else (eq_attr "fpu_single" "yes")
7405 (const_string "single") (const_string "double")))
7406 (set_attr "needs_delay_slot" "yes")
7407 (set_attr "fp_set" "unknown")])
7409 (define_insn_and_split "call_pcrel"
7410 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7411 (match_operand 1 "" ""))
7412 (use (reg:PSI FPSCR_REG))
7413 (use (reg:SI PIC_REG))
7414 (clobber (reg:SI PR_REG))
7415 (clobber (match_scratch:SI 2 "=r"))]
7422 rtx lab = PATTERN (gen_call_site ());
7424 if (SYMBOL_REF_LOCAL_P (operands[0]))
7425 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7427 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7428 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7431 [(set_attr "type" "call")
7432 (set (attr "fp_mode")
7433 (if_then_else (eq_attr "fpu_single" "yes")
7434 (const_string "single") (const_string "double")))
7435 (set_attr "needs_delay_slot" "yes")
7436 (set_attr "fp_set" "unknown")])
7438 (define_insn "call_compact"
7439 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7440 (match_operand 1 "" ""))
7441 (match_operand 2 "immediate_operand" "n")
7442 (use (reg:SI R0_REG))
7443 (use (reg:SI R1_REG))
7444 (use (reg:PSI FPSCR_REG))
7445 (clobber (reg:SI PR_REG))]
7446 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7448 [(set_attr "type" "call")
7449 (set (attr "fp_mode")
7450 (if_then_else (eq_attr "fpu_single" "yes")
7451 (const_string "single") (const_string "double")))
7452 (set_attr "needs_delay_slot" "yes")])
7454 (define_insn "call_compact_rettramp"
7455 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7456 (match_operand 1 "" ""))
7457 (match_operand 2 "immediate_operand" "n")
7458 (use (reg:SI R0_REG))
7459 (use (reg:SI R1_REG))
7460 (use (reg:PSI FPSCR_REG))
7461 (clobber (reg:SI R10_REG))
7462 (clobber (reg:SI PR_REG))]
7463 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7465 [(set_attr "type" "call")
7466 (set (attr "fp_mode")
7467 (if_then_else (eq_attr "fpu_single" "yes")
7468 (const_string "single") (const_string "double")))
7469 (set_attr "needs_delay_slot" "yes")])
7471 (define_insn "call_media"
7472 [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7473 (match_operand 1 "" ""))
7474 (clobber (reg:DI PR_MEDIA_REG))]
7477 [(set_attr "type" "jump_media")])
7479 (define_insn "call_valuei"
7480 [(set (match_operand 0 "" "=rf")
7481 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7482 (match_operand 2 "" "")))
7483 (use (reg:PSI FPSCR_REG))
7484 (clobber (reg:SI PR_REG))]
7488 if (TARGET_SH2A && (dbr_sequence_length () == 0))
7489 return \"jsr/n\\t@%1\";
7491 return \"jsr\\t@%1%#\";
7493 [(set_attr "type" "call")
7494 (set (attr "fp_mode")
7495 (if_then_else (eq_attr "fpu_single" "yes")
7496 (const_string "single") (const_string "double")))
7497 (set_attr "needs_delay_slot" "yes")
7498 (set_attr "fp_set" "unknown")])
7500 ;; This is TBR relative jump instruction for SH2A architecture.
7501 ;; Its use is enabled assigning an attribute "function_vector"
7502 ;; and the vector number to a function during its declaration.
7504 (define_insn "call_valuei_tbr_rel"
7505 [(set (match_operand 0 "" "=rf")
7506 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7507 (match_operand 2 "" "")))
7508 (use (reg:PSI FPSCR_REG))
7509 (clobber (reg:SI PR_REG))]
7510 "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7513 unsigned HOST_WIDE_INT vect_num;
7514 vect_num = sh2a_get_function_vector_number (operands[1]);
7515 operands[3] = GEN_INT (vect_num * 4);
7517 return \"jsr/n\\t@@(%O3,tbr)\";
7519 [(set_attr "type" "call")
7520 (set (attr "fp_mode")
7521 (if_then_else (eq_attr "fpu_single" "yes")
7522 (const_string "single") (const_string "double")))
7523 (set_attr "needs_delay_slot" "no")
7524 (set_attr "fp_set" "unknown")])
7526 (define_insn "call_valuei_pcrel"
7527 [(set (match_operand 0 "" "=rf")
7528 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7529 (match_operand 2 "" "")))
7530 (use (reg:PSI FPSCR_REG))
7531 (use (reg:SI PIC_REG))
7532 (use (match_operand 3 "" ""))
7533 (clobber (reg:SI PR_REG))]
7536 [(set_attr "type" "call")
7537 (set (attr "fp_mode")
7538 (if_then_else (eq_attr "fpu_single" "yes")
7539 (const_string "single") (const_string "double")))
7540 (set_attr "needs_delay_slot" "yes")
7541 (set_attr "fp_set" "unknown")])
7543 (define_insn_and_split "call_value_pcrel"
7544 [(set (match_operand 0 "" "=rf")
7545 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7546 (match_operand 2 "" "")))
7547 (use (reg:PSI FPSCR_REG))
7548 (use (reg:SI PIC_REG))
7549 (clobber (reg:SI PR_REG))
7550 (clobber (match_scratch:SI 3 "=r"))]
7557 rtx lab = PATTERN (gen_call_site ());
7559 if (SYMBOL_REF_LOCAL_P (operands[1]))
7560 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7562 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7563 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7564 operands[2], copy_rtx (lab)));
7567 [(set_attr "type" "call")
7568 (set (attr "fp_mode")
7569 (if_then_else (eq_attr "fpu_single" "yes")
7570 (const_string "single") (const_string "double")))
7571 (set_attr "needs_delay_slot" "yes")
7572 (set_attr "fp_set" "unknown")])
7574 (define_insn "call_value_compact"
7575 [(set (match_operand 0 "" "=rf")
7576 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7577 (match_operand 2 "" "")))
7578 (match_operand 3 "immediate_operand" "n")
7579 (use (reg:SI R0_REG))
7580 (use (reg:SI R1_REG))
7581 (use (reg:PSI FPSCR_REG))
7582 (clobber (reg:SI PR_REG))]
7583 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7585 [(set_attr "type" "call")
7586 (set (attr "fp_mode")
7587 (if_then_else (eq_attr "fpu_single" "yes")
7588 (const_string "single") (const_string "double")))
7589 (set_attr "needs_delay_slot" "yes")])
7591 (define_insn "call_value_compact_rettramp"
7592 [(set (match_operand 0 "" "=rf")
7593 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7594 (match_operand 2 "" "")))
7595 (match_operand 3 "immediate_operand" "n")
7596 (use (reg:SI R0_REG))
7597 (use (reg:SI R1_REG))
7598 (use (reg:PSI FPSCR_REG))
7599 (clobber (reg:SI R10_REG))
7600 (clobber (reg:SI PR_REG))]
7601 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7603 [(set_attr "type" "call")
7604 (set (attr "fp_mode")
7605 (if_then_else (eq_attr "fpu_single" "yes")
7606 (const_string "single") (const_string "double")))
7607 (set_attr "needs_delay_slot" "yes")])
7609 (define_insn "call_value_media"
7610 [(set (match_operand 0 "" "=rf")
7611 (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7612 (match_operand 2 "" "")))
7613 (clobber (reg:DI PR_MEDIA_REG))]
7616 [(set_attr "type" "jump_media")])
7618 (define_expand "call"
7619 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7620 (match_operand 1 "" ""))
7621 (match_operand 2 "" "")
7622 (use (reg:PSI FPSCR_REG))
7623 (clobber (reg:SI PR_REG))])]
7629 operands[0] = shmedia_prepare_call_address (operands[0], 0);
7630 emit_call_insn (gen_call_media (operands[0], operands[1]));
7633 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7635 rtx cookie_rtx = operands[2];
7636 long cookie = INTVAL (cookie_rtx);
7637 rtx func = XEXP (operands[0], 0);
7642 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7644 rtx reg = gen_reg_rtx (Pmode);
7646 emit_insn (gen_symGOTPLT2reg (reg, func));
7650 func = legitimize_pic_address (func, Pmode, 0);
7653 r0 = gen_rtx_REG (SImode, R0_REG);
7654 r1 = gen_rtx_REG (SImode, R1_REG);
7656 /* Since such a call function may use all call-clobbered
7657 registers, we force a mode switch earlier, so that we don't
7658 run out of registers when adjusting fpscr for the call. */
7659 emit_insn (gen_force_mode_for_call ());
7662 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7664 operands[0] = force_reg (SImode, operands[0]);
7666 emit_move_insn (r0, func);
7667 emit_move_insn (r1, cookie_rtx);
7669 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7670 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7673 emit_call_insn (gen_call_compact (operands[0], operands[1],
7678 else if (TARGET_SHCOMPACT && flag_pic
7679 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7680 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7682 rtx reg = gen_reg_rtx (Pmode);
7684 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7685 XEXP (operands[0], 0) = reg;
7687 if (!flag_pic && TARGET_SH2A
7688 && MEM_P (operands[0])
7689 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7691 if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7693 emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7698 if (flag_pic && TARGET_SH2
7699 && MEM_P (operands[0])
7700 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7702 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7707 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7708 operands[1] = operands[2];
7711 emit_call_insn (gen_calli (operands[0], operands[1]));
7715 (define_insn "call_pop_compact"
7716 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7717 (match_operand 1 "" ""))
7718 (match_operand 2 "immediate_operand" "n")
7719 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7720 (match_operand 3 "immediate_operand" "n")))
7721 (use (reg:SI R0_REG))
7722 (use (reg:SI R1_REG))
7723 (use (reg:PSI FPSCR_REG))
7724 (clobber (reg:SI PR_REG))]
7725 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7727 [(set_attr "type" "call")
7728 (set (attr "fp_mode")
7729 (if_then_else (eq_attr "fpu_single" "yes")
7730 (const_string "single") (const_string "double")))
7731 (set_attr "needs_delay_slot" "yes")])
7733 (define_insn "call_pop_compact_rettramp"
7734 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7735 (match_operand 1 "" ""))
7736 (match_operand 2 "immediate_operand" "n")
7737 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7738 (match_operand 3 "immediate_operand" "n")))
7739 (use (reg:SI R0_REG))
7740 (use (reg:SI R1_REG))
7741 (use (reg:PSI FPSCR_REG))
7742 (clobber (reg:SI R10_REG))
7743 (clobber (reg:SI PR_REG))]
7744 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7746 [(set_attr "type" "call")
7747 (set (attr "fp_mode")
7748 (if_then_else (eq_attr "fpu_single" "yes")
7749 (const_string "single") (const_string "double")))
7750 (set_attr "needs_delay_slot" "yes")])
7752 (define_expand "call_pop"
7753 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7754 (match_operand 1 "" ""))
7755 (match_operand 2 "" "")
7756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7757 (match_operand 3 "" "")))])]
7766 gcc_assert (operands[2] && INTVAL (operands[2]));
7767 cookie_rtx = operands[2];
7768 cookie = INTVAL (cookie_rtx);
7769 func = XEXP (operands[0], 0);
7773 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7775 rtx reg = gen_reg_rtx (Pmode);
7776 emit_insn (gen_symGOTPLT2reg (reg, func));
7780 func = legitimize_pic_address (func, Pmode, 0);
7783 r0 = gen_rtx_REG (SImode, R0_REG);
7784 r1 = gen_rtx_REG (SImode, R1_REG);
7786 /* Since such a call function may use all call-clobbered
7787 registers, we force a mode switch earlier, so that we don't
7788 run out of registers when adjusting fpscr for the call. */
7789 emit_insn (gen_force_mode_for_call ());
7791 operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7793 operands[0] = force_reg (SImode, operands[0]);
7795 emit_move_insn (r0, func);
7796 emit_move_insn (r1, cookie_rtx);
7798 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7799 emit_call_insn (gen_call_pop_compact_rettramp
7800 (operands[0], operands[1], operands[2], operands[3]));
7802 emit_call_insn (gen_call_pop_compact
7803 (operands[0], operands[1], operands[2], operands[3]));
7808 (define_expand "call_value"
7809 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7810 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7811 (match_operand 2 "" "")))
7812 (match_operand 3 "" "")
7813 (use (reg:PSI FPSCR_REG))
7814 (clobber (reg:SI PR_REG))])]
7820 operands[1] = shmedia_prepare_call_address (operands[1], 0);
7821 emit_call_insn (gen_call_value_media (operands[0], operands[1],
7825 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7827 rtx cookie_rtx = operands[3];
7828 long cookie = INTVAL (cookie_rtx);
7829 rtx func = XEXP (operands[1], 0);
7834 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7836 rtx reg = gen_reg_rtx (Pmode);
7838 emit_insn (gen_symGOTPLT2reg (reg, func));
7842 func = legitimize_pic_address (func, Pmode, 0);
7845 r0 = gen_rtx_REG (SImode, R0_REG);
7846 r1 = gen_rtx_REG (SImode, R1_REG);
7848 /* Since such a call function may use all call-clobbered
7849 registers, we force a mode switch earlier, so that we don't
7850 run out of registers when adjusting fpscr for the call. */
7851 emit_insn (gen_force_mode_for_call ());
7854 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7856 operands[1] = force_reg (SImode, operands[1]);
7858 emit_move_insn (r0, func);
7859 emit_move_insn (r1, cookie_rtx);
7861 if (cookie & CALL_COOKIE_RET_TRAMP (1))
7862 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7867 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7868 operands[2], operands[3]));
7872 else if (TARGET_SHCOMPACT && flag_pic
7873 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7874 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7876 rtx reg = gen_reg_rtx (Pmode);
7878 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7879 XEXP (operands[1], 0) = reg;
7881 if (!flag_pic && TARGET_SH2A
7882 && MEM_P (operands[1])
7883 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7885 if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7887 emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7888 XEXP (operands[1], 0), operands[2]));
7892 if (flag_pic && TARGET_SH2
7893 && MEM_P (operands[1])
7894 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7896 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7901 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7903 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7907 (define_insn "sibcalli"
7908 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7909 (match_operand 1 "" ""))
7910 (use (reg:PSI FPSCR_REG))
7914 [(set_attr "needs_delay_slot" "yes")
7915 (set (attr "fp_mode")
7916 (if_then_else (eq_attr "fpu_single" "yes")
7917 (const_string "single") (const_string "double")))
7918 (set_attr "type" "jump_ind")])
7920 (define_insn "sibcalli_pcrel"
7921 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7922 (match_operand 1 "" ""))
7923 (use (match_operand 2 "" ""))
7924 (use (reg:PSI FPSCR_REG))
7928 [(set_attr "needs_delay_slot" "yes")
7929 (set (attr "fp_mode")
7930 (if_then_else (eq_attr "fpu_single" "yes")
7931 (const_string "single") (const_string "double")))
7932 (set_attr "type" "jump_ind")])
7934 ;; This uses an unspec to describe that the symbol_ref is very close.
7935 (define_insn "sibcalli_thunk"
7936 [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7938 (match_operand 1 "" ""))
7939 (use (reg:PSI FPSCR_REG))
7943 [(set_attr "needs_delay_slot" "yes")
7944 (set (attr "fp_mode")
7945 (if_then_else (eq_attr "fpu_single" "yes")
7946 (const_string "single") (const_string "double")))
7947 (set_attr "type" "jump")
7948 (set_attr "length" "2")])
7950 (define_insn_and_split "sibcall_pcrel"
7951 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7952 (match_operand 1 "" ""))
7953 (use (reg:PSI FPSCR_REG))
7954 (clobber (match_scratch:SI 2 "=k"))
7962 rtx lab = PATTERN (gen_call_site ());
7965 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7966 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7968 SIBLING_CALL_P (call_insn) = 1;
7971 [(set_attr "needs_delay_slot" "yes")
7972 (set (attr "fp_mode")
7973 (if_then_else (eq_attr "fpu_single" "yes")
7974 (const_string "single") (const_string "double")))
7975 (set_attr "type" "jump_ind")])
7977 (define_insn "sibcall_compact"
7978 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7979 (match_operand 1 "" ""))
7981 (use (match_operand:SI 2 "register_operand" "z,x"))
7982 (use (reg:SI R1_REG))
7983 (use (reg:PSI FPSCR_REG))
7984 ;; We want to make sure the `x' above will only match MACH_REG
7985 ;; because sibcall_epilogue may clobber MACL_REG.
7986 (clobber (reg:SI MACL_REG))]
7990 jmp @%0\\n sts %2, r0"
7991 [(set_attr "needs_delay_slot" "yes,no")
7992 (set_attr "length" "2,4")
7993 (set (attr "fp_mode") (const_string "single"))
7994 (set_attr "type" "jump_ind")])
7996 (define_insn "sibcall_media"
7997 [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7998 (match_operand 1 "" ""))
7999 (use (reg:SI PR_MEDIA_REG))
8003 [(set_attr "type" "jump_media")])
8005 (define_expand "sibcall"
8007 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8008 (match_operand 1 "" ""))
8009 (match_operand 2 "" "")
8010 (use (reg:PSI FPSCR_REG))
8017 operands[0] = shmedia_prepare_call_address (operands[0], 1);
8018 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8021 else if (TARGET_SHCOMPACT && operands[2]
8022 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8024 rtx cookie_rtx = operands[2];
8025 long cookie = INTVAL (cookie_rtx);
8026 rtx func = XEXP (operands[0], 0);
8031 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8033 rtx reg = gen_reg_rtx (Pmode);
8035 emit_insn (gen_symGOT2reg (reg, func));
8039 func = legitimize_pic_address (func, Pmode, 0);
8042 /* FIXME: if we could tell whether all argument registers are
8043 already taken, we could decide whether to force the use of
8044 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8045 simple way to tell. We could use the CALL_COOKIE, but we
8046 can't currently tell a register used for regular argument
8047 passing from one that is unused. If we leave it up to reload
8048 to decide which register to use, it seems to always choose
8049 R0_REG, which leaves no available registers in SIBCALL_REGS
8050 to hold the address of the trampoline. */
8051 mach = gen_rtx_REG (SImode, MACH_REG);
8052 r1 = gen_rtx_REG (SImode, R1_REG);
8054 /* Since such a call function may use all call-clobbered
8055 registers, we force a mode switch earlier, so that we don't
8056 run out of registers when adjusting fpscr for the call. */
8057 emit_insn (gen_force_mode_for_call ());
8060 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8062 operands[0] = force_reg (SImode, operands[0]);
8064 /* We don't need a return trampoline, since the callee will
8065 return directly to the upper caller. */
8066 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8068 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8069 cookie_rtx = GEN_INT (cookie);
8072 emit_move_insn (mach, func);
8073 emit_move_insn (r1, cookie_rtx);
8075 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8078 else if (TARGET_SHCOMPACT && flag_pic
8079 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8080 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8082 rtx reg = gen_reg_rtx (Pmode);
8084 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8085 XEXP (operands[0], 0) = reg;
8087 if (flag_pic && TARGET_SH2
8088 && MEM_P (operands[0])
8089 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8090 /* The PLT needs the PIC register, but the epilogue would have
8091 to restore it, so we can only use PC-relative PIC calls for
8092 static functions. */
8093 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8095 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8099 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8101 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8105 (define_insn "sibcall_valuei"
8106 [(set (match_operand 0 "" "=rf")
8107 (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8108 (match_operand 2 "" "")))
8109 (use (reg:PSI FPSCR_REG))
8113 [(set_attr "needs_delay_slot" "yes")
8114 (set (attr "fp_mode")
8115 (if_then_else (eq_attr "fpu_single" "yes")
8116 (const_string "single") (const_string "double")))
8117 (set_attr "type" "jump_ind")])
8119 (define_insn "sibcall_valuei_pcrel"
8120 [(set (match_operand 0 "" "=rf")
8121 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8122 (match_operand 2 "" "")))
8123 (use (match_operand 3 "" ""))
8124 (use (reg:PSI FPSCR_REG))
8128 [(set_attr "needs_delay_slot" "yes")
8129 (set (attr "fp_mode")
8130 (if_then_else (eq_attr "fpu_single" "yes")
8131 (const_string "single") (const_string "double")))
8132 (set_attr "type" "jump_ind")])
8134 (define_insn_and_split "sibcall_value_pcrel"
8135 [(set (match_operand 0 "" "=rf")
8136 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8137 (match_operand 2 "" "")))
8138 (use (reg:PSI FPSCR_REG))
8139 (clobber (match_scratch:SI 3 "=k"))
8147 rtx lab = PATTERN (gen_call_site ());
8150 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8151 call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8155 SIBLING_CALL_P (call_insn) = 1;
8158 [(set_attr "needs_delay_slot" "yes")
8159 (set (attr "fp_mode")
8160 (if_then_else (eq_attr "fpu_single" "yes")
8161 (const_string "single") (const_string "double")))
8162 (set_attr "type" "jump_ind")])
8164 (define_insn "sibcall_value_compact"
8165 [(set (match_operand 0 "" "=rf,rf")
8166 (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8167 (match_operand 2 "" "")))
8169 (use (match_operand:SI 3 "register_operand" "z,x"))
8170 (use (reg:SI R1_REG))
8171 (use (reg:PSI FPSCR_REG))
8172 ;; We want to make sure the `x' above will only match MACH_REG
8173 ;; because sibcall_epilogue may clobber MACL_REG.
8174 (clobber (reg:SI MACL_REG))]
8178 jmp @%1\\n sts %3, r0"
8179 [(set_attr "needs_delay_slot" "yes,no")
8180 (set_attr "length" "2,4")
8181 (set (attr "fp_mode") (const_string "single"))
8182 (set_attr "type" "jump_ind")])
8184 (define_insn "sibcall_value_media"
8185 [(set (match_operand 0 "" "=rf")
8186 (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8187 (match_operand 2 "" "")))
8188 (use (reg:SI PR_MEDIA_REG))
8192 [(set_attr "type" "jump_media")])
8194 (define_expand "sibcall_value"
8196 [(set (match_operand 0 "arith_reg_operand" "")
8197 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8198 (match_operand 2 "" "")))
8199 (match_operand 3 "" "")
8200 (use (reg:PSI FPSCR_REG))
8207 operands[1] = shmedia_prepare_call_address (operands[1], 1);
8208 emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8212 else if (TARGET_SHCOMPACT && operands[3]
8213 && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8215 rtx cookie_rtx = operands[3];
8216 long cookie = INTVAL (cookie_rtx);
8217 rtx func = XEXP (operands[1], 0);
8222 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8224 rtx reg = gen_reg_rtx (Pmode);
8226 emit_insn (gen_symGOT2reg (reg, func));
8230 func = legitimize_pic_address (func, Pmode, 0);
8233 /* FIXME: if we could tell whether all argument registers are
8234 already taken, we could decide whether to force the use of
8235 MACH_REG or to stick to R0_REG. Unfortunately, there's no
8236 simple way to tell. We could use the CALL_COOKIE, but we
8237 can't currently tell a register used for regular argument
8238 passing from one that is unused. If we leave it up to reload
8239 to decide which register to use, it seems to always choose
8240 R0_REG, which leaves no available registers in SIBCALL_REGS
8241 to hold the address of the trampoline. */
8242 mach = gen_rtx_REG (SImode, MACH_REG);
8243 r1 = gen_rtx_REG (SImode, R1_REG);
8245 /* Since such a call function may use all call-clobbered
8246 registers, we force a mode switch earlier, so that we don't
8247 run out of registers when adjusting fpscr for the call. */
8248 emit_insn (gen_force_mode_for_call ());
8251 = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8253 operands[1] = force_reg (SImode, operands[1]);
8255 /* We don't need a return trampoline, since the callee will
8256 return directly to the upper caller. */
8257 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8259 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8260 cookie_rtx = GEN_INT (cookie);
8263 emit_move_insn (mach, func);
8264 emit_move_insn (r1, cookie_rtx);
8266 emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8267 operands[2], mach));
8270 else if (TARGET_SHCOMPACT && flag_pic
8271 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8272 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8274 rtx reg = gen_reg_rtx (Pmode);
8276 emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8277 XEXP (operands[1], 0) = reg;
8279 if (flag_pic && TARGET_SH2
8280 && MEM_P (operands[1])
8281 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8282 /* The PLT needs the PIC register, but the epilogue would have
8283 to restore it, so we can only use PC-relative PIC calls for
8284 static functions. */
8285 && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8287 emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8288 XEXP (operands[1], 0),
8293 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8295 emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8299 (define_insn "call_value_pop_compact"
8300 [(set (match_operand 0 "" "=rf")
8301 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8302 (match_operand 2 "" "")))
8303 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8304 (match_operand 4 "immediate_operand" "n")))
8305 (match_operand 3 "immediate_operand" "n")
8306 (use (reg:SI R0_REG))
8307 (use (reg:SI R1_REG))
8308 (use (reg:PSI FPSCR_REG))
8309 (clobber (reg:SI PR_REG))]
8310 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8312 [(set_attr "type" "call")
8313 (set (attr "fp_mode")
8314 (if_then_else (eq_attr "fpu_single" "yes")
8315 (const_string "single") (const_string "double")))
8316 (set_attr "needs_delay_slot" "yes")])
8318 (define_insn "call_value_pop_compact_rettramp"
8319 [(set (match_operand 0 "" "=rf")
8320 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8321 (match_operand 2 "" "")))
8322 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8323 (match_operand 4 "immediate_operand" "n")))
8324 (match_operand 3 "immediate_operand" "n")
8325 (use (reg:SI R0_REG))
8326 (use (reg:SI R1_REG))
8327 (use (reg:PSI FPSCR_REG))
8328 (clobber (reg:SI R10_REG))
8329 (clobber (reg:SI PR_REG))]
8330 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8332 [(set_attr "type" "call")
8333 (set (attr "fp_mode")
8334 (if_then_else (eq_attr "fpu_single" "yes")
8335 (const_string "single") (const_string "double")))
8336 (set_attr "needs_delay_slot" "yes")])
8338 (define_expand "call_value_pop"
8339 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8340 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8341 (match_operand 2 "" "")))
8342 (match_operand 3 "" "")
8343 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8344 (match_operand 4 "" "")))])]
8353 gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8354 cookie_rtx = operands[3];
8355 cookie = INTVAL (cookie_rtx);
8356 func = XEXP (operands[1], 0);
8360 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8362 rtx reg = gen_reg_rtx (Pmode);
8364 emit_insn (gen_symGOTPLT2reg (reg, func));
8368 func = legitimize_pic_address (func, Pmode, 0);
8371 r0 = gen_rtx_REG (SImode, R0_REG);
8372 r1 = gen_rtx_REG (SImode, R1_REG);
8374 /* Since such a call function may use all call-clobbered
8375 registers, we force a mode switch earlier, so that we don't
8376 run out of registers when adjusting fpscr for the call. */
8377 emit_insn (gen_force_mode_for_call ());
8379 operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8381 operands[1] = force_reg (SImode, operands[1]);
8383 emit_move_insn (r0, func);
8384 emit_move_insn (r1, cookie_rtx);
8386 if (cookie & CALL_COOKIE_RET_TRAMP (1))
8387 emit_call_insn (gen_call_value_pop_compact_rettramp
8388 (operands[0], operands[1], operands[2],
8389 operands[3], operands[4]));
8391 emit_call_insn (gen_call_value_pop_compact
8392 (operands[0], operands[1], operands[2],
8393 operands[3], operands[4]));
8398 (define_expand "sibcall_epilogue"
8403 sh_expand_epilogue (1);
8404 if (TARGET_SHCOMPACT)
8408 /* If epilogue clobbers r0, preserve it in macl. */
8409 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8410 if ((set = single_set (insn))
8411 && REG_P (SET_DEST (set))
8412 && REGNO (SET_DEST (set)) == R0_REG)
8414 rtx r0 = gen_rtx_REG (SImode, R0_REG);
8415 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8417 /* We can't tell at this point whether the sibcall is a
8418 sibcall_compact and, if it is, whether it uses r0 or
8419 mach as operand 2, so let the instructions that
8420 preserve r0 be optimized away if r0 turns out to be
8422 emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8423 emit_move_insn (r0, tmp);
8430 (define_insn "indirect_jump_compact"
8432 (match_operand:SI 0 "arith_reg_operand" "r"))]
8435 [(set_attr "needs_delay_slot" "yes")
8436 (set_attr "type" "jump_ind")])
8438 (define_expand "indirect_jump"
8440 (match_operand 0 "register_operand" ""))]
8444 if (GET_MODE (operands[0]) != Pmode)
8445 operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8448 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8449 ;; which can be present in structured code from indirect jumps which can not
8450 ;; be present in structured code. This allows -fprofile-arcs to work.
8452 ;; For SH1 processors.
8453 (define_insn "casesi_jump_1"
8455 (match_operand:SI 0 "register_operand" "r"))
8456 (use (label_ref (match_operand 1 "" "")))]
8459 [(set_attr "needs_delay_slot" "yes")
8460 (set_attr "type" "jump_ind")])
8462 ;; For all later processors.
8463 (define_insn "casesi_jump_2"
8464 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8465 (label_ref (match_operand 1 "" ""))))
8466 (use (label_ref (match_operand 2 "" "")))]
8468 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8470 [(set_attr "needs_delay_slot" "yes")
8471 (set_attr "type" "jump_ind")])
8473 (define_insn "casesi_jump_media"
8474 [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8475 (use (label_ref (match_operand 1 "" "")))]
8478 [(set_attr "type" "jump_media")])
8480 ;; Call subroutine returning any type.
8481 ;; ??? This probably doesn't work.
8483 (define_expand "untyped_call"
8484 [(parallel [(call (match_operand 0 "" "")
8486 (match_operand 1 "" "")
8487 (match_operand 2 "" "")])]
8488 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8493 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8495 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8497 rtx set = XVECEXP (operands[2], 0, i);
8498 emit_move_insn (SET_DEST (set), SET_SRC (set));
8501 /* The optimizer does not know that the call sets the function value
8502 registers we stored in the result block. We avoid problems by
8503 claiming that all hard registers are used and clobbered at this
8505 emit_insn (gen_blockage ());
8510 ;; ------------------------------------------------------------------------
8512 ;; ------------------------------------------------------------------------
8515 [(set (reg:SI T_REG)
8516 (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8517 (set (match_operand:SI 0 "arith_reg_dest" "=r")
8518 (plus:SI (match_dup 1) (const_int -1)))]
8521 [(set_attr "type" "arith")])
8528 ;; Load address of a label. This is only generated by the casesi expand,
8529 ;; and by machine_dependent_reorg (fixing up fp moves).
8530 ;; This must use unspec, because this only works for labels that are
8534 [(set (reg:SI R0_REG)
8535 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8538 [(set_attr "in_delay_slot" "no")
8539 (set_attr "type" "arith")])
8541 ;; machine_dependent_reorg will make this a `mova'.
8542 (define_insn "mova_const"
8543 [(set (reg:SI R0_REG)
8544 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8547 [(set_attr "in_delay_slot" "no")
8548 (set_attr "type" "arith")])
8550 (define_expand "GOTaddr2picreg"
8551 [(set (reg:SI R0_REG)
8552 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8554 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8555 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8558 if (TARGET_VXWORKS_RTP)
8560 rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8561 rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8562 emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8566 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8567 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8571 rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8572 rtx pic = operands[0];
8573 rtx lab = PATTERN (gen_call_site ());
8576 equiv = operands[1];
8577 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8578 UNSPEC_PCREL_SYMOFF);
8579 operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8581 if (Pmode == SImode)
8583 emit_insn (gen_movsi_const (pic, operands[1]));
8584 emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8588 emit_insn (gen_movdi_const (pic, operands[1]));
8589 emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8592 insn = emit_move_insn (operands[0], tr);
8594 set_unique_reg_note (insn, REG_EQUAL, equiv);
8601 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8604 (define_expand "vxworks_picreg"
8605 [(set (reg:SI PIC_REG)
8606 (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8607 (set (reg:SI R0_REG)
8608 (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8609 (set (reg:SI PIC_REG)
8610 (mem:SI (reg:SI PIC_REG)))
8611 (set (reg:SI PIC_REG)
8612 (mem:SI (plus:SI (reg:SI PIC_REG)
8614 "TARGET_VXWORKS_RTP")
8617 [(set (match_operand 0 "target_reg_operand" "=b")
8618 (const (unspec [(match_operand 1 "" "Csy")]
8619 UNSPEC_DATALABEL)))]
8620 "TARGET_SHMEDIA && flag_pic
8621 && satisfies_constraint_Csy (operands[1])"
8622 "ptb/u datalabel %1, %0"
8623 [(set_attr "type" "ptabs_media")
8624 (set_attr "length" "*")])
8626 (define_insn "ptrel_si"
8627 [(set (match_operand:SI 0 "target_reg_operand" "=b")
8628 (plus:SI (match_operand:SI 1 "register_operand" "r")
8630 (match_operand:SI 2 "" "")]
8632 "%O2: ptrel/u %1, %0"
8633 [(set_attr "type" "ptabs_media")])
8635 (define_insn "ptrel_di"
8636 [(set (match_operand:DI 0 "target_reg_operand" "=b")
8637 (plus:DI (match_operand:DI 1 "register_operand" "r")
8639 (match_operand:DI 2 "" "")]
8641 "%O2: ptrel/u %1, %0"
8642 [(set_attr "type" "ptabs_media")])
8644 (define_expand "builtin_setjmp_receiver"
8645 [(match_operand 0 "" "")]
8649 emit_insn (gen_GOTaddr2picreg ());
8653 (define_expand "call_site"
8654 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8658 static HOST_WIDE_INT i = 0;
8659 operands[0] = GEN_INT (i);
8663 ;; op0 = op1 + r12 but hide it before reload completed. See the comment
8664 ;; in symGOT_load expand.
8666 (define_insn_and_split "chk_guard_add"
8667 [(set (match_operand:SI 0 "register_operand" "=&r")
8668 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8673 "TARGET_SH1 && reload_completed"
8674 [(set (match_dup 0) (reg:SI PIC_REG))
8675 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8677 [(set_attr "type" "arith")])
8679 (define_expand "sym_label2reg"
8680 [(set (match_operand:SI 0 "" "")
8681 (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8682 (const (plus:SI (match_operand:SI 2 "" "")
8687 (define_expand "symGOT_load"
8688 [(set (match_dup 2) (match_operand 1 "" ""))
8689 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8690 (set (match_operand 0 "" "") (mem (match_dup 3)))]
8696 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8697 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8701 rtx reg = operands[2];
8703 if (Pmode == DImode)
8706 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8708 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8713 emit_insn (gen_movsi_const (reg, operands[1]));
8715 emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8719 emit_move_insn (operands[2], operands[1]);
8721 /* When stack protector inserts codes after the result is set to
8722 R0, @(rX, r12) will cause a spill failure for R0. Use a unspec
8723 insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8724 when rX is a GOT address for the guard symbol. Ugly but doesn't
8725 matter because this is a rare situation. */
8727 && flag_stack_protect
8728 && GET_CODE (operands[1]) == CONST
8729 && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8730 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8731 && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8732 \"__stack_chk_guard\") == 0)
8733 emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8735 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8736 gen_rtx_REG (Pmode, PIC_REG)));
8738 /* N.B. This is not constant for a GOTPLT relocation. */
8739 mem = gen_rtx_MEM (Pmode, operands[3]);
8740 MEM_NOTRAP_P (mem) = 1;
8741 /* ??? Should we have a special alias set for the GOT? */
8742 emit_move_insn (operands[0], mem);
8747 (define_expand "sym2GOT"
8748 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8752 (define_expand "symGOT2reg"
8753 [(match_operand 0 "" "") (match_operand 1 "" "")]
8759 gotsym = gen_sym2GOT (operands[1]);
8760 PUT_MODE (gotsym, Pmode);
8761 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8763 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8768 (define_expand "symGOTPLT2reg"
8769 [(match_operand 0 "" "") (match_operand 1 "" "")]
8773 rtx pltsym = gen_rtx_CONST (Pmode,
8774 gen_rtx_UNSPEC (Pmode,
8775 gen_rtvec (1, operands[1]),
8777 emit_insn (gen_symGOT_load (operands[0], pltsym));
8781 (define_expand "sym2GOTOFF"
8782 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8786 (define_expand "symGOTOFF2reg"
8787 [(match_operand 0 "" "") (match_operand 1 "" "")]
8791 rtx gotoffsym, insn;
8792 rtx t = (!can_create_pseudo_p ()
8794 : gen_reg_rtx (GET_MODE (operands[0])));
8796 gotoffsym = gen_sym2GOTOFF (operands[1]);
8797 PUT_MODE (gotoffsym, Pmode);
8798 emit_move_insn (t, gotoffsym);
8799 insn = emit_move_insn (operands[0],
8800 gen_rtx_PLUS (Pmode, t,
8801 gen_rtx_REG (Pmode, PIC_REG)));
8803 set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8808 (define_expand "symPLT_label2reg"
8809 [(set (match_operand:SI 0 "" "")
8812 [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8813 (const:SI (plus:SI (match_operand:SI 2 "" "")
8814 (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8815 ;; Even though the PIC register is not really used by the call
8816 ;; sequence in which this is expanded, the PLT code assumes the PIC
8817 ;; register is set, so we must not skip its initialization. Since
8818 ;; we only use this expand as part of calling sequences, and never
8819 ;; to take the address of a function, this is the best point to
8820 ;; insert the (use). Using the PLT to take the address of a
8821 ;; function would be wrong, not only because the PLT entry could
8822 ;; then be called from a function that doesn't initialize the PIC
8823 ;; register to the proper GOT, but also because pointers to the
8824 ;; same function might not compare equal, should they be set by
8825 ;; different shared libraries.
8826 (use (reg:SI PIC_REG))]
8830 (define_expand "sym2PIC"
8831 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8835 ;; TLS code generation.
8836 ;; ??? this should be a define_insn_and_split
8837 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8838 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8841 (define_insn "tls_global_dynamic"
8842 [(set (match_operand:SI 0 "register_operand" "=&z")
8843 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8846 (use (reg:PSI FPSCR_REG))
8847 (use (reg:SI PIC_REG))
8848 (clobber (reg:SI PR_REG))
8849 (clobber (scratch:SI))]
8855 \\tmova\\t2f,r0\\n\\
8856 \\tmov.l\\t2f,r1\\n\\
8859 \\tadd\\tr12,r4\\n\\
8863 1:\\t.long\\t%a1@TLSGD\\n\\
8864 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8867 [(set_attr "type" "tls_load")
8868 (set_attr "length" "26")])
8870 (define_insn "tls_local_dynamic"
8871 [(set (match_operand:SI 0 "register_operand" "=&z")
8872 (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8875 (use (reg:PSI FPSCR_REG))
8876 (use (reg:SI PIC_REG))
8877 (clobber (reg:SI PR_REG))
8878 (clobber (scratch:SI))]
8884 \\tmova\\t2f,r0\\n\\
8885 \\tmov.l\\t2f,r1\\n\\
8888 \\tadd\\tr12,r4\\n\\
8892 1:\\t.long\\t%a1@TLSLDM\\n\\
8893 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8896 [(set_attr "type" "tls_load")
8897 (set_attr "length" "26")])
8899 (define_expand "sym2DTPOFF"
8900 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8904 (define_expand "symDTPOFF2reg"
8905 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8910 rtx t = (!can_create_pseudo_p ()
8912 : gen_reg_rtx (GET_MODE (operands[0])));
8914 dtpoffsym = gen_sym2DTPOFF (operands[1]);
8915 PUT_MODE (dtpoffsym, Pmode);
8916 emit_move_insn (t, dtpoffsym);
8917 emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8921 (define_expand "sym2GOTTPOFF"
8922 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8926 (define_insn "tls_initial_exec"
8927 [(set (match_operand:SI 0 "register_operand" "=&r")
8928 (unspec:SI [(match_operand:SI 1 "" "")]
8930 (use (reg:SI GBR_REG))
8931 (use (reg:SI PIC_REG))
8932 (clobber (reg:SI R0_REG))]
8938 \\tstc\\tgbr,%0\\n\\
8939 \\tmov.l\\t@(r0,r12),r0\\n\\
8943 1:\\t.long\\t%a1\\n\\
8946 [(set_attr "type" "tls_load")
8947 (set_attr "length" "16")])
8949 (define_expand "sym2TPOFF"
8950 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8954 (define_expand "symTPOFF2reg"
8955 [(match_operand 0 "" "") (match_operand 1 "" "")]
8961 tpoffsym = gen_sym2TPOFF (operands[1]);
8962 PUT_MODE (tpoffsym, Pmode);
8963 emit_move_insn (operands[0], tpoffsym);
8967 (define_insn "load_gbr"
8968 [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8969 (use (reg:SI GBR_REG))]
8972 [(set_attr "type" "tls_load")])
8974 ;; case instruction for switch statements.
8976 ;; Operand 0 is index
8977 ;; operand 1 is the minimum bound
8978 ;; operand 2 is the maximum bound - minimum bound + 1
8979 ;; operand 3 is CODE_LABEL for the table;
8980 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8982 (define_expand "casesi"
8983 [(match_operand:SI 0 "arith_reg_operand" "")
8984 (match_operand:SI 1 "arith_reg_operand" "")
8985 (match_operand:SI 2 "arith_reg_operand" "")
8986 (match_operand 3 "" "") (match_operand 4 "" "")]
8990 rtx reg = gen_reg_rtx (SImode);
8991 rtx reg2 = gen_reg_rtx (SImode);
8994 rtx reg = gen_reg_rtx (DImode);
8995 rtx reg2 = gen_reg_rtx (DImode);
8996 rtx reg3 = gen_reg_rtx (Pmode);
8997 rtx reg4 = gen_reg_rtx (Pmode);
8998 rtx reg5 = gen_reg_rtx (Pmode);
9001 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9002 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9003 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9005 test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
9006 emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
9007 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9008 test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
9009 emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
9010 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9011 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9012 (Pmode, operands[3])));
9013 /* Messy: can we subreg to clean this up? */
9014 if (Pmode == DImode)
9015 load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9017 load = gen_casesi_load_media (reg4,
9018 gen_rtx_SUBREG (DImode, reg3, 0),
9020 PUT_MODE (SET_SRC (load), Pmode);
9022 /* ??? The following add could be eliminated if we used ptrel. */
9023 emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9024 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9028 operands[1] = copy_to_mode_reg (SImode, operands[1]);
9029 operands[2] = copy_to_mode_reg (SImode, operands[2]);
9030 /* If optimizing, casesi_worker depends on the mode of the instruction
9031 before label it 'uses' - operands[3]. */
9032 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9034 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9036 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9038 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9039 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9040 operands[3], but to lab. We will fix this up in
9041 machine_dependent_reorg. */
9046 (define_expand "casesi_0"
9047 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9048 (set (match_dup 4) (minus:SI (match_dup 4)
9049 (match_operand:SI 1 "arith_operand" "")))
9051 (gtu:SI (match_dup 4)
9052 (match_operand:SI 2 "arith_reg_operand" "")))
9054 (if_then_else (ne (reg:SI T_REG)
9056 (label_ref (match_operand 3 "" ""))
9061 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9062 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9063 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9065 (define_insn "casesi_worker_0"
9066 [(set (match_operand:SI 0 "register_operand" "=r,r")
9067 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9068 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9069 (clobber (match_scratch:SI 3 "=X,1"))
9070 (clobber (match_scratch:SI 4 "=&z,z"))]
9075 [(set (match_operand:SI 0 "register_operand" "")
9076 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9077 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9078 (clobber (match_scratch:SI 3 ""))
9079 (clobber (match_scratch:SI 4 ""))]
9080 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9081 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9082 (parallel [(set (match_dup 0)
9083 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9084 (label_ref (match_dup 2))] UNSPEC_CASESI))
9085 (clobber (match_dup 3))])
9086 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9087 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9090 [(set (match_operand:SI 0 "register_operand" "")
9091 (unspec:SI [(match_operand:SI 1 "register_operand" "")
9092 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9093 (clobber (match_scratch:SI 3 ""))
9094 (clobber (match_scratch:SI 4 ""))]
9095 "TARGET_SH2 && reload_completed"
9096 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9097 (parallel [(set (match_dup 0)
9098 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9099 (label_ref (match_dup 2))] UNSPEC_CASESI))
9100 (clobber (match_dup 3))])]
9101 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9103 (define_insn "casesi_worker_1"
9104 [(set (match_operand:SI 0 "register_operand" "=r,r")
9105 (unspec:SI [(reg:SI R0_REG)
9106 (match_operand:SI 1 "register_operand" "0,r")
9107 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9108 (clobber (match_scratch:SI 3 "=X,1"))]
9112 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9114 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9116 switch (GET_MODE (diff_vec))
9119 return \"shll2 %1\;mov.l @(r0,%1),%0\";
9121 return \"add %1,%1\;mov.w @(r0,%1),%0\";
9123 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9124 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9125 return \"mov.b @(r0,%1),%0\";
9130 [(set_attr "length" "4")])
9132 (define_insn "casesi_worker_2"
9133 [(set (match_operand:SI 0 "register_operand" "=r,r")
9134 (unspec:SI [(reg:SI R0_REG)
9135 (match_operand:SI 1 "register_operand" "0,r")
9136 (label_ref (match_operand 2 "" ""))
9137 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9138 (clobber (match_operand:SI 4 "" "=X,1"))]
9139 "TARGET_SH2 && reload_completed && flag_pic"
9142 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9145 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9147 switch (GET_MODE (diff_vec))
9150 output_asm_insn (\"shll2 %1\", operands);
9151 load = \"mov.l @(r0,%1),%0\"; break;
9153 output_asm_insn (\"add %1,%1\", operands);
9154 load = \"mov.w @(r0,%1),%0\"; break;
9156 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9157 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
9159 load = \"mov.b @(r0,%1),%0\";
9164 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9167 [(set_attr "length" "8")])
9169 (define_insn "casesi_shift_media"
9170 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9171 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9172 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9177 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9179 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9181 switch (GET_MODE (diff_vec))
9184 return \"shlli %1, 2, %0\";
9186 return \"shlli %1, 1, %0\";
9188 if (rtx_equal_p (operands[0], operands[1]))
9190 return \"add %1, r63, %0\";
9195 [(set_attr "type" "arith_media")])
9197 (define_insn "casesi_load_media"
9198 [(set (match_operand 0 "any_arith_reg_dest" "=r")
9199 (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9200 (match_operand:DI 2 "arith_reg_operand" "r")
9201 (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9205 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9207 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9209 switch (GET_MODE (diff_vec))
9212 return \"ldx.l %1, %2, %0\";
9215 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9216 return \"ldx.uw %1, %2, %0\";
9218 return \"ldx.w %1, %2, %0\";
9220 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9221 return \"ldx.ub %1, %2, %0\";
9222 return \"ldx.b %1, %2, %0\";
9227 [(set_attr "type" "load_media")])
9229 (define_expand "return"
9231 "reload_completed && ! sh_need_epilogue ()"
9236 emit_jump_insn (gen_return_media ());
9240 if (TARGET_SHCOMPACT
9241 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9243 emit_jump_insn (gen_shcompact_return_tramp ());
9248 (define_insn "*return_i"
9250 "TARGET_SH1 && ! (TARGET_SHCOMPACT
9251 && (crtl->args.info.call_cookie
9252 & CALL_COOKIE_RET_TRAMP (1)))
9254 && lookup_attribute (\"trap_exit\",
9255 DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9258 if (TARGET_SH2A && (dbr_sequence_length () == 0)
9259 && !current_function_interrupt)
9264 [(set_attr "type" "return")
9265 (set_attr "needs_delay_slot" "yes")])
9267 ;; trapa has no delay slot.
9268 (define_insn "*return_trapa"
9270 "TARGET_SH1 && !TARGET_SHCOMPACT
9271 && reload_completed"
9273 [(set_attr "type" "return")])
9275 (define_expand "shcompact_return_tramp"
9278 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9281 rtx reg = gen_rtx_REG (Pmode, R0_REG);
9283 function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9284 emit_jump_insn (gen_shcompact_return_tramp_i ());
9288 (define_insn "shcompact_return_tramp_i"
9289 [(parallel [(return) (use (reg:SI R0_REG))])]
9291 && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9293 [(set_attr "type" "jump_ind")
9294 (set_attr "needs_delay_slot" "yes")])
9296 (define_insn "return_media_i"
9297 [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9298 "TARGET_SHMEDIA && reload_completed"
9300 [(set_attr "type" "jump_media")])
9302 (define_insn "return_media_rte"
9304 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9306 [(set_attr "type" "jump_media")])
9308 (define_expand "return_media"
9310 "TARGET_SHMEDIA && reload_completed"
9313 int tr_regno = sh_media_register_for_return ();
9316 if (current_function_interrupt)
9318 emit_jump_insn (gen_return_media_rte ());
9323 rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9325 gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9327 tr = gen_rtx_REG (Pmode, tr_regno);
9328 emit_move_insn (tr, r18);
9331 tr = gen_rtx_REG (Pmode, tr_regno);
9333 emit_jump_insn (gen_return_media_i (tr));
9337 (define_insn "shcompact_preserve_incoming_args"
9338 [(set (match_operand:SI 0 "register_operand" "+r")
9339 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9342 [(set_attr "length" "0")])
9344 (define_insn "shcompact_incoming_args"
9345 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9346 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9347 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9348 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9349 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9350 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9351 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9352 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9353 (set (mem:BLK (reg:SI MACL_REG))
9354 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9355 (use (reg:SI R0_REG))
9356 (clobber (reg:SI R0_REG))
9357 (clobber (reg:SI MACL_REG))
9358 (clobber (reg:SI MACH_REG))
9359 (clobber (reg:SI PR_REG))]
9362 [(set_attr "needs_delay_slot" "yes")])
9364 (define_insn "shmedia_save_restore_regs_compact"
9365 [(set (reg:SI SP_REG)
9366 (plus:SI (reg:SI SP_REG)
9367 (match_operand:SI 0 "immediate_operand" "i")))
9368 (use (reg:SI R0_REG))
9369 (clobber (reg:SI PR_REG))]
9371 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9372 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9374 [(set_attr "needs_delay_slot" "yes")])
9376 (define_expand "prologue"
9379 "sh_expand_prologue (); DONE;")
9381 (define_expand "epilogue"
9386 sh_expand_epilogue (0);
9387 emit_jump_insn (gen_return ());
9391 (define_expand "eh_return"
9392 [(use (match_operand 0 "register_operand" ""))]
9395 rtx ra = operands[0];
9397 if (TARGET_SHMEDIA64)
9398 emit_insn (gen_eh_set_ra_di (ra));
9400 emit_insn (gen_eh_set_ra_si (ra));
9405 ;; Clobber the return address on the stack. We can't expand this
9406 ;; until we know where it will be put in the stack frame.
9408 (define_insn "eh_set_ra_si"
9409 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9411 (clobber (match_scratch:SI 1 "=&r"))]
9412 "! TARGET_SHMEDIA64"
9415 (define_insn "eh_set_ra_di"
9416 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9418 (clobber (match_scratch:DI 1 "=&r"))]
9423 [(unspec_volatile [(match_operand 0 "register_operand" "")]
9425 (clobber (match_scratch 1 ""))]
9430 sh_set_return_address (operands[0], operands[1]);
9434 (define_insn "blockage"
9435 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9438 [(set_attr "length" "0")])
9440 ;; Define movml instructions for SH2A target. Currently they are
9441 ;; used to push and pop all banked registers only.
9443 (define_insn "movml_push_banked"
9444 [(set (match_operand:SI 0 "register_operand" "=r")
9445 (plus (match_dup 0) (const_int -32)))
9446 (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9447 (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9448 (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9449 (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9450 (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9451 (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9452 (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9453 (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9454 "TARGET_SH2A && REGNO (operands[0]) == 15"
9456 [(set_attr "in_delay_slot" "no")])
9458 (define_insn "movml_pop_banked"
9459 [(set (match_operand:SI 0 "register_operand" "=r")
9460 (plus (match_dup 0) (const_int 32)))
9461 (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9462 (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9463 (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9464 (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9465 (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9466 (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9467 (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9468 (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9469 "TARGET_SH2A && REGNO (operands[0]) == 15"
9471 [(set_attr "in_delay_slot" "no")])
9473 ;; ------------------------------------------------------------------------
9475 ;; ------------------------------------------------------------------------
9478 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9479 (eq:SI (reg:SI T_REG) (const_int 1)))]
9482 [(set_attr "type" "arith")])
9484 (define_expand "cstore4_media"
9485 [(set (match_operand:SI 0 "register_operand" "=r")
9486 (match_operator:SI 1 "sh_float_comparison_operator"
9487 [(match_operand 2 "logical_operand" "")
9488 (match_operand 3 "cmp_operand" "")]))]
9492 enum machine_mode mode = GET_MODE (operands[2]);
9493 enum rtx_code code = GET_CODE (operands[1]);
9495 if (mode == VOIDmode)
9496 mode = GET_MODE (operands[3]);
9497 if (operands[2] == const0_rtx)
9499 if (code == EQ || code == NE)
9500 operands[2] = operands[3], operands[3] = const0_rtx;
9503 operands[2] = force_reg (mode, operands[2]);
9504 if (operands[3] != const0_rtx)
9505 operands[3] = force_reg (mode, operands[3]);
9511 swap = invert = !FLOAT_MODE_P (mode);
9516 swap = FLOAT_MODE_P (mode), invert = !swap;
9521 swap = true, invert = false;
9528 swap = invert = false;
9532 swap = invert = true;
9541 rtx tem = operands[2];
9542 operands[2] = operands[3];
9544 code = swap_condition (code);
9549 rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9550 code = reverse_condition (code);
9551 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9552 emit_insn (gen_cstore4_media (tem, operands[1],
9553 operands[2], operands[3]));
9556 operands[3] = const0_rtx;
9559 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9562 (define_expand "cstoresi4"
9563 [(set (match_operand:SI 0 "register_operand" "=r")
9564 (match_operator:SI 1 "comparison_operator"
9565 [(match_operand:SI 2 "cmpsi_operand" "")
9566 (match_operand:SI 3 "arith_operand" "")]))]
9567 "TARGET_SH1 || TARGET_SHMEDIA"
9568 "if (TARGET_SHMEDIA)
9570 emit_insn (gen_cstore4_media (operands[0], operands[1],
9571 operands[2], operands[3]));
9575 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9576 && sh_expand_t_scc (operands))
9579 if (! currently_expanding_to_rtl)
9582 sh_emit_compare_and_set (operands, SImode);
9586 (define_expand "cstoredi4"
9587 [(set (match_operand:SI 0 "register_operand" "=r")
9588 (match_operator:SI 1 "comparison_operator"
9589 [(match_operand:DI 2 "arith_operand" "")
9590 (match_operand:DI 3 "arith_operand" "")]))]
9591 "TARGET_SH2 || TARGET_SHMEDIA"
9592 "if (TARGET_SHMEDIA)
9594 emit_insn (gen_cstore4_media (operands[0], operands[1],
9595 operands[2], operands[3]));
9599 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9600 && sh_expand_t_scc (operands))
9603 if (! currently_expanding_to_rtl)
9606 sh_emit_compare_and_set (operands, DImode);
9612 ;; sne moves the complement of the T reg to DEST like this:
9616 ;; This is better than xoring compare result with 1 because it does
9617 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
9620 (define_expand "movnegt"
9621 [(set (match_dup 1) (const_int -1))
9622 (parallel [(set (match_operand:SI 0 "" "")
9623 (neg:SI (plus:SI (reg:SI T_REG)
9626 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9631 operands[1] = gen_reg_rtx (SImode);
9635 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9636 ;; This prevents a regression that occurred when we switched from xor to
9640 [(set (match_operand:SI 0 "arith_reg_dest" "")
9641 (plus:SI (reg:SI T_REG)
9644 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9645 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9648 (define_expand "cstoresf4"
9649 [(set (match_operand:SI 0 "register_operand" "=r")
9650 (match_operator:SI 1 "sh_float_comparison_operator"
9651 [(match_operand:SF 2 "arith_operand" "")
9652 (match_operand:SF 3 "arith_operand" "")]))]
9653 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9654 "if (TARGET_SHMEDIA)
9656 emit_insn (gen_cstore4_media (operands[0], operands[1],
9657 operands[2], operands[3]));
9661 if (! currently_expanding_to_rtl)
9664 sh_emit_compare_and_set (operands, SFmode);
9668 (define_expand "cstoredf4"
9669 [(set (match_operand:SI 0 "register_operand" "=r")
9670 (match_operator:SI 1 "sh_float_comparison_operator"
9671 [(match_operand:DF 2 "arith_operand" "")
9672 (match_operand:DF 3 "arith_operand" "")]))]
9673 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9674 "if (TARGET_SHMEDIA)
9676 emit_insn (gen_cstore4_media (operands[0], operands[1],
9677 operands[2], operands[3]));
9681 if (! currently_expanding_to_rtl)
9684 sh_emit_compare_and_set (operands, DFmode);
9689 ;; -------------------------------------------------------------------------
9690 ;; Instructions to cope with inline literal tables
9691 ;; -------------------------------------------------------------------------
9693 ; 2 byte integer in line
9695 (define_insn "consttable_2"
9696 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9697 (match_operand 1 "" "")]
9702 if (operands[1] != const0_rtx)
9703 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9706 [(set_attr "length" "2")
9707 (set_attr "in_delay_slot" "no")])
9709 ; 4 byte integer in line
9711 (define_insn "consttable_4"
9712 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9713 (match_operand 1 "" "")]
9718 if (operands[1] != const0_rtx)
9720 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9721 mark_symbol_refs_as_used (operands[0]);
9725 [(set_attr "length" "4")
9726 (set_attr "in_delay_slot" "no")])
9728 ; 8 byte integer in line
9730 (define_insn "consttable_8"
9731 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9732 (match_operand 1 "" "")]
9737 if (operands[1] != const0_rtx)
9738 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9741 [(set_attr "length" "8")
9742 (set_attr "in_delay_slot" "no")])
9744 ; 4 byte floating point
9746 (define_insn "consttable_sf"
9747 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9748 (match_operand 1 "" "")]
9753 if (operands[1] != const0_rtx)
9756 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9757 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9761 [(set_attr "length" "4")
9762 (set_attr "in_delay_slot" "no")])
9764 ; 8 byte floating point
9766 (define_insn "consttable_df"
9767 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9768 (match_operand 1 "" "")]
9773 if (operands[1] != const0_rtx)
9776 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9777 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9781 [(set_attr "length" "8")
9782 (set_attr "in_delay_slot" "no")])
9784 ;; Alignment is needed for some constant tables; it may also be added for
9785 ;; Instructions at the start of loops, or after unconditional branches.
9786 ;; ??? We would get more accurate lengths if we did instruction
9787 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9788 ;; here is too conservative.
9790 ; align to a two byte boundary
9792 (define_expand "align_2"
9793 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9797 ; align to a four byte boundary
9798 ;; align_4 and align_log are instructions for the starts of loops, or
9799 ;; after unconditional branches, which may take up extra room.
9801 (define_expand "align_4"
9802 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9806 ; align to a cache line boundary
9808 (define_insn "align_log"
9809 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9812 [(set_attr "length" "0")
9813 (set_attr "in_delay_slot" "no")])
9815 ; emitted at the end of the literal table, used to emit the
9816 ; 32bit branch labels if needed.
9818 (define_insn "consttable_end"
9819 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9821 "* return output_jump_label_table ();"
9822 [(set_attr "in_delay_slot" "no")])
9824 ; emitted at the end of the window in the literal table.
9826 (define_insn "consttable_window_end"
9827 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9830 [(set_attr "length" "0")
9831 (set_attr "in_delay_slot" "no")])
9833 ;; -------------------------------------------------------------------------
9835 ;; -------------------------------------------------------------------------
9837 ;; String/block move insn.
9839 (define_expand "movmemsi"
9840 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9841 (mem:BLK (match_operand:BLK 1 "" "")))
9842 (use (match_operand:SI 2 "nonmemory_operand" ""))
9843 (use (match_operand:SI 3 "immediate_operand" ""))
9844 (clobber (reg:SI PR_REG))
9845 (clobber (reg:SI R4_REG))
9846 (clobber (reg:SI R5_REG))
9847 (clobber (reg:SI R0_REG))])]
9848 "TARGET_SH1 && ! TARGET_SH5"
9851 if(expand_block_move (operands))
9856 (define_insn "block_move_real"
9857 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9858 (mem:BLK (reg:SI R5_REG)))
9859 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9860 (clobber (reg:SI PR_REG))
9861 (clobber (reg:SI R0_REG))])]
9862 "TARGET_SH1 && ! TARGET_HARD_SH4"
9864 [(set_attr "type" "sfunc")
9865 (set_attr "needs_delay_slot" "yes")])
9867 (define_insn "block_lump_real"
9868 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9869 (mem:BLK (reg:SI R5_REG)))
9870 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9871 (use (reg:SI R6_REG))
9872 (clobber (reg:SI PR_REG))
9873 (clobber (reg:SI T_REG))
9874 (clobber (reg:SI R4_REG))
9875 (clobber (reg:SI R5_REG))
9876 (clobber (reg:SI R6_REG))
9877 (clobber (reg:SI R0_REG))])]
9878 "TARGET_SH1 && ! TARGET_HARD_SH4"
9880 [(set_attr "type" "sfunc")
9881 (set_attr "needs_delay_slot" "yes")])
9883 (define_insn "block_move_real_i4"
9884 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9885 (mem:BLK (reg:SI R5_REG)))
9886 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9887 (clobber (reg:SI PR_REG))
9888 (clobber (reg:SI R0_REG))
9889 (clobber (reg:SI R1_REG))
9890 (clobber (reg:SI R2_REG))])]
9893 [(set_attr "type" "sfunc")
9894 (set_attr "needs_delay_slot" "yes")])
9896 (define_insn "block_lump_real_i4"
9897 [(parallel [(set (mem:BLK (reg:SI R4_REG))
9898 (mem:BLK (reg:SI R5_REG)))
9899 (use (match_operand:SI 0 "arith_reg_operand" "r"))
9900 (use (reg:SI R6_REG))
9901 (clobber (reg:SI PR_REG))
9902 (clobber (reg:SI T_REG))
9903 (clobber (reg:SI R4_REG))
9904 (clobber (reg:SI R5_REG))
9905 (clobber (reg:SI R6_REG))
9906 (clobber (reg:SI R0_REG))
9907 (clobber (reg:SI R1_REG))
9908 (clobber (reg:SI R2_REG))
9909 (clobber (reg:SI R3_REG))])]
9912 [(set_attr "type" "sfunc")
9913 (set_attr "needs_delay_slot" "yes")])
9915 ;; -------------------------------------------------------------------------
9916 ;; Floating point instructions.
9917 ;; -------------------------------------------------------------------------
9919 ;; ??? All patterns should have a type attribute.
9921 (define_expand "movpsi"
9922 [(set (match_operand:PSI 0 "register_operand" "")
9923 (match_operand:PSI 1 "general_movsrc_operand" ""))]
9924 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9927 ;; The c / m alternative is a fake to guide reload to load directly into
9928 ;; fpscr, since reload doesn't know how to use post-increment.
9929 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9930 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9931 ;; predicate after reload.
9932 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9933 ;; like a mac -> gpr move.
9934 (define_insn "fpu_switch"
9935 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9936 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9938 && (! reload_completed
9939 || true_regnum (operands[0]) != FPSCR_REG
9940 || !MEM_P (operands[1])
9941 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9943 ! precision stays the same
9952 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9953 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9956 [(set (reg:PSI FPSCR_REG)
9957 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9958 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9961 rtx fpscr, mem, new_insn;
9963 fpscr = SET_DEST (PATTERN (curr_insn));
9964 mem = SET_SRC (PATTERN (curr_insn));
9965 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9967 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9968 add_reg_note (new_insn, REG_INC, operands[0]);
9973 [(set (reg:PSI FPSCR_REG)
9974 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9975 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9976 && (flag_peephole2 ? epilogue_completed : reload_completed)"
9979 rtx fpscr, mem, new_insn;
9981 fpscr = SET_DEST (PATTERN (curr_insn));
9982 mem = SET_SRC (PATTERN (curr_insn));
9983 mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9985 new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9986 add_reg_note (new_insn, REG_INC, operands[0]);
9988 if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9989 emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9993 ;; ??? This uses the fp unit, but has no type indicating that.
9994 ;; If we did that, this would either give a bogus latency or introduce
9995 ;; a bogus FIFO constraint.
9996 ;; Since this insn is currently only used for prologues/epilogues,
9997 ;; it is probably best to claim no function unit, which matches the
9999 (define_insn "toggle_sz"
10000 [(set (reg:PSI FPSCR_REG)
10001 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10002 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10004 [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10006 ;; There's no way we can use it today, since optimize mode switching
10007 ;; doesn't enable us to know from which mode we're switching to the
10008 ;; mode it requests, to tell whether we can use a relative mode switch
10009 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10011 (define_insn "toggle_pr"
10012 [(set (reg:PSI FPSCR_REG)
10013 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10014 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10016 [(set_attr "type" "fpscr_toggle")])
10018 (define_expand "addsf3"
10019 [(set (match_operand:SF 0 "arith_reg_operand" "")
10020 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10021 (match_operand:SF 2 "arith_reg_operand" "")))]
10022 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10027 expand_sf_binop (&gen_addsf3_i, operands);
10032 (define_insn "*addsf3_media"
10033 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10034 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10035 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10036 "TARGET_SHMEDIA_FPU"
10037 "fadd.s %1, %2, %0"
10038 [(set_attr "type" "fparith_media")])
10040 (define_insn_and_split "unary_sf_op"
10041 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10046 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10047 (match_operator:SF 2 "unary_float_operator"
10048 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10049 (parallel [(match_operand 4
10050 "const_int_operand" "n")]))]))
10051 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10052 "TARGET_SHMEDIA_FPU"
10054 "TARGET_SHMEDIA_FPU && reload_completed"
10055 [(set (match_dup 5) (match_dup 6))]
10058 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10059 rtx op1 = gen_rtx_REG (SFmode,
10060 (true_regnum (operands[1])
10061 + (INTVAL (operands[4]) ^ endian)));
10063 operands[7] = gen_rtx_REG (SFmode,
10064 (true_regnum (operands[0])
10065 + (INTVAL (operands[3]) ^ endian)));
10066 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10068 [(set_attr "type" "fparith_media")])
10070 (define_insn_and_split "binary_sf_op0"
10071 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10073 (match_operator:SF 3 "binary_float_operator"
10074 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10075 (parallel [(const_int 0)]))
10076 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10077 (parallel [(const_int 0)]))])
10080 (parallel [(const_int 1)]))))]
10081 "TARGET_SHMEDIA_FPU"
10083 "&& reload_completed"
10084 [(set (match_dup 4) (match_dup 5))]
10087 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10088 rtx op1 = gen_rtx_REG (SFmode,
10089 true_regnum (operands[1]) + endian);
10090 rtx op2 = gen_rtx_REG (SFmode,
10091 true_regnum (operands[2]) + endian);
10093 operands[4] = gen_rtx_REG (SFmode,
10094 true_regnum (operands[0]) + endian);
10095 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10097 [(set_attr "type" "fparith_media")])
10099 (define_insn_and_split "binary_sf_op1"
10100 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10104 (parallel [(const_int 0)]))
10105 (match_operator:SF 3 "binary_float_operator"
10106 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10107 (parallel [(const_int 1)]))
10108 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10109 (parallel [(const_int 1)]))])))]
10110 "TARGET_SHMEDIA_FPU"
10112 "&& reload_completed"
10113 [(set (match_dup 4) (match_dup 5))]
10116 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10117 rtx op1 = gen_rtx_REG (SFmode,
10118 true_regnum (operands[1]) + (1 ^ endian));
10119 rtx op2 = gen_rtx_REG (SFmode,
10120 true_regnum (operands[2]) + (1 ^ endian));
10122 operands[4] = gen_rtx_REG (SFmode,
10123 true_regnum (operands[0]) + (1 ^ endian));
10124 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10126 [(set_attr "type" "fparith_media")])
10128 (define_insn "addsf3_i"
10129 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10130 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10131 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10132 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10135 [(set_attr "type" "fp")
10136 (set_attr "fp_mode" "single")])
10138 (define_expand "subsf3"
10139 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10140 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10141 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10142 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10147 expand_sf_binop (&gen_subsf3_i, operands);
10152 (define_insn "*subsf3_media"
10153 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10154 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10155 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10156 "TARGET_SHMEDIA_FPU"
10157 "fsub.s %1, %2, %0"
10158 [(set_attr "type" "fparith_media")])
10160 (define_insn "subsf3_i"
10161 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10162 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10163 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10164 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10167 [(set_attr "type" "fp")
10168 (set_attr "fp_mode" "single")])
10170 (define_expand "mulsf3"
10171 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10172 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10173 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10174 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10177 (define_insn "*mulsf3_media"
10178 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10179 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10180 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10181 "TARGET_SHMEDIA_FPU"
10182 "fmul.s %1, %2, %0"
10183 [(set_attr "type" "fparith_media")])
10185 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10186 ;; register in feeding fp instructions. Thus, in order to generate fmac,
10187 ;; we start out with a mulsf pattern that does not depend on fpscr.
10188 ;; This is split after combine to introduce the dependency, in order to
10189 ;; get mode switching and scheduling right.
10190 (define_insn_and_split "mulsf3_ie"
10191 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10192 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10193 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10196 "TARGET_SH4 || TARGET_SH2A_SINGLE"
10200 emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10201 get_fpscr_rtx ()));
10204 [(set_attr "type" "fp")])
10206 (define_insn "mulsf3_i4"
10207 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10208 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10209 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10210 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10213 [(set_attr "type" "fp")
10214 (set_attr "fp_mode" "single")])
10216 (define_insn "mac_media"
10217 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10218 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10219 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10220 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10221 "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10222 "fmac.s %1, %2, %0"
10223 [(set_attr "type" "fparith_media")])
10225 (define_insn "*macsf3"
10226 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10227 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10228 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10229 (match_operand:SF 3 "arith_reg_operand" "0")))
10230 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10231 "TARGET_SH2E && TARGET_FMAC"
10233 [(set_attr "type" "fp")
10234 (set_attr "fp_mode" "single")])
10236 (define_expand "divsf3"
10237 [(set (match_operand:SF 0 "arith_reg_operand" "")
10238 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10239 (match_operand:SF 2 "arith_reg_operand" "")))]
10240 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10245 expand_sf_binop (&gen_divsf3_i, operands);
10250 (define_insn "*divsf3_media"
10251 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10252 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10253 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10254 "TARGET_SHMEDIA_FPU"
10255 "fdiv.s %1, %2, %0"
10256 [(set_attr "type" "fdiv_media")])
10258 (define_insn "divsf3_i"
10259 [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10260 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10261 (match_operand:SF 2 "arith_reg_operand" "f")))
10262 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10265 [(set_attr "type" "fdiv")
10266 (set_attr "fp_mode" "single")])
10268 (define_insn "floatdisf2"
10269 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10270 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10271 "TARGET_SHMEDIA_FPU"
10273 [(set_attr "type" "fpconv_media")])
10275 (define_expand "floatsisf2"
10276 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10277 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10278 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10281 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10283 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10288 (define_insn "*floatsisf2_media"
10289 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10290 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10291 "TARGET_SHMEDIA_FPU"
10293 [(set_attr "type" "fpconv_media")])
10295 (define_insn "floatsisf2_i4"
10296 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10297 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10298 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10299 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10301 [(set_attr "type" "fp")
10302 (set_attr "fp_mode" "single")])
10304 (define_insn "*floatsisf2_ie"
10305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10307 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10309 [(set_attr "type" "fp")])
10311 (define_insn "fix_truncsfdi2"
10312 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10313 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10314 "TARGET_SHMEDIA_FPU"
10316 [(set_attr "type" "fpconv_media")])
10318 (define_expand "fix_truncsfsi2"
10319 [(set (match_operand:SI 0 "fpul_operand" "=y")
10320 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10321 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10324 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10326 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10331 (define_insn "*fix_truncsfsi2_media"
10332 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10333 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10334 "TARGET_SHMEDIA_FPU"
10336 [(set_attr "type" "fpconv_media")])
10338 (define_insn "fix_truncsfsi2_i4"
10339 [(set (match_operand:SI 0 "fpul_operand" "=y")
10340 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10341 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10342 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10344 [(set_attr "type" "ftrc_s")
10345 (set_attr "fp_mode" "single")])
10347 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
10348 ;; fix_truncsfsi2_i4.
10349 ;; (define_insn "fix_truncsfsi2_i4_2"
10350 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10351 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10352 ;; (use (reg:PSI FPSCR_REG))
10353 ;; (clobber (reg:SI FPUL_REG))]
10356 ;; [(set_attr "length" "4")
10357 ;; (set_attr "fp_mode" "single")])
10360 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10361 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10362 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10363 ;; (clobber (reg:SI FPUL_REG))]
10365 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10366 ;; (use (match_dup 2))])
10367 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10369 (define_insn "*fixsfsi"
10370 [(set (match_operand:SI 0 "fpul_operand" "=y")
10371 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10372 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10374 [(set_attr "type" "fp")])
10376 (define_insn "cmpgtsf_t"
10377 [(set (reg:SI T_REG)
10378 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10379 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10380 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10382 [(set_attr "type" "fp_cmp")
10383 (set_attr "fp_mode" "single")])
10385 (define_insn "cmpeqsf_t"
10386 [(set (reg:SI T_REG)
10387 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10388 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10389 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10391 [(set_attr "type" "fp_cmp")
10392 (set_attr "fp_mode" "single")])
10394 (define_insn "ieee_ccmpeqsf_t"
10395 [(set (reg:SI T_REG)
10396 (ior:SI (reg:SI T_REG)
10397 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10398 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10399 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10400 "* return output_ieee_ccmpeq (insn, operands);"
10401 [(set_attr "length" "4")])
10404 (define_insn "cmpgtsf_t_i4"
10405 [(set (reg:SI T_REG)
10406 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10407 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10408 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10409 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10411 [(set_attr "type" "fp_cmp")
10412 (set_attr "fp_mode" "single")])
10414 (define_insn "cmpeqsf_t_i4"
10415 [(set (reg:SI T_REG)
10416 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10417 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10418 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10419 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10421 [(set_attr "type" "fp_cmp")
10422 (set_attr "fp_mode" "single")])
10424 (define_insn "*ieee_ccmpeqsf_t_4"
10425 [(set (reg:SI T_REG)
10426 (ior:SI (reg:SI T_REG)
10427 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10428 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10429 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10430 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10431 "* return output_ieee_ccmpeq (insn, operands);"
10432 [(set_attr "length" "4")
10433 (set_attr "fp_mode" "single")])
10435 (define_insn "cmpeqsf_media"
10436 [(set (match_operand:SI 0 "register_operand" "=r")
10437 (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10438 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10439 "TARGET_SHMEDIA_FPU"
10440 "fcmpeq.s %1, %2, %0"
10441 [(set_attr "type" "fcmp_media")])
10443 (define_insn "cmpgtsf_media"
10444 [(set (match_operand:SI 0 "register_operand" "=r")
10445 (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10446 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10447 "TARGET_SHMEDIA_FPU"
10448 "fcmpgt.s %1, %2, %0"
10449 [(set_attr "type" "fcmp_media")])
10451 (define_insn "cmpgesf_media"
10452 [(set (match_operand:SI 0 "register_operand" "=r")
10453 (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10454 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10455 "TARGET_SHMEDIA_FPU"
10456 "fcmpge.s %1, %2, %0"
10457 [(set_attr "type" "fcmp_media")])
10459 (define_insn "cmpunsf_media"
10460 [(set (match_operand:SI 0 "register_operand" "=r")
10461 (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10462 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10463 "TARGET_SHMEDIA_FPU"
10464 "fcmpun.s %1, %2, %0"
10465 [(set_attr "type" "fcmp_media")])
10467 (define_expand "cbranchsf4"
10469 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10470 [(match_operand:SF 1 "arith_operand" "")
10471 (match_operand:SF 2 "arith_operand" "")])
10472 (match_operand 3 "" "")
10474 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10477 if (TARGET_SHMEDIA)
10478 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10481 sh_emit_compare_and_branch (operands, SFmode);
10485 (define_expand "negsf2"
10486 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10487 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10488 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10493 expand_sf_unop (&gen_negsf2_i, operands);
10498 (define_insn "*negsf2_media"
10499 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10500 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10501 "TARGET_SHMEDIA_FPU"
10503 [(set_attr "type" "fmove_media")])
10505 (define_insn "negsf2_i"
10506 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10507 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10508 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10511 [(set_attr "type" "fmove")
10512 (set_attr "fp_mode" "single")])
10514 (define_expand "sqrtsf2"
10515 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10516 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10517 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10522 expand_sf_unop (&gen_sqrtsf2_i, operands);
10527 (define_insn "*sqrtsf2_media"
10528 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10529 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10530 "TARGET_SHMEDIA_FPU"
10532 [(set_attr "type" "fdiv_media")])
10534 (define_insn "sqrtsf2_i"
10535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10537 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10540 [(set_attr "type" "fdiv")
10541 (set_attr "fp_mode" "single")])
10543 (define_insn "rsqrtsf2"
10544 [(set (match_operand:SF 0 "register_operand" "=f")
10545 (div:SF (match_operand:SF 1 "immediate_operand" "i")
10546 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10547 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10548 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10549 && operands[1] == CONST1_RTX (SFmode)"
10551 [(set_attr "type" "fsrra")
10552 (set_attr "fp_mode" "single")])
10554 (define_insn "fsca"
10555 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10557 (unspec:SF [(mult:SF
10558 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10559 (match_operand:SF 2 "immediate_operand" "i"))
10561 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10563 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10564 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10565 && operands[2] == sh_fsca_int2sf ()"
10567 [(set_attr "type" "fsca")
10568 (set_attr "fp_mode" "single")])
10570 (define_expand "sinsf2"
10571 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10572 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10574 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10577 rtx scaled = gen_reg_rtx (SFmode);
10578 rtx truncated = gen_reg_rtx (SImode);
10579 rtx fsca = gen_reg_rtx (V2SFmode);
10580 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10582 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10583 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10584 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10585 get_fpscr_rtx ()));
10586 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10590 (define_expand "cossf2"
10591 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10592 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10594 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10597 rtx scaled = gen_reg_rtx (SFmode);
10598 rtx truncated = gen_reg_rtx (SImode);
10599 rtx fsca = gen_reg_rtx (V2SFmode);
10600 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10602 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10603 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10604 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10605 get_fpscr_rtx ()));
10606 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10610 (define_expand "sindf2"
10611 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10612 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10614 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10617 rtx scaled = gen_reg_rtx (DFmode);
10618 rtx truncated = gen_reg_rtx (SImode);
10619 rtx fsca = gen_reg_rtx (V2SFmode);
10620 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10621 rtx sfresult = gen_reg_rtx (SFmode);
10623 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10624 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10625 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10626 get_fpscr_rtx ()));
10627 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10628 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10632 (define_expand "cosdf2"
10633 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10634 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10636 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10639 rtx scaled = gen_reg_rtx (DFmode);
10640 rtx truncated = gen_reg_rtx (SImode);
10641 rtx fsca = gen_reg_rtx (V2SFmode);
10642 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10643 rtx sfresult = gen_reg_rtx (SFmode);
10645 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10646 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10647 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10648 get_fpscr_rtx ()));
10649 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10650 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10654 (define_expand "abssf2"
10655 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10656 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10657 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10662 expand_sf_unop (&gen_abssf2_i, operands);
10667 (define_insn "*abssf2_media"
10668 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10669 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10670 "TARGET_SHMEDIA_FPU"
10672 [(set_attr "type" "fmove_media")])
10674 (define_insn "abssf2_i"
10675 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10676 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10677 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10680 [(set_attr "type" "fmove")
10681 (set_attr "fp_mode" "single")])
10683 (define_expand "adddf3"
10684 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10685 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10686 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10687 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10690 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10692 expand_df_binop (&gen_adddf3_i, operands);
10697 (define_insn "*adddf3_media"
10698 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10699 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10700 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701 "TARGET_SHMEDIA_FPU"
10702 "fadd.d %1, %2, %0"
10703 [(set_attr "type" "dfparith_media")])
10705 (define_insn "adddf3_i"
10706 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10707 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10708 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10709 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10710 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10712 [(set_attr "type" "dfp_arith")
10713 (set_attr "fp_mode" "double")])
10715 (define_expand "subdf3"
10716 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10717 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10718 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10719 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10722 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10724 expand_df_binop (&gen_subdf3_i, operands);
10729 (define_insn "*subdf3_media"
10730 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10731 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10733 "TARGET_SHMEDIA_FPU"
10734 "fsub.d %1, %2, %0"
10735 [(set_attr "type" "dfparith_media")])
10737 (define_insn "subdf3_i"
10738 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10739 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10741 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10742 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10744 [(set_attr "type" "dfp_arith")
10745 (set_attr "fp_mode" "double")])
10747 (define_expand "muldf3"
10748 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10749 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10750 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10751 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10754 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10756 expand_df_binop (&gen_muldf3_i, operands);
10761 (define_insn "*muldf3_media"
10762 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10763 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10764 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10765 "TARGET_SHMEDIA_FPU"
10766 "fmul.d %1, %2, %0"
10767 [(set_attr "type" "dfmul_media")])
10769 (define_insn "muldf3_i"
10770 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10771 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10772 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10773 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10774 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10776 [(set_attr "type" "dfp_mul")
10777 (set_attr "fp_mode" "double")])
10779 (define_expand "divdf3"
10780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10781 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10782 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10783 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10786 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10788 expand_df_binop (&gen_divdf3_i, operands);
10793 (define_insn "*divdf3_media"
10794 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10795 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10796 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10797 "TARGET_SHMEDIA_FPU"
10798 "fdiv.d %1, %2, %0"
10799 [(set_attr "type" "dfdiv_media")])
10801 (define_insn "divdf3_i"
10802 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10803 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10804 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10805 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10806 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10808 [(set_attr "type" "dfdiv")
10809 (set_attr "fp_mode" "double")])
10811 (define_insn "floatdidf2"
10812 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10813 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10814 "TARGET_SHMEDIA_FPU"
10816 [(set_attr "type" "dfpconv_media")])
10818 (define_expand "floatsidf2"
10819 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10820 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10821 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10824 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10826 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10827 get_fpscr_rtx ()));
10832 (define_insn "*floatsidf2_media"
10833 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10834 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10835 "TARGET_SHMEDIA_FPU"
10837 [(set_attr "type" "dfpconv_media")])
10839 (define_insn "floatsidf2_i"
10840 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10841 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10842 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10843 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10845 [(set_attr "type" "dfp_conv")
10846 (set_attr "fp_mode" "double")])
10848 (define_insn "fix_truncdfdi2"
10849 [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10850 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10851 "TARGET_SHMEDIA_FPU"
10853 [(set_attr "type" "dfpconv_media")])
10855 (define_expand "fix_truncdfsi2"
10856 [(set (match_operand:SI 0 "fpul_operand" "")
10857 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10858 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10861 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10863 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10864 get_fpscr_rtx ()));
10869 (define_insn "*fix_truncdfsi2_media"
10870 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10871 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872 "TARGET_SHMEDIA_FPU"
10874 [(set_attr "type" "dfpconv_media")])
10876 (define_insn "fix_truncdfsi2_i"
10877 [(set (match_operand:SI 0 "fpul_operand" "=y")
10878 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10879 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882 [(set_attr "type" "dfp_conv")
10883 (set_attr "dfp_comp" "no")
10884 (set_attr "fp_mode" "double")])
10886 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
10887 ;; fix_truncdfsi2_i.
10888 ;; (define_insn "fix_truncdfsi2_i4"
10889 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10890 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10891 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10892 ;; (clobber (reg:SI FPUL_REG))]
10895 ;; [(set_attr "length" "4")
10896 ;; (set_attr "fp_mode" "double")])
10899 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10900 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10901 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
10902 ;; (clobber (reg:SI FPUL_REG))]
10904 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10905 ;; (use (match_dup 2))])
10906 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
10908 (define_insn "cmpgtdf_t"
10909 [(set (reg:SI T_REG)
10910 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10911 (match_operand:DF 1 "arith_reg_operand" "f")))
10912 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10913 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10915 [(set_attr "type" "dfp_cmp")
10916 (set_attr "fp_mode" "double")])
10918 (define_insn "cmpeqdf_t"
10919 [(set (reg:SI T_REG)
10920 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10921 (match_operand:DF 1 "arith_reg_operand" "f")))
10922 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10923 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10925 [(set_attr "type" "dfp_cmp")
10926 (set_attr "fp_mode" "double")])
10928 (define_insn "*ieee_ccmpeqdf_t"
10929 [(set (reg:SI T_REG)
10930 (ior:SI (reg:SI T_REG)
10931 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10932 (match_operand:DF 1 "arith_reg_operand" "f"))))
10933 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10934 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10935 "* return output_ieee_ccmpeq (insn, operands);"
10936 [(set_attr "length" "4")
10937 (set_attr "fp_mode" "double")])
10939 (define_insn "cmpeqdf_media"
10940 [(set (match_operand:SI 0 "register_operand" "=r")
10941 (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10942 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10943 "TARGET_SHMEDIA_FPU"
10944 "fcmpeq.d %1,%2,%0"
10945 [(set_attr "type" "fcmp_media")])
10947 (define_insn "cmpgtdf_media"
10948 [(set (match_operand:SI 0 "register_operand" "=r")
10949 (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10950 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10951 "TARGET_SHMEDIA_FPU"
10952 "fcmpgt.d %1,%2,%0"
10953 [(set_attr "type" "fcmp_media")])
10955 (define_insn "cmpgedf_media"
10956 [(set (match_operand:SI 0 "register_operand" "=r")
10957 (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10958 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10959 "TARGET_SHMEDIA_FPU"
10960 "fcmpge.d %1,%2,%0"
10961 [(set_attr "type" "fcmp_media")])
10963 (define_insn "cmpundf_media"
10964 [(set (match_operand:SI 0 "register_operand" "=r")
10965 (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10966 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10967 "TARGET_SHMEDIA_FPU"
10968 "fcmpun.d %1,%2,%0"
10969 [(set_attr "type" "fcmp_media")])
10971 (define_expand "cbranchdf4"
10973 (if_then_else (match_operator 0 "sh_float_comparison_operator"
10974 [(match_operand:DF 1 "arith_operand" "")
10975 (match_operand:DF 2 "arith_operand" "")])
10976 (match_operand 3 "" "")
10978 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10981 if (TARGET_SHMEDIA)
10982 emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10985 sh_emit_compare_and_branch (operands, DFmode);
10990 (define_expand "negdf2"
10991 [(set (match_operand:DF 0 "arith_reg_operand" "")
10992 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10993 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10996 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10998 expand_df_unop (&gen_negdf2_i, operands);
11003 (define_insn "*negdf2_media"
11004 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11006 "TARGET_SHMEDIA_FPU"
11008 [(set_attr "type" "fmove_media")])
11010 (define_insn "negdf2_i"
11011 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11012 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11013 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11014 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11016 [(set_attr "type" "fmove")
11017 (set_attr "fp_mode" "double")])
11019 (define_expand "sqrtdf2"
11020 [(set (match_operand:DF 0 "arith_reg_operand" "")
11021 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11022 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11025 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11027 expand_df_unop (&gen_sqrtdf2_i, operands);
11032 (define_insn "*sqrtdf2_media"
11033 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11034 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11035 "TARGET_SHMEDIA_FPU"
11037 [(set_attr "type" "dfdiv_media")])
11039 (define_insn "sqrtdf2_i"
11040 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11041 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11042 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11043 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11045 [(set_attr "type" "dfdiv")
11046 (set_attr "fp_mode" "double")])
11048 (define_expand "absdf2"
11049 [(set (match_operand:DF 0 "arith_reg_operand" "")
11050 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11051 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11054 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11056 expand_df_unop (&gen_absdf2_i, operands);
11061 (define_insn "*absdf2_media"
11062 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11063 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11064 "TARGET_SHMEDIA_FPU"
11066 [(set_attr "type" "fmove_media")])
11068 (define_insn "absdf2_i"
11069 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11070 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11071 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11072 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11074 [(set_attr "type" "fmove")
11075 (set_attr "fp_mode" "double")])
11077 (define_expand "extendsfdf2"
11078 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11079 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11080 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11083 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11085 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11086 get_fpscr_rtx ()));
11091 (define_insn "*extendsfdf2_media"
11092 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11093 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11094 "TARGET_SHMEDIA_FPU"
11096 [(set_attr "type" "dfpconv_media")])
11098 (define_insn "extendsfdf2_i4"
11099 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11100 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11101 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11102 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11104 [(set_attr "type" "fp")
11105 (set_attr "fp_mode" "double")])
11107 (define_expand "truncdfsf2"
11108 [(set (match_operand:SF 0 "fpul_operand" "")
11109 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11110 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11113 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11115 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11116 get_fpscr_rtx ()));
11121 (define_insn "*truncdfsf2_media"
11122 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11123 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11124 "TARGET_SHMEDIA_FPU"
11126 [(set_attr "type" "dfpconv_media")])
11128 (define_insn "truncdfsf2_i4"
11129 [(set (match_operand:SF 0 "fpul_operand" "=y")
11130 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11131 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11132 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11134 [(set_attr "type" "fp")
11135 (set_attr "fp_mode" "double")])
11137 ;; Bit field extract patterns. These give better code for packed bitfields,
11138 ;; because they allow auto-increment addresses to be generated.
11140 (define_expand "insv"
11141 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11142 (match_operand:SI 1 "immediate_operand" "")
11143 (match_operand:SI 2 "immediate_operand" ""))
11144 (match_operand:SI 3 "general_operand" ""))]
11145 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11148 rtx addr_target, orig_address, shift_reg, qi_val;
11149 HOST_WIDE_INT bitsize, size, v = 0;
11150 rtx x = operands[3];
11152 if (TARGET_SH2A && TARGET_BITOPS
11153 && (satisfies_constraint_Sbw (operands[0])
11154 || satisfies_constraint_Sbv (operands[0]))
11155 && satisfies_constraint_M (operands[1])
11156 && satisfies_constraint_K03 (operands[2]))
11158 if (satisfies_constraint_N (operands[3]))
11160 emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11163 else if (satisfies_constraint_M (operands[3]))
11165 emit_insn (gen_bset_m2a (operands[0], operands[2]));
11168 else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11169 && satisfies_constraint_M (operands[1]))
11171 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11174 else if (REG_P (operands[3])
11175 && satisfies_constraint_M (operands[1]))
11177 emit_insn (gen_bld_reg (operands[3], const0_rtx));
11178 emit_insn (gen_bst_m2a (operands[0], operands[2]));
11182 /* ??? expmed doesn't care for non-register predicates. */
11183 if (! memory_operand (operands[0], VOIDmode)
11184 || ! immediate_operand (operands[1], VOIDmode)
11185 || ! immediate_operand (operands[2], VOIDmode)
11186 || ! general_operand (x, VOIDmode))
11188 /* If this isn't a 16 / 24 / 32 bit field, or if
11189 it doesn't start on a byte boundary, then fail. */
11190 bitsize = INTVAL (operands[1]);
11191 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11192 || (INTVAL (operands[2]) % 8) != 0)
11195 size = bitsize / 8;
11196 orig_address = XEXP (operands[0], 0);
11197 shift_reg = gen_reg_rtx (SImode);
11198 if (CONST_INT_P (x))
11201 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11205 emit_insn (gen_movsi (shift_reg, operands[3]));
11206 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11208 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11210 operands[0] = replace_equiv_address (operands[0], addr_target);
11211 emit_insn (gen_movqi (operands[0], qi_val));
11215 if (CONST_INT_P (x))
11217 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11220 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11221 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11223 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11224 emit_insn (gen_movqi (operands[0], qi_val));
11230 (define_insn "movua"
11231 [(set (match_operand:SI 0 "register_operand" "=z")
11232 (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11236 [(set_attr "type" "movua")])
11238 ;; We shouldn't need this, but cse replaces increments with references
11239 ;; to other regs before flow has a chance to create post_inc
11240 ;; addressing modes, and only postreload's cse_move2add brings the
11241 ;; increments back to a usable form.
11243 [(set (match_operand:SI 0 "register_operand" "")
11244 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11245 (const_int 32) (const_int 0)))
11246 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11247 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11248 [(set (match_operand:SI 0 "register_operand" "")
11249 (sign_extract:SI (mem:SI (post_inc:SI
11250 (match_operand:SI 1 "register_operand" "")))
11251 (const_int 32) (const_int 0)))]
11254 (define_expand "extv"
11255 [(set (match_operand:SI 0 "register_operand" "")
11256 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11257 (match_operand 2 "const_int_operand" "")
11258 (match_operand 3 "const_int_operand" "")))]
11259 "TARGET_SH4A_ARCH || TARGET_SH2A"
11261 if (TARGET_SH2A && TARGET_BITOPS
11262 && (satisfies_constraint_Sbw (operands[1])
11263 || satisfies_constraint_Sbv (operands[1]))
11264 && satisfies_constraint_M (operands[2])
11265 && satisfies_constraint_K03 (operands[3]))
11267 emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11268 if (REGNO (operands[0]) != T_REG)
11269 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11272 if (TARGET_SH4A_ARCH
11273 && INTVAL (operands[2]) == 32
11274 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11275 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11277 rtx src = adjust_address (operands[1], BLKmode, 0);
11278 set_mem_size (src, 4);
11279 emit_insn (gen_movua (operands[0], src));
11286 (define_expand "extzv"
11287 [(set (match_operand:SI 0 "register_operand" "")
11288 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11289 (match_operand 2 "const_int_operand" "")
11290 (match_operand 3 "const_int_operand" "")))]
11291 "TARGET_SH4A_ARCH || TARGET_SH2A"
11293 if (TARGET_SH2A && TARGET_BITOPS
11294 && (satisfies_constraint_Sbw (operands[1])
11295 || satisfies_constraint_Sbv (operands[1]))
11296 && satisfies_constraint_M (operands[2])
11297 && satisfies_constraint_K03 (operands[3]))
11299 emit_insn (gen_bld_m2a (operands[1], operands[3]));
11300 if (REGNO (operands[0]) != T_REG)
11301 emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11304 if (TARGET_SH4A_ARCH
11305 && INTVAL (operands[2]) == 32
11306 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11307 && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11309 rtx src = adjust_address (operands[1], BLKmode, 0);
11310 set_mem_size (src, 4);
11311 emit_insn (gen_movua (operands[0], src));
11318 ;; SH2A instructions for bitwise operations.
11320 ;; Clear a bit in a memory location.
11321 (define_insn "bclr_m2a"
11322 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11324 (not:QI (ashift:QI (const_int 1)
11325 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11327 "TARGET_SH2A && TARGET_BITOPS"
11330 bclr.b\\t%1,@(0,%t0)"
11331 [(set_attr "length" "4,4")])
11333 (define_insn "bclrmem_m2a"
11334 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11335 (and:QI (match_dup 0)
11336 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11337 "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11340 bclr.b\\t%W1,@(0,%t0)"
11341 [(set_attr "length" "4,4")])
11343 ;; Set a bit in a memory location.
11344 (define_insn "bset_m2a"
11345 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11347 (ashift:QI (const_int 1)
11348 (match_operand:QI 1 "const_int_operand" "K03,K03"))
11350 "TARGET_SH2A && TARGET_BITOPS"
11353 bset.b\\t%1,@(0,%t0)"
11354 [(set_attr "length" "4,4")])
11356 (define_insn "bsetmem_m2a"
11357 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11358 (ior:QI (match_dup 0)
11359 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11360 "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11363 bset.b\\t%V1,@(0,%t0)"
11364 [(set_attr "length" "4,4")])
11366 ;;; Transfer the contents of the T bit to a specified bit of memory.
11367 (define_insn "bst_m2a"
11368 [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11369 (if_then_else (eq (reg:SI T_REG) (const_int 0))
11371 (not:QI (ashift:QI (const_int 1)
11372 (match_operand:QI 1 "const_int_operand" "K03,K03")))
11375 (ashift:QI (const_int 1) (match_dup 1))
11377 "TARGET_SH2A && TARGET_BITOPS"
11380 bst.b\\t%1,@(0,%t0)"
11381 [(set_attr "length" "4")])
11383 ;; Store a specified bit of memory in the T bit.
11384 (define_insn "bld_m2a"
11385 [(set (reg:SI T_REG)
11387 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11389 (match_operand 1 "const_int_operand" "K03,K03")))]
11390 "TARGET_SH2A && TARGET_BITOPS"
11393 bld.b\\t%1,@(0,%t0)"
11394 [(set_attr "length" "4,4")])
11396 ;; Store a specified bit of memory in the T bit.
11397 (define_insn "bldsign_m2a"
11398 [(set (reg:SI T_REG)
11400 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11402 (match_operand 1 "const_int_operand" "K03,K03")))]
11403 "TARGET_SH2A && TARGET_BITOPS"
11406 bld.b\\t%1,@(0,%t0)"
11407 [(set_attr "length" "4,4")])
11409 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11410 (define_insn "bld_reg"
11411 [(set (reg:SI T_REG)
11412 (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11414 (match_operand 1 "const_int_operand" "K03")))]
11418 (define_insn "*bld_regqi"
11419 [(set (reg:SI T_REG)
11420 (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11422 (match_operand 1 "const_int_operand" "K03")))]
11426 ;; Take logical and of a specified bit of memory with the T bit and
11427 ;; store its result in the T bit.
11428 (define_insn "band_m2a"
11429 [(set (reg:SI T_REG)
11430 (and:SI (reg:SI T_REG)
11432 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11434 (match_operand 1 "const_int_operand" "K03,K03"))))]
11435 "TARGET_SH2A && TARGET_BITOPS"
11438 band.b\\t%1,@(0,%t0)"
11439 [(set_attr "length" "4,4")])
11441 (define_insn "bandreg_m2a"
11442 [(set (match_operand:SI 0 "register_operand" "=r,r")
11443 (and:SI (zero_extract:SI
11444 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11446 (match_operand 2 "const_int_operand" "K03,K03"))
11447 (match_operand:SI 3 "register_operand" "r,r")))]
11448 "TARGET_SH2A && TARGET_BITOPS"
11450 band.b\\t%2,%1\;movt\\t%0
11451 band.b\\t%2,@(0,%t1)\;movt\\t%0"
11452 [(set_attr "length" "6,6")])
11454 ;; Take logical or of a specified bit of memory with the T bit and
11455 ;; store its result in the T bit.
11456 (define_insn "bor_m2a"
11457 [(set (reg:SI T_REG)
11458 (ior:SI (reg:SI T_REG)
11460 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11462 (match_operand 1 "const_int_operand" "K03,K03"))))]
11463 "TARGET_SH2A && TARGET_BITOPS"
11466 bor.b\\t%1,@(0,%t0)"
11467 [(set_attr "length" "4,4")])
11469 (define_insn "borreg_m2a"
11470 [(set (match_operand:SI 0 "register_operand" "=r,r")
11471 (ior:SI (zero_extract:SI
11472 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11474 (match_operand 2 "const_int_operand" "K03,K03"))
11475 (match_operand:SI 3 "register_operand" "=r,r")))]
11476 "TARGET_SH2A && TARGET_BITOPS"
11478 bor.b\\t%2,%1\;movt\\t%0
11479 bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11480 [(set_attr "length" "6,6")])
11482 ;; Take exclusive or of a specified bit of memory with the T bit and
11483 ;; store its result in the T bit.
11484 (define_insn "bxor_m2a"
11485 [(set (reg:SI T_REG)
11486 (xor:SI (reg:SI T_REG)
11488 (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11490 (match_operand 1 "const_int_operand" "K03,K03"))))]
11491 "TARGET_SH2A && TARGET_BITOPS"
11494 bxor.b\\t%1,@(0,%t0)"
11495 [(set_attr "length" "4,4")])
11497 (define_insn "bxorreg_m2a"
11498 [(set (match_operand:SI 0 "register_operand" "=r,r")
11499 (xor:SI (zero_extract:SI
11500 (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11502 (match_operand 2 "const_int_operand" "K03,K03"))
11503 (match_operand:SI 3 "register_operand" "=r,r")))]
11504 "TARGET_SH2A && TARGET_BITOPS"
11506 bxor.b\\t%2,%1\;movt\\t%0
11507 bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11508 [(set_attr "length" "6,6")])
11511 ;; -------------------------------------------------------------------------
11513 ;; -------------------------------------------------------------------------
11514 ;; This matches cases where the bit in a memory location is set.
11516 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11517 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11519 (ior:SI (match_dup 0)
11520 (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11522 (match_operand 3 "arith_reg_operand" "r,r"))]
11523 "TARGET_SH2A && TARGET_BITOPS
11524 && satisfies_constraint_Pso (operands[2])
11525 && REGNO (operands[0]) == REGNO (operands[3])"
11526 [(set (match_dup 1)
11527 (ior:QI (match_dup 1)
11531 ;; This matches cases where the bit in a memory location is cleared.
11533 [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11534 (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11536 (and:SI (match_dup 0)
11537 (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11539 (match_operand 3 "arith_reg_operand" "r,r"))]
11540 "TARGET_SH2A && TARGET_BITOPS
11541 && satisfies_constraint_Psz (operands[2])
11542 && REGNO (operands[0]) == REGNO (operands[3])"
11543 [(set (match_dup 1)
11544 (and:QI (match_dup 1)
11548 ;; This matches cases where a stack pointer increment at the start of the
11549 ;; epilogue combines with a stack slot read loading the return value.
11552 [(set (match_operand:SI 0 "arith_reg_operand" "")
11553 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11554 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11555 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11558 ;; See the comment on the dt combiner pattern above.
11561 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11562 (plus:SI (match_dup 0)
11564 (set (reg:SI T_REG)
11565 (eq:SI (match_dup 0)
11570 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11571 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
11572 ;; reload when the constant is too large for a reg+offset address.
11574 ;; ??? We would get much better code if this was done in reload. This would
11575 ;; require modifying find_reloads_address to recognize that if the constant
11576 ;; is out-of-range for an immediate add, then we get better code by reloading
11577 ;; the constant into a register than by reloading the sum into a register,
11578 ;; since the former is one instruction shorter if the address does not need
11579 ;; to be offsettable. Unfortunately this does not work, because there is
11580 ;; only one register, r0, that can be used as an index register. This register
11581 ;; is also the function return value register. So, if we try to force reload
11582 ;; to use double-reg addresses, then we end up with some instructions that
11583 ;; need to use r0 twice. The only way to fix this is to change the calling
11584 ;; convention so that r0 is not used to return values.
11587 [(set (match_operand:SI 0 "register_operand" "=r")
11588 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11589 (set (mem:SI (match_dup 0))
11590 (match_operand:SI 2 "general_movsrc_operand" ""))]
11591 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11592 "mov.l %2,@(%0,%1)")
11595 [(set (match_operand:SI 0 "register_operand" "=r")
11596 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11597 (set (match_operand:SI 2 "general_movdst_operand" "")
11598 (mem:SI (match_dup 0)))]
11599 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11600 "mov.l @(%0,%1),%2")
11603 [(set (match_operand:SI 0 "register_operand" "=r")
11604 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11605 (set (mem:HI (match_dup 0))
11606 (match_operand:HI 2 "general_movsrc_operand" ""))]
11607 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11608 "mov.w %2,@(%0,%1)")
11611 [(set (match_operand:SI 0 "register_operand" "=r")
11612 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11613 (set (match_operand:HI 2 "general_movdst_operand" "")
11614 (mem:HI (match_dup 0)))]
11615 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11616 "mov.w @(%0,%1),%2")
11619 [(set (match_operand:SI 0 "register_operand" "=r")
11620 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11621 (set (mem:QI (match_dup 0))
11622 (match_operand:QI 2 "general_movsrc_operand" ""))]
11623 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11624 "mov.b %2,@(%0,%1)")
11627 [(set (match_operand:SI 0 "register_operand" "=r")
11628 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11629 (set (match_operand:QI 2 "general_movdst_operand" "")
11630 (mem:QI (match_dup 0)))]
11631 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11632 "mov.b @(%0,%1),%2")
11635 [(set (match_operand:SI 0 "register_operand" "=r")
11636 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11637 (set (mem:SF (match_dup 0))
11638 (match_operand:SF 2 "general_movsrc_operand" ""))]
11639 "TARGET_SH1 && REGNO (operands[0]) == 0
11640 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11641 || (GET_CODE (operands[2]) == SUBREG
11642 && REGNO (SUBREG_REG (operands[2])) < 16))
11643 && reg_unused_after (operands[0], insn)"
11644 "mov.l %2,@(%0,%1)")
11647 [(set (match_operand:SI 0 "register_operand" "=r")
11648 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11649 (set (match_operand:SF 2 "general_movdst_operand" "")
11651 (mem:SF (match_dup 0)))]
11652 "TARGET_SH1 && REGNO (operands[0]) == 0
11653 && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11654 || (GET_CODE (operands[2]) == SUBREG
11655 && REGNO (SUBREG_REG (operands[2])) < 16))
11656 && reg_unused_after (operands[0], insn)"
11657 "mov.l @(%0,%1),%2")
11660 [(set (match_operand:SI 0 "register_operand" "=r")
11661 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11662 (set (mem:SF (match_dup 0))
11663 (match_operand:SF 2 "general_movsrc_operand" ""))]
11664 "TARGET_SH2E && REGNO (operands[0]) == 0
11665 && ((REG_P (operands[2])
11666 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11667 || (GET_CODE (operands[2]) == SUBREG
11668 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11669 && reg_unused_after (operands[0], insn)"
11670 "fmov{.s|} %2,@(%0,%1)")
11673 [(set (match_operand:SI 0 "register_operand" "=r")
11674 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11675 (set (match_operand:SF 2 "general_movdst_operand" "")
11677 (mem:SF (match_dup 0)))]
11678 "TARGET_SH2E && REGNO (operands[0]) == 0
11679 && ((REG_P (operands[2])
11680 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11681 || (GET_CODE (operands[2]) == SUBREG
11682 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11683 && reg_unused_after (operands[0], insn)"
11684 "fmov{.s|} @(%0,%1),%2")
11686 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
11687 (define_insn "sp_switch_1"
11688 [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11692 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11693 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11694 return \"mov r0,r15\";
11696 [(set_attr "length" "10")])
11698 ;; Switch back to the original stack for interrupt functions with the
11699 ;; sp_switch attribute. */
11700 (define_insn "sp_switch_2"
11703 "mov.l @r15+,r15\;mov.l @r15+,r0"
11704 [(set_attr "length" "4")])
11706 ;; Integer vector moves
11708 (define_expand "movv8qi"
11709 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11710 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11712 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11714 (define_insn "movv8qi_i"
11715 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11716 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11718 && (register_operand (operands[0], V8QImode)
11719 || sh_register_operand (operands[1], V8QImode))"
11726 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11727 (set_attr "length" "4,4,16,4,4")])
11730 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11731 (subreg:V8QI (const_int 0) 0))]
11733 [(set (match_dup 0)
11734 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11735 (const_int 0) (const_int 0) (const_int 0)
11736 (const_int 0) (const_int 0)]))])
11739 [(set (match_operand 0 "arith_reg_dest" "")
11740 (match_operand 1 "sh_rep_vec" ""))]
11741 "TARGET_SHMEDIA && reload_completed
11742 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11743 && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11744 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11745 && (XVECEXP (operands[1], 0, 0) != const0_rtx
11746 || XVECEXP (operands[1], 0, 1) != const0_rtx)
11747 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11748 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11749 [(set (match_dup 0) (match_dup 1))
11753 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11754 rtx elt1 = XVECEXP (operands[1], 0, 1);
11757 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11761 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11762 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11764 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11765 operands[1] = XVECEXP (operands[1], 0, 0);
11768 if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11770 = GEN_INT (TARGET_LITTLE_ENDIAN
11771 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11772 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11775 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11777 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11783 [(set (match_operand 0 "arith_reg_dest" "")
11784 (match_operand 1 "sh_const_vec" ""))]
11785 "TARGET_SHMEDIA && reload_completed
11786 && GET_MODE (operands[0]) == GET_MODE (operands[1])
11787 && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11788 [(set (match_dup 0) (match_dup 1))]
11791 rtx v = operands[1];
11792 enum machine_mode new_mode
11793 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11795 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11797 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11800 (define_expand "movv2hi"
11801 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11802 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11804 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11806 (define_insn "movv2hi_i"
11807 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11808 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11810 && (register_operand (operands[0], V2HImode)
11811 || sh_register_operand (operands[1], V2HImode))"
11818 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11819 (set_attr "length" "4,4,16,4,4")
11820 (set (attr "highpart")
11821 (cond [(match_test "sh_contains_memref_p (insn)")
11822 (const_string "user")]
11823 (const_string "ignore")))])
11825 (define_expand "movv4hi"
11826 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11827 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11829 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11831 (define_insn "movv4hi_i"
11832 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11833 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11835 && (register_operand (operands[0], V4HImode)
11836 || sh_register_operand (operands[1], V4HImode))"
11843 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11844 (set_attr "length" "4,4,16,4,4")
11845 (set_attr "highpart" "depend")])
11847 (define_expand "movv2si"
11848 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11849 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11851 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11853 (define_insn "movv2si_i"
11854 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11855 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11857 && (register_operand (operands[0], V2SImode)
11858 || sh_register_operand (operands[1], V2SImode))"
11865 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
11866 (set_attr "length" "4,4,16,4,4")
11867 (set_attr "highpart" "depend")])
11869 ;; Multimedia Intrinsics
11871 (define_insn "absv2si2"
11872 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11873 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11876 [(set_attr "type" "mcmp_media")
11877 (set_attr "highpart" "depend")])
11879 (define_insn "absv4hi2"
11880 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11881 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11884 [(set_attr "type" "mcmp_media")
11885 (set_attr "highpart" "depend")])
11887 (define_insn "addv2si3"
11888 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11889 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11890 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11892 "madd.l %1, %2, %0"
11893 [(set_attr "type" "arith_media")
11894 (set_attr "highpart" "depend")])
11896 (define_insn "addv4hi3"
11897 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11898 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11899 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11901 "madd.w %1, %2, %0"
11902 [(set_attr "type" "arith_media")
11903 (set_attr "highpart" "depend")])
11905 (define_insn_and_split "addv2hi3"
11906 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11907 (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11908 (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11915 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11916 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11917 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11918 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11919 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11921 emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11922 emit_insn (gen_truncdisi2 (si_dst, di_dst));
11925 [(set_attr "highpart" "must_split")])
11927 (define_insn "ssaddv2si3"
11928 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11929 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11930 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11932 "madds.l %1, %2, %0"
11933 [(set_attr "type" "mcmp_media")
11934 (set_attr "highpart" "depend")])
11936 (define_insn "usaddv8qi3"
11937 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11938 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11939 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11941 "madds.ub %1, %2, %0"
11942 [(set_attr "type" "mcmp_media")
11943 (set_attr "highpart" "depend")])
11945 (define_insn "ssaddv4hi3"
11946 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11947 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11948 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11950 "madds.w %1, %2, %0"
11951 [(set_attr "type" "mcmp_media")
11952 (set_attr "highpart" "depend")])
11954 (define_insn "negcmpeqv8qi"
11955 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11956 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11957 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11959 "mcmpeq.b %N1, %N2, %0"
11960 [(set_attr "type" "mcmp_media")
11961 (set_attr "highpart" "depend")])
11963 (define_insn "negcmpeqv2si"
11964 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11965 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11966 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11968 "mcmpeq.l %N1, %N2, %0"
11969 [(set_attr "type" "mcmp_media")
11970 (set_attr "highpart" "depend")])
11972 (define_insn "negcmpeqv4hi"
11973 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11974 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11975 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11977 "mcmpeq.w %N1, %N2, %0"
11978 [(set_attr "type" "mcmp_media")
11979 (set_attr "highpart" "depend")])
11981 (define_insn "negcmpgtuv8qi"
11982 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11983 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11984 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11986 "mcmpgt.ub %N1, %N2, %0"
11987 [(set_attr "type" "mcmp_media")
11988 (set_attr "highpart" "depend")])
11990 (define_insn "negcmpgtv2si"
11991 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11992 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11993 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11995 "mcmpgt.l %N1, %N2, %0"
11996 [(set_attr "type" "mcmp_media")
11997 (set_attr "highpart" "depend")])
11999 (define_insn "negcmpgtv4hi"
12000 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12001 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12002 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12004 "mcmpgt.w %N1, %N2, %0"
12005 [(set_attr "type" "mcmp_media")
12006 (set_attr "highpart" "depend")])
12008 (define_insn "mcmv"
12009 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12010 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12011 (match_operand:DI 2 "arith_reg_operand" "r"))
12012 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12013 (not:DI (match_dup 2)))))]
12016 [(set_attr "type" "arith_media")
12017 (set_attr "highpart" "depend")])
12019 (define_insn "mcnvs_lw"
12020 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12022 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12023 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12025 "mcnvs.lw %N1, %N2, %0"
12026 [(set_attr "type" "mcmp_media")])
12028 (define_insn "mcnvs_wb"
12029 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12031 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12032 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12034 "mcnvs.wb %N1, %N2, %0"
12035 [(set_attr "type" "mcmp_media")])
12037 (define_insn "mcnvs_wub"
12038 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12040 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12041 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12043 "mcnvs.wub %N1, %N2, %0"
12044 [(set_attr "type" "mcmp_media")])
12046 (define_insn "mextr_rl"
12047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12048 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12049 (match_operand:HI 3 "mextr_bit_offset" "i"))
12050 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12051 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12052 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12055 static char templ[21];
12057 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12058 (int) INTVAL (operands[3]) >> 3);
12061 [(set_attr "type" "arith_media")])
12063 (define_insn "*mextr_lr"
12064 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12065 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12066 (match_operand:HI 3 "mextr_bit_offset" "i"))
12067 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12068 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12069 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12072 static char templ[21];
12074 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12075 (int) INTVAL (operands[4]) >> 3);
12078 [(set_attr "type" "arith_media")])
12080 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12081 ; vector then varies depending on endianness.
12082 (define_expand "mextr1"
12083 [(match_operand:DI 0 "arith_reg_dest" "")
12084 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12085 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12089 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12090 GEN_INT (1 * 8), GEN_INT (7 * 8)));
12094 (define_expand "mextr2"
12095 [(match_operand:DI 0 "arith_reg_dest" "")
12096 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12097 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12101 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12102 GEN_INT (2 * 8), GEN_INT (6 * 8)));
12106 (define_expand "mextr3"
12107 [(match_operand:DI 0 "arith_reg_dest" "")
12108 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12109 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12113 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12114 GEN_INT (3 * 8), GEN_INT (5 * 8)));
12118 (define_expand "mextr4"
12119 [(match_operand:DI 0 "arith_reg_dest" "")
12120 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12121 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12125 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12126 GEN_INT (4 * 8), GEN_INT (4 * 8)));
12130 (define_expand "mextr5"
12131 [(match_operand:DI 0 "arith_reg_dest" "")
12132 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12133 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12137 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12138 GEN_INT (5 * 8), GEN_INT (3 * 8)));
12142 (define_expand "mextr6"
12143 [(match_operand:DI 0 "arith_reg_dest" "")
12144 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12145 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12149 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12150 GEN_INT (6 * 8), GEN_INT (2 * 8)));
12154 (define_expand "mextr7"
12155 [(match_operand:DI 0 "arith_reg_dest" "")
12156 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12157 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12161 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12162 GEN_INT (7 * 8), GEN_INT (1 * 8)));
12166 (define_expand "mmacfx_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_mmacfx_wl_i (operands[0], operands[3],
12175 operands[1], operands[2]));
12179 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12181 (define_insn "mmacfx_wl_i"
12182 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12184 (match_operand:V2SI 1 "arith_reg_operand" "0")
12189 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12190 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12193 "mmacfx.wl %2, %3, %0"
12194 [(set_attr "type" "mac_media")
12195 (set_attr "highpart" "depend")])
12197 (define_expand "mmacnfx_wl"
12198 [(match_operand:V2SI 0 "arith_reg_dest" "")
12199 (match_operand:V2HI 1 "extend_reg_operand" "")
12200 (match_operand:V2HI 2 "extend_reg_operand" "")
12201 (match_operand:V2SI 3 "arith_reg_operand" "")]
12205 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12206 operands[1], operands[2]));
12210 (define_insn "mmacnfx_wl_i"
12211 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12213 (match_operand:V2SI 1 "arith_reg_operand" "0")
12218 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12219 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12222 "mmacnfx.wl %2, %3, %0"
12223 [(set_attr "type" "mac_media")
12224 (set_attr "highpart" "depend")])
12226 (define_insn "mulv2si3"
12227 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12228 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12229 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12231 "mmul.l %1, %2, %0"
12232 [(set_attr "type" "d2mpy_media")
12233 (set_attr "highpart" "depend")])
12235 (define_insn "mulv4hi3"
12236 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12237 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12238 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12240 "mmul.w %1, %2, %0"
12241 [(set_attr "type" "dmpy_media")
12242 (set_attr "highpart" "depend")])
12244 (define_insn "mmulfx_l"
12245 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12249 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12250 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12253 "mmulfx.l %1, %2, %0"
12254 [(set_attr "type" "d2mpy_media")
12255 (set_attr "highpart" "depend")])
12257 (define_insn "mmulfx_w"
12258 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12262 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12263 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12266 "mmulfx.w %1, %2, %0"
12267 [(set_attr "type" "dmpy_media")
12268 (set_attr "highpart" "depend")])
12270 (define_insn "mmulfxrp_w"
12271 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12276 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12277 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12281 "mmulfxrp.w %1, %2, %0"
12282 [(set_attr "type" "dmpy_media")
12283 (set_attr "highpart" "depend")])
12286 (define_expand "mmulhi_wl"
12287 [(match_operand:V2SI 0 "arith_reg_dest" "")
12288 (match_operand:V4HI 1 "arith_reg_operand" "")
12289 (match_operand:V4HI 2 "arith_reg_operand" "")]
12293 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12294 (operands[0], operands[1], operands[2]));
12298 (define_expand "mmullo_wl"
12299 [(match_operand:V2SI 0 "arith_reg_dest" "")
12300 (match_operand:V4HI 1 "arith_reg_operand" "")
12301 (match_operand:V4HI 2 "arith_reg_operand" "")]
12305 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12306 (operands[0], operands[1], operands[2]));
12310 (define_insn "mmul23_wl"
12311 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12314 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12315 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12316 (parallel [(const_int 2) (const_int 3)])))]
12318 "* return (TARGET_LITTLE_ENDIAN
12319 ? \"mmulhi.wl %1, %2, %0\"
12320 : \"mmullo.wl %1, %2, %0\");"
12321 [(set_attr "type" "dmpy_media")
12322 (set (attr "highpart")
12323 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12324 (const_string "user")))])
12326 (define_insn "mmul01_wl"
12327 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12330 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12331 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12332 (parallel [(const_int 0) (const_int 1)])))]
12334 "* return (TARGET_LITTLE_ENDIAN
12335 ? \"mmullo.wl %1, %2, %0\"
12336 : \"mmulhi.wl %1, %2, %0\");"
12337 [(set_attr "type" "dmpy_media")
12338 (set (attr "highpart")
12339 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12340 (const_string "user")))])
12343 (define_expand "mmulsum_wq"
12344 [(match_operand:DI 0 "arith_reg_dest" "")
12345 (match_operand:V4HI 1 "arith_reg_operand" "")
12346 (match_operand:V4HI 2 "arith_reg_operand" "")
12347 (match_operand:DI 3 "arith_reg_operand" "")]
12351 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12352 operands[1], operands[2]));
12356 (define_insn "mmulsum_wq_i"
12357 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12358 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12363 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12364 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12365 (parallel [(const_int 0)]))
12366 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12367 (sign_extend:V4DI (match_dup 3)))
12368 (parallel [(const_int 1)])))
12370 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12371 (sign_extend:V4DI (match_dup 3)))
12372 (parallel [(const_int 2)]))
12373 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12374 (sign_extend:V4DI (match_dup 3)))
12375 (parallel [(const_int 3)]))))))]
12377 "mmulsum.wq %2, %3, %0"
12378 [(set_attr "type" "mac_media")])
12380 (define_expand "mperm_w"
12381 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12382 (match_operand:V4HI 1 "arith_reg_operand" "r")
12383 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12387 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12388 (operands[0], operands[1], operands[2]));
12392 ; This use of vec_select isn't exactly correct according to rtl.texi
12393 ; (because not constant), but it seems a straightforward extension.
12394 (define_insn "mperm_w_little"
12395 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12397 (match_operand:V4HI 1 "arith_reg_operand" "r")
12399 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12400 (const_int 2) (const_int 0))
12401 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12402 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12403 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12404 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12405 "mperm.w %1, %N2, %0"
12406 [(set_attr "type" "arith_media")])
12408 (define_insn "mperm_w_big"
12409 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12411 (match_operand:V4HI 1 "arith_reg_operand" "r")
12413 [(zero_extract:QI (not:QI (match_operand:QI 2
12414 "extend_reg_or_0_operand" "rZ"))
12415 (const_int 2) (const_int 0))
12416 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12417 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12418 (zero_extract:QI (not:QI (match_dup 2))
12419 (const_int 2) (const_int 6))])))]
12420 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12421 "mperm.w %1, %N2, %0"
12422 [(set_attr "type" "arith_media")])
12424 (define_insn "mperm_w0"
12425 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12426 (vec_duplicate:V4HI (truncate:HI (match_operand 1
12427 "trunc_hi_operand" "r"))))]
12429 "mperm.w %1, r63, %0"
12430 [(set_attr "type" "arith_media")
12431 (set_attr "highpart" "ignore")])
12433 (define_expand "msad_ubq"
12434 [(match_operand:DI 0 "arith_reg_dest" "")
12435 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12436 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12437 (match_operand:DI 3 "arith_reg_operand" "")]
12441 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12442 operands[1], operands[2]));
12446 (define_insn "msad_ubq_i"
12447 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12452 (match_operand:DI 1 "arith_reg_operand" "0")
12453 (abs:DI (vec_select:DI
12456 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12458 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12459 (parallel [(const_int 0)]))))
12460 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12461 (zero_extend:V8DI (match_dup 3)))
12462 (parallel [(const_int 1)]))))
12464 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12465 (zero_extend:V8DI (match_dup 3)))
12466 (parallel [(const_int 2)])))
12467 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12468 (zero_extend:V8DI (match_dup 3)))
12469 (parallel [(const_int 3)])))))
12472 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12473 (zero_extend:V8DI (match_dup 3)))
12474 (parallel [(const_int 4)])))
12475 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12476 (zero_extend:V8DI (match_dup 3)))
12477 (parallel [(const_int 5)]))))
12479 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12480 (zero_extend:V8DI (match_dup 3)))
12481 (parallel [(const_int 6)])))
12482 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12483 (zero_extend:V8DI (match_dup 3)))
12484 (parallel [(const_int 7)])))))))]
12486 "msad.ubq %N2, %N3, %0"
12487 [(set_attr "type" "mac_media")])
12489 (define_insn "mshalds_l"
12490 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12493 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12494 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12495 (const_int 31)))))]
12497 "mshalds.l %1, %2, %0"
12498 [(set_attr "type" "mcmp_media")
12499 (set_attr "highpart" "depend")])
12501 (define_insn "mshalds_w"
12502 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12505 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12506 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12507 (const_int 15)))))]
12509 "mshalds.w %1, %2, %0"
12510 [(set_attr "type" "mcmp_media")
12511 (set_attr "highpart" "depend")])
12513 (define_insn "ashrv2si3"
12514 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12515 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12516 (match_operand:DI 2 "arith_reg_operand" "r")))]
12518 "mshard.l %1, %2, %0"
12519 [(set_attr "type" "arith_media")
12520 (set_attr "highpart" "depend")])
12522 (define_insn "ashrv4hi3"
12523 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12524 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12525 (match_operand:DI 2 "arith_reg_operand" "r")))]
12527 "mshard.w %1, %2, %0"
12528 [(set_attr "type" "arith_media")
12529 (set_attr "highpart" "depend")])
12531 (define_insn "mshards_q"
12532 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12534 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12535 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12537 "mshards.q %1, %N2, %0"
12538 [(set_attr "type" "mcmp_media")])
12540 (define_expand "mshfhi_b"
12541 [(match_operand:V8QI 0 "arith_reg_dest" "")
12542 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12543 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12547 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12548 (operands[0], operands[1], operands[2]));
12552 (define_expand "mshflo_b"
12553 [(match_operand:V8QI 0 "arith_reg_dest" "")
12554 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12555 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12559 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12560 (operands[0], operands[1], operands[2]));
12564 (define_insn "mshf4_b"
12566 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12568 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12569 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12570 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12571 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12573 "* return (TARGET_LITTLE_ENDIAN
12574 ? \"mshfhi.b %N1, %N2, %0\"
12575 : \"mshflo.b %N1, %N2, %0\");"
12576 [(set_attr "type" "arith_media")
12577 (set (attr "highpart")
12578 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12579 (const_string "user")))])
12581 (define_insn "mshf0_b"
12583 (match_operand:V8QI 0 "arith_reg_dest" "=r")
12585 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12586 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12587 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12588 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12590 "* return (TARGET_LITTLE_ENDIAN
12591 ? \"mshflo.b %N1, %N2, %0\"
12592 : \"mshfhi.b %N1, %N2, %0\");"
12593 [(set_attr "type" "arith_media")
12594 (set (attr "highpart")
12595 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12596 (const_string "user")))])
12598 (define_expand "mshfhi_l"
12599 [(match_operand:V2SI 0 "arith_reg_dest" "")
12600 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12601 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12605 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12606 (operands[0], operands[1], operands[2]));
12610 (define_expand "mshflo_l"
12611 [(match_operand:V2SI 0 "arith_reg_dest" "")
12612 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12613 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12617 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12618 (operands[0], operands[1], operands[2]));
12622 (define_insn "mshf4_l"
12623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12625 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12626 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12627 (parallel [(const_int 1) (const_int 3)])))]
12629 "* return (TARGET_LITTLE_ENDIAN
12630 ? \"mshfhi.l %N1, %N2, %0\"
12631 : \"mshflo.l %N1, %N2, %0\");"
12632 [(set_attr "type" "arith_media")
12633 (set (attr "highpart")
12634 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12635 (const_string "user")))])
12637 (define_insn "mshf0_l"
12638 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12640 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12641 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12642 (parallel [(const_int 0) (const_int 2)])))]
12644 "* return (TARGET_LITTLE_ENDIAN
12645 ? \"mshflo.l %N1, %N2, %0\"
12646 : \"mshfhi.l %N1, %N2, %0\");"
12647 [(set_attr "type" "arith_media")
12648 (set (attr "highpart")
12649 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12650 (const_string "user")))])
12652 (define_expand "mshfhi_w"
12653 [(match_operand:V4HI 0 "arith_reg_dest" "")
12654 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12655 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12659 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12660 (operands[0], operands[1], operands[2]));
12664 (define_expand "mshflo_w"
12665 [(match_operand:V4HI 0 "arith_reg_dest" "")
12666 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12667 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12671 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12672 (operands[0], operands[1], operands[2]));
12676 (define_insn "mshf4_w"
12677 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12679 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12680 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12681 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12683 "* return (TARGET_LITTLE_ENDIAN
12684 ? \"mshfhi.w %N1, %N2, %0\"
12685 : \"mshflo.w %N1, %N2, %0\");"
12686 [(set_attr "type" "arith_media")
12687 (set (attr "highpart")
12688 (cond [(eq_attr "endian" "big") (const_string "ignore")]
12689 (const_string "user")))])
12691 (define_insn "mshf0_w"
12692 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12694 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12695 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12696 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12698 "* return (TARGET_LITTLE_ENDIAN
12699 ? \"mshflo.w %N1, %N2, %0\"
12700 : \"mshfhi.w %N1, %N2, %0\");"
12701 [(set_attr "type" "arith_media")
12702 (set (attr "highpart")
12703 (cond [(eq_attr "endian" "little") (const_string "ignore")]
12704 (const_string "user")))])
12706 (define_insn "mshflo_w_x"
12707 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12709 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12710 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12711 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12713 "mshflo.w %N1, %N2, %0"
12714 [(set_attr "type" "arith_media")
12715 (set_attr "highpart" "ignore")])
12717 /* These are useful to expand ANDs and as combiner patterns. */
12718 (define_insn_and_split "mshfhi_l_di"
12719 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12720 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12722 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12723 (const_int -4294967296))))]
12726 mshfhi.l %N1, %N2, %0
12728 "TARGET_SHMEDIA && reload_completed
12729 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12730 [(set (match_dup 3) (match_dup 4))
12731 (set (match_dup 5) (match_dup 6))]
12734 operands[3] = gen_lowpart (SImode, operands[0]);
12735 operands[4] = gen_highpart (SImode, operands[1]);
12736 operands[5] = gen_highpart (SImode, operands[0]);
12737 operands[6] = gen_highpart (SImode, operands[2]);
12739 [(set_attr "type" "arith_media")])
12741 (define_insn "*mshfhi_l_di_rev"
12742 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12743 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12744 (const_int -4294967296))
12745 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12748 "mshfhi.l %N2, %N1, %0"
12749 [(set_attr "type" "arith_media")])
12752 [(set (match_operand:DI 0 "arith_reg_dest" "")
12753 (ior:DI (zero_extend:DI (match_operand:SI 1
12754 "extend_reg_or_0_operand" ""))
12755 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12756 (const_int -4294967296))))
12757 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12762 emit_insn (gen_ashldi3_media (operands[3],
12763 simplify_gen_subreg (DImode, operands[1],
12766 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12770 (define_insn "mshflo_l_di"
12771 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12772 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12773 (const_int 4294967295))
12774 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12778 "mshflo.l %N1, %N2, %0"
12779 [(set_attr "type" "arith_media")
12780 (set_attr "highpart" "ignore")])
12782 (define_insn "*mshflo_l_di_rev"
12783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12784 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12786 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12787 (const_int 4294967295))))]
12790 "mshflo.l %N2, %N1, %0"
12791 [(set_attr "type" "arith_media")
12792 (set_attr "highpart" "ignore")])
12794 ;; Combiner pattern for trampoline initialization.
12795 (define_insn_and_split "*double_shori"
12796 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12797 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12799 (match_operand:DI 2 "const_int_operand" "n")))]
12801 && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12803 "rtx_equal_p (operands[0], operands[1])"
12807 HOST_WIDE_INT v = INTVAL (operands[2]);
12809 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12810 emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12813 [(set_attr "highpart" "ignore")])
12816 (define_insn "*mshflo_l_di_x"
12817 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12818 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12820 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12824 "mshflo.l %N1, %N2, %0"
12825 [(set_attr "type" "arith_media")
12826 (set_attr "highpart" "ignore")])
12828 (define_insn_and_split "concat_v2sf"
12829 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12830 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12831 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12832 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12836 mshflo.l %N1, %N2, %0
12839 "TARGET_SHMEDIA && reload_completed
12840 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12841 [(set (match_dup 3) (match_dup 1))
12842 (set (match_dup 4) (match_dup 2))]
12845 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12846 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12848 [(set_attr "type" "arith_media")
12849 (set_attr "highpart" "ignore")])
12851 (define_insn "*mshflo_l_di_x_rev"
12852 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12853 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12855 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12858 "mshflo.l %N2, %N1, %0"
12859 [(set_attr "type" "arith_media")
12860 (set_attr "highpart" "ignore")])
12862 (define_insn "ashlv2si3"
12863 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12864 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12865 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12867 "mshlld.l %1, %2, %0"
12868 [(set_attr "type" "arith_media")
12869 (set_attr "highpart" "depend")])
12872 [(set (match_operand 0 "any_register_operand" "")
12873 (match_operator 3 "shift_operator"
12874 [(match_operand 1 "any_register_operand" "")
12875 (match_operand 2 "shift_count_reg_operand" "")]))]
12876 "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12877 [(set (match_dup 0) (match_dup 3))]
12880 rtx count = operands[2];
12881 enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12883 while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12884 || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12885 || GET_CODE (count) == TRUNCATE)
12886 count = XEXP (count, 0);
12887 inner_mode = GET_MODE (count);
12888 count = simplify_gen_subreg (outer_mode, count, inner_mode,
12889 subreg_lowpart_offset (outer_mode, inner_mode));
12890 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12891 operands[1], count);
12894 (define_insn "ashlv4hi3"
12895 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12896 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12897 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12899 "mshlld.w %1, %2, %0"
12900 [(set_attr "type" "arith_media")
12901 (set_attr "highpart" "depend")])
12903 (define_insn "lshrv2si3"
12904 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12905 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12906 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12908 "mshlrd.l %1, %2, %0"
12909 [(set_attr "type" "arith_media")
12910 (set_attr "highpart" "depend")])
12912 (define_insn "lshrv4hi3"
12913 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12914 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12915 (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12917 "mshlrd.w %1, %2, %0"
12918 [(set_attr "type" "arith_media")
12919 (set_attr "highpart" "depend")])
12921 (define_insn "subv2si3"
12922 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12923 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12924 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12926 "msub.l %N1, %2, %0"
12927 [(set_attr "type" "arith_media")
12928 (set_attr "highpart" "depend")])
12930 (define_insn "subv4hi3"
12931 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12932 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12933 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12935 "msub.w %N1, %2, %0"
12936 [(set_attr "type" "arith_media")
12937 (set_attr "highpart" "depend")])
12939 (define_insn_and_split "subv2hi3"
12940 [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12941 (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12942 (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12949 rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12950 rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12951 rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12952 rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12953 rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12955 emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12956 emit_insn (gen_truncdisi2 (si_dst, di_dst));
12959 [(set_attr "highpart" "must_split")])
12961 (define_insn "sssubv2si3"
12962 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12963 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12964 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12966 "msubs.l %N1, %2, %0"
12967 [(set_attr "type" "mcmp_media")
12968 (set_attr "highpart" "depend")])
12970 (define_insn "ussubv8qi3"
12971 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12972 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12973 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12975 "msubs.ub %N1, %2, %0"
12976 [(set_attr "type" "mcmp_media")
12977 (set_attr "highpart" "depend")])
12979 (define_insn "sssubv4hi3"
12980 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12981 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12982 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12984 "msubs.w %N1, %2, %0"
12985 [(set_attr "type" "mcmp_media")
12986 (set_attr "highpart" "depend")])
12988 ;; Floating Point Intrinsics
12990 (define_insn "fcosa_s"
12991 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12992 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12996 [(set_attr "type" "atrans_media")])
12998 (define_insn "fsina_s"
12999 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13000 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13004 [(set_attr "type" "atrans_media")])
13006 (define_insn "fipr"
13007 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13008 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13009 "fp_arith_reg_operand" "f")
13010 (match_operand:V4SF 2
13011 "fp_arith_reg_operand" "f"))
13012 (parallel [(const_int 0)]))
13013 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13014 (parallel [(const_int 1)])))
13015 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13016 (parallel [(const_int 2)]))
13017 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13018 (parallel [(const_int 3)])))))]
13020 "fipr.s %1, %2, %0"
13021 [(set_attr "type" "fparith_media")])
13023 (define_insn "fsrra_s"
13024 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13025 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13029 [(set_attr "type" "atrans_media")])
13031 (define_insn "ftrv"
13032 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13036 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13037 (parallel [(const_int 0) (const_int 5)
13038 (const_int 10) (const_int 15)]))
13039 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13041 (vec_select:V4SF (match_dup 1)
13042 (parallel [(const_int 4) (const_int 9)
13043 (const_int 14) (const_int 3)]))
13044 (vec_select:V4SF (match_dup 2)
13045 (parallel [(const_int 1) (const_int 2)
13046 (const_int 3) (const_int 0)]))))
13049 (vec_select:V4SF (match_dup 1)
13050 (parallel [(const_int 8) (const_int 13)
13051 (const_int 2) (const_int 7)]))
13052 (vec_select:V4SF (match_dup 2)
13053 (parallel [(const_int 2) (const_int 3)
13054 (const_int 0) (const_int 1)])))
13056 (vec_select:V4SF (match_dup 1)
13057 (parallel [(const_int 12) (const_int 1)
13058 (const_int 6) (const_int 11)]))
13059 (vec_select:V4SF (match_dup 2)
13060 (parallel [(const_int 3) (const_int 0)
13061 (const_int 1) (const_int 2)]))))))]
13063 "ftrv.s %1, %2, %0"
13064 [(set_attr "type" "fparith_media")])
13066 (define_insn "ldhi_l"
13067 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13069 (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13072 (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13076 [(set_attr "type" "load_media")])
13078 (define_insn "ldhi_q"
13079 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13081 (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13084 (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13088 [(set_attr "type" "load_media")])
13090 (define_insn_and_split "*ldhi_q_comb0"
13091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13093 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13094 "register_operand" "r")
13095 (match_operand:SI 2
13096 "ua_offset" "I06"))
13099 (plus:SI (and:SI (match_dup 1) (const_int 7))
13102 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13106 "emit_insn (gen_ldhi_q (operands[0],
13107 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13111 (define_insn_and_split "*ldhi_q_comb1"
13112 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13114 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13115 "register_operand" "r")
13116 (match_operand:SI 2
13117 "ua_offset" "I06"))
13120 (plus:SI (and:SI (plus:SI (match_dup 1) (match_operand:SI 3
13121 "ua_offset" "I06"))
13125 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13126 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13130 "emit_insn (gen_ldhi_q (operands[0],
13131 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13135 (define_insn "ldlo_l"
13136 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13138 (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13140 (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13141 (and:SI (match_dup 1) (const_int 3))))]
13144 [(set_attr "type" "load_media")])
13146 (define_insn "ldlo_q"
13147 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13149 (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13151 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13152 (and:SI (match_dup 1) (const_int 7))))]
13155 [(set_attr "type" "load_media")])
13157 (define_insn_and_split "*ldlo_q_comb0"
13158 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13160 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13161 (match_operand:SI 2 "ua_offset" "I06"))
13163 (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13164 (and:SI (match_dup 1) (const_int 7))))]
13165 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13169 "emit_insn (gen_ldlo_q (operands[0],
13170 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13173 (define_insn_and_split "*ldlo_q_comb1"
13174 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13176 (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13177 (match_operand:SI 2 "ua_offset" "I06"))
13179 (minus:SI (const_int 8)
13180 (and:SI (plus:SI (match_dup 1)
13181 (match_operand:SI 3 "ua_offset" "I06"))
13183 (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13184 "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13185 && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13189 "emit_insn (gen_ldlo_q (operands[0],
13190 gen_rtx_PLUS (SImode, operands[1], operands[2])));
13193 (define_insn "sthi_l"
13194 [(set (zero_extract:SI
13195 (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13198 (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13200 (match_operand:SI 1 "arith_reg_operand" "r"))]
13203 [(set_attr "type" "ustore_media")])
13205 ;; All unaligned stores are considered to be 'narrow' because they typically
13206 ;; operate on less that a quadword, and when they operate on a full quadword,
13207 ;; the vanilla store high / store low sequence will cause a stall if not
13208 ;; scheduled apart.
13209 (define_insn "sthi_q"
13210 [(set (zero_extract:DI
13211 (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13214 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13216 (match_operand:DI 1 "arith_reg_operand" "r"))]
13219 [(set_attr "type" "ustore_media")])
13221 (define_insn_and_split "*sthi_q_comb0"
13222 [(set (zero_extract:DI
13223 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13224 "register_operand" "r")
13225 (match_operand:SI 1 "ua_offset"
13229 (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13231 (match_operand:DI 2 "arith_reg_operand" "r"))]
13232 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13236 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13240 (define_insn_and_split "*sthi_q_comb1"
13241 [(set (zero_extract:DI
13242 (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13243 "register_operand" "r")
13244 (match_operand:SI 1 "ua_offset"
13248 (plus:SI (and:SI (plus:SI (match_dup 0)
13249 (match_operand:SI 2 "ua_offset" "I06"))
13253 (match_operand:DI 3 "arith_reg_operand" "r"))]
13254 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13255 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13259 "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13263 ;; This is highpart user because the address is used as full 64 bit.
13264 (define_insn "stlo_l"
13265 [(set (zero_extract:SI
13266 (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13268 (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13269 (and:SI (match_dup 0) (const_int 3)))
13270 (match_operand:SI 1 "arith_reg_operand" "r"))]
13273 [(set_attr "type" "ustore_media")])
13275 (define_insn "stlo_q"
13276 [(set (zero_extract:DI
13277 (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13279 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13280 (and:SI (match_dup 0) (const_int 7)))
13281 (match_operand:DI 1 "arith_reg_operand" "r"))]
13284 [(set_attr "type" "ustore_media")])
13286 (define_insn_and_split "*stlo_q_comb0"
13287 [(set (zero_extract:DI
13288 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13289 (match_operand:SI 1 "ua_offset" "I06"))
13291 (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13292 (and:SI (match_dup 0) (const_int 7)))
13293 (match_operand:DI 2 "arith_reg_operand" "r"))]
13294 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13298 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13302 (define_insn_and_split "*stlo_q_comb1"
13303 [(set (zero_extract:DI
13304 (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13305 (match_operand:SI 1 "ua_offset" "I06"))
13307 (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13308 (match_operand:SI 2
13309 "ua_offset" "I06"))
13311 (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13312 (match_operand:DI 3 "arith_reg_operand" "r"))]
13313 "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13317 "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13321 (define_insn "ldhi_l64"
13322 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13324 (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13327 (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13331 [(set_attr "type" "load_media")])
13333 (define_insn "ldhi_q64"
13334 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13336 (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13339 (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13343 [(set_attr "type" "load_media")])
13345 (define_insn "ldlo_l64"
13346 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13348 (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13350 (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13351 (and:DI (match_dup 1) (const_int 3))))]
13354 [(set_attr "type" "load_media")])
13356 (define_insn "ldlo_q64"
13357 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13359 (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13361 (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13362 (and:DI (match_dup 1) (const_int 7))))]
13365 [(set_attr "type" "load_media")])
13367 (define_insn "sthi_l64"
13368 [(set (zero_extract:SI
13369 (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13372 (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13374 (match_operand:SI 1 "arith_reg_operand" "r"))]
13377 [(set_attr "type" "ustore_media")])
13379 (define_insn "sthi_q64"
13380 [(set (zero_extract:DI
13381 (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13384 (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13386 (match_operand:DI 1 "arith_reg_operand" "r"))]
13389 [(set_attr "type" "ustore_media")])
13391 (define_insn "stlo_l64"
13392 [(set (zero_extract:SI
13393 (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13395 (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13396 (and:DI (match_dup 0) (const_int 3)))
13397 (match_operand:SI 1 "arith_reg_operand" "r"))]
13400 [(set_attr "type" "ustore_media")])
13402 (define_insn "stlo_q64"
13403 [(set (zero_extract:DI
13404 (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13406 (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13407 (and:DI (match_dup 0) (const_int 7)))
13408 (match_operand:DI 1 "arith_reg_operand" "r"))]
13411 [(set_attr "type" "ustore_media")])
13414 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13415 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13419 [(set_attr "type" "arith_media")])
13421 (define_insn "nsbsi"
13422 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13424 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13428 [(set_attr "type" "arith_media")])
13430 (define_insn "nsbdi"
13431 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13433 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13437 [(set_attr "type" "arith_media")])
13439 (define_expand "ffsdi2"
13440 [(set (match_operand:DI 0 "arith_reg_dest" "")
13441 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13445 rtx scratch = gen_reg_rtx (DImode);
13448 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13449 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13450 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13451 emit_insn (gen_nsbdi (scratch, scratch));
13452 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13453 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13454 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13455 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13460 (define_expand "ffssi2"
13461 [(set (match_operand:SI 0 "arith_reg_dest" "")
13462 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13466 rtx scratch = gen_reg_rtx (SImode);
13467 rtx discratch = gen_reg_rtx (DImode);
13470 emit_insn (gen_adddi3 (discratch,
13471 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13473 emit_insn (gen_andcdi3 (discratch,
13474 simplify_gen_subreg (DImode, operands[1], SImode, 0),
13476 emit_insn (gen_nsbsi (scratch, discratch));
13477 last = emit_insn (gen_subsi3 (operands[0],
13478 force_reg (SImode, GEN_INT (63)), scratch));
13479 set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13484 (define_insn "byterev"
13485 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13486 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13487 (parallel [(const_int 7) (const_int 6) (const_int 5)
13488 (const_int 4) (const_int 3) (const_int 2)
13489 (const_int 1) (const_int 0)])))]
13492 [(set_attr "type" "arith_media")])
13494 (define_insn "*prefetch_media"
13495 [(prefetch (match_operand:QI 0 "address_operand" "p")
13496 (match_operand:SI 1 "const_int_operand" "n")
13497 (match_operand:SI 2 "const_int_operand" "n"))]
13501 operands[0] = gen_rtx_MEM (QImode, operands[0]);
13502 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
13505 [(set_attr "type" "other")])
13507 (define_insn "*prefetch_i4"
13508 [(prefetch (match_operand:SI 0 "register_operand" "r")
13509 (match_operand:SI 1 "const_int_operand" "n")
13510 (match_operand:SI 2 "const_int_operand" "n"))]
13511 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13514 return \"pref @%0\";
13516 [(set_attr "type" "other")])
13518 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13519 ;; for accesses to [0x80000000,0xffffffff]. This makes it an unsuitable
13520 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13521 (define_expand "prefetch"
13522 [(prefetch (match_operand 0 "address_operand" "p")
13523 (match_operand:SI 1 "const_int_operand" "n")
13524 (match_operand:SI 2 "const_int_operand" "n"))]
13525 "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13526 && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13529 if (GET_MODE (operands[0]) != Pmode
13530 || !CONST_INT_P (operands[1])
13531 || !CONST_INT_P (operands[2]))
13533 if (! TARGET_SHMEDIA)
13534 operands[0] = force_reg (Pmode, operands[0]);
13537 (define_insn "prefetch_m2a"
13538 [(prefetch (match_operand:SI 0 "register_operand" "r")
13539 (match_operand:SI 1 "const_int_operand" "n")
13540 (match_operand:SI 2 "const_int_operand" "n"))]
13543 [(set_attr "type" "other")])
13545 (define_insn "alloco_i"
13546 [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13547 (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13553 if (GET_CODE (operands[0]) == PLUS)
13555 xops[0] = XEXP (operands[0], 0);
13556 xops[1] = XEXP (operands[0], 1);
13560 xops[0] = operands[0];
13561 xops[1] = const0_rtx;
13563 output_asm_insn (\"alloco %0, %1\", xops);
13566 [(set_attr "type" "other")])
13569 [(set (match_operand 0 "any_register_operand" "")
13570 (match_operand 1 "" ""))]
13571 "TARGET_SHMEDIA && reload_completed"
13572 [(set (match_dup 0) (match_dup 1))]
13577 for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13582 ; Stack Protector Patterns
13584 (define_expand "stack_protect_set"
13585 [(set (match_operand 0 "memory_operand" "")
13586 (match_operand 1 "memory_operand" ""))]
13589 if (TARGET_SHMEDIA)
13591 if (TARGET_SHMEDIA64)
13592 emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13594 emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13597 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13602 (define_insn "stack_protect_set_si"
13603 [(set (match_operand:SI 0 "memory_operand" "=m")
13604 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13605 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13607 "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13608 [(set_attr "type" "other")
13609 (set_attr "length" "6")])
13611 (define_insn "stack_protect_set_si_media"
13612 [(set (match_operand:SI 0 "memory_operand" "=m")
13613 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13614 (set (match_scratch:SI 2 "=&r") (const_int 0))]
13616 "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13617 [(set_attr "type" "other")
13618 (set_attr "length" "12")])
13620 (define_insn "stack_protect_set_di_media"
13621 [(set (match_operand:DI 0 "memory_operand" "=m")
13622 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13623 (set (match_scratch:DI 2 "=&r") (const_int 0))]
13625 "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13626 [(set_attr "type" "other")
13627 (set_attr "length" "12")])
13629 (define_expand "stack_protect_test"
13630 [(match_operand 0 "memory_operand" "")
13631 (match_operand 1 "memory_operand" "")
13632 (match_operand 2 "" "")]
13635 if (TARGET_SHMEDIA)
13637 rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13640 test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13641 if (TARGET_SHMEDIA64)
13643 emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13645 emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13649 emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13651 emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13656 emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13657 emit_jump_insn (gen_branch_true (operands[2]));
13663 (define_insn "stack_protect_test_si"
13664 [(set (reg:SI T_REG)
13665 (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13666 (match_operand:SI 1 "memory_operand" "m")]
13668 (set (match_scratch:SI 2 "=&r") (const_int 0))
13669 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13671 "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13672 [(set_attr "type" "other")
13673 (set_attr "length" "10")])
13675 (define_insn "stack_protect_test_si_media"
13676 [(set (match_operand:SI 0 "register_operand" "=&r")
13677 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13678 (match_operand:SI 2 "memory_operand" "m")]
13680 (set (match_scratch:SI 3 "=&r") (const_int 0))]
13682 "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13683 [(set_attr "type" "other")
13684 (set_attr "length" "16")])
13686 (define_insn "stack_protect_test_di_media"
13687 [(set (match_operand:DI 0 "register_operand" "=&r")
13688 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13689 (match_operand:DI 2 "memory_operand" "m")]
13691 (set (match_scratch:DI 3 "=&r") (const_int 0))]
13693 "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13694 [(set_attr "type" "other")
13695 (set_attr "length" "16")])