1 ;;- Machine description for Hitachi / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
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)
139 ;; These are used with unspec_volatile.
145 (UNSPECV_WINDOW_END 10)
146 (UNSPECV_CONST_END 11)
149 ;; -------------------------------------------------------------------------
151 ;; -------------------------------------------------------------------------
156 "sh1,sh2,sh3,sh3e,sh4,sh5"
157 (const (symbol_ref "sh_cpu_attr")))
159 (define_attr "endian" "big,little"
160 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
161 (const_string "little") (const_string "big"))))
163 ;; Indicate if the default fpu mode is single precision.
164 (define_attr "fpu_single" "yes,no"
165 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
166 (const_string "yes") (const_string "no"))))
168 (define_attr "fmovd" "yes,no"
169 (const (if_then_else (symbol_ref "TARGET_FMOVD")
170 (const_string "yes") (const_string "no"))))
172 (define_attr "issues" "1,2"
173 (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
175 ;; cbranch conditional branch instructions
176 ;; jump unconditional jumps
177 ;; arith ordinary arithmetic
178 ;; arith3 a compound insn that behaves similarly to a sequence of
179 ;; three insns of type arith
180 ;; arith3b like above, but might end with a redirected branch
182 ;; load_si Likewise, SImode variant for general register.
184 ;; move register to register
185 ;; fmove register to register, floating point
186 ;; smpy word precision integer multiply
187 ;; dmpy longword or doublelongword precision integer multiply
189 ;; pload load of pr reg, which can't be put into delay slot of rts
190 ;; prset copy register to pr reg, ditto
191 ;; pstore store of pr reg, which can't be put into delay slot of jsr
192 ;; prget copy pr to register, ditto
193 ;; pcload pc relative load of constant value
194 ;; pcload_si Likewise, SImode variant for general register.
195 ;; rte return from exception
196 ;; sfunc special function call with known used registers
197 ;; call function call
199 ;; fdiv floating point divide (or square root)
200 ;; gp_fpul move between general purpose register and fpul
201 ;; dfp_arith, dfp_cmp,dfp_conv
202 ;; dfdiv double precision floating point divide (or square root)
203 ;; nil no-op move, will be deleted.
206 "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,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,ptabs,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
207 (const_string "other"))
209 ;; We define a new attribute namely "insn_class".We use
210 ;; this for DFA based pipeline description.
211 ;; Although the "type" attribute covers almost all insn
212 ;; classes,it is more convenient to define new attribute
213 ;; for certain reservations.
215 ;; mt_group SH4 "mt" group instructions.
217 ;; ex_group SH4 "ex" group instructions.They mostly
218 ;; overlap with arithmetic instructions but
219 ;; new attribute defined to distinguish from
220 ;; mt group instructions.
222 ;; lds_to_fpscr The "type" attribute couldn't sufficiently
223 ;; distinguish it from others.It is part of
224 ;; new attribute.Similar case with ldsmem_to_fpscr
227 (define_attr "insn_class"
228 "mt_group,ex_group,lds_to_fpscr,ldsmem_to_fpscr,cwb,none"
229 (const_string "none"))
231 ;; Indicate what precision must be selected in fpscr for this insn, if any.
233 (define_attr "fp_mode" "single,double,none" (const_string "none"))
235 ; If a conditional branch destination is within -252..258 bytes away
236 ; from the instruction it can be 2 bytes long. Something in the
237 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
238 ; branches are initially assumed to be 16 bytes long.
239 ; In machine_dependent_reorg, we split all branches that are longer than
242 ;; The maximum range used for SImode constant pool entries is 1018. A final
243 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
244 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
245 ;; instruction around the pool table, 2 bytes of alignment before the table,
246 ;; and 30 bytes of alignment after the table. That gives a maximum total
247 ;; pool size of 1058 bytes.
248 ;; Worst case code/pool content size ratio is 1:2 (using asms).
249 ;; Thus, in the worst case, there is one instruction in front of a maximum
250 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
251 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
252 ;; If we have a forward branch, the initial table will be put after the
253 ;; unconditional branch.
255 ;; ??? We could do much better by keeping track of the actual pcloads within
256 ;; the branch range and in the pcload range in front of the branch range.
258 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
260 (define_attr "short_cbranch_p" "no,yes"
261 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
263 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
265 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
267 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
269 ] (const_string "no")))
271 (define_attr "med_branch_p" "no,yes"
272 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
275 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
277 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
280 ] (const_string "no")))
282 (define_attr "med_cbranch_p" "no,yes"
283 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
286 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
288 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
291 ] (const_string "no")))
293 (define_attr "braf_branch_p" "no,yes"
294 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
296 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
299 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
301 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
304 ] (const_string "no")))
306 (define_attr "braf_cbranch_p" "no,yes"
307 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
309 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
312 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
314 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
317 ] (const_string "no")))
319 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
320 ; For wider ranges, we need a combination of a code and a data part.
321 ; If we can get a scratch register for a long range jump, the code
322 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
323 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
324 ; long; otherwise, it must be 6 bytes long.
326 ; All other instructions are two bytes long by default.
328 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
329 ;; but getattrtab doesn't understand this.
330 (define_attr "length" ""
331 (cond [(eq_attr "type" "cbranch")
332 (cond [(eq_attr "short_cbranch_p" "yes")
334 (eq_attr "med_cbranch_p" "yes")
336 (eq_attr "braf_cbranch_p" "yes")
338 ;; ??? using pc is not computed transitively.
339 (ne (match_dup 0) (match_dup 0))
341 (ne (symbol_ref ("flag_pic")) (const_int 0))
344 (eq_attr "type" "jump")
345 (cond [(eq_attr "med_branch_p" "yes")
347 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
349 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
350 (symbol_ref "code_for_indirect_jump_scratch")))
351 (if_then_else (eq_attr "braf_branch_p" "yes")
354 (eq_attr "braf_branch_p" "yes")
356 ;; ??? using pc is not computed transitively.
357 (ne (match_dup 0) (match_dup 0))
359 (ne (symbol_ref ("flag_pic")) (const_int 0))
362 (eq_attr "type" "pt")
363 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
364 (const_int 20) (const_int 12))
365 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
369 ;; (define_function_unit {name} {num-units} {n-users} {test}
370 ;; {ready-delay} {issue-delay} [{conflict-list}])
372 ;; Load and store instructions save a cycle if they are aligned on a
373 ;; four byte boundary. Using a function unit for stores encourages
374 ;; gcc to separate load and store instructions by one instruction,
375 ;; which makes it more likely that the linker will be able to word
376 ;; align them when relaxing.
378 ;; Loads have a latency of two.
379 ;; However, call insns can have a delay slot, so that we want one more
380 ;; insn to be scheduled between the load of the function address and the call.
381 ;; This is equivalent to a latency of three.
382 ;; We cannot use a conflict list for this, because we need to distinguish
383 ;; between the actual call address and the function arguments.
384 ;; ADJUST_COST can only properly handle reductions of the cost, so we
385 ;; use a latency of three here.
386 ;; We only do this for SImode loads of general registers, to make the work
387 ;; for ADJUST_COST easier.
388 (define_function_unit "memory" 1 0
389 (and (eq_attr "issues" "1")
390 (eq_attr "type" "load_si,pcload_si"))
392 (define_function_unit "memory" 1 0
393 (and (eq_attr "issues" "1")
394 (eq_attr "type" "load,pcload,pload,store,pstore"))
397 (define_function_unit "int" 1 0
398 (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
400 (define_function_unit "int" 1 0
401 (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
403 (define_function_unit "int" 1 0
404 (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
406 ;; ??? These are approximations.
407 (define_function_unit "mpy" 1 0
408 (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
409 (define_function_unit "mpy" 1 0
410 (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
412 (define_function_unit "fp" 1 0
413 (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
414 (define_function_unit "fp" 1 0
415 (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
419 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
420 ;; costs by at least two.
421 ;; There will be single increments of the modeled that don't correspond
422 ;; to the actual target ;; whenever two insns to be issued depend one a
423 ;; single resource, and the scheduler picks to be the first one.
424 ;; If we multiplied the costs just by two, just two of these single
425 ;; increments would amount to an actual cycle. By picking a larger
426 ;; factor, we can ameliorate the effect; However, we then have to make sure
427 ;; that only two insns are modeled as issued per actual cycle.
428 ;; Moreover, we need a way to specify the latency of insns that don't
429 ;; use an actual function unit.
430 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
432 (define_function_unit "issue" 2 0
433 (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
436 (define_function_unit "issue" 2 0
437 (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
440 ;; There is no point in providing exact scheduling information about branches,
441 ;; because they are at the starts / ends of basic blocks anyways.
443 ;; Some insns cannot be issued before/after another insn in the same cycle,
444 ;; irrespective of the type of the other insn.
446 ;; default is dual-issue, but can't be paired with an insn that
447 ;; uses multiple function units.
448 (define_function_unit "single_issue" 1 0
449 (and (eq_attr "issues" "2")
450 (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
452 [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
454 (define_function_unit "single_issue" 1 0
455 (and (eq_attr "issues" "2")
456 (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
460 ;; arith3 insns are always pairable at the start, but not inecessarily at
461 ;; the end; however, there doesn't seem to be a way to express that.
462 (define_function_unit "single_issue" 1 0
463 (and (eq_attr "issues" "2")
464 (eq_attr "type" "arith3"))
468 ;; arith3b insn are pairable at the end and have latency that prevents pairing
469 ;; with the following branch, but we don't want this latency be respected;
470 ;; When the following branch is immediately adjacent, we can redirect the
471 ;; internal branch, which is likly to be a larger win.
472 (define_function_unit "single_issue" 1 0
473 (and (eq_attr "issues" "2")
474 (eq_attr "type" "arith3b"))
478 ;; calls introduce a longisch delay that is likely to flush the pipelines.
479 (define_function_unit "single_issue" 1 0
480 (and (eq_attr "issues" "2")
481 (eq_attr "type" "call,sfunc"))
483 [(eq_attr "type" "!call") (eq_attr "type" "call")])
485 ;; Load and store instructions have no alignment peculiarities for the SH4,
486 ;; but they use the load-store unit, which they share with the fmove type
487 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
488 ;; Loads have a latency of two.
489 ;; However, call insns can only paired with a preceding insn, and have
490 ;; a delay slot, so that we want two more insns to be scheduled between the
491 ;; load of the function address and the call. This is equivalent to a
493 ;; We cannot use a conflict list for this, because we need to distinguish
494 ;; between the actual call address and the function arguments.
495 ;; ADJUST_COST can only properly handle reductions of the cost, so we
496 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
497 ;; We only do this for SImode loads of general registers, to make the work
498 ;; for ADJUST_COST easier.
500 ;; When specifying different latencies for different insns using the
501 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
502 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
503 ;; for an executing insn E and a candidate insn C.
504 ;; Therefore, we define three different function units for load_store:
505 ;; load_store, load and load_si.
507 (define_function_unit "load_si" 1 0
508 (and (eq_attr "issues" "2")
509 (eq_attr "type" "load_si,pcload_si")) 30 10)
510 (define_function_unit "load" 1 0
511 (and (eq_attr "issues" "2")
512 (eq_attr "type" "load,pcload,pload")) 20 10)
513 (define_function_unit "load_store" 1 0
514 (and (eq_attr "issues" "2")
515 (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
518 (define_function_unit "int" 1 0
519 (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
521 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
522 ;; spurious FIFO constraint; the multiply instructions use the "int"
523 ;; unit actually only for two cycles.
524 (define_function_unit "int" 1 0
525 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
527 ;; We use a fictous "mpy" unit to express the actual latency.
528 (define_function_unit "mpy" 1 0
529 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
531 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
532 ;; spurious FIFO constraint.
533 (define_function_unit "int" 1 0
534 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
536 ;; We use a fictous "gp_fpul" unit to express the actual latency.
537 (define_function_unit "gp_fpul" 1 0
538 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
540 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
541 ;; Thus, a simple single-precision fp operation could finish if issued in
542 ;; the very next cycle, but stalls when issued two or three cycles later.
543 ;; Similarily, a divide / sqrt can work without stalls if issued in
544 ;; the very next cycle, while it would have to block if issued two or
545 ;; three cycles later.
546 ;; There is no way to model this with gcc's function units. This problem is
547 ;; actually mentioned in md.texi. Tackling this problem requires first that
548 ;; it is possible to speak about the target in an open discussion.
550 ;; However, simple double-precision operations always conflict.
552 (define_function_unit "fp" 1 0
553 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
554 [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
556 ;; The "fp" unit is for pipeline stages F1 and F2.
558 (define_function_unit "fp" 1 0
559 (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
561 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
562 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
564 (define_function_unit "fp" 1 0
565 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
567 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
568 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
569 ;; We also use it to give the actual latency here.
570 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
571 ;; but that will hardly matter in practice for scheduling.
572 (define_function_unit "fdiv" 1 0
573 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
575 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
576 ;; that we can't express.
578 (define_function_unit "fp" 1 0
579 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
581 (define_function_unit "fp" 1 0
582 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
584 (define_function_unit "fp" 1 0
585 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
587 (define_function_unit "fdiv" 1 0
588 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
590 ;; This should be enough for pt insns to be moved 5 insns ahead of
591 ;; corresponding branches.
592 (define_function_unit "pt" 1 0
593 (eq_attr "type" "pt,ptabs") 10 2)
595 ; Definitions for filling branch delay slots.
597 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
599 ;; ??? This should be (nil) instead of (const_int 0)
600 (define_attr "hit_stack" "yes,no"
601 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
604 (const_string "yes")))
606 (define_attr "interrupt_function" "no,yes"
607 (const (symbol_ref "current_function_interrupt")))
609 (define_attr "in_delay_slot" "yes,no"
610 (cond [(eq_attr "type" "cbranch") (const_string "no")
611 (eq_attr "type" "pcload,pcload_si") (const_string "no")
612 (eq_attr "needs_delay_slot" "yes") (const_string "no")
613 (eq_attr "length" "2") (const_string "yes")
614 ] (const_string "no")))
616 (define_attr "is_sfunc" ""
617 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
620 (eq_attr "needs_delay_slot" "yes")
621 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
623 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
624 ;; and thus we can't put a pop instruction in its delay slot.
625 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
626 ;; instruction can go in the delay slot.
628 ;; Since a normal return (rts) implicitly uses the PR register,
629 ;; we can't allow PR register loads in an rts delay slot.
632 (eq_attr "type" "return")
633 [(and (eq_attr "in_delay_slot" "yes")
634 (ior (and (eq_attr "interrupt_function" "no")
635 (eq_attr "type" "!pload,prset"))
636 (and (eq_attr "interrupt_function" "yes")
638 (ne (symbol_ref "TARGET_SH3") (const_int 0))
639 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
641 ;; Since a call implicitly uses the PR register, we can't allow
642 ;; a PR register store in a jsr delay slot.
645 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
646 [(and (eq_attr "in_delay_slot" "yes")
647 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
649 ;; Say that we have annulled true branches, since this gives smaller and
650 ;; faster code when branches are predicted as not taken.
653 (and (eq_attr "type" "cbranch")
654 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
655 [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
657 ;; -------------------------------------------------------------------------
658 ;; SImode signed integer comparisons
659 ;; -------------------------------------------------------------------------
663 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
664 (match_operand:SI 1 "arith_operand" "L,r"))
668 [(set_attr "insn_class" "mt_group")])
670 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
671 ;; That would still allow reload to create cmpi instructions, but would
672 ;; perhaps allow forcing the constant into a register when that is better.
673 ;; Probably should use r0 for mem/imm compares, but force constant into a
674 ;; register for pseudo/imm compares.
676 (define_insn "cmpeqsi_t"
678 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
679 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
685 [(set_attr "insn_class" "mt_group,mt_group,mt_group")])
687 (define_insn "cmpgtsi_t"
689 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
690 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
695 [(set_attr "insn_class" "mt_group,mt_group")])
697 (define_insn "cmpgesi_t"
699 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
700 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
705 [(set_attr "insn_class" "mt_group,mt_group")])
707 ;; -------------------------------------------------------------------------
708 ;; SImode unsigned integer comparisons
709 ;; -------------------------------------------------------------------------
711 (define_insn "cmpgeusi_t"
713 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
714 (match_operand:SI 1 "arith_reg_operand" "r")))]
717 [(set_attr "insn_class" "mt_group")])
719 (define_insn "cmpgtusi_t"
721 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
722 (match_operand:SI 1 "arith_reg_operand" "r")))]
725 [(set_attr "insn_class" "mt_group")])
727 ;; We save the compare operands in the cmpxx patterns and use them when
728 ;; we generate the branch.
730 (define_expand "cmpsi"
732 (compare (match_operand:SI 0 "arith_operand" "")
733 (match_operand:SI 1 "arith_operand" "")))]
737 sh_compare_op0 = operands[0];
738 sh_compare_op1 = operands[1];
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
746 ;; ??? Could get better scheduling by splitting the initial test from the
747 ;; rest of the insn after reload. However, the gain would hardly justify
748 ;; the sh.md size increase necessary to do that.
752 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
753 (match_operand:DI 1 "arith_operand" "r"))
756 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
758 [(set_attr "length" "6")
759 (set_attr "type" "arith3b")])
761 (define_insn "cmpeqdi_t"
763 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
764 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
767 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
768 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
769 [(set_attr "length" "6")
770 (set_attr "type" "arith3b")])
774 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
775 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
776 ;; If we applied this split when not optimizing, it would only be
777 ;; applied during the machine-dependent reorg, when no new basic blocks
779 "TARGET_SH1 && reload_completed && optimize"
780 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
781 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
782 (label_ref (match_dup 6))
784 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
789 = gen_rtx_REG (SImode,
790 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
792 = (operands[1] == const0_rtx
794 : gen_rtx_REG (SImode,
795 true_regnum (operands[1])
796 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
797 operands[4] = gen_lowpart (SImode, operands[0]);
798 operands[5] = gen_lowpart (SImode, operands[1]);
799 operands[6] = gen_label_rtx ();
802 (define_insn "cmpgtdi_t"
804 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
805 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
808 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
809 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
810 [(set_attr "length" "8")
811 (set_attr "type" "arith3")])
813 (define_insn "cmpgedi_t"
815 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
816 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
819 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
821 [(set_attr "length" "8,2")
822 (set_attr "type" "arith3,arith")])
824 ;; -------------------------------------------------------------------------
825 ;; DImode unsigned integer comparisons
826 ;; -------------------------------------------------------------------------
828 (define_insn "cmpgeudi_t"
830 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
831 (match_operand:DI 1 "arith_reg_operand" "r")))]
833 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
834 [(set_attr "length" "8")
835 (set_attr "type" "arith3")])
837 (define_insn "cmpgtudi_t"
839 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
840 (match_operand:DI 1 "arith_reg_operand" "r")))]
842 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
843 [(set_attr "length" "8")
844 (set_attr "type" "arith3")])
846 (define_insn "cmpeqdi_media"
847 [(set (match_operand:DI 0 "register_operand" "=r,r")
848 (eq:DI (match_operand:DI 1 "register_operand" "%r,r")
849 (match_operand:DI 2 "arith_reg_or_0_operand" "N,r")))]
855 (define_insn "cmpgtdi_media"
856 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
857 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
858 (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
865 (define_insn "cmpgtudi_media"
866 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
867 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
868 (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
875 ;; We save the compare operands in the cmpxx patterns and use them when
876 ;; we generate the branch.
878 (define_expand "cmpdi"
880 (compare (match_operand:DI 0 "arith_operand" "")
881 (match_operand:DI 1 "arith_operand" "")))]
882 "TARGET_SH2 || TARGET_SHMEDIA"
885 sh_compare_op0 = operands[0];
886 sh_compare_op1 = operands[1];
889 ;; -------------------------------------------------------------------------
890 ;; Conditional move instructions
891 ;; -------------------------------------------------------------------------
893 ;; The insn names may seem reversed, but note that cmveq performs the move
894 ;; if op1 == 0, and cmvne does it if op1 != 0.
896 (define_insn "movdicc_false"
897 [(set (match_operand:DI 0 "register_operand" "=r")
898 (if_then_else:DI (eq (match_operand:DI 1 "register_operand" "r")
900 (match_operand:DI 2 "register_operand" "r")
901 (match_operand:DI 3 "register_operand" "0")))]
905 (define_insn "movdicc_true"
906 [(set (match_operand:DI 0 "register_operand" "=r")
907 (if_then_else:DI (ne (match_operand:DI 1 "register_operand" "r")
909 (match_operand:DI 2 "register_operand" "r")
910 (match_operand:DI 3 "register_operand" "0")))]
914 (define_expand "movdicc"
915 [(set (match_operand:DI 0 "register_operand" "")
916 (if_then_else:DI (match_operand 1 "comparison_operator" "")
917 (match_operand:DI 2 "register_operand" "")
918 (match_operand:DI 3 "register_operand" "")))]
922 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
923 && GET_MODE (sh_compare_op0) == DImode
924 && sh_compare_op1 == const0_rtx)
925 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
926 sh_compare_op0, sh_compare_op1);
934 tmp = gen_reg_rtx (DImode);
936 switch (GET_CODE (operands[1]))
939 emit_insn (gen_seq (tmp));
940 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944 emit_insn (gen_seq (tmp));
945 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
949 emit_insn (gen_sgt (tmp));
950 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
954 emit_insn (gen_slt (tmp));
955 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
959 emit_insn (gen_slt (tmp));
960 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
964 emit_insn (gen_sgt (tmp));
965 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
969 emit_insn (gen_sgtu (tmp));
970 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
974 emit_insn (gen_sltu (tmp));
975 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
979 emit_insn (gen_sltu (tmp));
980 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
984 emit_insn (gen_sgtu (tmp));
985 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
989 emit_insn (gen_sunordered (tmp));
990 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
994 emit_insn (gen_sunordered (tmp));
995 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1012 ;; -------------------------------------------------------------------------
1013 ;; Addition instructions
1014 ;; -------------------------------------------------------------------------
1016 (define_expand "adddi3"
1017 [(set (match_operand:DI 0 "arith_reg_operand" "")
1018 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1019 (match_operand:DI 2 "arith_operand" "")))]
1025 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1027 operands[2] = force_reg (DImode, operands[2]);
1028 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1033 (define_insn "*adddi3_media"
1034 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1035 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1036 (match_operand:DI 2 "arith_operand" "r,P")))]
1042 (define_insn "*adddi3z_media"
1043 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1045 (plus:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
1046 (match_operand:SI 2 "arith_reg_or_0_operand" "r,n"))))]
1050 addz.l %1, r63, %0")
1052 (define_insn "adddi3_compact"
1053 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1054 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1055 (match_operand:DI 2 "arith_reg_operand" "r")))
1056 (clobber (reg:SI T_REG))]
1059 [(set_attr "length" "6")])
1062 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1063 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1064 (match_operand:DI 2 "arith_reg_operand" "r")))
1065 (clobber (reg:SI T_REG))]
1066 "TARGET_SH1 && reload_completed"
1070 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1071 high0 = gen_rtx_REG (SImode,
1072 true_regnum (operands[0])
1073 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1074 high2 = gen_rtx_REG (SImode,
1075 true_regnum (operands[2])
1076 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1077 emit_insn (gen_clrt ());
1078 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1079 emit_insn (gen_addc1 (high0, high0, high2));
1084 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1085 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1086 (match_operand:SI 2 "arith_reg_operand" "r"))
1089 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1092 [(set_attr "type" "arith")
1093 (set_attr "insn_class" "ex_group")])
1095 (define_insn "addc1"
1096 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1097 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1098 (match_operand:SI 2 "arith_reg_operand" "r"))
1100 (clobber (reg:SI T_REG))]
1103 [(set_attr "type" "arith")
1104 (set_attr "insn_class" "ex_group")])
1106 (define_expand "addsi3"
1107 [(set (match_operand:SI 0 "arith_reg_operand" "")
1108 (plus:SI (match_operand:SI 1 "arith_operand" "")
1109 (match_operand:SI 2 "arith_operand" "")))]
1114 operands[1] = force_reg (SImode, operands[1]);
1117 (define_insn "addsi3_media"
1118 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1119 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
1120 (match_operand:SI 2 "arith_operand" "r,P")))]
1126 (define_insn "*addsi3_compact"
1127 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1128 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1129 (match_operand:SI 2 "arith_operand" "rI")))]
1132 [(set_attr "type" "arith")
1133 (set_attr "insn_class" "ex_group")])
1135 ;; -------------------------------------------------------------------------
1136 ;; Subtraction instructions
1137 ;; -------------------------------------------------------------------------
1139 (define_expand "subdi3"
1140 [(set (match_operand:DI 0 "arith_reg_operand" "")
1141 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1142 (match_operand:DI 2 "arith_reg_operand" "")))]
1148 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1153 (define_insn "*subdi3_media"
1154 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1155 (minus:DI (match_operand:DI 1 "arith_reg_operand" "r")
1156 (match_operand:DI 2 "arith_reg_operand" "r")))]
1160 (define_insn "subdi3_compact"
1161 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1162 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1163 (match_operand:DI 2 "arith_reg_operand" "r")))
1164 (clobber (reg:SI T_REG))]
1167 [(set_attr "length" "6")])
1170 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1171 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1172 (match_operand:DI 2 "arith_reg_operand" "r")))
1173 (clobber (reg:SI T_REG))]
1174 "TARGET_SH1 && reload_completed"
1178 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1179 high0 = gen_rtx_REG (SImode,
1180 true_regnum (operands[0])
1181 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1182 high2 = gen_rtx_REG (SImode,
1183 true_regnum (operands[2])
1184 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1185 emit_insn (gen_clrt ());
1186 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1187 emit_insn (gen_subc1 (high0, high0, high2));
1192 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1193 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1194 (match_operand:SI 2 "arith_reg_operand" "r"))
1197 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1200 [(set_attr "type" "arith")
1201 (set_attr "insn_class" "ex_group")])
1203 (define_insn "subc1"
1204 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1205 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1206 (match_operand:SI 2 "arith_reg_operand" "r"))
1208 (clobber (reg:SI T_REG))]
1211 [(set_attr "type" "arith")
1212 (set_attr "insn_class" "ex_group")])
1214 (define_insn "*subsi3_internal"
1215 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1216 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1217 (match_operand:SI 2 "arith_reg_operand" "r")))]
1220 [(set_attr "type" "arith")
1221 (set_attr "insn_class" "ex_group")])
1223 (define_insn "*subsi3_media"
1224 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1225 (minus:SI (match_operand:SI 1 "arith_reg_operand" "r")
1226 (match_operand:SI 2 "arith_reg_operand" "r")))]
1230 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1231 ;; will sometimes save one instruction. Otherwise we might get
1232 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1235 (define_expand "subsi3"
1236 [(set (match_operand:SI 0 "arith_reg_operand" "")
1237 (minus:SI (match_operand:SI 1 "arith_operand" "")
1238 (match_operand:SI 2 "arith_reg_operand" "")))]
1242 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1244 emit_insn (gen_negsi2 (operands[0], operands[2]));
1245 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1250 if (no_new_pseudos && ! arith_reg_operand (operands[1], SImode))
1252 operands[1] = force_reg (SImode, operands[1]);
1256 ;; -------------------------------------------------------------------------
1257 ;; Division instructions
1258 ;; -------------------------------------------------------------------------
1260 ;; We take advantage of the library routines which don't clobber as many
1261 ;; registers as a normal function call would.
1263 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1264 ;; also has an effect on the register that holds the address of the sfunc.
1265 ;; To make this work, we have an extra dummy insns that shows the use
1266 ;; of this register for reorg.
1268 (define_insn "use_sfunc_addr"
1269 [(set (reg:SI PR_REG)
1270 (unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1273 [(set_attr "length" "0")])
1275 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1276 ;; hard register 0. If we used hard register 0, then the next instruction
1277 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1278 ;; gets allocated to a stack slot that needs its address reloaded, then
1279 ;; there is nothing to prevent reload from using r0 to reload the address.
1280 ;; This reload would clobber the value in r0 we are trying to store.
1281 ;; If we let reload allocate r0, then this problem can never happen.
1283 (define_insn "udivsi3_i1"
1284 [(set (match_operand:SI 0 "register_operand" "=z")
1285 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1286 (clobber (reg:SI T_REG))
1287 (clobber (reg:SI PR_REG))
1288 (clobber (reg:SI R4_REG))
1289 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1290 "TARGET_SH1 && ! TARGET_SH4"
1292 [(set_attr "type" "sfunc")
1293 (set_attr "needs_delay_slot" "yes")])
1295 ; Since shmedia-nofpu code could be linked against shcompact code, and
1296 ; the udivsi3 libcall has the same name, we must consider all registers
1297 ; clobbered that are in the union of the registers clobbered by the
1298 ; shmedia and the shcompact implementation. Note, if the shcompact
1299 ; implemenation actually used shcompact code, we'd need to clobber
1300 ; also r23 and fr23.
1301 (define_insn "udivsi3_i1_media"
1302 [(set (match_operand:SI 0 "register_operand" "=z")
1303 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1304 (clobber (reg:SI T_MEDIA_REG))
1305 (clobber (reg:SI PR_MEDIA_REG))
1306 (clobber (reg:SI R20_REG))
1307 (clobber (reg:SI R21_REG))
1308 (clobber (reg:SI R22_REG))
1309 (clobber (reg:DI TR0_REG))
1310 (clobber (reg:DI TR1_REG))
1311 (clobber (reg:DI TR2_REG))
1312 (use (match_operand:DI 1 "target_operand" "b"))]
1313 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1315 [(set_attr "type" "sfunc")
1316 (set_attr "needs_delay_slot" "yes")])
1318 (define_expand "udivsi3_i4_media"
1319 [(set (match_dup 2) (zero_extend:DI (reg:SI R4_REG)))
1320 (set (match_dup 3) (zero_extend:DI (reg:SI R5_REG)))
1321 (set (match_dup 4) (float:DF (match_dup 2)))
1322 (set (match_dup 5) (float:DF (match_dup 3)))
1323 (set (match_dup 6) (div:DF (match_dup 4) (match_dup 5)))
1324 (set (subreg:DI (match_operand:SI 0 "register_operand" "=r") 0)
1325 (fix:DI (match_dup 6)))]
1326 "TARGET_SHMEDIA_FPU"
1329 operands[2] = gen_reg_rtx (DImode);
1330 operands[3] = gen_reg_rtx (DImode);
1331 operands[4] = gen_reg_rtx (DFmode);
1332 operands[5] = gen_reg_rtx (DFmode);
1333 operands[6] = gen_reg_rtx (DFmode);
1336 (define_insn "udivsi3_i4"
1337 [(set (match_operand:SI 0 "register_operand" "=y")
1338 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1339 (clobber (reg:SI T_REG))
1340 (clobber (reg:SI PR_REG))
1341 (clobber (reg:DF DR0_REG))
1342 (clobber (reg:DF DR2_REG))
1343 (clobber (reg:DF DR4_REG))
1344 (clobber (reg:SI R0_REG))
1345 (clobber (reg:SI R1_REG))
1346 (clobber (reg:SI R4_REG))
1347 (clobber (reg:SI R5_REG))
1348 (use (reg:PSI FPSCR_REG))
1349 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1352 [(set_attr "type" "sfunc")
1353 (set_attr "fp_mode" "double")
1354 (set_attr "needs_delay_slot" "yes")])
1356 (define_insn "udivsi3_i4_single"
1357 [(set (match_operand:SI 0 "register_operand" "=y")
1358 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1359 (clobber (reg:SI T_REG))
1360 (clobber (reg:SI PR_REG))
1361 (clobber (reg:DF DR0_REG))
1362 (clobber (reg:DF DR2_REG))
1363 (clobber (reg:DF DR4_REG))
1364 (clobber (reg:SI R0_REG))
1365 (clobber (reg:SI R1_REG))
1366 (clobber (reg:SI R4_REG))
1367 (clobber (reg:SI R5_REG))
1368 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1369 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1371 [(set_attr "type" "sfunc")
1372 (set_attr "needs_delay_slot" "yes")])
1374 (define_expand "udivsi3"
1375 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1376 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1377 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1378 (parallel [(set (match_operand:SI 0 "register_operand" "")
1379 (udiv:SI (reg:SI R4_REG)
1381 (clobber (reg:SI T_REG))
1382 (clobber (reg:SI PR_REG))
1383 (clobber (reg:SI R4_REG))
1384 (use (match_dup 3))])]
1390 operands[3] = gen_reg_rtx (Pmode);
1391 /* Emit the move of the address to a pseudo outside of the libcall. */
1392 if (TARGET_HARD_SH4 && TARGET_SH3E)
1394 emit_move_insn (operands[3],
1395 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1396 if (TARGET_FPU_SINGLE)
1397 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1399 last = gen_udivsi3_i4 (operands[0], operands[3]);
1401 else if (TARGET_SHMEDIA_FPU)
1402 last = gen_udivsi3_i4_media (operands[0]);
1403 else if (TARGET_SH5)
1405 emit_move_insn (operands[3],
1406 gen_rtx_SYMBOL_REF (Pmode,
1412 last = gen_udivsi3_i1_media (operands[0],
1415 : gen_rtx_SUBREG (DImode, operands[3],
1417 else if (TARGET_FPU_ANY)
1418 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1420 last = gen_udivsi3_i1 (operands[0], operands[3]);
1424 emit_move_insn (operands[3],
1425 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1426 last = gen_udivsi3_i1 (operands[0], operands[3]);
1428 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1429 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1430 last = emit_insn (last);
1431 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1432 invariant code motion can move it. */
1433 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1434 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1438 (define_insn "divsi3_i1"
1439 [(set (match_operand:SI 0 "register_operand" "=z")
1440 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1441 (clobber (reg:SI T_REG))
1442 (clobber (reg:SI PR_REG))
1443 (clobber (reg:SI R1_REG))
1444 (clobber (reg:SI R2_REG))
1445 (clobber (reg:SI R3_REG))
1446 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1447 "TARGET_SH1 && ! TARGET_SH4"
1449 [(set_attr "type" "sfunc")
1450 (set_attr "needs_delay_slot" "yes")])
1452 ; Since shmedia-nofpu code could be linked against shcompact code, and
1453 ; the udivsi3 libcall has the same name, we must consider all registers
1454 ; clobbered that are in the union of the registers clobbered by the
1455 ; shmedia and the shcompact implementation. Note, if the shcompact
1456 ; implemenation actually used shcompact code, we'd need to clobber
1457 ; also r22, r23 and fr23.
1458 (define_insn "divsi3_i1_media"
1459 [(set (match_operand:SI 0 "register_operand" "=z")
1460 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1461 (clobber (reg:SI T_MEDIA_REG))
1462 (clobber (reg:SI PR_MEDIA_REG))
1463 (clobber (reg:SI R1_REG))
1464 (clobber (reg:SI R2_REG))
1465 (clobber (reg:SI R3_REG))
1466 (clobber (reg:SI R20_REG))
1467 (clobber (reg:SI R21_REG))
1468 (clobber (reg:DI TR0_REG))
1469 (clobber (reg:DI TR1_REG))
1470 (clobber (reg:DI TR2_REG))
1471 (use (match_operand:DI 1 "target_operand" "b"))]
1472 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1475 (define_expand "divsi3_i4_media"
1476 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1477 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1478 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1479 (set (match_operand:SI 0 "register_operand" "=r")
1480 (fix:SI (match_dup 5)))]
1481 "TARGET_SHMEDIA_FPU"
1484 operands[3] = gen_reg_rtx (DFmode);
1485 operands[4] = gen_reg_rtx (DFmode);
1486 operands[5] = gen_reg_rtx (DFmode);
1489 (define_insn "divsi3_i4"
1490 [(set (match_operand:SI 0 "register_operand" "=y")
1491 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1492 (clobber (reg:SI PR_REG))
1493 (clobber (reg:DF DR0_REG))
1494 (clobber (reg:DF DR2_REG))
1495 (use (reg:PSI FPSCR_REG))
1496 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1497 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1499 [(set_attr "type" "sfunc")
1500 (set_attr "fp_mode" "double")
1501 (set_attr "needs_delay_slot" "yes")])
1503 (define_insn "divsi3_i4_single"
1504 [(set (match_operand:SI 0 "register_operand" "=y")
1505 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1506 (clobber (reg:SI PR_REG))
1507 (clobber (reg:DF DR0_REG))
1508 (clobber (reg:DF DR2_REG))
1509 (clobber (reg:SI R2_REG))
1510 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1511 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1513 [(set_attr "type" "sfunc")
1514 (set_attr "needs_delay_slot" "yes")])
1516 (define_expand "divsi3"
1517 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1518 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1519 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1520 (parallel [(set (match_operand:SI 0 "register_operand" "")
1521 (div:SI (reg:SI R4_REG)
1523 (clobber (reg:SI T_REG))
1524 (clobber (reg:SI PR_REG))
1525 (clobber (reg:SI R1_REG))
1526 (clobber (reg:SI R2_REG))
1527 (clobber (reg:SI R3_REG))
1528 (use (match_dup 3))])]
1532 rtx first = 0, last;
1534 operands[3] = gen_reg_rtx (Pmode);
1535 /* Emit the move of the address to a pseudo outside of the libcall. */
1536 if (TARGET_HARD_SH4 && TARGET_SH3E)
1538 emit_move_insn (operands[3],
1539 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1540 if (TARGET_FPU_SINGLE)
1541 last = gen_divsi3_i4_single (operands[0], operands[3]);
1543 last = gen_divsi3_i4 (operands[0], operands[3]);
1545 else if (TARGET_SHMEDIA_FPU)
1547 operands[1] = force_reg (SImode, operands[1]);
1548 operands[2] = force_reg (SImode, operands[2]);
1549 last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1552 else if (TARGET_SH5)
1554 emit_move_insn (operands[3],
1555 gen_rtx_SYMBOL_REF (Pmode,
1561 last = gen_divsi3_i1_media (operands[0],
1564 : gen_rtx_SUBREG (DImode, operands[3],
1566 else if (TARGET_FPU_ANY)
1567 last = gen_divsi3_i4_single (operands[0], operands[3]);
1569 last = gen_divsi3_i1 (operands[0], operands[3]);
1573 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1574 last = gen_divsi3_i1 (operands[0], operands[3]);
1578 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1579 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1581 last = emit_insn (last);
1582 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1583 invariant code motion can move it. */
1584 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1585 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1589 ;; -------------------------------------------------------------------------
1590 ;; Multiplication instructions
1591 ;; -------------------------------------------------------------------------
1593 (define_insn "umulhisi3_i"
1594 [(set (reg:SI MACL_REG)
1595 (mult:SI (zero_extend:SI
1596 (match_operand:HI 0 "arith_reg_operand" "r"))
1598 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1601 [(set_attr "type" "smpy")])
1603 (define_insn "mulhisi3_i"
1604 [(set (reg:SI MACL_REG)
1605 (mult:SI (sign_extend:SI
1606 (match_operand:HI 0 "arith_reg_operand" "r"))
1608 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1611 [(set_attr "type" "smpy")])
1613 (define_expand "mulhisi3"
1614 [(set (reg:SI MACL_REG)
1615 (mult:SI (sign_extend:SI
1616 (match_operand:HI 1 "arith_reg_operand" ""))
1618 (match_operand:HI 2 "arith_reg_operand" ""))))
1619 (set (match_operand:SI 0 "arith_reg_operand" "")
1626 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1627 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1628 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1629 invariant code motion can move it. */
1630 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1631 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1635 (define_expand "umulhisi3"
1636 [(set (reg:SI MACL_REG)
1637 (mult:SI (zero_extend:SI
1638 (match_operand:HI 1 "arith_reg_operand" ""))
1640 (match_operand:HI 2 "arith_reg_operand" ""))))
1641 (set (match_operand:SI 0 "arith_reg_operand" "")
1648 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1649 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1650 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1651 invariant code motion can move it. */
1652 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1653 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1657 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1658 ;; a call to a routine which clobbers known registers.
1661 [(set (match_operand:SI 1 "register_operand" "=z")
1662 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663 (clobber (reg:SI MACL_REG))
1664 (clobber (reg:SI T_REG))
1665 (clobber (reg:SI PR_REG))
1666 (clobber (reg:SI R3_REG))
1667 (clobber (reg:SI R2_REG))
1668 (clobber (reg:SI R1_REG))
1669 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1672 [(set_attr "type" "sfunc")
1673 (set_attr "needs_delay_slot" "yes")])
1675 (define_expand "mulsi3_call"
1676 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1677 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1678 (parallel[(set (match_operand:SI 0 "register_operand" "")
1679 (mult:SI (reg:SI R4_REG)
1681 (clobber (reg:SI MACL_REG))
1682 (clobber (reg:SI T_REG))
1683 (clobber (reg:SI PR_REG))
1684 (clobber (reg:SI R3_REG))
1685 (clobber (reg:SI R2_REG))
1686 (clobber (reg:SI R1_REG))
1687 (use (match_operand:SI 3 "register_operand" ""))])]
1691 (define_insn "mul_l"
1692 [(set (reg:SI MACL_REG)
1693 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1694 (match_operand:SI 1 "arith_reg_operand" "r")))]
1697 [(set_attr "type" "dmpy")])
1699 (define_expand "mulsi3"
1700 [(set (reg:SI MACL_REG)
1701 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1702 (match_operand:SI 2 "arith_reg_operand" "")))
1703 (set (match_operand:SI 0 "arith_reg_operand" "")
1712 /* The address must be set outside the libcall,
1713 since it goes into a pseudo. */
1714 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1715 rtx addr = force_reg (SImode, sym);
1716 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1719 last = emit_insn (insns);
1723 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1725 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1726 /* consec_sets_giv can only recognize the first insn that sets a
1727 giv as the giv insn. So we must tag this also with a REG_EQUAL
1729 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1731 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1732 invariant code motion can move it. */
1733 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1734 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1738 (define_insn "mulsidi3_i"
1739 [(set (reg:SI MACH_REG)
1743 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1744 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1746 (set (reg:SI MACL_REG)
1747 (mult:SI (match_dup 0)
1751 [(set_attr "type" "dmpy")])
1753 (define_expand "mulsidi3"
1754 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1755 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1756 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1757 "TARGET_SH2 || TARGET_SHMEDIA"
1762 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1768 (define_insn "mulsidi3_media"
1769 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1771 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1773 "muls.l %1, %2, %0")
1775 (define_insn "mulsidi3_compact"
1776 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1778 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1779 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1780 (clobber (reg:SI MACH_REG))
1781 (clobber (reg:SI MACL_REG))]
1786 [(set (match_operand:DI 0 "arith_reg_operand" "")
1788 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1789 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1790 (clobber (reg:SI MACH_REG))
1791 (clobber (reg:SI MACL_REG))]
1796 rtx low_dst = gen_lowpart (SImode, operands[0]);
1797 rtx high_dst = gen_highpart (SImode, operands[0]);
1799 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1801 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1802 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1803 /* We need something to tag the possible REG_EQUAL notes on to. */
1804 emit_move_insn (operands[0], operands[0]);
1808 (define_insn "umulsidi3_i"
1809 [(set (reg:SI MACH_REG)
1813 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1814 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1816 (set (reg:SI MACL_REG)
1817 (mult:SI (match_dup 0)
1821 [(set_attr "type" "dmpy")])
1823 (define_expand "umulsidi3"
1824 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1825 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1826 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1827 "TARGET_SH2 || TARGET_SHMEDIA"
1832 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1838 (define_insn "umulsidi3_media"
1839 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1840 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1843 "mulu.l %1, %2, %0")
1845 (define_insn "umulsidi3_compact"
1846 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1848 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1849 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1850 (clobber (reg:SI MACH_REG))
1851 (clobber (reg:SI MACL_REG))]
1856 [(set (match_operand:DI 0 "arith_reg_operand" "")
1857 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1858 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1859 (clobber (reg:SI MACH_REG))
1860 (clobber (reg:SI MACL_REG))]
1865 rtx low_dst = gen_lowpart (SImode, operands[0]);
1866 rtx high_dst = gen_highpart (SImode, operands[0]);
1868 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1870 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1871 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1872 /* We need something to tag the possible REG_EQUAL notes on to. */
1873 emit_move_insn (operands[0], operands[0]);
1877 (define_insn "smulsi3_highpart_i"
1878 [(set (reg:SI MACH_REG)
1882 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1883 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1885 (clobber (reg:SI MACL_REG))]
1888 [(set_attr "type" "dmpy")])
1890 (define_expand "smulsi3_highpart"
1892 [(set (reg:SI MACH_REG)
1896 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1897 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1899 (clobber (reg:SI MACL_REG))])
1900 (set (match_operand:SI 0 "arith_reg_operand" "")
1907 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1908 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1909 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1910 invariant code motion can move it. */
1911 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1912 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1913 /* expand_binop can't find a suitable code in mul_highpart_optab to
1914 make a REG_EQUAL note from, so make one here.
1915 ??? Alternatively, we could put this at the calling site of expand_binop,
1916 i.e. expand_mult_highpart. */
1918 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1923 (define_insn "umulsi3_highpart_i"
1924 [(set (reg:SI MACH_REG)
1928 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1929 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1931 (clobber (reg:SI MACL_REG))]
1934 [(set_attr "type" "dmpy")])
1936 (define_expand "umulsi3_highpart"
1938 [(set (reg:SI MACH_REG)
1942 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1943 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1945 (clobber (reg:SI MACL_REG))])
1946 (set (match_operand:SI 0 "arith_reg_operand" "")
1953 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1954 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1955 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1956 invariant code motion can move it. */
1957 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1958 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1962 ;; -------------------------------------------------------------------------
1963 ;; Logical operations
1964 ;; -------------------------------------------------------------------------
1967 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1968 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1969 (match_operand:SI 2 "logical_operand" "r,L")))]
1972 [(set_attr "type" "arith")
1973 (set_attr "insn_class" "ex_group")])
1975 ;; If the constant is 255, then emit a extu.b instruction instead of an
1976 ;; and, since that will give better code.
1978 (define_expand "andsi3"
1979 [(set (match_operand:SI 0 "arith_reg_operand" "")
1980 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1981 (match_operand:SI 2 "logical_operand" "")))]
1985 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1987 emit_insn (gen_zero_extendqisi2 (operands[0],
1988 gen_lowpart (QImode, operands[1])));
1993 (define_insn_and_split "anddi3"
1994 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1995 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1996 (match_operand:DI 2 "and_operand" "r,P,n")))]
2003 && ! logical_operand (operands[2], DImode)"
2007 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2008 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2010 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2014 (define_insn "*andcdi3"
2015 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2016 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2017 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2021 (define_insn "iorsi3"
2022 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2023 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2024 (match_operand:SI 2 "logical_operand" "r,L")))]
2027 [(set_attr "type" "arith")
2028 (set_attr "insn_class" "ex_group")])
2030 (define_insn "iordi3"
2031 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2032 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2033 (match_operand:DI 2 "logical_operand" "r,P")))]
2039 (define_insn "xorsi3"
2040 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2041 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2042 (match_operand:SI 2 "logical_operand" "L,r")))]
2045 [(set_attr "type" "arith")
2046 (set_attr "insn_class" "ex_group")])
2048 (define_insn "xordi3"
2049 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2050 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2051 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2057 ;; -------------------------------------------------------------------------
2058 ;; Shifts and rotates
2059 ;; -------------------------------------------------------------------------
2061 (define_insn "rotlsi3_1"
2062 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2063 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2066 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2069 [(set_attr "type" "arith")
2070 (set_attr "insn_class" "ex_group")])
2072 (define_insn "rotlsi3_31"
2073 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2074 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2076 (clobber (reg:SI T_REG))]
2079 [(set_attr "type" "arith")
2080 (set_attr "insn_class" "ex_group")])
2082 (define_insn "rotlsi3_16"
2083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2084 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2088 [(set_attr "type" "arith")
2089 (set_attr "insn_class" "ex_group")])
2091 (define_expand "rotlsi3"
2092 [(set (match_operand:SI 0 "arith_reg_operand" "")
2093 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2094 (match_operand:SI 2 "immediate_operand" "")))]
2098 static const char rot_tab[] = {
2099 000, 000, 000, 000, 000, 000, 010, 001,
2100 001, 001, 011, 013, 003, 003, 003, 003,
2101 003, 003, 003, 003, 003, 013, 012, 002,
2102 002, 002, 010, 000, 000, 000, 000, 000,
2107 if (GET_CODE (operands[2]) != CONST_INT)
2109 count = INTVAL (operands[2]);
2110 choice = rot_tab[count];
2111 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2117 emit_move_insn (operands[0], operands[1]);
2118 count -= (count & 16) * 2;
2121 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2128 parts[0] = gen_reg_rtx (SImode);
2129 parts[1] = gen_reg_rtx (SImode);
2130 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2131 parts[choice-1] = operands[1];
2132 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2133 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2134 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2135 count = (count & ~16) - 8;
2139 for (; count > 0; count--)
2140 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2141 for (; count < 0; count++)
2142 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2147 (define_insn "*rotlhi3_8"
2148 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2149 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2153 [(set_attr "type" "arith")
2154 (set_attr "insn_class" "ex_group")])
2156 (define_expand "rotlhi3"
2157 [(set (match_operand:HI 0 "arith_reg_operand" "")
2158 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2159 (match_operand:HI 2 "immediate_operand" "")))]
2163 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2170 ;; This pattern is used by init_expmed for computing the costs of shift
2173 (define_insn_and_split "ashlsi3_std"
2174 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2175 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2176 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2177 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2179 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2180 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2188 && GET_CODE (operands[2]) == CONST_INT
2189 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2190 [(set (match_dup 3) (match_dup 2))
2192 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2193 (clobber (match_dup 4))])]
2194 "operands[4] = gen_rtx_SCRATCH (SImode);"
2195 [(set_attr "length" "*,*,*,4")
2196 (set_attr "type" "dyn_shift,arith,arith,arith")
2197 (set_attr "insn_class" "ex_group,ex_group,ex_group,ex_group")])
2199 (define_insn "ashlhi3_k"
2200 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2201 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2202 (match_operand:HI 2 "const_int_operand" "M,K")))]
2203 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2207 [(set_attr "type" "arith")
2208 (set_attr "insn_class" "ex_group")])
2210 (define_insn "ashlsi3_n"
2211 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2212 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2213 (match_operand:SI 2 "const_int_operand" "n")))
2214 (clobber (reg:SI T_REG))]
2215 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2217 [(set (attr "length")
2218 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2220 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2222 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2224 (const_string "8")))
2225 (set_attr "type" "arith")
2226 (set_attr "insn_class" "ex_group")])
2229 [(set (match_operand:SI 0 "arith_reg_operand" "")
2230 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2231 (match_operand:SI 2 "const_int_operand" "n")))
2232 (clobber (reg:SI T_REG))]
2233 "TARGET_SH1 && reload_completed"
2234 [(use (reg:SI R0_REG))]
2237 gen_shifty_op (ASHIFT, operands);
2241 (define_insn "ashlsi3_media"
2242 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2243 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2244 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2248 shlli.l %1, %2, %0")
2250 (define_expand "ashlsi3"
2251 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2252 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2253 (match_operand:SI 2 "nonmemory_operand" "")))
2254 (clobber (reg:SI T_REG))])]
2260 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2263 if (GET_CODE (operands[2]) == CONST_INT
2264 && sh_dynamicalize_shift_p (operands[2]))
2265 operands[2] = force_reg (SImode, operands[2]);
2268 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2271 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2275 (define_insn "ashlhi3"
2276 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2277 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2278 (match_operand:HI 2 "const_int_operand" "n")))
2279 (clobber (reg:SI T_REG))]
2282 [(set (attr "length")
2283 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2285 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2287 (const_string "6")))
2288 (set_attr "type" "arith")])
2291 [(set (match_operand:HI 0 "arith_reg_operand" "")
2292 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2293 (match_operand:HI 2 "const_int_operand" "n")))
2294 (clobber (reg:SI T_REG))]
2295 "TARGET_SH1 && reload_completed"
2296 [(use (reg:SI R0_REG))]
2299 gen_shifty_hi_op (ASHIFT, operands);
2304 ; arithmetic shift right
2307 (define_insn "ashrsi3_k"
2308 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2309 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2310 (match_operand:SI 2 "const_int_operand" "M")))
2311 (clobber (reg:SI T_REG))]
2312 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2314 [(set_attr "type" "arith")
2315 (set_attr "insn_class" "ex_group")])
2317 ;; We can't do HImode right shifts correctly unless we start out with an
2318 ;; explicit zero / sign extension; doing that would result in worse overall
2319 ;; code, so just let the machine independent code widen the mode.
2320 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2323 ;; ??? This should be a define expand.
2325 (define_insn "ashrsi2_16"
2326 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2327 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2331 [(set_attr "length" "4")])
2334 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2335 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2338 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2339 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2340 "operands[2] = gen_lowpart (HImode, operands[0]);")
2342 ;; ??? This should be a define expand.
2344 (define_insn "ashrsi2_31"
2345 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2346 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2348 (clobber (reg:SI T_REG))]
2351 [(set_attr "length" "4")])
2354 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2355 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2357 (clobber (reg:SI T_REG))]
2362 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2363 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2367 (define_insn "ashlsi_c"
2368 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2369 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2371 (lt:SI (match_dup 1) (const_int 0)))]
2374 [(set_attr "type" "arith")
2375 (set_attr "insn_class" "ex_group")])
2377 (define_insn "ashrsi3_d"
2378 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2379 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2380 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2383 [(set_attr "type" "dyn_shift")
2384 (set_attr "insn_class" "ex_group")])
2386 (define_insn "ashrsi3_n"
2387 [(set (reg:SI R4_REG)
2388 (ashiftrt:SI (reg:SI R4_REG)
2389 (match_operand:SI 0 "const_int_operand" "i")))
2390 (clobber (reg:SI T_REG))
2391 (clobber (reg:SI PR_REG))
2392 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2395 [(set_attr "type" "sfunc")
2396 (set_attr "needs_delay_slot" "yes")])
2398 (define_insn "ashrsi3_media"
2399 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2400 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2401 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2405 shari.l %1, %2, %0")
2407 (define_expand "ashrsi3"
2408 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2409 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2410 (match_operand:SI 2 "nonmemory_operand" "")))
2411 (clobber (reg:SI T_REG))])]
2417 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2420 if (expand_ashiftrt (operands))
2426 ;; logical shift right
2428 (define_insn "lshrsi3_d"
2429 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2430 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2431 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2434 [(set_attr "type" "dyn_shift")
2435 (set_attr "insn_class" "ex_group")])
2437 ;; Only the single bit shift clobbers the T bit.
2439 (define_insn "lshrsi3_m"
2440 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2441 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2442 (match_operand:SI 2 "const_int_operand" "M")))
2443 (clobber (reg:SI T_REG))]
2444 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2446 [(set_attr "type" "arith")
2447 (set_attr "insn_class" "ex_group")])
2449 (define_insn "lshrsi3_k"
2450 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2451 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2452 (match_operand:SI 2 "const_int_operand" "K")))]
2453 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2454 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2456 [(set_attr "type" "arith")
2457 (set_attr "insn_class" "ex_group")])
2459 (define_insn "lshrsi3_n"
2460 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2461 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2462 (match_operand:SI 2 "const_int_operand" "n")))
2463 (clobber (reg:SI T_REG))]
2464 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2466 [(set (attr "length")
2467 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2469 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2471 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2473 (const_string "8")))
2474 (set_attr "type" "arith")])
2477 [(set (match_operand:SI 0 "arith_reg_operand" "")
2478 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2479 (match_operand:SI 2 "const_int_operand" "n")))
2480 (clobber (reg:SI T_REG))]
2481 "TARGET_SH1 && reload_completed"
2482 [(use (reg:SI R0_REG))]
2485 gen_shifty_op (LSHIFTRT, operands);
2489 (define_insn "lshrsi3_media"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2492 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2496 shlri.l %1, %2, %0")
2498 (define_expand "lshrsi3"
2499 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2500 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2501 (match_operand:SI 2 "nonmemory_operand" "")))
2502 (clobber (reg:SI T_REG))])]
2508 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2511 if (GET_CODE (operands[2]) == CONST_INT
2512 && sh_dynamicalize_shift_p (operands[2]))
2513 operands[2] = force_reg (SImode, operands[2]);
2514 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2516 rtx count = copy_to_mode_reg (SImode, operands[2]);
2517 emit_insn (gen_negsi2 (count, count));
2518 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2521 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2525 ;; ??? This should be a define expand.
2527 (define_insn "ashldi3_k"
2528 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2529 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2531 (clobber (reg:SI T_REG))]
2533 "shll %R0\;rotcl %S0"
2534 [(set_attr "length" "4")
2535 (set_attr "type" "arith")
2536 (set_attr "insn_class" "ex_group")])
2538 (define_insn "ashldi3_media"
2539 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2540 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2541 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2547 (define_expand "ashldi3"
2548 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2549 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2550 (match_operand:DI 2 "immediate_operand" "")))
2551 (clobber (reg:SI T_REG))])]
2557 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2560 if (GET_CODE (operands[2]) != CONST_INT
2561 || INTVAL (operands[2]) != 1)
2565 ;; ??? This should be a define expand.
2567 (define_insn "lshrdi3_k"
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2569 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2571 (clobber (reg:SI T_REG))]
2573 "shlr %S0\;rotcr %R0"
2574 [(set_attr "length" "4")
2575 (set_attr "type" "arith")
2576 (set_attr "insn_class" "ex_group")])
2578 (define_insn "lshrdi3_media"
2579 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2580 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2581 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2587 (define_expand "lshrdi3"
2588 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2589 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2590 (match_operand:DI 2 "immediate_operand" "")))
2591 (clobber (reg:SI T_REG))])]
2597 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2600 if (GET_CODE (operands[2]) != CONST_INT
2601 || INTVAL (operands[2]) != 1)
2605 ;; ??? This should be a define expand.
2607 (define_insn "ashrdi3_k"
2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2609 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2611 (clobber (reg:SI T_REG))]
2613 "shar %S0\;rotcr %R0"
2614 [(set_attr "length" "4")
2615 (set_attr "type" "arith")
2616 (set_attr "insn_class" "ex_group")])
2618 (define_insn "ashrdi3_media"
2619 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2620 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2621 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2627 (define_expand "ashrdi3"
2628 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2629 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2630 (match_operand:DI 2 "immediate_operand" "")))
2631 (clobber (reg:SI T_REG))])]
2637 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2640 if (GET_CODE (operands[2]) != CONST_INT
2641 || INTVAL (operands[2]) != 1)
2645 ;; combined left/right shift
2648 [(set (match_operand:SI 0 "register_operand" "")
2649 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2650 (match_operand:SI 2 "const_int_operand" "n"))
2651 (match_operand:SI 3 "const_int_operand" "n")))]
2652 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2653 [(use (reg:SI R0_REG))]
2654 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2658 [(set (match_operand:SI 0 "register_operand" "")
2659 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2660 (match_operand:SI 2 "const_int_operand" "n"))
2661 (match_operand:SI 3 "const_int_operand" "n")))
2662 (clobber (reg:SI T_REG))]
2663 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2664 [(use (reg:SI R0_REG))]
2665 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2669 [(set (match_operand:SI 0 "register_operand" "=r")
2670 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2671 (match_operand:SI 2 "const_int_operand" "n"))
2672 (match_operand:SI 3 "const_int_operand" "n")))
2673 (clobber (reg:SI T_REG))]
2674 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2676 [(set (attr "length")
2677 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2679 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2681 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2683 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2685 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2687 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2689 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2690 (const_string "16")]
2691 (const_string "18")))
2692 (set_attr "type" "arith")])
2695 [(set (match_operand:SI 0 "register_operand" "=z")
2696 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2697 (match_operand:SI 2 "const_int_operand" "n"))
2698 (match_operand:SI 3 "const_int_operand" "n")))
2699 (clobber (reg:SI T_REG))]
2700 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2702 [(set (attr "length")
2703 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2705 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2707 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2709 (const_string "10")))
2710 (set_attr "type" "arith")])
2712 ;; shift left / and combination with a scratch register: The combine pass
2713 ;; does not accept the individual instructions, even though they are
2714 ;; cheap. But it needs a precise description so that it is usable after
2716 (define_insn "and_shl_scratch"
2717 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2721 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2722 (match_operand:SI 2 "const_int_operand" "N,n"))
2723 (match_operand:SI 3 "" "0,r"))
2724 (match_operand:SI 4 "const_int_operand" "n,n"))
2725 (match_operand:SI 5 "const_int_operand" "n,n")))
2726 (clobber (reg:SI T_REG))]
2729 [(set (attr "length")
2730 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2732 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2734 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2736 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2737 (const_string "10")]
2738 (const_string "12")))
2739 (set_attr "type" "arith")])
2742 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2746 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2747 (match_operand:SI 2 "const_int_operand" "N,n"))
2748 (match_operand:SI 3 "register_operand" "0,r"))
2749 (match_operand:SI 4 "const_int_operand" "n,n"))
2750 (match_operand:SI 5 "const_int_operand" "n,n")))
2751 (clobber (reg:SI T_REG))]
2753 [(use (reg:SI R0_REG))]
2756 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2758 if (INTVAL (operands[2]))
2760 gen_shifty_op (LSHIFTRT, operands);
2762 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2763 operands[2] = operands[4];
2764 gen_shifty_op (ASHIFT, operands);
2765 if (INTVAL (operands[5]))
2767 operands[2] = operands[5];
2768 gen_shifty_op (LSHIFTRT, operands);
2773 ;; signed left/right shift combination.
2775 [(set (match_operand:SI 0 "register_operand" "=r")
2777 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2778 (match_operand:SI 2 "const_int_operand" "n"))
2779 (match_operand:SI 3 "const_int_operand" "n")
2781 (clobber (reg:SI T_REG))]
2783 [(use (reg:SI R0_REG))]
2784 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2787 (define_insn "shl_sext_ext"
2788 [(set (match_operand:SI 0 "register_operand" "=r")
2790 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2791 (match_operand:SI 2 "const_int_operand" "n"))
2792 (match_operand:SI 3 "const_int_operand" "n")
2794 (clobber (reg:SI T_REG))]
2795 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2797 [(set (attr "length")
2798 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2800 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2802 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2804 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2806 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2808 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2810 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2812 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2813 (const_string "16")]
2814 (const_string "18")))
2815 (set_attr "type" "arith")])
2817 (define_insn "shl_sext_sub"
2818 [(set (match_operand:SI 0 "register_operand" "=z")
2820 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2821 (match_operand:SI 2 "const_int_operand" "n"))
2822 (match_operand:SI 3 "const_int_operand" "n")
2824 (clobber (reg:SI T_REG))]
2825 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2827 [(set (attr "length")
2828 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2830 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2832 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2834 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2835 (const_string "12")]
2836 (const_string "14")))
2837 (set_attr "type" "arith")])
2839 ;; These patterns are found in expansions of DImode shifts by 16, and
2840 ;; allow the xtrct instruction to be generated from C source.
2842 (define_insn "xtrct_left"
2843 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2844 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2846 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2850 [(set_attr "type" "arith")
2851 (set_attr "insn_class" "ex_group")])
2853 (define_insn "xtrct_right"
2854 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2855 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2857 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2861 [(set_attr "type" "arith")
2862 (set_attr "insn_class" "ex_group")])
2864 ;; -------------------------------------------------------------------------
2866 ;; -------------------------------------------------------------------------
2869 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2870 (neg:SI (plus:SI (reg:SI T_REG)
2871 (match_operand:SI 1 "arith_reg_operand" "r"))))
2873 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2877 [(set_attr "type" "arith")
2878 (set_attr "insn_class" "ex_group")])
2880 (define_insn "*negdi_media"
2881 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2882 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2886 (define_expand "negdi2"
2887 [(set (match_operand:DI 0 "arith_reg_operand" "")
2888 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
2889 (clobber (reg:SI T_REG))]
2895 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2896 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2898 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2899 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2901 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2902 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2904 emit_insn (gen_clrt ());
2905 emit_insn (gen_negc (low_dst, low_src));
2906 emit_insn (gen_negc (high_dst, high_src));
2911 (define_insn "negsi2"
2912 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2916 [(set_attr "type" "arith")
2917 (set_attr "insn_class" "ex_group")])
2919 (define_insn "one_cmplsi2"
2920 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2921 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2924 [(set_attr "type" "arith")
2925 (set_attr "insn_class" "ex_group")])
2927 (define_expand "one_cmpldi2"
2928 [(set (match_operand:DI 0 "arith_reg_operand" "")
2929 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2931 "TARGET_SHMEDIA" "")
2933 ;; -------------------------------------------------------------------------
2934 ;; Zero extension instructions
2935 ;; -------------------------------------------------------------------------
2937 (define_insn "zero_extendsidi2"
2938 [(set (match_operand:DI 0 "register_operand" "=r")
2939 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2941 "addz.l %1, r63, %0")
2943 (define_insn "zero_extendhidi2"
2944 [(set (match_operand:DI 0 "register_operand" "=r,r")
2945 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
2952 [(set (match_operand:DI 0 "register_operand" "=r")
2953 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2954 "TARGET_SHMEDIA && reload_completed"
2955 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2956 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))])
2958 (define_insn "zero_extendqidi2"
2959 [(set (match_operand:DI 0 "register_operand" "=r,r")
2960 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2966 (define_insn "zero_extendhisi2"
2967 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2968 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2971 [(set_attr "type" "arith")
2972 (set_attr "insn_class" "ex_group")])
2974 (define_insn "zero_extendqisi2"
2975 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2979 [(set_attr "type" "arith")
2980 (set_attr "insn_class" "ex_group")])
2982 (define_insn "zero_extendqihi2"
2983 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2984 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
2987 [(set_attr "type" "arith")
2988 (set_attr "insn_class" "ex_group")])
2990 ;; -------------------------------------------------------------------------
2991 ;; Sign extension instructions
2992 ;; -------------------------------------------------------------------------
2994 ;; ??? This should be a define expand.
2995 ;; ??? Or perhaps it should be dropped?
2997 ;; convert_move generates good code for SH[1-4].
2998 (define_insn "extendsidi2"
2999 [(set (match_operand:DI 0 "register_operand" "=r,r")
3000 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3006 (define_insn "extendhidi2"
3007 [(set (match_operand:DI 0 "register_operand" "=r,r")
3008 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3015 [(set (match_operand:DI 0 "register_operand" "=r")
3016 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
3017 "TARGET_SHMEDIA && reload_completed"
3018 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3019 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))])
3021 (define_insn "extendqidi2"
3022 [(set (match_operand:DI 0 "register_operand" "=r,r")
3023 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
3030 [(set (match_operand:DI 0 "register_operand" "=r")
3031 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
3032 "TARGET_SHMEDIA && reload_completed"
3033 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3034 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))])
3036 (define_insn "extendhisi2"
3037 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3038 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3043 [(set_attr "type" "arith,load")
3044 (set_attr "insn_class" "ex_group,*")])
3046 (define_insn "extendqisi2"
3047 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3048 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3053 [(set_attr "type" "arith,load")
3054 (set_attr "insn_class" "ex_group,*")])
3056 (define_insn "extendqihi2"
3057 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3058 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3063 [(set_attr "type" "arith,load")
3064 (set_attr "insn_class" "ex_group,*")])
3066 ;; -------------------------------------------------------------------------
3067 ;; Move instructions
3068 ;; -------------------------------------------------------------------------
3070 ;; define push and pop so it is easy for sh.c
3071 ;; We can't use push and pop on SHcompact because the stack must always
3072 ;; be 8-byte aligned.
3074 (define_expand "push"
3075 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3076 (match_operand:SI 0 "register_operand" "r,l,x"))]
3077 "TARGET_SH1 && ! TARGET_SH5"
3080 (define_expand "pop"
3081 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3082 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3083 "TARGET_SH1 && ! TARGET_SH5"
3086 (define_expand "push_e"
3087 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3088 (match_operand:SF 0 "" ""))
3089 (use (reg:PSI FPSCR_REG))
3090 (clobber (scratch:SI))])]
3091 "TARGET_SH1 && ! TARGET_SH5"
3094 (define_insn "push_fpul"
3095 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3096 "TARGET_SH3E && ! TARGET_SH5"
3098 [(set_attr "type" "store")
3099 (set_attr "hit_stack" "yes")])
3101 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3103 (define_expand "push_4"
3104 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3105 (match_operand:DF 0 "" ""))
3106 (use (reg:PSI FPSCR_REG))
3107 (clobber (scratch:SI))])]
3108 "TARGET_SH1 && ! TARGET_SH5"
3111 (define_expand "pop_e"
3112 [(parallel [(set (match_operand:SF 0 "" "")
3113 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3114 (use (reg:PSI FPSCR_REG))
3115 (clobber (scratch:SI))])]
3116 "TARGET_SH1 && ! TARGET_SH5"
3119 (define_insn "pop_fpul"
3120 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3121 "TARGET_SH3E && ! TARGET_SH5"
3123 [(set_attr "type" "load")
3124 (set_attr "hit_stack" "yes")])
3126 (define_expand "pop_4"
3127 [(parallel [(set (match_operand:DF 0 "" "")
3128 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3129 (use (reg:PSI FPSCR_REG))
3130 (clobber (scratch:SI))])]
3131 "TARGET_SH1 && ! TARGET_SH5"
3134 ;; These two patterns can happen as the result of optimization, when
3135 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3136 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3139 [(set (reg:SI T_REG) (const_int 0))]
3144 [(set (reg:SI T_REG) (const_int 1))]
3148 ;; t/r must come after r/r, lest reload will try to reload stuff like
3149 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3150 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3151 (define_insn "movsi_i"
3152 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3153 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3156 && (register_operand (operands[0], SImode)
3157 || register_operand (operands[1], SImode))"
3174 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3175 (set_attr "insn_class" "*,*,mt_group,*,*,*,*,*,*,*,*,*,*,*,*")
3176 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3178 ;; t/r must come after r/r, lest reload will try to reload stuff like
3179 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3180 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3181 ;; will require a reload.
3182 (define_insn "movsi_ie"
3183 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
3184 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3186 && (register_operand (operands[0], SImode)
3187 || register_operand (operands[1], SImode))"
3208 ! move optimized away"
3209 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,gp_fpul,nil")
3210 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3212 (define_insn "movsi_i_lowpart"
3213 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3214 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3216 && (register_operand (operands[0], SImode)
3217 || register_operand (operands[1], SImode))"
3227 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3229 (define_insn "*movsi_media"
3230 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b*k,r,b*k")
3231 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,r,f,f,r,*b*k,T"))]
3233 && (register_operand (operands[0], SImode)
3234 || register_operand (operands[1], SImode))"
3249 [(set_attr "type" "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3250 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3252 (define_insn "*movsi_media_nofpu"
3253 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b*k,r,b*k")
3254 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b*k,T"))]
3256 && (register_operand (operands[0], SImode)
3257 || register_operand (operands[1], SImode))"
3267 [(set_attr "type" "move,move,*,load,store,ptabs,move,pt")
3268 (set_attr "length" "4,4,8,4,4,4,4,12")])
3271 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3272 (match_operand:SI 1 "immediate_operand" "s"))]
3273 "TARGET_SHMEDIA && reload_completed
3274 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3275 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3278 operands[2] = shallow_copy_rtx (operands[1]);
3279 PUT_MODE (operands[2], DImode);
3283 [(set (match_operand:SI 0 "register_operand" "=r")
3284 (match_operand:SI 1 "immediate_operand" "n"))]
3286 && ((GET_CODE (operands[1]) == CONST_INT
3287 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3288 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3289 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3291 (define_expand "movsi"
3292 [(set (match_operand:SI 0 "general_movdst_operand" "")
3293 (match_operand:SI 1 "general_movsrc_operand" ""))]
3295 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3297 (define_expand "ic_invalidate_line"
3298 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3299 (match_dup 1)] UNSPEC_ICACHE)
3300 (clobber (scratch:SI))])]
3301 "TARGET_HARD_SH4 || TARGET_SH5"
3306 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3309 else if (TARGET_SHCOMPACT)
3311 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3312 operands[1] = force_reg (Pmode, operands[1]);
3313 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3316 operands[0] = force_reg (Pmode, operands[0]);
3317 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3321 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3322 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3323 ;; the requirement *1*00 for associative address writes. The alignment of
3324 ;; %0 implies that its least significant bit is cleared,
3325 ;; thus we clear the V bit of a matching entry if there is one.
3326 (define_insn "ic_invalidate_line_i"
3327 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3328 (match_operand:SI 1 "register_operand" "r")]
3330 (clobber (match_scratch:SI 2 "=&r"))]
3332 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3333 [(set_attr "length" "8")
3334 (set_attr "insn_class" "cwb")])
3336 (define_insn "ic_invalidate_line_media"
3337 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3341 [(set_attr "length" "8")])
3343 (define_insn "ic_invalidate_line_compact"
3344 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3345 (match_operand:SI 1 "register_operand" "r")]
3347 (clobber (reg:SI PR_REG))]
3350 [(set_attr "type" "sfunc")
3351 (set_attr "needs_delay_slot" "yes")])
3353 (define_insn "movqi_i"
3354 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3355 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3357 && (arith_reg_operand (operands[0], QImode)
3358 || arith_reg_operand (operands[1], QImode))"
3366 [(set_attr "type" "move,load,store,move,move,move")])
3368 (define_insn "*movqi_media"
3369 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3370 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3372 && (arith_reg_operand (operands[0], QImode)
3373 || arith_reg_operand (operands[1], QImode))"
3380 (define_expand "movqi"
3381 [(set (match_operand:QI 0 "general_operand" "")
3382 (match_operand:QI 1 "general_operand" ""))]
3384 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3386 (define_insn "movhi_i"
3387 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3388 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3390 && (arith_reg_operand (operands[0], HImode)
3391 || arith_reg_operand (operands[1], HImode))"
3401 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3403 (define_insn "*movhi_media"
3404 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3405 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3407 && (arith_reg_operand (operands[0], HImode)
3408 || arith_reg_operand (operands[1], HImode))"
3417 [(set (match_operand:HI 0 "register_operand" "=r")
3418 (match_operand:HI 1 "immediate_operand" "n"))]
3419 "TARGET_SHMEDIA && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3420 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3422 (define_expand "movhi"
3423 [(set (match_operand:HI 0 "general_movdst_operand" "")
3424 (match_operand:HI 1 "general_movsrc_operand" ""))]
3426 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3428 ;; ??? This should be a define expand.
3430 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3431 ;; compiled with -m2 -ml -O3 -funroll-loops
3433 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3434 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3436 && (arith_reg_operand (operands[0], DImode)
3437 || arith_reg_operand (operands[1], DImode))"
3438 "* return output_movedouble (insn, operands, DImode);"
3439 [(set_attr "length" "4")
3440 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3442 ;; If the output is a register and the input is memory or a register, we have
3443 ;; to be careful and see which word needs to be loaded first.
3446 [(set (match_operand:DI 0 "general_movdst_operand" "")
3447 (match_operand:DI 1 "general_movsrc_operand" ""))]
3448 "TARGET_SH1 && reload_completed"
3449 [(set (match_dup 2) (match_dup 3))
3450 (set (match_dup 4) (match_dup 5))]
3455 if ((GET_CODE (operands[0]) == MEM
3456 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3457 || (GET_CODE (operands[1]) == MEM
3458 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3461 if (GET_CODE (operands[0]) == REG)
3462 regno = REGNO (operands[0]);
3463 else if (GET_CODE (operands[0]) == SUBREG)
3464 regno = subreg_regno (operands[0]);
3465 else if (GET_CODE (operands[0]) == MEM)
3471 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3473 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3474 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3475 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3476 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3480 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3481 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3482 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3483 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3486 if (operands[2] == 0 || operands[3] == 0
3487 || operands[4] == 0 || operands[5] == 0)
3491 (define_insn "*movdi_media"
3492 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b*k,r,b*k")
3493 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,r,f,f,r,*b*k,T"))]
3495 && (register_operand (operands[0], DImode)
3496 || register_operand (operands[1], DImode))"
3511 [(set_attr "type" "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3512 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3514 (define_insn "*movdi_media_nofpu"
3515 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b*k,r,b*k")
3516 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b*k,T"))]
3518 && (register_operand (operands[0], DImode)
3519 || register_operand (operands[1], DImode))"
3529 [(set_attr "type" "move,move,*,load,store,ptabs,move,pt")
3530 (set_attr "length" "4,4,16,4,4,4,4,*")])
3533 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3534 (match_operand:DI 1 "immediate_operand" "s"))]
3535 "TARGET_SHMEDIA && reload_completed
3536 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3537 [(set (match_dup 0) (match_dup 1))]
3542 if (TARGET_SHMEDIA64)
3543 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3545 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3547 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3553 (define_expand "movdi_const"
3554 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3555 (const:DI (sign_extend:DI
3558 (match_operand:DI 1 "immediate_operand" "s")
3561 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3569 (const_int 32)))))))))
3571 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3579 (const_int 16)))))))))
3581 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3587 (match_dup 1))))))))]
3588 "TARGET_SHMEDIA64 && reload_completed
3589 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3592 if (GET_CODE (operands[1]) == LABEL_REF
3593 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3594 LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3595 else if (GOTOFF_P (operands[1])
3596 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3597 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3599 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3602 (define_expand "movdi_const_32bit"
3603 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3604 (const:DI (sign_extend:DI
3607 (match_operand:DI 1 "immediate_operand" "s")
3610 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3616 (match_dup 1))))))))]
3617 "TARGET_SHMEDIA32 && reload_completed
3618 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3621 if (GET_CODE (operands[1]) == LABEL_REF
3622 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3623 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3624 else if (GOTOFF_P (operands[1])
3625 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3626 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3628 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3631 (define_expand "movdi_const_16bit"
3632 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3633 (const:DI (sign_extend:DI
3635 (match_operand:DI 1 "immediate_operand" "s")))))]
3636 "TARGET_SHMEDIA && flag_pic && reload_completed
3637 && GET_CODE (operands[1]) == SYMBOL_REF"
3641 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3642 (match_operand:DI 1 "immediate_operand" "i"))]
3643 "TARGET_SHMEDIA && reload_completed
3644 && GET_CODE (operands[1]) == CONST_INT
3645 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3646 [(set (match_dup 0) (match_dup 2))
3650 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3651 unsigned HOST_WIDE_INT low = val;
3652 unsigned HOST_WIDE_INT high = val;
3653 unsigned HOST_WIDE_INT sign;
3654 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3656 /* Sign-extend the 16 least-significant bits. */
3661 /* Arithmetic shift right the word by 16 bits. */
3664 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3669 /* If we can't generate the constant with a two-insn movi / shori
3670 sequence, try some other strategies. */
3671 if (! CONST_OK_FOR_J (high))
3673 /* Try constant load / left shift. We know VAL != 0. */
3674 val2 = val ^ (val-1);
3677 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3679 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3680 || (! CONST_OK_FOR_J (high >> 16)
3681 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3683 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3684 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3685 GEN_INT (trailing_zeroes));
3689 /* Try constant load / right shift. */
3690 val2 = (val >> 15) + 1;
3691 if (val2 == (val2 & -val2))
3693 int shift = 49 - exact_log2 (val2);
3695 val2 = trunc_int_for_mode (val << shift, DImode);
3696 if (CONST_OK_FOR_J (val2))
3698 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3704 val2 = val & 0xffff;
3705 if ((val >> 16 & 0xffff) == val2
3706 && (val >> 32 & 0xffff) == val2
3707 && (val >> 48 & 0xffff) == val2)
3709 val2 = (HOST_WIDE_INT) val >> 48;
3710 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3711 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3714 /* Try movi / mshflo.l */
3715 val2 = (HOST_WIDE_INT) val >> 32;
3716 if (val2 == trunc_int_for_mode (val, SImode))
3718 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3722 /* Try movi / mshflo.l w/ r63. */
3723 val2 = val + ((HOST_WIDE_INT) -1 << 32);
3724 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
3726 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3732 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3735 operands[2] = GEN_INT (val2);
3739 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3740 (match_operand:DI 1 "immediate_operand" "F"))]
3741 "TARGET_SHMEDIA && reload_completed
3742 && GET_CODE (operands[1]) == CONST_DOUBLE"
3743 [(set (match_dup 0) (match_dup 2))
3745 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3746 (zero_extend:DI (truncate:HI (match_dup 1)))))]
3749 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
3750 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
3751 unsigned HOST_WIDE_INT val = low;
3752 unsigned HOST_WIDE_INT sign;
3754 /* Sign-extend the 16 least-significant bits. */
3758 operands[1] = GEN_INT (val);
3760 /* Arithmetic shift right the double-word by 16 bits. */
3762 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
3765 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3769 /* This will only be true if high is a sign-extension of low, i.e.,
3770 it must be either 0 or (unsigned)-1, and be zero iff the
3771 most-significant bit of low is set. */
3772 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
3773 operands[2] = GEN_INT (low);
3775 operands[2] = immed_double_const (low, high, DImode);
3778 (define_insn "shori_media"
3779 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
3780 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
3784 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
3790 (define_expand "movdi"
3791 [(set (match_operand:DI 0 "general_movdst_operand" "")
3792 (match_operand:DI 1 "general_movsrc_operand" ""))]
3794 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
3796 (define_insn "movdf_media"
3797 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
3798 (match_operand:DF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
3800 && (register_operand (operands[0], DFmode)
3801 || register_operand (operands[1], DFmode))"
3812 [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
3814 (define_insn "movdf_media_nofpu"
3815 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3816 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
3818 && (register_operand (operands[0], DFmode)
3819 || register_operand (operands[1], DFmode))"
3825 [(set_attr "type" "move,*,load,store")])
3828 [(set (match_operand:DF 0 "arith_reg_operand" "")
3829 (match_operand:DF 1 "immediate_operand" ""))]
3830 "TARGET_SHMEDIA && reload_completed"
3831 [(set (match_dup 3) (match_dup 2))]
3834 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
3836 REAL_VALUE_TYPE value;
3838 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
3839 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
3841 if (HOST_BITS_PER_WIDE_INT >= 64)
3842 operands[2] = immed_double_const ((unsigned long) values[endian]
3843 | ((HOST_WIDE_INT) values[1 - endian]
3845 else if (HOST_BITS_PER_WIDE_INT == 32)
3846 operands[2] = immed_double_const (values[endian], values[1 - endian],
3851 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
3854 ;; ??? This should be a define expand.
3856 (define_insn "movdf_k"
3857 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3858 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
3860 && (! TARGET_SH4 || reload_completed
3861 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
3862 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
3863 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
3864 && (arith_reg_operand (operands[0], DFmode)
3865 || arith_reg_operand (operands[1], DFmode))"
3866 "* return output_movedouble (insn, operands, DFmode);"
3867 [(set_attr "length" "4")
3868 (set_attr "type" "move,pcload,load,store")])
3870 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
3871 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
3872 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
3873 ;; the d/m/c/X alternative, which is split later into single-precision
3874 ;; instructions. And when not optimizing, no splits are done before fixing
3875 ;; up pcloads, so we need usable length information for that.
3876 (define_insn "movdf_i4"
3877 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
3878 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
3879 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
3880 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
3882 && (arith_reg_operand (operands[0], DFmode)
3883 || arith_reg_operand (operands[1], DFmode))"
3895 [(set_attr_alternative "length"
3896 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
3898 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
3899 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3900 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3902 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
3903 ;; We can't use 4-byte push/pop on SHcompact, so we have to
3904 ;; increment or decrement r15 explicitly.
3906 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3907 (const_int 10) (const_int 8))
3909 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3910 (const_int 10) (const_int 8))])
3911 (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
3912 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
3913 (const_string "double")
3914 (const_string "none")))])
3916 ;; Moving DFmode between fp/general registers through memory
3917 ;; (the top of the stack) is faster than moving through fpul even for
3918 ;; little endian. Because the type of an instruction is important for its
3919 ;; scheduling, it is beneficial to split these operations, rather than
3920 ;; emitting them in one single chunk, even if this will expose a stack
3921 ;; use that will prevent scheduling of other stack accesses beyond this
3924 [(set (match_operand:DF 0 "register_operand" "")
3925 (match_operand:DF 1 "register_operand" ""))
3926 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3927 (clobber (match_scratch:SI 3 "=X"))]
3928 "TARGET_SH4 && reload_completed
3929 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
3935 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
3937 emit_move_insn (stack_pointer_rtx,
3938 plus_constant (stack_pointer_rtx, -8));
3939 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3942 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
3943 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
3944 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
3945 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3946 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3947 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3949 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
3950 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
3951 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3952 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
3954 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3958 ;; local-alloc sometimes allocates scratch registers even when not required,
3959 ;; so we must be prepared to handle these.
3961 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
3963 [(set (match_operand:DF 0 "general_movdst_operand" "")
3964 (match_operand:DF 1 "general_movsrc_operand" ""))
3965 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3966 (clobber (match_scratch:SI 3 "X"))]
3969 && true_regnum (operands[0]) < 16
3970 && true_regnum (operands[1]) < 16"
3971 [(set (match_dup 0) (match_dup 1))]
3974 /* If this was a reg <-> mem operation with base + index reg addressing,
3975 we have to handle this in a special way. */
3976 rtx mem = operands[0];
3978 if (! memory_operand (mem, DFmode))
3983 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
3984 mem = SUBREG_REG (mem);
3985 if (GET_CODE (mem) == MEM)
3987 rtx addr = XEXP (mem, 0);
3988 if (GET_CODE (addr) == PLUS
3989 && GET_CODE (XEXP (addr, 0)) == REG
3990 && GET_CODE (XEXP (addr, 1)) == REG)
3993 rtx reg0 = gen_rtx (REG, Pmode, 0);
3994 rtx regop = operands[store_p], word0 ,word1;
3996 if (GET_CODE (regop) == SUBREG)
3997 alter_subreg (®op);
3998 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4002 mem = copy_rtx (mem);
4003 PUT_MODE (mem, SImode);
4004 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4005 alter_subreg (&word0);
4006 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4007 alter_subreg (&word1);
4008 if (store_p || ! refers_to_regno_p (REGNO (word0),
4009 REGNO (word0) + 1, addr, 0))
4012 ? gen_movsi_ie (mem, word0)
4013 : gen_movsi_ie (word0, mem));
4014 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4015 mem = copy_rtx (mem);
4017 ? gen_movsi_ie (mem, word1)
4018 : gen_movsi_ie (word1, mem));
4019 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4023 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4024 emit_insn (gen_movsi_ie (word1, mem));
4025 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4026 mem = copy_rtx (mem);
4027 emit_insn (gen_movsi_ie (word0, mem));
4034 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4036 [(set (match_operand:DF 0 "register_operand" "")
4037 (match_operand:DF 1 "memory_operand" ""))
4038 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4039 (clobber (reg:SI R0_REG))]
4040 "TARGET_SH4 && reload_completed"
4041 [(parallel [(set (match_dup 0) (match_dup 1))
4043 (clobber (scratch:SI))])]
4046 (define_expand "reload_indf"
4047 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4048 (match_operand:DF 1 "immediate_operand" "FQ"))
4049 (use (reg:PSI FPSCR_REG))
4050 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4054 (define_expand "reload_outdf"
4055 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4056 (match_operand:DF 1 "register_operand" "af,r"))
4057 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4061 ;; Simplify no-op moves.
4063 [(set (match_operand:SF 0 "register_operand" "")
4064 (match_operand:SF 1 "register_operand" ""))
4065 (use (match_operand:PSI 2 "fpscr_operand" ""))
4066 (clobber (match_scratch:SI 3 "X"))]
4067 "TARGET_SH3E && reload_completed
4068 && true_regnum (operands[0]) == true_regnum (operands[1])"
4069 [(set (match_dup 0) (match_dup 0))]
4072 ;; fmovd substitute post-reload splits
4074 [(set (match_operand:DF 0 "register_operand" "")
4075 (match_operand:DF 1 "register_operand" ""))
4076 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4077 (clobber (match_scratch:SI 3 "X"))]
4078 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4079 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4080 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4084 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4085 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4086 gen_rtx (REG, SFmode, src), operands[2]));
4087 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4088 gen_rtx (REG, SFmode, src + 1), operands[2]));
4093 [(set (match_operand:DF 0 "register_operand" "")
4094 (mem:DF (match_operand:SI 1 "register_operand" "")))
4095 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4096 (clobber (match_scratch:SI 3 "X"))]
4097 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4098 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4099 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4103 int regno = true_regnum (operands[0]);
4105 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4107 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4108 regno + !! TARGET_LITTLE_ENDIAN),
4109 mem2, operands[2]));
4110 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4111 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4112 regno + ! TARGET_LITTLE_ENDIAN),
4113 gen_rtx (MEM, SFmode, operands[1]),
4119 [(set (match_operand:DF 0 "register_operand" "")
4120 (match_operand:DF 1 "memory_operand" ""))
4121 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4122 (clobber (match_scratch:SI 3 "X"))]
4123 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4124 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4128 int regno = true_regnum (operands[0]);
4129 rtx addr, insn, adjust = NULL_RTX;
4130 rtx mem2 = copy_rtx (operands[1]);
4131 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4132 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4134 PUT_MODE (mem2, SFmode);
4135 operands[1] = copy_rtx (mem2);
4136 addr = XEXP (mem2, 0);
4137 if (GET_CODE (addr) != POST_INC)
4139 /* If we have to modify the stack pointer, the value that we have
4140 read with post-increment might be modified by an interrupt,
4141 so write it back. */
4142 if (REGNO (addr) == STACK_POINTER_REGNUM)
4143 adjust = gen_push_e (reg0);
4145 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4146 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4148 addr = XEXP (addr, 0);
4149 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4150 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4151 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4155 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4160 [(set (match_operand:DF 0 "memory_operand" "")
4161 (match_operand:DF 1 "register_operand" ""))
4162 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4163 (clobber (match_scratch:SI 3 "X"))]
4164 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4165 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4169 int regno = true_regnum (operands[1]);
4170 rtx insn, addr, adjust = NULL_RTX;
4172 operands[0] = copy_rtx (operands[0]);
4173 PUT_MODE (operands[0], SFmode);
4174 insn = emit_insn (gen_movsf_ie (operands[0],
4175 gen_rtx (REG, SFmode,
4176 regno + ! TARGET_LITTLE_ENDIAN),
4178 operands[0] = copy_rtx (operands[0]);
4179 addr = XEXP (operands[0], 0);
4180 if (GET_CODE (addr) != PRE_DEC)
4182 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4183 emit_insn_before (adjust, insn);
4184 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4186 addr = XEXP (addr, 0);
4188 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4189 insn = emit_insn (gen_movsf_ie (operands[0],
4190 gen_rtx (REG, SFmode,
4191 regno + !! TARGET_LITTLE_ENDIAN),
4193 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4197 ;; If the output is a register and the input is memory or a register, we have
4198 ;; to be careful and see which word needs to be loaded first.
4201 [(set (match_operand:DF 0 "general_movdst_operand" "")
4202 (match_operand:DF 1 "general_movsrc_operand" ""))]
4203 "TARGET_SH1 && reload_completed"
4204 [(set (match_dup 2) (match_dup 3))
4205 (set (match_dup 4) (match_dup 5))]
4210 if ((GET_CODE (operands[0]) == MEM
4211 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4212 || (GET_CODE (operands[1]) == MEM
4213 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4216 if (GET_CODE (operands[0]) == REG)
4217 regno = REGNO (operands[0]);
4218 else if (GET_CODE (operands[0]) == SUBREG)
4219 regno = subreg_regno (operands[0]);
4220 else if (GET_CODE (operands[0]) == MEM)
4226 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4228 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4229 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4230 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4231 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4235 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4236 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4237 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4238 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4241 if (operands[2] == 0 || operands[3] == 0
4242 || operands[4] == 0 || operands[5] == 0)
4246 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4247 ;; used only once, let combine add in the index again.
4250 [(set (match_operand:SI 0 "register_operand" "")
4251 (match_operand:SI 1 "" ""))
4252 (clobber (match_operand 2 "register_operand" ""))]
4253 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4254 [(use (reg:SI R0_REG))]
4257 rtx addr, reg, const_int;
4259 if (GET_CODE (operands[1]) != MEM)
4261 addr = XEXP (operands[1], 0);
4262 if (GET_CODE (addr) != PLUS)
4264 reg = XEXP (addr, 0);
4265 const_int = XEXP (addr, 1);
4266 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4267 && GET_CODE (const_int) == CONST_INT))
4269 emit_move_insn (operands[2], const_int);
4270 emit_move_insn (operands[0],
4271 change_address (operands[1], VOIDmode,
4272 gen_rtx_PLUS (SImode, reg, operands[2])));
4277 [(set (match_operand:SI 1 "" "")
4278 (match_operand:SI 0 "register_operand" ""))
4279 (clobber (match_operand 2 "register_operand" ""))]
4280 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4281 [(use (reg:SI R0_REG))]
4284 rtx addr, reg, const_int;
4286 if (GET_CODE (operands[1]) != MEM)
4288 addr = XEXP (operands[1], 0);
4289 if (GET_CODE (addr) != PLUS)
4291 reg = XEXP (addr, 0);
4292 const_int = XEXP (addr, 1);
4293 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4294 && GET_CODE (const_int) == CONST_INT))
4296 emit_move_insn (operands[2], const_int);
4297 emit_move_insn (change_address (operands[1], VOIDmode,
4298 gen_rtx_PLUS (SImode, reg, operands[2])),
4303 (define_expand "movdf"
4304 [(set (match_operand:DF 0 "general_movdst_operand" "")
4305 (match_operand:DF 1 "general_movsrc_operand" ""))]
4309 if (prepare_move_operands (operands, DFmode)) DONE;
4312 if (TARGET_SHMEDIA_FPU)
4313 emit_insn (gen_movdf_media (operands[0], operands[1]));
4315 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4320 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4325 (define_insn "movv2sf_i"
4326 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4327 (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4329 && (fp_arith_reg_operand (operands[0], V2SFmode)
4330 || fp_arith_reg_operand (operands[1], V2SFmode))"
4337 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f")
4338 (match_operand:V2SF 1 "nonimmediate_operand" "f"))]
4339 "TARGET_SHMEDIA_FPU && reload_completed
4340 && fp_arith_reg_operand (operands[0], V2SFmode)
4341 && fp_arith_reg_operand (operands[1], V2SFmode)"
4342 [(set (subreg:DF (match_dup 0) 0) (subreg:DF (match_dup 1) 0))])
4344 (define_expand "movv2sf"
4345 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4346 (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4347 "TARGET_SHMEDIA_FPU"
4350 if (prepare_move_operands (operands, V2SFmode))
4354 (define_insn_and_split "*movv4sf_i"
4355 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4356 (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4357 "TARGET_SHMEDIA_FPU"
4359 "&& reload_completed"
4365 for (i = 0; i < 4/2; i++)
4369 if (GET_CODE (operands[0]) == MEM)
4370 x = gen_rtx_MEM (V2SFmode,
4371 plus_constant (XEXP (operands[0], 0),
4372 i * GET_MODE_SIZE (V2SFmode)));
4375 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4379 if (GET_CODE (operands[1]) == MEM)
4380 y = gen_rtx_MEM (V2SFmode,
4381 plus_constant (XEXP (operands[1], 0),
4382 i * GET_MODE_SIZE (V2SFmode)));
4385 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4389 emit_insn (gen_movv2sf_i (x, y));
4394 [(set_attr "length" "8")])
4396 (define_expand "movv4sf"
4397 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4398 (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4399 "TARGET_SHMEDIA_FPU"
4402 if (prepare_move_operands (operands, V4SFmode))
4406 (define_insn_and_split "*movv16sf_i"
4407 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4408 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4409 "TARGET_SHMEDIA_FPU"
4411 "&& reload_completed"
4417 for (i = 0; i < 16/2; i++)
4421 if (GET_CODE (operands[0]) == MEM)
4422 x = gen_rtx_MEM (V2SFmode,
4423 plus_constant (XEXP (operands[0], 0),
4424 i * GET_MODE_SIZE (V2SFmode)));
4427 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4431 if (GET_CODE (operands[1]) == MEM)
4432 y = gen_rtx_MEM (V2SFmode,
4433 plus_constant (XEXP (operands[1], 0),
4434 i * GET_MODE_SIZE (V2SFmode)));
4437 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4441 emit_insn (gen_movv2sf_i (x, y));
4446 [(set_attr "length" "32")])
4448 (define_expand "movv16sf"
4449 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4450 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4451 "TARGET_SHMEDIA_FPU"
4454 if (prepare_move_operands (operands, V16SFmode))
4458 (define_insn "movsf_media"
4459 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4460 (match_operand:SF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
4462 && (register_operand (operands[0], SFmode)
4463 || register_operand (operands[1], SFmode))"
4474 [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
4476 (define_insn "movsf_media_nofpu"
4477 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4478 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4480 && (register_operand (operands[0], SFmode)
4481 || register_operand (operands[1], SFmode))"
4487 [(set_attr "type" "move,*,load,store")])
4490 [(set (match_operand:SF 0 "arith_reg_operand" "")
4491 (match_operand:SF 1 "immediate_operand" ""))]
4492 "TARGET_SHMEDIA && reload_completed"
4493 [(set (match_dup 3) (match_dup 2))]
4497 REAL_VALUE_TYPE value;
4499 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4500 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4501 operands[2] = GEN_INT (values);
4503 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4506 (define_insn "movsf_i"
4507 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4508 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4511 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4512 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4513 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4514 && (arith_reg_operand (operands[0], SFmode)
4515 || arith_reg_operand (operands[1], SFmode))"
4524 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4526 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4527 ;; update_flow_info would not know where to put REG_EQUAL notes
4528 ;; when the destination changes mode.
4529 (define_insn "movsf_ie"
4530 [(set (match_operand:SF 0 "general_movdst_operand"
4531 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4532 (match_operand:SF 1 "general_movsrc_operand"
4533 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4534 (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"))
4535 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4538 && (arith_reg_operand (operands[0], SFmode)
4539 || arith_reg_operand (operands[1], SFmode)
4540 || arith_reg_operand (operands[3], SImode)
4541 || (fpul_operand (operands[0], SFmode)
4542 && memory_operand (operands[1], SFmode)
4543 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4544 || (fpul_operand (operands[1], SFmode)
4545 && memory_operand (operands[0], SFmode)
4546 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4566 ! move optimized away"
4567 [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
4568 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4569 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4570 (const_string "single")
4571 (const_string "none")))])
4574 [(set (match_operand:SF 0 "register_operand" "")
4575 (match_operand:SF 1 "register_operand" ""))
4576 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4577 (clobber (reg:SI FPUL_REG))]
4579 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4581 (clobber (scratch:SI))])
4582 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4584 (clobber (scratch:SI))])]
4587 (define_expand "movsf"
4588 [(set (match_operand:SF 0 "general_movdst_operand" "")
4589 (match_operand:SF 1 "general_movsrc_operand" ""))]
4593 if (prepare_move_operands (operands, SFmode))
4597 if (TARGET_SHMEDIA_FPU)
4598 emit_insn (gen_movsf_media (operands[0], operands[1]));
4600 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4605 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4610 (define_insn "mov_nop"
4611 [(set (match_operand 0 "register_operand" "") (match_dup 0))]
4614 [(set_attr "length" "0")
4615 (set_attr "type" "nil")])
4617 (define_expand "reload_insf"
4618 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4619 (match_operand:SF 1 "immediate_operand" "FQ"))
4620 (use (reg:PSI FPSCR_REG))
4621 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4625 (define_expand "reload_insi"
4626 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4627 (match_operand:SF 1 "immediate_operand" "FQ"))
4628 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4632 (define_insn "*movsi_y"
4633 [(set (match_operand:SI 0 "register_operand" "=y,y")
4634 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4635 (clobber (match_scratch:SI 2 "=&z,r"))]
4637 && (reload_in_progress || reload_completed)"
4639 [(set_attr "length" "4")
4640 (set_attr "type" "pcload,move")])
4643 [(set (match_operand:SI 0 "register_operand" "")
4644 (match_operand:SI 1 "immediate_operand" ""))
4645 (clobber (match_operand:SI 2 "register_operand" ""))]
4647 [(set (match_dup 2) (match_dup 1))
4648 (set (match_dup 0) (match_dup 2))]
4652 [(set (match_operand:SI 0 "register_operand" "")
4653 (match_operand:SI 1 "memory_operand" ""))
4654 (clobber (reg:SI R0_REG))]
4656 [(set (match_dup 0) (match_dup 1))]
4659 ;; ------------------------------------------------------------------------
4660 ;; Define the real conditional branch instructions.
4661 ;; ------------------------------------------------------------------------
4663 (define_insn "branch_true"
4664 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4665 (label_ref (match_operand 0 "" ""))
4668 "* return output_branch (1, insn, operands);"
4669 [(set_attr "type" "cbranch")])
4671 (define_insn "branch_false"
4672 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4673 (label_ref (match_operand 0 "" ""))
4676 "* return output_branch (0, insn, operands);"
4677 [(set_attr "type" "cbranch")])
4679 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4680 ;; which destination is too far away.
4681 ;; The const_int_operand is distinct for each branch target; it avoids
4682 ;; unwanted matches with redundant_insn.
4683 (define_insn "block_branch_redirect"
4684 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4687 [(set_attr "length" "0")])
4689 ;; This one has the additional purpose to record a possible scratch register
4690 ;; for the following branch.
4691 (define_insn "indirect_jump_scratch"
4692 [(set (match_operand 0 "register_operand" "=r")
4693 (unspec [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
4696 [(set_attr "length" "0")])
4698 ;; Conditional branch insns
4700 (define_expand "beq_media"
4702 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4703 (match_operand:DI 2 "arith_operand" "r,O"))
4704 (label_ref:DI (match_operand 0 "" ""))
4709 (define_insn "beq_media_i"
4711 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4712 (match_operand:DI 2 "arith_operand" "r,O"))
4713 (match_operand:DI 0 "target_operand" "b,b")
4720 (define_expand "bne_media"
4722 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4723 (match_operand:DI 2 "arith_operand" "r,O"))
4724 (label_ref:DI (match_operand 0 "" ""))
4729 (define_insn "bne_media_i"
4731 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4732 (match_operand:DI 2 "arith_operand" "r,O"))
4733 (match_operand:DI 0 "target_operand" "b,b")
4740 (define_expand "bgt_media"
4742 (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4743 (match_operand:DI 2 "arith_reg_operand" "r"))
4744 (label_ref:DI (match_operand 0 "" ""))
4749 (define_insn "bgt_media_i"
4751 (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4752 (match_operand:DI 2 "arith_reg_operand" "r"))
4753 (match_operand:DI 0 "target_operand" "b")
4758 (define_expand "bge_media"
4760 (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4761 (match_operand:DI 2 "arith_reg_operand" "r"))
4762 (label_ref:DI (match_operand 0 "" ""))
4767 (define_insn "bge_media_i"
4769 (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4770 (match_operand:DI 2 "arith_reg_operand" "r"))
4771 (match_operand:DI 0 "target_operand" "b")
4776 (define_expand "bgtu_media"
4778 (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4779 (match_operand:DI 2 "arith_reg_operand" "r"))
4780 (label_ref:DI (match_operand 0 "" ""))
4785 (define_insn "bgtu_media_i"
4787 (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4788 (match_operand:DI 2 "arith_reg_operand" "r"))
4789 (match_operand:DI 0 "target_operand" "b")
4794 (define_expand "bgeu_media"
4796 (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4797 (match_operand:DI 2 "arith_reg_operand" "r"))
4798 (label_ref:DI (match_operand 0 "" ""))
4803 (define_insn "bgeu_media_i"
4805 (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4806 (match_operand:DI 2 "arith_reg_operand" "r"))
4807 (match_operand:DI 0 "target_operand" "b")
4812 ;; These are only needed to make invert_jump() happy.
4813 (define_insn "*ble_media_i"
4815 (if_then_else (le (match_operand:DI 1 "arith_reg_operand" "r")
4816 (match_operand:DI 2 "arith_reg_operand" "r"))
4817 (match_operand:DI 0 "target_operand" "b")
4822 (define_insn "*blt_media_i"
4824 (if_then_else (lt (match_operand:DI 1 "arith_reg_operand" "r")
4825 (match_operand:DI 2 "arith_reg_operand" "r"))
4826 (match_operand:DI 0 "target_operand" "b")
4831 (define_insn "*bleu_media_i"
4833 (if_then_else (leu (match_operand:DI 1 "arith_reg_operand" "r")
4834 (match_operand:DI 2 "arith_reg_operand" "r"))
4835 (match_operand:DI 0 "target_operand" "b")
4840 (define_insn "*bltu_media_i"
4842 (if_then_else (ltu (match_operand:DI 1 "arith_reg_operand" "r")
4843 (match_operand:DI 2 "arith_reg_operand" "r"))
4844 (match_operand:DI 0 "target_operand" "b")
4849 (define_expand "beq"
4851 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4852 (label_ref (match_operand 0 "" ""))
4859 if (GET_MODE (sh_compare_op0) != DImode)
4861 rtx tmp = gen_reg_rtx (DImode);
4863 emit_insn (gen_seq (tmp));
4864 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4868 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4869 emit_jump_insn (gen_beq_media (operands[0],
4870 sh_compare_op0, sh_compare_op1));
4874 from_compare (operands, EQ);
4877 (define_expand "bne"
4879 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4880 (label_ref (match_operand 0 "" ""))
4887 if (GET_MODE (sh_compare_op0) != DImode)
4889 rtx tmp = gen_reg_rtx (DImode);
4891 emit_insn (gen_seq (tmp));
4892 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
4896 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4897 emit_jump_insn (gen_bne_media (operands[0],
4898 sh_compare_op0, sh_compare_op1));
4902 from_compare (operands, EQ);
4905 (define_expand "bgt"
4907 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4908 (label_ref (match_operand 0 "" ""))
4915 if (GET_MODE (sh_compare_op0) != DImode)
4917 rtx tmp = gen_reg_rtx (DImode);
4919 emit_insn (gen_sgt (tmp));
4920 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4924 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4925 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4926 emit_jump_insn (gen_bgt_media (operands[0],
4927 sh_compare_op0, sh_compare_op1));
4931 from_compare (operands, GT);
4934 (define_expand "blt"
4936 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4937 (label_ref (match_operand 0 "" ""))
4944 if (GET_MODE (sh_compare_op0) != DImode)
4946 rtx tmp = gen_reg_rtx (DImode);
4948 emit_insn (gen_slt (tmp));
4949 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4953 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4954 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4955 emit_jump_insn (gen_bgt_media (operands[0],
4956 sh_compare_op1, sh_compare_op0));
4960 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4962 rtx tmp = sh_compare_op0;
4963 sh_compare_op0 = sh_compare_op1;
4964 sh_compare_op1 = tmp;
4965 emit_insn (gen_bgt (operands[0]));
4968 from_compare (operands, GE);
4971 (define_expand "ble"
4973 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4974 (label_ref (match_operand 0 "" ""))
4981 if (GET_MODE (sh_compare_op0) != DImode)
4983 rtx tmp = gen_reg_rtx (DImode);
4985 emit_insn (gen_sle (tmp));
4986 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4990 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4991 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4992 emit_jump_insn (gen_bge_media (operands[0],
4993 sh_compare_op1, sh_compare_op0));
4999 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5001 rtx tmp = sh_compare_op0;
5002 sh_compare_op0 = sh_compare_op1;
5003 sh_compare_op1 = tmp;
5004 emit_insn (gen_bge (operands[0]));
5007 from_compare (operands, GT);
5010 (define_expand "bge"
5012 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5013 (label_ref (match_operand 0 "" ""))
5020 if (GET_MODE (sh_compare_op0) != DImode)
5022 rtx tmp = gen_reg_rtx (DImode);
5024 emit_insn (gen_sge (tmp));
5025 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5029 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5030 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5031 emit_jump_insn (gen_bge_media (operands[0],
5032 sh_compare_op0, sh_compare_op1));
5038 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5040 rtx tmp = sh_compare_op0;
5041 sh_compare_op0 = sh_compare_op1;
5042 sh_compare_op1 = tmp;
5043 emit_insn (gen_ble (operands[0]));
5046 from_compare (operands, GE);
5049 (define_expand "bgtu"
5051 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5052 (label_ref (match_operand 0 "" ""))
5059 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5060 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5061 emit_jump_insn (gen_bgtu_media (operands[0],
5062 sh_compare_op0, sh_compare_op1));
5066 from_compare (operands, GTU);
5069 (define_expand "bltu"
5071 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5072 (label_ref (match_operand 0 "" ""))
5079 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5080 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5081 emit_jump_insn (gen_bgtu_media (operands[0],
5082 sh_compare_op1, sh_compare_op0));
5086 from_compare (operands, GEU);
5089 (define_expand "bgeu"
5091 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5092 (label_ref (match_operand 0 "" ""))
5099 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5100 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5101 emit_jump_insn (gen_bgeu_media (operands[0],
5102 sh_compare_op0, sh_compare_op1));
5106 from_compare (operands, GEU);
5109 (define_expand "bleu"
5111 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5112 (label_ref (match_operand 0 "" ""))
5119 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5120 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5121 emit_jump_insn (gen_bgeu_media (operands[0],
5122 sh_compare_op1, sh_compare_op0));
5126 from_compare (operands, GTU);
5129 (define_expand "bunordered"
5130 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5132 (if_then_else (ne (match_dup 1) (const_int 0))
5133 (label_ref:DI (match_operand 0 "" ""))
5138 operands[1] = gen_reg_rtx (DImode);
5139 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5140 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5143 ;; ------------------------------------------------------------------------
5144 ;; Jump and linkage insns
5145 ;; ------------------------------------------------------------------------
5147 (define_insn "jump_compact"
5149 (label_ref (match_operand 0 "" "")))]
5153 /* The length is 16 if the delay slot is unfilled. */
5154 if (get_attr_length(insn) > 4)
5155 return output_far_jump(insn, operands[0]);
5157 return \"bra %l0%#\";
5159 [(set_attr "type" "jump")
5160 (set_attr "needs_delay_slot" "yes")])
5162 (define_insn "jump_media"
5164 (match_operand:DI 0 "target_operand" "b"))]
5168 (define_expand "jump"
5170 (label_ref (match_operand 0 "" "")))]
5175 emit_jump_insn (gen_jump_compact (operands[0]));
5176 else if (TARGET_SHMEDIA)
5178 if (reload_in_progress || reload_completed)
5180 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5186 (define_insn "force_mode_for_call"
5187 [(use (reg:PSI FPSCR_REG))]
5190 [(set_attr "length" "0")
5191 (set (attr "fp_mode")
5192 (if_then_else (eq_attr "fpu_single" "yes")
5193 (const_string "single") (const_string "double")))])
5195 (define_insn "calli"
5196 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5197 (match_operand 1 "" ""))
5198 (use (reg:PSI FPSCR_REG))
5199 (clobber (reg:SI PR_REG))]
5202 [(set_attr "type" "call")
5203 (set (attr "fp_mode")
5204 (if_then_else (eq_attr "fpu_single" "yes")
5205 (const_string "single") (const_string "double")))
5206 (set_attr "needs_delay_slot" "yes")])
5208 ;; This is a pc-rel call, using bsrf, for use with PIC.
5210 (define_insn "calli_pcrel"
5211 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5212 (match_operand 1 "" ""))
5213 (use (reg:PSI FPSCR_REG))
5214 (use (reg:SI PIC_REG))
5215 (use (match_operand 2 "" ""))
5216 (clobber (reg:SI PR_REG))]
5219 [(set_attr "type" "call")
5220 (set (attr "fp_mode")
5221 (if_then_else (eq_attr "fpu_single" "yes")
5222 (const_string "single") (const_string "double")))
5223 (set_attr "needs_delay_slot" "yes")])
5225 (define_insn_and_split "call_pcrel"
5226 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5227 (match_operand 1 "" ""))
5228 (use (reg:PSI FPSCR_REG))
5229 (use (reg:SI PIC_REG))
5230 (clobber (reg:SI PR_REG))
5231 (clobber (match_scratch:SI 2 "=r"))]
5238 rtx lab = PATTERN (gen_call_site ());
5240 if (SYMBOL_REF_FLAG (operands[0]))
5241 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5243 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5244 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5247 [(set_attr "type" "call")
5248 (set (attr "fp_mode")
5249 (if_then_else (eq_attr "fpu_single" "yes")
5250 (const_string "single") (const_string "double")))
5251 (set_attr "needs_delay_slot" "yes")])
5253 (define_insn "call_compact"
5254 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5255 (match_operand 1 "" ""))
5256 (match_operand 2 "immediate_operand" "n")
5257 (use (reg:SI R0_REG))
5258 (use (reg:SI R1_REG))
5259 (use (reg:PSI FPSCR_REG))
5260 (clobber (reg:SI PR_REG))]
5261 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5263 [(set_attr "type" "call")
5264 (set (attr "fp_mode")
5265 (if_then_else (eq_attr "fpu_single" "yes")
5266 (const_string "single") (const_string "double")))
5267 (set_attr "needs_delay_slot" "yes")])
5269 (define_insn "call_compact_rettramp"
5270 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5271 (match_operand 1 "" ""))
5272 (match_operand 2 "immediate_operand" "n")
5273 (use (reg:SI R0_REG))
5274 (use (reg:SI R1_REG))
5275 (use (reg:PSI FPSCR_REG))
5276 (clobber (reg:SI R10_REG))
5277 (clobber (reg:SI PR_REG))]
5278 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5280 [(set_attr "type" "call")
5281 (set (attr "fp_mode")
5282 (if_then_else (eq_attr "fpu_single" "yes")
5283 (const_string "single") (const_string "double")))
5284 (set_attr "needs_delay_slot" "yes")])
5286 (define_insn "call_media"
5287 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5288 (match_operand 1 "" ""))
5289 (clobber (reg:DI PR_MEDIA_REG))]
5293 (define_insn "call_valuei"
5294 [(set (match_operand 0 "" "=rf")
5295 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5296 (match_operand 2 "" "")))
5297 (use (reg:PSI FPSCR_REG))
5298 (clobber (reg:SI PR_REG))]
5301 [(set_attr "type" "call")
5302 (set (attr "fp_mode")
5303 (if_then_else (eq_attr "fpu_single" "yes")
5304 (const_string "single") (const_string "double")))
5305 (set_attr "needs_delay_slot" "yes")])
5307 (define_insn "call_valuei_pcrel"
5308 [(set (match_operand 0 "" "=rf")
5309 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5310 (match_operand 2 "" "")))
5311 (use (reg:PSI FPSCR_REG))
5312 (use (reg:SI PIC_REG))
5313 (use (match_operand 3 "" ""))
5314 (clobber (reg:SI PR_REG))]
5317 [(set_attr "type" "call")
5318 (set (attr "fp_mode")
5319 (if_then_else (eq_attr "fpu_single" "yes")
5320 (const_string "single") (const_string "double")))
5321 (set_attr "needs_delay_slot" "yes")])
5323 (define_insn_and_split "call_value_pcrel"
5324 [(set (match_operand 0 "" "=rf")
5325 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5326 (match_operand 2 "" "")))
5327 (use (reg:PSI FPSCR_REG))
5328 (use (reg:SI PIC_REG))
5329 (clobber (reg:SI PR_REG))
5330 (clobber (match_scratch:SI 3 "=r"))]
5337 rtx lab = PATTERN (gen_call_site ());
5339 if (SYMBOL_REF_FLAG (operands[1]))
5340 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5342 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5343 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5347 [(set_attr "type" "call")
5348 (set (attr "fp_mode")
5349 (if_then_else (eq_attr "fpu_single" "yes")
5350 (const_string "single") (const_string "double")))
5351 (set_attr "needs_delay_slot" "yes")])
5353 (define_insn "call_value_compact"
5354 [(set (match_operand 0 "" "=rf")
5355 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5356 (match_operand 2 "" "")))
5357 (match_operand 3 "immediate_operand" "n")
5358 (use (reg:SI R0_REG))
5359 (use (reg:SI R1_REG))
5360 (use (reg:PSI FPSCR_REG))
5361 (clobber (reg:SI PR_REG))]
5362 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5364 [(set_attr "type" "call")
5365 (set (attr "fp_mode")
5366 (if_then_else (eq_attr "fpu_single" "yes")
5367 (const_string "single") (const_string "double")))
5368 (set_attr "needs_delay_slot" "yes")])
5370 (define_insn "call_value_compact_rettramp"
5371 [(set (match_operand 0 "" "=rf")
5372 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5373 (match_operand 2 "" "")))
5374 (match_operand 3 "immediate_operand" "n")
5375 (use (reg:SI R0_REG))
5376 (use (reg:SI R1_REG))
5377 (use (reg:PSI FPSCR_REG))
5378 (clobber (reg:SI R10_REG))
5379 (clobber (reg:SI PR_REG))]
5380 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5382 [(set_attr "type" "call")
5383 (set (attr "fp_mode")
5384 (if_then_else (eq_attr "fpu_single" "yes")
5385 (const_string "single") (const_string "double")))
5386 (set_attr "needs_delay_slot" "yes")])
5388 (define_insn "call_value_media"
5389 [(set (match_operand 0 "" "=rf")
5390 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5391 (match_operand 2 "" "")))
5392 (clobber (reg:DI PR_MEDIA_REG))]
5396 (define_expand "call"
5397 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5398 (match_operand 1 "" ""))
5399 (match_operand 2 "" "")
5400 (use (reg:PSI FPSCR_REG))
5401 (clobber (reg:SI PR_REG))])]
5407 operands[0] = XEXP (operands[0], 0);
5408 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5410 if (! SYMBOL_REF_FLAG (operands[0]))
5412 rtx reg = gen_reg_rtx (Pmode);
5414 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5419 operands[0] = gen_sym2PIC (operands[0]);
5420 PUT_MODE (operands[0], Pmode);
5423 if (GET_MODE (operands[0]) == SImode)
5425 if (GET_CODE (operands[0]) == REG)
5426 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5427 else if (GET_CODE (operands[0]) == SUBREG)
5429 operands[0] = SUBREG_REG (operands[0]);
5430 if (GET_MODE (operands[0]) != DImode)
5431 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5435 operands[0] = shallow_copy_rtx (operands[0]);
5436 PUT_MODE (operands[0], DImode);
5439 if (! target_reg_operand (operands[0], DImode))
5440 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5441 emit_call_insn (gen_call_media (operands[0], operands[1]));
5444 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5446 rtx cookie_rtx = operands[2];
5447 long cookie = INTVAL (cookie_rtx);
5448 rtx func = XEXP (operands[0], 0);
5453 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5455 rtx reg = gen_reg_rtx (Pmode);
5457 emit_insn (gen_symGOTPLT2reg (reg, func));
5461 func = legitimize_pic_address (func, Pmode, 0);
5464 r0 = gen_rtx_REG (SImode, R0_REG);
5465 r1 = gen_rtx_REG (SImode, R1_REG);
5467 /* Since such a call function may use all call-clobbered
5468 registers, we force a mode switch earlier, so that we don't
5469 run out of registers when adjusting fpscr for the call. */
5470 emit_insn (gen_force_mode_for_call ());
5472 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5473 \"__GCC_shcompact_call_trampoline\");
5476 rtx reg = gen_reg_rtx (Pmode);
5478 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5481 operands[0] = force_reg (SImode, operands[0]);
5483 emit_move_insn (r0, func);
5484 emit_move_insn (r1, cookie_rtx);
5486 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5487 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5490 emit_call_insn (gen_call_compact (operands[0], operands[1],
5495 else if (TARGET_SHCOMPACT && flag_pic
5496 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5497 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5499 rtx reg = gen_reg_rtx (Pmode);
5501 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5502 XEXP (operands[0], 0) = reg;
5504 if (flag_pic && TARGET_SH2
5505 && GET_CODE (operands[0]) == MEM
5506 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5508 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5512 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5514 emit_call_insn (gen_calli (operands[0], operands[1]));
5518 (define_insn "call_pop_compact"
5519 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5520 (match_operand 1 "" ""))
5521 (match_operand 2 "immediate_operand" "n")
5522 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5523 (match_operand 3 "immediate_operand" "n")))
5524 (use (reg:SI R0_REG))
5525 (use (reg:SI R1_REG))
5526 (use (reg:PSI FPSCR_REG))
5527 (clobber (reg:SI PR_REG))]
5528 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5530 [(set_attr "type" "call")
5531 (set (attr "fp_mode")
5532 (if_then_else (eq_attr "fpu_single" "yes")
5533 (const_string "single") (const_string "double")))
5534 (set_attr "needs_delay_slot" "yes")])
5536 (define_insn "call_pop_compact_rettramp"
5537 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5538 (match_operand 1 "" ""))
5539 (match_operand 2 "immediate_operand" "n")
5540 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5541 (match_operand 3 "immediate_operand" "n")))
5542 (use (reg:SI R0_REG))
5543 (use (reg:SI R1_REG))
5544 (use (reg:PSI FPSCR_REG))
5545 (clobber (reg:SI R10_REG))
5546 (clobber (reg:SI PR_REG))]
5547 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5549 [(set_attr "type" "call")
5550 (set (attr "fp_mode")
5551 (if_then_else (eq_attr "fpu_single" "yes")
5552 (const_string "single") (const_string "double")))
5553 (set_attr "needs_delay_slot" "yes")])
5555 (define_expand "call_pop"
5556 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5557 (match_operand 1 "" ""))
5558 (match_operand 2 "" "")
5559 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5560 (match_operand 3 "" "")))])]
5564 if (operands[2] && INTVAL (operands[2]))
5566 rtx cookie_rtx = operands[2];
5567 long cookie = INTVAL (cookie_rtx);
5568 rtx func = XEXP (operands[0], 0);
5573 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5575 rtx reg = gen_reg_rtx (Pmode);
5577 emit_insn (gen_symGOTPLT2reg (reg, func));
5581 func = legitimize_pic_address (func, Pmode, 0);
5584 r0 = gen_rtx_REG (SImode, R0_REG);
5585 r1 = gen_rtx_REG (SImode, R1_REG);
5587 /* Since such a call function may use all call-clobbered
5588 registers, we force a mode switch earlier, so that we don't
5589 run out of registers when adjusting fpscr for the call. */
5590 emit_insn (gen_force_mode_for_call ());
5592 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5593 \"__GCC_shcompact_call_trampoline\");
5596 rtx reg = gen_reg_rtx (Pmode);
5598 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5601 operands[0] = force_reg (SImode, operands[0]);
5603 emit_move_insn (r0, func);
5604 emit_move_insn (r1, cookie_rtx);
5606 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5607 emit_call_insn (gen_call_pop_compact_rettramp
5608 (operands[0], operands[1], operands[2], operands[3]));
5610 emit_call_insn (gen_call_pop_compact
5611 (operands[0], operands[1], operands[2], operands[3]));
5619 (define_expand "call_value"
5620 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5621 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5622 (match_operand 2 "" "")))
5623 (match_operand 3 "" "")
5624 (use (reg:PSI FPSCR_REG))
5625 (clobber (reg:SI PR_REG))])]
5631 operands[1] = XEXP (operands[1], 0);
5632 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5634 if (! SYMBOL_REF_FLAG (operands[1]))
5636 rtx reg = gen_reg_rtx (Pmode);
5638 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5643 operands[1] = gen_sym2PIC (operands[1]);
5644 PUT_MODE (operands[1], Pmode);
5647 if (GET_MODE (operands[1]) == SImode)
5649 if (GET_CODE (operands[1]) == REG)
5650 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5651 else if (GET_CODE (operands[1]) == SUBREG)
5653 operands[1] = SUBREG_REG (operands[1]);
5654 if (GET_MODE (operands[1]) != DImode)
5655 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5659 operands[1] = shallow_copy_rtx (operands[1]);
5660 PUT_MODE (operands[1], DImode);
5663 if (! target_reg_operand (operands[1], DImode))
5664 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5665 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5669 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5671 rtx cookie_rtx = operands[3];
5672 long cookie = INTVAL (cookie_rtx);
5673 rtx func = XEXP (operands[1], 0);
5678 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5680 rtx reg = gen_reg_rtx (Pmode);
5682 emit_insn (gen_symGOTPLT2reg (reg, func));
5686 func = legitimize_pic_address (func, Pmode, 0);
5689 r0 = gen_rtx_REG (SImode, R0_REG);
5690 r1 = gen_rtx_REG (SImode, R1_REG);
5692 /* Since such a call function may use all call-clobbered
5693 registers, we force a mode switch earlier, so that we don't
5694 run out of registers when adjusting fpscr for the call. */
5695 emit_insn (gen_force_mode_for_call ());
5697 operands[1] = gen_rtx_SYMBOL_REF (SImode,
5698 \"__GCC_shcompact_call_trampoline\");
5701 rtx reg = gen_reg_rtx (Pmode);
5703 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5706 operands[1] = force_reg (SImode, operands[1]);
5708 emit_move_insn (r0, func);
5709 emit_move_insn (r1, cookie_rtx);
5711 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5712 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
5717 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
5718 operands[2], operands[3]));
5722 else if (TARGET_SHCOMPACT && flag_pic
5723 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
5724 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
5726 rtx reg = gen_reg_rtx (Pmode);
5728 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
5729 XEXP (operands[1], 0) = reg;
5731 if (flag_pic && TARGET_SH2
5732 && GET_CODE (operands[1]) == MEM
5733 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5735 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
5740 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
5742 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
5746 (define_insn "sibcalli"
5747 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5748 (match_operand 1 "" ""))
5749 (use (reg:PSI FPSCR_REG))
5753 [(set_attr "needs_delay_slot" "yes")
5754 (set (attr "fp_mode")
5755 (if_then_else (eq_attr "fpu_single" "yes")
5756 (const_string "single") (const_string "double")))
5757 (set_attr "type" "jump_ind")])
5759 (define_insn "sibcalli_pcrel"
5760 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5761 (match_operand 1 "" ""))
5762 (use (match_operand 2 "" ""))
5763 (use (reg:PSI FPSCR_REG))
5767 [(set_attr "needs_delay_slot" "yes")
5768 (set (attr "fp_mode")
5769 (if_then_else (eq_attr "fpu_single" "yes")
5770 (const_string "single") (const_string "double")))
5771 (set_attr "type" "jump_ind")])
5773 (define_insn_and_split "sibcall_pcrel"
5774 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5775 (match_operand 1 "" ""))
5776 (use (reg:PSI FPSCR_REG))
5777 (clobber (match_scratch:SI 2 "=k"))
5785 rtx lab = PATTERN (gen_call_site ());
5788 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5789 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
5791 SIBLING_CALL_P (call_insn) = 1;
5794 [(set_attr "needs_delay_slot" "yes")
5795 (set (attr "fp_mode")
5796 (if_then_else (eq_attr "fpu_single" "yes")
5797 (const_string "single") (const_string "double")))
5798 (set_attr "type" "jump_ind")])
5800 (define_insn "sibcall_compact"
5801 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
5802 (match_operand 1 "" ""))
5804 (use (match_operand 2 "register_operand" "z,x"))
5805 (use (reg:SI R1_REG))
5806 (use (reg:PSI FPSCR_REG))
5807 ;; We want to make sure the `x' above will only match MACH_REG
5808 ;; because sibcall_epilogue may clobber MACL_REG.
5809 (clobber (reg:SI MACL_REG))]
5813 jmp @%0\\n sts %2, r0"
5814 [(set_attr "needs_delay_slot" "yes,no")
5815 (set_attr "length" "2,4")
5816 (set (attr "fp_mode") (const_string "single"))
5817 (set_attr "type" "jump_ind")])
5819 (define_insn "sibcall_media"
5820 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
5821 (match_operand 1 "" ""))
5826 (define_expand "sibcall"
5828 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5829 (match_operand 1 "" ""))
5830 (match_operand 2 "" "")
5831 (use (reg:PSI FPSCR_REG))
5838 operands[0] = XEXP (operands[0], 0);
5839 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5841 if (! SYMBOL_REF_FLAG (operands[0]))
5843 rtx reg = gen_reg_rtx (Pmode);
5845 /* We must not use GOTPLT for sibcalls, because PIC_REG
5846 must be restored before the PLT code gets to run. */
5847 emit_insn (gen_symGOT2reg (reg, operands[0]));
5852 operands[0] = gen_sym2PIC (operands[0]);
5853 PUT_MODE (operands[0], Pmode);
5856 if (GET_MODE (operands[0]) == SImode)
5858 if (GET_CODE (operands[0]) == REG)
5859 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5860 else if (GET_CODE (operands[0]) == SUBREG)
5862 operands[0] = SUBREG_REG (operands[0]);
5863 if (GET_MODE (operands[0]) != DImode)
5864 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5868 operands[0] = shallow_copy_rtx (operands[0]);
5869 PUT_MODE (operands[0], DImode);
5872 if (! target_reg_operand (operands[0], DImode))
5873 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5874 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
5877 else if (TARGET_SHCOMPACT && operands[2]
5878 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
5880 rtx cookie_rtx = operands[2];
5881 long cookie = INTVAL (cookie_rtx);
5882 rtx func = XEXP (operands[0], 0);
5887 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5889 rtx reg = gen_reg_rtx (Pmode);
5891 emit_insn (gen_symGOT2reg (reg, func));
5895 func = legitimize_pic_address (func, Pmode, 0);
5898 /* FIXME: if we could tell whether all argument registers are
5899 already taken, we could decide whether to force the use of
5900 MACH_REG or to stick to R0_REG. Unfortunately, there's no
5901 simple way to tell. We could use the CALL_COOKIE, but we
5902 can't currently tell a register used for regular argument
5903 passing from one that is unused. If we leave it up to reload
5904 to decide which register to use, it seems to always choose
5905 R0_REG, which leaves no available registers in SIBCALL_REGS
5906 to hold the address of the trampoline. */
5907 mach = gen_rtx_REG (SImode, MACH_REG);
5908 r1 = gen_rtx_REG (SImode, R1_REG);
5910 /* Since such a call function may use all call-clobbered
5911 registers, we force a mode switch earlier, so that we don't
5912 run out of registers when adjusting fpscr for the call. */
5913 emit_insn (gen_force_mode_for_call ());
5915 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5916 \"__GCC_shcompact_call_trampoline\");
5919 rtx reg = gen_reg_rtx (Pmode);
5921 emit_insn (gen_symGOT2reg (reg, operands[0]));
5924 operands[0] = force_reg (SImode, operands[0]);
5926 /* We don't need a return trampoline, since the callee will
5927 return directly to the upper caller. */
5928 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5930 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
5931 cookie_rtx = GEN_INT (cookie);
5934 emit_move_insn (mach, func);
5935 emit_move_insn (r1, cookie_rtx);
5937 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
5940 else if (TARGET_SHCOMPACT && flag_pic
5941 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5942 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5944 rtx reg = gen_reg_rtx (Pmode);
5946 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
5947 XEXP (operands[0], 0) = reg;
5949 if (flag_pic && TARGET_SH2
5950 && GET_CODE (operands[0]) == MEM
5951 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5952 /* The PLT needs the PIC register, but the epilogue would have
5953 to restore it, so we can only use PC-relative PIC calls for
5954 static functions. */
5955 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5957 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
5961 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5963 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
5967 (define_expand "sibcall_value"
5968 [(set (match_operand 0 "" "")
5969 (call (match_operand 1 "" "")
5970 (match_operand 2 "" "")))
5971 (match_operand 3 "" "")]
5975 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5979 (define_insn "call_value_pop_compact"
5980 [(set (match_operand 0 "" "=rf")
5981 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5982 (match_operand 2 "" "")))
5983 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5984 (match_operand 4 "immediate_operand" "n")))
5985 (match_operand 3 "immediate_operand" "n")
5986 (use (reg:SI R0_REG))
5987 (use (reg:SI R1_REG))
5988 (use (reg:PSI FPSCR_REG))
5989 (clobber (reg:SI PR_REG))]
5990 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5992 [(set_attr "type" "call")
5993 (set (attr "fp_mode")
5994 (if_then_else (eq_attr "fpu_single" "yes")
5995 (const_string "single") (const_string "double")))
5996 (set_attr "needs_delay_slot" "yes")])
5998 (define_insn "call_value_pop_compact_rettramp"
5999 [(set (match_operand 0 "" "=rf")
6000 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6001 (match_operand 2 "" "")))
6002 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6003 (match_operand 4 "immediate_operand" "n")))
6004 (match_operand 3 "immediate_operand" "n")
6005 (use (reg:SI R0_REG))
6006 (use (reg:SI R1_REG))
6007 (use (reg:PSI FPSCR_REG))
6008 (clobber (reg:SI R10_REG))
6009 (clobber (reg:SI PR_REG))]
6010 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6012 [(set_attr "type" "call")
6013 (set (attr "fp_mode")
6014 (if_then_else (eq_attr "fpu_single" "yes")
6015 (const_string "single") (const_string "double")))
6016 (set_attr "needs_delay_slot" "yes")])
6018 (define_expand "call_value_pop"
6019 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6020 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6021 (match_operand 2 "" "")))
6022 (match_operand 3 "" "")
6023 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6024 (match_operand 4 "" "")))])]
6028 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6030 rtx cookie_rtx = operands[3];
6031 long cookie = INTVAL (cookie_rtx);
6032 rtx func = XEXP (operands[1], 0);
6037 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6039 rtx reg = gen_reg_rtx (Pmode);
6041 emit_insn (gen_symGOTPLT2reg (reg, func));
6045 func = legitimize_pic_address (func, Pmode, 0);
6048 r0 = gen_rtx_REG (SImode, R0_REG);
6049 r1 = gen_rtx_REG (SImode, R1_REG);
6051 /* Since such a call function may use all call-clobbered
6052 registers, we force a mode switch earlier, so that we don't
6053 run out of registers when adjusting fpscr for the call. */
6054 emit_insn (gen_force_mode_for_call ());
6056 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6057 \"__GCC_shcompact_call_trampoline\");
6060 rtx reg = gen_reg_rtx (Pmode);
6062 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6065 operands[1] = force_reg (SImode, operands[1]);
6067 emit_move_insn (r0, func);
6068 emit_move_insn (r1, cookie_rtx);
6070 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6071 emit_call_insn (gen_call_value_pop_compact_rettramp
6072 (operands[0], operands[1], operands[2],
6073 operands[3], operands[4]));
6075 emit_call_insn (gen_call_value_pop_compact
6076 (operands[0], operands[1], operands[2],
6077 operands[3], operands[4]));
6085 (define_expand "sibcall_epilogue"
6090 sh_expand_epilogue ();
6091 if (TARGET_SHCOMPACT)
6095 /* If epilogue clobbers r0, preserve it in macl. */
6096 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6097 if ((set = single_set (insn))
6098 && GET_CODE (SET_DEST (set)) == REG
6099 && REGNO (SET_DEST (set)) == R0_REG)
6101 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6102 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6105 /* We can't tell at this point whether the sibcall is a
6106 sibcall_compact and, if it is, whether it uses r0 or
6107 mach as operand 2, so let the instructions that
6108 preserve r0 be optimized away if r0 turns out to be
6110 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6111 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6113 i = emit_move_insn (r0, tmp);
6114 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6122 (define_insn "indirect_jump_compact"
6124 (match_operand:SI 0 "arith_reg_operand" "r"))]
6127 [(set_attr "needs_delay_slot" "yes")
6128 (set_attr "type" "jump_ind")])
6130 (define_expand "indirect_jump"
6132 (match_operand 0 "register_operand" ""))]
6136 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6137 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6140 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6141 ;; which can be present in structured code from indirect jumps which can not
6142 ;; be present in structured code. This allows -fprofile-arcs to work.
6144 ;; For SH1 processors.
6145 (define_insn "casesi_jump_1"
6147 (match_operand:SI 0 "register_operand" "r"))
6148 (use (label_ref (match_operand 1 "" "")))]
6151 [(set_attr "needs_delay_slot" "yes")
6152 (set_attr "type" "jump_ind")])
6154 ;; For all later processors.
6155 (define_insn "casesi_jump_2"
6156 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6157 (label_ref (match_operand 1 "" ""))))
6158 (use (label_ref (match_operand 2 "" "")))]
6160 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6162 [(set_attr "needs_delay_slot" "yes")
6163 (set_attr "type" "jump_ind")])
6165 (define_insn "casesi_jump_media"
6166 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6167 (use (label_ref (match_operand 1 "" "")))]
6171 ;; Call subroutine returning any type.
6172 ;; ??? This probably doesn't work.
6174 (define_expand "untyped_call"
6175 [(parallel [(call (match_operand 0 "" "")
6177 (match_operand 1 "" "")
6178 (match_operand 2 "" "")])]
6179 "TARGET_SH3E || TARGET_SHMEDIA"
6184 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6186 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6188 rtx set = XVECEXP (operands[2], 0, i);
6189 emit_move_insn (SET_DEST (set), SET_SRC (set));
6192 /* The optimizer does not know that the call sets the function value
6193 registers we stored in the result block. We avoid problems by
6194 claiming that all hard registers are used and clobbered at this
6196 emit_insn (gen_blockage ());
6201 ;; ------------------------------------------------------------------------
6203 ;; ------------------------------------------------------------------------
6206 [(set (reg:SI T_REG)
6207 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6208 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6211 [(set_attr "type" "arith")])
6218 ;; Load address of a label. This is only generated by the casesi expand,
6219 ;; and by machine_dependent_reorg (fixing up fp moves).
6220 ;; This must use unspec, because this only works for labels that are
6224 [(set (reg:SI R0_REG)
6225 (unspec [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6228 [(set_attr "in_delay_slot" "no")
6229 (set_attr "type" "arith")])
6231 ;; machine_dependent_reorg() will make this a `mova'.
6232 (define_insn "mova_const"
6233 [(set (reg:SI R0_REG)
6234 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6237 [(set_attr "in_delay_slot" "no")
6238 (set_attr "type" "arith")])
6240 (define_expand "GOTaddr2picreg"
6241 [(set (reg:SI R0_REG)
6242 (unspec [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6244 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6245 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6248 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6249 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6252 operands[1] = gen_datalabel_ref (operands[1]);
6256 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6257 rtx dipic = operands[0];
6258 rtx lab = PATTERN (gen_call_site ());
6261 equiv = operands[1];
6262 operands[1] = gen_rtx_MINUS (DImode,
6266 gen_rtx_MINUS (DImode,
6267 gen_rtx_CONST (DImode,
6270 operands[1] = gen_sym2PIC (operands[1]);
6271 PUT_MODE (operands[1], DImode);
6273 if (GET_MODE (dipic) != DImode)
6274 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6276 if (TARGET_SHMEDIA64)
6277 emit_insn (gen_movdi_const (dipic, operands[1]));
6279 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6281 emit_insn (gen_ptrel (tr, dipic, lab));
6283 if (GET_MODE (operands[0]) != GET_MODE (tr))
6284 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6286 insn = emit_move_insn (operands[0], tr);
6288 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6296 ;; When generating PIC, we must match label_refs especially, because
6297 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6298 ;; them to do, because they can't be loaded directly into
6299 ;; non-branch-target registers.
6301 [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6302 (match_operand:DI 1 "" "T"))]
6303 "TARGET_SHMEDIA && flag_pic
6304 && EXTRA_CONSTRAINT_T (operands[1])"
6306 [(set_attr "type" "pt")
6307 (set_attr "length" "*")])
6310 [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6311 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6312 UNSPEC_DATALABEL)))]
6313 "TARGET_SHMEDIA && flag_pic
6314 && EXTRA_CONSTRAINT_T (operands[1])"
6315 "ptb/u datalabel %1, %0"
6316 [(set_attr "type" "pt")
6317 (set_attr "length" "*")])
6319 (define_insn "ptrel"
6320 [(set (match_operand:DI 0 "target_reg_operand" "=bk")
6321 (plus (match_operand:DI 1 "register_operand" "r")
6323 (match_operand:DI 2 "" "")]
6325 "%O2: ptrel/u %1, %0"
6326 [(set_attr "type" "ptabs")])
6328 (define_expand "builtin_setjmp_receiver"
6329 [(match_operand 0 "" "")]
6333 emit_insn (gen_GOTaddr2picreg ());
6337 (define_expand "call_site"
6338 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6342 static HOST_WIDE_INT i = 0;
6343 operands[0] = GEN_INT (i);
6347 (define_expand "sym_label2reg"
6348 [(set (match_operand:SI 0 "" "")
6351 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6354 (match_operand:SI 2 "" "")
6358 (define_expand "symGOT_load"
6359 [(set (match_dup 2) (match_operand 1 "" ""))
6360 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6361 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6367 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6368 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6372 rtx reg = operands[2];
6374 if (GET_MODE (reg) != DImode)
6375 reg = gen_rtx_SUBREG (DImode, reg, 0);
6378 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6380 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6383 emit_move_insn (operands[2], operands[1]);
6385 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6387 gen_rtx_REG (Pmode, PIC_REG)));
6389 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6391 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6398 (define_expand "sym2GOT"
6399 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6403 (define_expand "symGOT2reg"
6404 [(match_operand 0 "" "") (match_operand 1 "" "")]
6410 gotsym = gen_sym2GOT (operands[1]);
6411 PUT_MODE (gotsym, Pmode);
6412 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6414 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6419 (define_expand "sym2GOTPLT"
6420 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6424 (define_expand "symGOTPLT2reg"
6425 [(match_operand 0 "" "") (match_operand 1 "" "")]
6429 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6433 (define_expand "sym2GOTOFF"
6434 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6438 (define_expand "symGOTOFF2reg"
6439 [(match_operand 0 "" "") (match_operand 1 "" "")]
6443 rtx gotoffsym, insn;
6444 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6446 gotoffsym = gen_sym2GOTOFF (operands[1]);
6447 PUT_MODE (gotoffsym, Pmode);
6448 emit_move_insn (t, gotoffsym);
6449 insn = emit_move_insn (operands[0],
6450 gen_rtx_PLUS (Pmode, t,
6451 gen_rtx_REG (Pmode, PIC_REG)));
6453 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6459 (define_expand "symPLT_label2reg"
6460 [(set (match_operand:SI 0 "" "")
6463 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6467 (match_operand:SI 2 "" "")
6469 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6470 ;; Even though the PIC register is not really used by the call
6471 ;; sequence in which this is expanded, the PLT code assumes the PIC
6472 ;; register is set, so we must not skip its initialization. Since
6473 ;; we only use this expand as part of calling sequences, and never
6474 ;; to take the address of a function, this is the best point to
6475 ;; insert the (use). Using the PLT to take the address of a
6476 ;; function would be wrong, not only because the PLT entry could
6477 ;; then be called from a function that doesn't initialize the PIC
6478 ;; register to the proper GOT, but also because pointers to the
6479 ;; same function might not compare equal, should they be set by
6480 ;; different shared libraries.
6481 (use (reg:SI PIC_REG))]
6485 (define_expand "sym2PIC"
6486 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6490 ;; case instruction for switch statements.
6492 ;; Operand 0 is index
6493 ;; operand 1 is the minimum bound
6494 ;; operand 2 is the maximum bound - minimum bound + 1
6495 ;; operand 3 is CODE_LABEL for the table;
6496 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6498 (define_expand "casesi"
6499 [(match_operand:SI 0 "arith_reg_operand" "")
6500 (match_operand:SI 1 "arith_reg_operand" "")
6501 (match_operand:SI 2 "arith_reg_operand" "")
6502 (match_operand 3 "" "") (match_operand 4 "" "")]
6506 rtx reg = gen_reg_rtx (SImode);
6507 rtx reg2 = gen_reg_rtx (SImode);
6510 rtx reg = gen_reg_rtx (DImode);
6511 rtx reg2 = gen_reg_rtx (DImode);
6512 rtx reg3 = gen_reg_rtx (DImode);
6513 rtx reg4 = gen_reg_rtx (DImode);
6514 rtx reg5 = gen_reg_rtx (DImode);
6516 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6517 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6518 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6520 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6521 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6522 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6523 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6524 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6525 (DImode, operands[3])));
6526 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6527 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6528 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6532 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6533 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6534 /* If optimizing, casesi_worker depends on the mode of the instruction
6535 before label it 'uses' - operands[3]. */
6536 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6538 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6540 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6542 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6543 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6544 operands[3], but to lab. We will fix this up in
6545 machine_dependent_reorg. */
6550 (define_expand "casesi_0"
6551 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6552 (set (match_dup 4) (minus:SI (match_dup 4)
6553 (match_operand:SI 1 "arith_operand" "")))
6555 (gtu:SI (match_dup 4)
6556 (match_operand:SI 2 "arith_reg_operand" "")))
6558 (if_then_else (ne (reg:SI T_REG)
6560 (label_ref (match_operand 3 "" ""))
6565 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6566 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6567 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6569 (define_insn "casesi_worker_0"
6570 [(set (match_operand:SI 0 "register_operand" "=r,r")
6571 (unspec:SI [(match_operand 1 "register_operand" "0,r")
6572 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6573 (clobber (match_scratch:SI 3 "=X,1"))
6574 (clobber (match_scratch:SI 4 "=&z,z"))]
6579 [(set (match_operand:SI 0 "register_operand" "")
6580 (unspec [(match_operand 1 "register_operand" "")
6581 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6582 (clobber (match_scratch:SI 3 ""))
6583 (clobber (match_scratch:SI 4 ""))]
6584 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6585 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6586 (parallel [(set (match_dup 0)
6587 (unspec [(reg:SI R0_REG) (match_dup 1)
6588 (label_ref (match_dup 2))] UNSPEC_CASESI))
6589 (clobber (match_dup 3))])
6590 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6591 "LABEL_NUSES (operands[2])++;")
6594 [(set (match_operand:SI 0 "register_operand" "")
6595 (unspec:SI [(match_operand 1 "register_operand" "")
6596 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6597 (clobber (match_scratch:SI 3 ""))
6598 (clobber (match_scratch:SI 4 ""))]
6599 "TARGET_SH2 && reload_completed"
6600 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6601 (parallel [(set (match_dup 0)
6602 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6603 (label_ref (match_dup 2))] UNSPEC_CASESI))
6604 (clobber (match_dup 3))])]
6605 "LABEL_NUSES (operands[2])++;")
6607 (define_insn "*casesi_worker"
6608 [(set (match_operand:SI 0 "register_operand" "=r,r")
6609 (unspec [(reg:SI R0_REG) (match_operand 1 "register_operand" "0,r")
6610 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6611 (clobber (match_scratch:SI 3 "=X,1"))]
6615 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6617 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6620 switch (GET_MODE (diff_vec))
6623 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6625 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6627 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6628 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6629 return \"mov.b @(r0,%1),%0\";
6634 [(set_attr "length" "4")])
6636 (define_insn "casesi_shift_media"
6637 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6638 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6639 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6644 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6646 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6649 switch (GET_MODE (diff_vec))
6652 return \"shlli %1, 2, %0\";
6654 return \"shlli %1, 1, %0\";
6656 if (rtx_equal_p (operands[0], operands[1]))
6658 return \"add %1, r63, %0\";
6664 (define_insn "casesi_load_media"
6665 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6666 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6667 (match_operand 2 "arith_reg_operand" "r")
6668 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6672 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6674 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6677 switch (GET_MODE (diff_vec))
6680 return \"ldx.l %1, %2, %0\";
6683 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6684 return \"ldx.uw %1, %2, %0\";
6686 return \"ldx.w %1, %2, %0\";
6688 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6689 return \"ldx.ub %1, %2, %0\";
6690 return \"ldx.b %1, %2, %0\";
6696 (define_expand "return"
6698 "reload_completed && ! sh_need_epilogue ()"
6703 emit_jump_insn (gen_return_media ());
6707 if (TARGET_SHCOMPACT
6708 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
6710 emit_jump_insn (gen_shcompact_return_tramp ());
6715 (define_insn "*return_i"
6717 "TARGET_SH1 && ! (TARGET_SHCOMPACT
6718 && (current_function_args_info.call_cookie
6719 & CALL_COOKIE_RET_TRAMP (1)))
6720 && reload_completed"
6722 [(set_attr "type" "return")
6723 (set_attr "needs_delay_slot" "yes")])
6725 (define_expand "shcompact_return_tramp"
6728 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6731 rtx reg = gen_rtx_REG (Pmode, R0_REG);
6732 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
6733 \"__GCC_shcompact_return_trampoline\");
6736 emit_insn (gen_symGOTPLT2reg (reg, sym));
6738 emit_move_insn (reg, sym);
6740 emit_jump_insn (gen_shcompact_return_tramp_i ());
6744 (define_insn "shcompact_return_tramp_i"
6745 [(parallel [(return) (use (reg:SI R0_REG))])]
6747 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6749 [(set_attr "type" "jump_ind")
6750 (set_attr "needs_delay_slot" "yes")])
6752 (define_insn "return_media_i"
6753 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
6754 "TARGET_SHMEDIA && reload_completed"
6757 (define_expand "return_media"
6759 "TARGET_SHMEDIA && reload_completed"
6762 int tr_regno = sh_media_register_for_return ();
6767 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
6770 tr = gen_rtx_REG (DImode, tr_regno);
6771 emit_move_insn (tr, r18);
6774 tr = gen_rtx_REG (DImode, tr_regno);
6776 emit_jump_insn (gen_return_media_i (tr));
6780 (define_insn "shcompact_preserve_incoming_args"
6781 [(set (match_operand 0 "register_operand" "+r")
6782 (unspec [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
6785 [(set_attr "length" "0")])
6787 (define_insn "shcompact_incoming_args"
6788 [(set (reg:SI R2_REG) (unspec [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
6789 (set (reg:SI R3_REG) (unspec [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
6790 (set (reg:SI R4_REG) (unspec [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
6791 (set (reg:SI R5_REG) (unspec [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
6792 (set (reg:SI R6_REG) (unspec [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
6793 (set (reg:SI R7_REG) (unspec [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
6794 (set (reg:SI R8_REG) (unspec [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
6795 (set (reg:SI R9_REG) (unspec [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
6796 (set (mem:BLK (reg:SI MACL_REG))
6797 (unspec [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
6798 (use (reg:SI R0_REG))
6799 (clobber (reg:SI R0_REG))
6800 (clobber (reg:SI MACL_REG))
6801 (clobber (reg:SI MACH_REG))
6802 (clobber (reg:SI PR_REG))]
6805 [(set_attr "needs_delay_slot" "yes")])
6807 (define_insn "shmedia_save_restore_regs_compact"
6808 [(set (reg:SI SP_REG)
6809 (plus:SI (reg:SI SP_REG)
6810 (match_operand:SI 0 "immediate_operand" "i")))
6811 (use (reg:SI R0_REG))
6812 (clobber (reg:SI PR_REG))]
6814 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
6815 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
6817 [(set_attr "needs_delay_slot" "yes")])
6819 (define_expand "prologue"
6822 "sh_expand_prologue (); DONE;")
6824 (define_expand "epilogue"
6829 sh_expand_epilogue ();
6830 emit_jump_insn (gen_return ());
6834 (define_insn "blockage"
6835 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6838 [(set_attr "length" "0")])
6840 ;; ------------------------------------------------------------------------
6842 ;; ------------------------------------------------------------------------
6845 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6846 (eq:SI (reg:SI T_REG) (const_int 1)))]
6849 [(set_attr "type" "arith")])
6851 (define_expand "seq"
6852 [(set (match_operand:SI 0 "arith_reg_operand" "")
6859 if (GET_MODE (operands[0]) != DImode)
6860 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6861 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6862 if (sh_compare_op1 != const0_rtx)
6863 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6864 ? GET_MODE (sh_compare_op0)
6865 : GET_MODE (sh_compare_op1),
6868 switch (GET_MODE (sh_compare_op0))
6871 emit_insn (gen_cmpeqdi_media (operands[0],
6872 sh_compare_op0, sh_compare_op1));
6876 if (! TARGET_SHMEDIA_FPU)
6878 emit_insn (gen_cmpeqsf_media (operands[0],
6879 sh_compare_op0, sh_compare_op1));
6883 if (! TARGET_SHMEDIA_FPU)
6885 emit_insn (gen_cmpeqdf_media (operands[0],
6886 sh_compare_op0, sh_compare_op1));
6894 operands[1] = prepare_scc_operands (EQ);
6897 (define_expand "slt"
6898 [(set (match_operand:SI 0 "arith_reg_operand" "")
6905 if (GET_MODE (operands[0]) != DImode)
6906 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6907 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6908 if (sh_compare_op1 != const0_rtx)
6909 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6910 ? GET_MODE (sh_compare_op0)
6911 : GET_MODE (sh_compare_op1),
6914 switch (GET_MODE (sh_compare_op0))
6917 emit_insn (gen_cmpgtdi_media (operands[0],
6918 sh_compare_op1, sh_compare_op0));
6922 if (! TARGET_SHMEDIA_FPU)
6924 emit_insn (gen_cmpgtsf_media (operands[0],
6925 sh_compare_op1, sh_compare_op0));
6929 if (! TARGET_SHMEDIA_FPU)
6931 emit_insn (gen_cmpgtdf_media (operands[0],
6932 sh_compare_op1, sh_compare_op0));
6940 operands[1] = prepare_scc_operands (LT);
6943 (define_expand "sle"
6944 [(match_operand:SI 0 "arith_reg_operand" "")]
6948 rtx tmp = sh_compare_op0;
6952 if (GET_MODE (operands[0]) != DImode)
6953 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6954 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6955 if (sh_compare_op1 != const0_rtx)
6956 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6957 ? GET_MODE (sh_compare_op0)
6958 : GET_MODE (sh_compare_op1),
6961 switch (GET_MODE (sh_compare_op0))
6965 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
6967 emit_insn (gen_cmpgtdi_media (tmp,
6968 sh_compare_op0, sh_compare_op1));
6969 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
6974 if (! TARGET_SHMEDIA_FPU)
6976 emit_insn (gen_cmpgesf_media (operands[0],
6977 sh_compare_op1, sh_compare_op0));
6981 if (! TARGET_SHMEDIA_FPU)
6983 emit_insn (gen_cmpgedf_media (operands[0],
6984 sh_compare_op1, sh_compare_op0));
6993 sh_compare_op0 = sh_compare_op1;
6994 sh_compare_op1 = tmp;
6995 emit_insn (gen_sge (operands[0]));
6999 (define_expand "sgt"
7000 [(set (match_operand:SI 0 "arith_reg_operand" "")
7007 if (GET_MODE (operands[0]) != DImode)
7008 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7009 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7010 if (sh_compare_op1 != const0_rtx)
7011 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7012 ? GET_MODE (sh_compare_op0)
7013 : GET_MODE (sh_compare_op1),
7016 switch (GET_MODE (sh_compare_op0))
7019 emit_insn (gen_cmpgtdi_media (operands[0],
7020 sh_compare_op0, sh_compare_op1));
7024 if (! TARGET_SHMEDIA_FPU)
7026 emit_insn (gen_cmpgtsf_media (operands[0],
7027 sh_compare_op0, sh_compare_op1));
7031 if (! TARGET_SHMEDIA_FPU)
7033 emit_insn (gen_cmpgtdf_media (operands[0],
7034 sh_compare_op0, sh_compare_op1));
7042 operands[1] = prepare_scc_operands (GT);
7045 (define_expand "sge"
7046 [(set (match_operand:SI 0 "arith_reg_operand" "")
7053 if (GET_MODE (operands[0]) != DImode)
7054 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7055 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7056 if (sh_compare_op1 != const0_rtx)
7057 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7058 ? GET_MODE (sh_compare_op0)
7059 : GET_MODE (sh_compare_op1),
7062 switch (GET_MODE (sh_compare_op0))
7066 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7068 emit_insn (gen_cmpgtdi_media (tmp,
7069 sh_compare_op1, sh_compare_op0));
7070 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7075 if (! TARGET_SHMEDIA_FPU)
7077 emit_insn (gen_cmpgesf_media (operands[0],
7078 sh_compare_op0, sh_compare_op1));
7082 if (! TARGET_SHMEDIA_FPU)
7084 emit_insn (gen_cmpgedf_media (operands[0],
7085 sh_compare_op0, sh_compare_op1));
7094 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7098 rtx lab = gen_label_rtx ();
7099 prepare_scc_operands (EQ);
7100 emit_jump_insn (gen_branch_true (lab));
7101 prepare_scc_operands (GT);
7103 emit_insn (gen_movt (operands[0]));
7106 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7109 operands[1] = prepare_scc_operands (GE);
7112 (define_expand "sgtu"
7113 [(set (match_operand:SI 0 "arith_reg_operand" "")
7120 if (GET_MODE (operands[0]) != DImode)
7121 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7122 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7123 if (sh_compare_op1 != const0_rtx)
7124 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7125 ? GET_MODE (sh_compare_op0)
7126 : GET_MODE (sh_compare_op1),
7129 emit_insn (gen_cmpgtudi_media (operands[0],
7130 sh_compare_op0, sh_compare_op1));
7133 operands[1] = prepare_scc_operands (GTU);
7136 (define_expand "sltu"
7137 [(set (match_operand:SI 0 "arith_reg_operand" "")
7144 if (GET_MODE (operands[0]) != DImode)
7145 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7146 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7147 if (sh_compare_op1 != const0_rtx)
7148 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7149 ? GET_MODE (sh_compare_op0)
7150 : GET_MODE (sh_compare_op1),
7153 emit_insn (gen_cmpgtudi_media (operands[0],
7154 sh_compare_op1, sh_compare_op0));
7157 operands[1] = prepare_scc_operands (LTU);
7160 (define_expand "sleu"
7161 [(set (match_operand:SI 0 "arith_reg_operand" "")
7170 if (GET_MODE (operands[0]) != DImode)
7171 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7172 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7173 if (sh_compare_op1 != const0_rtx)
7174 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7175 ? GET_MODE (sh_compare_op0)
7176 : GET_MODE (sh_compare_op1),
7179 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7181 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7182 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7186 operands[1] = prepare_scc_operands (LEU);
7189 (define_expand "sgeu"
7190 [(set (match_operand:SI 0 "arith_reg_operand" "")
7199 if (GET_MODE (operands[0]) != DImode)
7200 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7201 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7202 if (sh_compare_op1 != const0_rtx)
7203 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7204 ? GET_MODE (sh_compare_op0)
7205 : GET_MODE (sh_compare_op1),
7208 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7210 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7211 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7216 operands[1] = prepare_scc_operands (GEU);
7219 ;; sne moves the complement of the T reg to DEST like this:
7223 ;; This is better than xoring compare result with 1 because it does
7224 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7227 (define_expand "sne"
7228 [(set (match_dup 2) (const_int -1))
7229 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7230 (neg:SI (plus:SI (match_dup 1)
7233 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7242 if (GET_MODE (operands[0]) != DImode)
7243 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7245 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7248 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7249 if (sh_compare_op1 != const0_rtx)
7250 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7251 ? GET_MODE (sh_compare_op0)
7252 : GET_MODE (sh_compare_op1),
7255 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7257 emit_insn (gen_seq (tmp));
7258 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7263 operands[1] = prepare_scc_operands (EQ);
7264 operands[2] = gen_reg_rtx (SImode);
7267 (define_expand "sunordered"
7268 [(set (match_operand:DI 0 "arith_reg_operand" "")
7269 (unordered:DI (match_dup 1) (match_dup 2)))]
7270 "TARGET_SHMEDIA_FPU"
7273 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7274 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7277 ;; Use the same trick for FP sle / sge
7278 (define_expand "movnegt"
7279 [(set (match_dup 2) (const_int -1))
7280 (parallel [(set (match_operand 0 "" "")
7281 (neg:SI (plus:SI (match_dup 1)
7284 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7287 "operands[2] = gen_reg_rtx (SImode);")
7289 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7290 ;; This prevents a regression that occurred when we switched from xor to
7294 [(set (match_operand:SI 0 "arith_reg_operand" "")
7295 (plus:SI (reg:SI T_REG)
7298 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7299 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7302 ;; -------------------------------------------------------------------------
7303 ;; Instructions to cope with inline literal tables
7304 ;; -------------------------------------------------------------------------
7306 ; 2 byte integer in line
7308 (define_insn "consttable_2"
7309 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7310 (match_operand 1 "" "")]
7315 if (operands[1] != const0_rtx)
7316 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7319 [(set_attr "length" "2")
7320 (set_attr "in_delay_slot" "no")])
7322 ; 4 byte integer in line
7324 (define_insn "consttable_4"
7325 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7326 (match_operand 1 "" "")]
7331 if (operands[1] != const0_rtx)
7332 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7335 [(set_attr "length" "4")
7336 (set_attr "in_delay_slot" "no")])
7338 ; 8 byte integer in line
7340 (define_insn "consttable_8"
7341 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7342 (match_operand 1 "" "")]
7347 if (operands[1] != const0_rtx)
7348 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7351 [(set_attr "length" "8")
7352 (set_attr "in_delay_slot" "no")])
7354 ; 4 byte floating point
7356 (define_insn "consttable_sf"
7357 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7358 (match_operand 1 "" "")]
7363 if (operands[1] != const0_rtx)
7366 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7367 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7371 [(set_attr "length" "4")
7372 (set_attr "in_delay_slot" "no")])
7374 ; 8 byte floating point
7376 (define_insn "consttable_df"
7377 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7378 (match_operand 1 "" "")]
7383 if (operands[1] != const0_rtx)
7386 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7387 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7391 [(set_attr "length" "8")
7392 (set_attr "in_delay_slot" "no")])
7394 ;; Alignment is needed for some constant tables; it may also be added for
7395 ;; Instructions at the start of loops, or after unconditional branches.
7396 ;; ??? We would get more accurate lengths if we did instruction
7397 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7398 ;; here is too conservative.
7400 ; align to a two byte boundary
7402 (define_expand "align_2"
7403 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7407 ; align to a four byte boundary
7408 ;; align_4 and align_log are instructions for the starts of loops, or
7409 ;; after unconditional branches, which may take up extra room.
7411 (define_expand "align_4"
7412 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7416 ; align to a cache line boundary
7418 (define_insn "align_log"
7419 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7422 [(set_attr "length" "0")
7423 (set_attr "in_delay_slot" "no")])
7425 ; emitted at the end of the literal table, used to emit the
7426 ; 32bit branch labels if needed.
7428 (define_insn "consttable_end"
7429 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7431 "* return output_jump_label_table ();"
7432 [(set_attr "in_delay_slot" "no")])
7434 ; emitted at the end of the window in the literal table.
7436 (define_insn "consttable_window_end"
7437 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7440 [(set_attr "length" "0")
7441 (set_attr "in_delay_slot" "no")])
7443 ;; -------------------------------------------------------------------------
7445 ;; -------------------------------------------------------------------------
7447 ;; String/block move insn.
7449 (define_expand "movstrsi"
7450 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7451 (mem:BLK (match_operand:BLK 1 "" "")))
7452 (use (match_operand:SI 2 "nonmemory_operand" ""))
7453 (use (match_operand:SI 3 "immediate_operand" ""))
7454 (clobber (reg:SI PR_REG))
7455 (clobber (reg:SI R4_REG))
7456 (clobber (reg:SI R5_REG))
7457 (clobber (reg:SI R0_REG))])]
7458 "TARGET_SH1 && ! TARGET_SH5"
7461 if(expand_block_move (operands))
7466 (define_insn "block_move_real"
7467 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7468 (mem:BLK (reg:SI R5_REG)))
7469 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7470 (clobber (reg:SI PR_REG))
7471 (clobber (reg:SI R0_REG))])]
7472 "TARGET_SH1 && ! TARGET_HARD_SH4"
7474 [(set_attr "type" "sfunc")
7475 (set_attr "needs_delay_slot" "yes")])
7477 (define_insn "block_lump_real"
7478 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7479 (mem:BLK (reg:SI R5_REG)))
7480 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7481 (use (reg:SI R6_REG))
7482 (clobber (reg:SI PR_REG))
7483 (clobber (reg:SI T_REG))
7484 (clobber (reg:SI R4_REG))
7485 (clobber (reg:SI R5_REG))
7486 (clobber (reg:SI R6_REG))
7487 (clobber (reg:SI R0_REG))])]
7488 "TARGET_SH1 && ! TARGET_HARD_SH4"
7490 [(set_attr "type" "sfunc")
7491 (set_attr "needs_delay_slot" "yes")])
7493 (define_insn "block_move_real_i4"
7494 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7495 (mem:BLK (reg:SI R5_REG)))
7496 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7497 (clobber (reg:SI PR_REG))
7498 (clobber (reg:SI R0_REG))
7499 (clobber (reg:SI R1_REG))
7500 (clobber (reg:SI R2_REG))])]
7503 [(set_attr "type" "sfunc")
7504 (set_attr "needs_delay_slot" "yes")])
7506 (define_insn "block_lump_real_i4"
7507 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7508 (mem:BLK (reg:SI R5_REG)))
7509 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7510 (use (reg:SI R6_REG))
7511 (clobber (reg:SI PR_REG))
7512 (clobber (reg:SI T_REG))
7513 (clobber (reg:SI R4_REG))
7514 (clobber (reg:SI R5_REG))
7515 (clobber (reg:SI R6_REG))
7516 (clobber (reg:SI R0_REG))
7517 (clobber (reg:SI R1_REG))
7518 (clobber (reg:SI R2_REG))
7519 (clobber (reg:SI R3_REG))])]
7522 [(set_attr "type" "sfunc")
7523 (set_attr "needs_delay_slot" "yes")])
7525 ;; -------------------------------------------------------------------------
7526 ;; Floating point instructions.
7527 ;; -------------------------------------------------------------------------
7529 ;; ??? All patterns should have a type attribute.
7531 (define_expand "fpu_switch0"
7532 [(set (match_operand:SI 0 "" "") (match_dup 2))
7533 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7537 operands[1] = get_fpscr_rtx ();
7538 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7540 operands[2] = legitimize_pic_address (operands[2], SImode,
7541 no_new_pseudos ? operands[0] : 0);
7544 (define_expand "fpu_switch1"
7545 [(set (match_operand:SI 0 "" "") (match_dup 2))
7546 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7547 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7551 operands[1] = get_fpscr_rtx ();
7552 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7554 operands[2] = legitimize_pic_address (operands[2], SImode,
7555 no_new_pseudos ? operands[0] : 0);
7556 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7559 (define_expand "movpsi"
7560 [(set (match_operand:PSI 0 "register_operand" "")
7561 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7565 ;; The c / m alternative is a fake to guide reload to load directly into
7566 ;; fpscr, since reload doesn't know how to use post-increment.
7567 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7568 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7569 ;; predicate after reload.
7570 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
7571 ;; like a gpr <-> fpul move.
7572 (define_insn "fpu_switch"
7573 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7574 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7576 && (! reload_completed
7577 || true_regnum (operands[0]) != FPSCR_REG
7578 || GET_CODE (operands[1]) != MEM
7579 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7581 ! precision stays the same
7589 [(set_attr "length" "0,2,2,4,2,2,2,2")
7590 (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")
7591 (set_attr "insn_class" "ldsmem_to_fpscr,*,*,lds_to_fpscr,*,*,*,*")])
7594 [(set (reg:PSI FPSCR_REG)
7595 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7596 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7597 [(set (match_dup 0) (match_dup 0))]
7600 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7601 gen_rtx (MEM, PSImode,
7602 gen_rtx (POST_INC, Pmode,
7604 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7608 [(set (reg:PSI FPSCR_REG)
7609 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7611 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7614 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7615 gen_rtx (MEM, PSImode,
7616 gen_rtx (POST_INC, Pmode,
7618 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7621 ;; ??? This uses the fp unit, but has no type indicating that.
7622 ;; If we did that, this would either give a bogus latency or introduce
7623 ;; a bogus FIFO constraint.
7624 ;; Since this insn is currently only used for prologues/epilogues,
7625 ;; it is probably best to claim no function unit, which matches the
7627 (define_insn "toggle_sz"
7628 [(set (reg:PSI FPSCR_REG)
7629 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7633 (define_expand "addsf3"
7634 [(set (match_operand:SF 0 "arith_reg_operand" "")
7635 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7636 (match_operand:SF 2 "arith_reg_operand" "")))]
7637 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7642 expand_sf_binop (&gen_addsf3_i, operands);
7647 (define_insn "*addsf3_media"
7648 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7649 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7650 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7651 "TARGET_SHMEDIA_FPU"
7652 "fadd.s %1, %2, %0")
7654 (define_insn "addsf3_i"
7655 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7656 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
7657 (match_operand:SF 2 "arith_reg_operand" "f")))
7658 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7661 [(set_attr "type" "fp")
7662 (set_attr "fp_mode" "single")])
7664 (define_expand "subsf3"
7665 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7666 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7667 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7668 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7673 expand_sf_binop (&gen_subsf3_i, operands);
7678 (define_insn "*subsf3_media"
7679 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7680 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7681 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7682 "TARGET_SHMEDIA_FPU"
7683 "fsub.s %1, %2, %0")
7685 (define_insn "subsf3_i"
7686 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7687 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
7688 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7689 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7692 [(set_attr "type" "fp")
7693 (set_attr "fp_mode" "single")])
7695 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
7696 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
7697 ;; mixed-precision SH4 targets. To allow it to be still generated for the
7698 ;; SH3E, we use a separate insn for SH3E mulsf3.
7700 (define_expand "mulsf3"
7701 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7702 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7703 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7704 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7708 expand_sf_binop (&gen_mulsf3_i4, operands);
7709 else if (TARGET_SH3E)
7710 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
7711 if (! TARGET_SHMEDIA)
7715 (define_insn "*mulsf3_media"
7716 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7717 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7718 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7719 "TARGET_SHMEDIA_FPU"
7720 "fmul.s %1, %2, %0")
7722 (define_insn "mulsf3_i4"
7723 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7724 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7725 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7726 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7729 [(set_attr "type" "fp")
7730 (set_attr "fp_mode" "single")])
7732 (define_insn "mulsf3_ie"
7733 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7734 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7735 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7736 "TARGET_SH3E && ! TARGET_SH4"
7738 [(set_attr "type" "fp")])
7740 (define_insn "*mac_media"
7741 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7742 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7743 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7744 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
7745 "TARGET_SHMEDIA_FPU"
7746 "fmac.s %1, %2, %0")
7748 (define_insn "*macsf3"
7749 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7750 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
7751 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7752 (match_operand:SF 3 "arith_reg_operand" "0")))
7753 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
7754 "TARGET_SH3E && ! TARGET_SH4"
7756 [(set_attr "type" "fp")
7757 (set_attr "fp_mode" "single")])
7759 (define_expand "divsf3"
7760 [(set (match_operand:SF 0 "arith_reg_operand" "")
7761 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
7762 (match_operand:SF 2 "arith_reg_operand" "")))]
7763 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7768 expand_sf_binop (&gen_divsf3_i, operands);
7773 (define_insn "*divsf3_media"
7774 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7775 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7776 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7777 "TARGET_SHMEDIA_FPU"
7778 "fdiv.s %1, %2, %0")
7780 (define_insn "divsf3_i"
7781 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7782 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
7783 (match_operand:SF 2 "arith_reg_operand" "f")))
7784 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7787 [(set_attr "type" "fdiv")
7788 (set_attr "fp_mode" "single")])
7790 (define_insn "floatdisf2"
7791 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7792 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
7793 "TARGET_SHMEDIA_FPU"
7796 (define_expand "floatsisf2"
7797 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7798 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
7799 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7804 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7809 (define_insn "*floatsisf2_media"
7810 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7811 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
7812 "TARGET_SHMEDIA_FPU"
7815 (define_insn "floatsisf2_i4"
7816 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7817 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
7818 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7821 [(set_attr "type" "fp")
7822 (set_attr "fp_mode" "single")])
7824 (define_insn "*floatsisf2_ie"
7825 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7826 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
7827 "TARGET_SH3E && ! TARGET_SH4"
7829 [(set_attr "type" "fp")])
7831 (define_insn "fix_truncsfdi2"
7832 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
7833 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7834 "TARGET_SHMEDIA_FPU"
7837 (define_expand "fix_truncsfsi2"
7838 [(set (match_operand:SI 0 "fpul_operand" "=y")
7839 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7840 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7845 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7850 (define_insn "*fix_truncsfsi2_media"
7851 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
7852 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7853 "TARGET_SHMEDIA_FPU"
7856 (define_insn "fix_truncsfsi2_i4"
7857 [(set (match_operand:SI 0 "fpul_operand" "=y")
7858 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7859 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7862 [(set_attr "type" "fp")
7863 (set_attr "fp_mode" "single")])
7865 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
7866 ;; fix_truncsfsi2_i4.
7867 ;; (define_insn "fix_truncsfsi2_i4_2"
7868 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7869 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7870 ;; (use (reg:PSI FPSCR_REG))
7871 ;; (clobber (reg:SI FPUL_REG))]
7874 ;; [(set_attr "length" "4")
7875 ;; (set_attr "fp_mode" "single")])
7878 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7879 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7880 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
7881 ;; (clobber (reg:SI FPUL_REG))]
7883 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
7884 ;; (use (match_dup 2))])
7885 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
7887 (define_insn "*fixsfsi"
7888 [(set (match_operand:SI 0 "fpul_operand" "=y")
7889 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7890 "TARGET_SH3E && ! TARGET_SH4"
7892 [(set_attr "type" "fp")])
7894 (define_insn "cmpgtsf_t"
7895 [(set (reg:SI T_REG)
7896 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7897 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7898 "TARGET_SH3E && ! TARGET_SH4"
7900 [(set_attr "type" "fp")
7901 (set_attr "fp_mode" "single")])
7903 (define_insn "cmpeqsf_t"
7904 [(set (reg:SI T_REG)
7905 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7906 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7907 "TARGET_SH3E && ! TARGET_SH4"
7909 [(set_attr "type" "fp")
7910 (set_attr "fp_mode" "single")])
7912 (define_insn "ieee_ccmpeqsf_t"
7913 [(set (reg:SI T_REG)
7914 (ior:SI (reg:SI T_REG)
7915 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7916 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
7917 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
7918 "* return output_ieee_ccmpeq (insn, operands);"
7919 [(set_attr "length" "4")])
7922 (define_insn "cmpgtsf_t_i4"
7923 [(set (reg:SI T_REG)
7924 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7925 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7926 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7929 [(set_attr "type" "fp")
7930 (set_attr "fp_mode" "single")])
7932 (define_insn "cmpeqsf_t_i4"
7933 [(set (reg:SI T_REG)
7934 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7935 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7936 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7939 [(set_attr "type" "fp")
7940 (set_attr "fp_mode" "single")])
7942 (define_insn "*ieee_ccmpeqsf_t_4"
7943 [(set (reg:SI T_REG)
7944 (ior:SI (reg:SI T_REG)
7945 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7946 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
7947 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7948 "TARGET_IEEE && TARGET_SH4"
7949 "* return output_ieee_ccmpeq (insn, operands);"
7950 [(set_attr "length" "4")
7951 (set_attr "fp_mode" "single")])
7953 (define_insn "cmpeqsf_media"
7954 [(set (match_operand:DI 0 "register_operand" "=r")
7955 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7956 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7957 "TARGET_SHMEDIA_FPU"
7958 "fcmpeq.s %1, %2, %0")
7960 (define_insn "cmpgtsf_media"
7961 [(set (match_operand:DI 0 "register_operand" "=r")
7962 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7963 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7964 "TARGET_SHMEDIA_FPU"
7965 "fcmpgt.s %1, %2, %0")
7967 (define_insn "cmpgesf_media"
7968 [(set (match_operand:DI 0 "register_operand" "=r")
7969 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7970 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7971 "TARGET_SHMEDIA_FPU"
7972 "fcmpge.s %1, %2, %0")
7974 (define_insn "cmpunsf_media"
7975 [(set (match_operand:DI 0 "register_operand" "=r")
7976 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7977 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7978 "TARGET_SHMEDIA_FPU"
7979 "fcmpun.s %1, %2, %0")
7981 (define_expand "cmpsf"
7982 [(set (reg:SI T_REG)
7983 (compare (match_operand:SF 0 "arith_operand" "")
7984 (match_operand:SF 1 "arith_operand" "")))]
7985 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7988 sh_compare_op0 = operands[0];
7989 sh_compare_op1 = operands[1];
7993 (define_expand "negsf2"
7994 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7995 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
7996 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8001 expand_sf_unop (&gen_negsf2_i, operands);
8006 (define_insn "*negsf2_media"
8007 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8008 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8009 "TARGET_SHMEDIA_FPU"
8012 (define_insn "negsf2_i"
8013 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8014 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8015 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8018 [(set_attr "type" "fmove")
8019 (set_attr "fp_mode" "single")])
8021 (define_expand "sqrtsf2"
8022 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8023 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8024 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8029 expand_sf_unop (&gen_sqrtsf2_i, operands);
8034 (define_insn "*sqrtsf2_media"
8035 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8036 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8037 "TARGET_SHMEDIA_FPU"
8040 (define_insn "sqrtsf2_i"
8041 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8042 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8043 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8046 [(set_attr "type" "fdiv")
8047 (set_attr "fp_mode" "single")])
8049 (define_expand "abssf2"
8050 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8051 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8052 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8057 expand_sf_unop (&gen_abssf2_i, operands);
8062 (define_insn "*abssf2_media"
8063 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8064 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8065 "TARGET_SHMEDIA_FPU"
8068 (define_insn "abssf2_i"
8069 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8070 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8071 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8074 [(set_attr "type" "fmove")
8075 (set_attr "fp_mode" "single")])
8077 (define_expand "adddf3"
8078 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8079 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8080 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8081 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8086 expand_df_binop (&gen_adddf3_i, operands);
8091 (define_insn "*adddf3_media"
8092 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8093 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8094 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8095 "TARGET_SHMEDIA_FPU"
8096 "fadd.d %1, %2, %0")
8098 (define_insn "adddf3_i"
8099 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8100 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8101 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8102 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8105 [(set_attr "type" "dfp_arith")
8106 (set_attr "fp_mode" "double")])
8108 (define_expand "subdf3"
8109 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8110 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8111 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8112 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8117 expand_df_binop (&gen_subdf3_i, operands);
8122 (define_insn "*subdf3_media"
8123 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8124 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8125 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8126 "TARGET_SHMEDIA_FPU"
8127 "fsub.d %1, %2, %0")
8129 (define_insn "subdf3_i"
8130 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8131 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8132 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8133 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8136 [(set_attr "type" "dfp_arith")
8137 (set_attr "fp_mode" "double")])
8139 (define_expand "muldf3"
8140 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8141 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8142 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8143 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8148 expand_df_binop (&gen_muldf3_i, operands);
8153 (define_insn "*muldf3_media"
8154 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8155 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8156 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8157 "TARGET_SHMEDIA_FPU"
8158 "fmul.d %1, %2, %0")
8160 (define_insn "muldf3_i"
8161 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8162 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8163 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8164 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8167 [(set_attr "type" "dfp_arith")
8168 (set_attr "fp_mode" "double")])
8170 (define_expand "divdf3"
8171 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8172 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8173 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8174 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8179 expand_df_binop (&gen_divdf3_i, operands);
8184 (define_insn "*divdf3_media"
8185 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8186 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8187 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8188 "TARGET_SHMEDIA_FPU"
8189 "fdiv.d %1, %2, %0")
8191 (define_insn "divdf3_i"
8192 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8193 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8194 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8195 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8198 [(set_attr "type" "dfdiv")
8199 (set_attr "fp_mode" "double")])
8201 (define_insn "floatdidf2"
8202 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8203 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8204 "TARGET_SHMEDIA_FPU"
8207 (define_expand "floatsidf2"
8208 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8209 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8210 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8215 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8221 (define_insn "*floatsidf2_media"
8222 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8223 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8224 "TARGET_SHMEDIA_FPU"
8227 (define_insn "floatsidf2_i"
8228 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8229 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8230 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8233 [(set_attr "type" "dfp_conv")
8234 (set_attr "fp_mode" "double")])
8236 (define_insn "fix_truncdfdi2"
8237 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8238 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8239 "TARGET_SHMEDIA_FPU"
8242 (define_expand "fix_truncdfsi2"
8243 [(set (match_operand:SI 0 "fpul_operand" "")
8244 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8245 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8250 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8256 (define_insn "*fix_truncdfsi2_media"
8257 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8258 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8259 "TARGET_SHMEDIA_FPU"
8262 (define_insn "fix_truncdfsi2_i"
8263 [(set (match_operand:SI 0 "fpul_operand" "=y")
8264 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8265 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8268 [(set_attr "type" "dfp_conv")
8269 (set_attr "fp_mode" "double")])
8271 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8272 ;; fix_truncdfsi2_i.
8273 ;; (define_insn "fix_truncdfsi2_i4"
8274 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8275 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8276 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8277 ;; (clobber (reg:SI FPUL_REG))]
8280 ;; [(set_attr "length" "4")
8281 ;; (set_attr "fp_mode" "double")])
8284 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8285 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8286 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8287 ;; (clobber (reg:SI FPUL_REG))]
8289 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8290 ;; (use (match_dup 2))])
8291 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8293 (define_insn "cmpgtdf_t"
8294 [(set (reg:SI T_REG)
8295 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8296 (match_operand:DF 1 "arith_reg_operand" "f")))
8297 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8300 [(set_attr "type" "dfp_cmp")
8301 (set_attr "fp_mode" "double")])
8303 (define_insn "cmpeqdf_t"
8304 [(set (reg:SI T_REG)
8305 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8306 (match_operand:DF 1 "arith_reg_operand" "f")))
8307 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8310 [(set_attr "type" "dfp_cmp")
8311 (set_attr "fp_mode" "double")])
8313 (define_insn "*ieee_ccmpeqdf_t"
8314 [(set (reg:SI T_REG)
8315 (ior:SI (reg:SI T_REG)
8316 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8317 (match_operand:DF 1 "arith_reg_operand" "f"))))
8318 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8319 "TARGET_IEEE && TARGET_SH4"
8320 "* return output_ieee_ccmpeq (insn, operands);"
8321 [(set_attr "length" "4")
8322 (set_attr "fp_mode" "double")])
8324 (define_insn "cmpeqdf_media"
8325 [(set (match_operand:DI 0 "register_operand" "=r")
8326 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8327 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8328 "TARGET_SHMEDIA_FPU"
8329 "fcmpeq.d %1,%2,%0")
8331 (define_insn "cmpgtdf_media"
8332 [(set (match_operand:DI 0 "register_operand" "=r")
8333 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8334 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8335 "TARGET_SHMEDIA_FPU"
8336 "fcmpgt.d %1,%2,%0")
8338 (define_insn "cmpgedf_media"
8339 [(set (match_operand:DI 0 "register_operand" "=r")
8340 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8341 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8342 "TARGET_SHMEDIA_FPU"
8343 "fcmpge.d %1,%2,%0")
8345 (define_insn "cmpundf_media"
8346 [(set (match_operand:DI 0 "register_operand" "=r")
8347 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8348 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8349 "TARGET_SHMEDIA_FPU"
8350 "fcmpun.d %1,%2,%0")
8352 (define_expand "cmpdf"
8353 [(set (reg:SI T_REG)
8354 (compare (match_operand:DF 0 "arith_operand" "")
8355 (match_operand:DF 1 "arith_operand" "")))]
8356 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8359 sh_compare_op0 = operands[0];
8360 sh_compare_op1 = operands[1];
8364 (define_expand "negdf2"
8365 [(set (match_operand:DF 0 "arith_reg_operand" "")
8366 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8367 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8372 expand_df_unop (&gen_negdf2_i, operands);
8377 (define_insn "*negdf2_media"
8378 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8379 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8380 "TARGET_SHMEDIA_FPU"
8383 (define_insn "negdf2_i"
8384 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8385 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8386 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8389 [(set_attr "type" "fmove")
8390 (set_attr "fp_mode" "double")])
8392 (define_expand "sqrtdf2"
8393 [(set (match_operand:DF 0 "arith_reg_operand" "")
8394 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8395 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8400 expand_df_unop (&gen_sqrtdf2_i, operands);
8405 (define_insn "*sqrtdf2_media"
8406 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8407 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8408 "TARGET_SHMEDIA_FPU"
8411 (define_insn "sqrtdf2_i"
8412 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8413 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8414 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8417 [(set_attr "type" "dfdiv")
8418 (set_attr "fp_mode" "double")])
8420 (define_expand "absdf2"
8421 [(set (match_operand:DF 0 "arith_reg_operand" "")
8422 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8423 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8428 expand_df_unop (&gen_absdf2_i, operands);
8433 (define_insn "*absdf2_media"
8434 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8435 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8436 "TARGET_SHMEDIA_FPU"
8439 (define_insn "absdf2_i"
8440 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8441 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8442 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8445 [(set_attr "type" "fmove")
8446 (set_attr "fp_mode" "double")])
8448 (define_expand "extendsfdf2"
8449 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8450 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8451 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8456 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8462 (define_insn "*extendsfdf2_media"
8463 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8464 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8465 "TARGET_SHMEDIA_FPU"
8468 (define_insn "extendsfdf2_i4"
8469 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8470 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8471 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8474 [(set_attr "type" "fp")
8475 (set_attr "fp_mode" "double")])
8477 (define_expand "truncdfsf2"
8478 [(set (match_operand:SF 0 "fpul_operand" "")
8479 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8480 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8485 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8491 (define_insn "*truncdfsf2_media"
8492 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8493 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8494 "TARGET_SHMEDIA_FPU"
8497 (define_insn "truncdfsf2_i4"
8498 [(set (match_operand:SF 0 "fpul_operand" "=y")
8499 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8500 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8503 [(set_attr "type" "fp")
8504 (set_attr "fp_mode" "double")])
8506 ;; Bit field extract patterns. These give better code for packed bitfields,
8507 ;; because they allow auto-increment addresses to be generated.
8509 (define_expand "insv"
8510 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8511 (match_operand:SI 1 "immediate_operand" "")
8512 (match_operand:SI 2 "immediate_operand" ""))
8513 (match_operand:SI 3 "general_operand" ""))]
8514 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8517 rtx addr_target, orig_address, shift_reg, qi_val;
8518 HOST_WIDE_INT bitsize, size, v;
8519 rtx x = operands[3];
8521 /* ??? expmed doesn't care for non-register predicates. */
8522 if (! memory_operand (operands[0], VOIDmode)
8523 || ! immediate_operand (operands[1], VOIDmode)
8524 || ! immediate_operand (operands[2], VOIDmode)
8525 || ! general_operand (x, VOIDmode))
8527 /* If this isn't a 16 / 24 / 32 bit field, or if
8528 it doesn't start on a byte boundary, then fail. */
8529 bitsize = INTVAL (operands[1]);
8530 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8531 || (INTVAL (operands[2]) % 8) != 0)
8535 orig_address = XEXP (operands[0], 0);
8536 shift_reg = gen_reg_rtx (SImode);
8537 if (GET_CODE (x) == CONST_INT)
8540 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8544 emit_insn (gen_movsi (shift_reg, operands[3]));
8545 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8547 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8549 operands[0] = replace_equiv_address (operands[0], addr_target);
8550 emit_insn (gen_movqi (operands[0], qi_val));
8554 if (GET_CODE (x) == CONST_INT)
8556 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8559 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8560 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8562 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8563 emit_insn (gen_movqi (operands[0], qi_val));
8569 ;; -------------------------------------------------------------------------
8571 ;; -------------------------------------------------------------------------
8573 ;; This matches cases where a stack pointer increment at the start of the
8574 ;; epilogue combines with a stack slot read loading the return value.
8577 [(set (match_operand:SI 0 "arith_reg_operand" "")
8578 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8579 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8580 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8583 ;; See the comment on the dt combiner pattern above.
8586 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8587 (plus:SI (match_dup 0)
8590 (eq:SI (match_dup 0)
8595 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
8596 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
8597 ;; reload when the constant is too large for a reg+offset address.
8599 ;; ??? We would get much better code if this was done in reload. This would
8600 ;; require modifying find_reloads_address to recognize that if the constant
8601 ;; is out-of-range for an immediate add, then we get better code by reloading
8602 ;; the constant into a register than by reloading the sum into a register,
8603 ;; since the former is one instruction shorter if the address does not need
8604 ;; to be offsettable. Unfortunately this does not work, because there is
8605 ;; only one register, r0, that can be used as an index register. This register
8606 ;; is also the function return value register. So, if we try to force reload
8607 ;; to use double-reg addresses, then we end up with some instructions that
8608 ;; need to use r0 twice. The only way to fix this is to change the calling
8609 ;; convention so that r0 is not used to return values.
8612 [(set (match_operand:SI 0 "register_operand" "=r")
8613 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8614 (set (mem:SI (match_dup 0))
8615 (match_operand:SI 2 "general_movsrc_operand" ""))]
8616 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8617 "mov.l %2,@(%0,%1)")
8620 [(set (match_operand:SI 0 "register_operand" "=r")
8621 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8622 (set (match_operand:SI 2 "general_movdst_operand" "")
8623 (mem:SI (match_dup 0)))]
8624 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8625 "mov.l @(%0,%1),%2")
8628 [(set (match_operand:SI 0 "register_operand" "=r")
8629 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8630 (set (mem:HI (match_dup 0))
8631 (match_operand:HI 2 "general_movsrc_operand" ""))]
8632 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8633 "mov.w %2,@(%0,%1)")
8636 [(set (match_operand:SI 0 "register_operand" "=r")
8637 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8638 (set (match_operand:HI 2 "general_movdst_operand" "")
8639 (mem:HI (match_dup 0)))]
8640 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8641 "mov.w @(%0,%1),%2")
8644 [(set (match_operand:SI 0 "register_operand" "=r")
8645 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8646 (set (mem:QI (match_dup 0))
8647 (match_operand:QI 2 "general_movsrc_operand" ""))]
8648 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8649 "mov.b %2,@(%0,%1)")
8652 [(set (match_operand:SI 0 "register_operand" "=r")
8653 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8654 (set (match_operand:QI 2 "general_movdst_operand" "")
8655 (mem:QI (match_dup 0)))]
8656 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8657 "mov.b @(%0,%1),%2")
8660 [(set (match_operand:SI 0 "register_operand" "=r")
8661 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8662 (set (mem:SF (match_dup 0))
8663 (match_operand:SF 2 "general_movsrc_operand" ""))]
8664 "TARGET_SH1 && REGNO (operands[0]) == 0
8665 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8666 || (GET_CODE (operands[2]) == SUBREG
8667 && REGNO (SUBREG_REG (operands[2])) < 16))
8668 && reg_unused_after (operands[0], insn)"
8669 "mov.l %2,@(%0,%1)")
8672 [(set (match_operand:SI 0 "register_operand" "=r")
8673 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8674 (set (match_operand:SF 2 "general_movdst_operand" "")
8676 (mem:SF (match_dup 0)))]
8677 "TARGET_SH1 && REGNO (operands[0]) == 0
8678 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8679 || (GET_CODE (operands[2]) == SUBREG
8680 && REGNO (SUBREG_REG (operands[2])) < 16))
8681 && reg_unused_after (operands[0], insn)"
8682 "mov.l @(%0,%1),%2")
8685 [(set (match_operand:SI 0 "register_operand" "=r")
8686 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8687 (set (mem:SF (match_dup 0))
8688 (match_operand:SF 2 "general_movsrc_operand" ""))]
8689 "TARGET_SH3E && REGNO (operands[0]) == 0
8690 && ((GET_CODE (operands[2]) == REG
8691 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8692 || (GET_CODE (operands[2]) == SUBREG
8693 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8694 && reg_unused_after (operands[0], insn)"
8695 "fmov{.s|} %2,@(%0,%1)")
8698 [(set (match_operand:SI 0 "register_operand" "=r")
8699 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8700 (set (match_operand:SF 2 "general_movdst_operand" "")
8702 (mem:SF (match_dup 0)))]
8703 "TARGET_SH3E && REGNO (operands[0]) == 0
8704 && ((GET_CODE (operands[2]) == REG
8705 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8706 || (GET_CODE (operands[2]) == SUBREG
8707 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8708 && reg_unused_after (operands[0], insn)"
8709 "fmov{.s|} @(%0,%1),%2")
8711 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
8712 (define_insn "sp_switch_1"
8719 xoperands[0] = sp_switch;
8720 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
8721 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
8722 return \"mov r0,r15\";
8724 [(set_attr "length" "10")])
8726 ;; Switch back to the original stack for interrupt functions with the
8727 ;; sp_switch attribute. */
8728 (define_insn "sp_switch_2"
8731 "mov.l @r15+,r15\;mov.l @r15+,r0"
8732 [(set_attr "length" "4")])
8734 ;; Integer vector moves
8736 (define_expand "movv8qi"
8737 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
8738 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
8740 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
8742 (define_insn "movv8qi_i"
8743 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
8744 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8746 && (register_operand (operands[0], V8QImode)
8747 || register_operand (operands[1], V8QImode))"
8754 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
8755 (set_attr "length" "4,4,16,4,4")])
8758 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
8759 (subreg:V8QI (const_int 0) 0))]
8762 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
8763 (const_int 0) (const_int 0) (const_int 0)
8764 (const_int 0) (const_int 0)]))])
8767 [(set (match_operand 0 "arith_reg_dest" "")
8768 (match_operand 1 "sh_rep_vec" ""))]
8769 "TARGET_SHMEDIA && reload_completed
8770 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8771 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
8772 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
8773 && (XVECEXP (operands[1], 0, 0) != const0_rtx
8774 || XVECEXP (operands[1], 0, 1) != const0_rtx)"
8775 [(set (match_dup 0) (match_dup 1))
8779 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
8780 rtx elt1 = XVECEXP (operands[1], 0, 1);
8783 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
8785 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
8786 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
8787 operands[1] = XVECEXP (operands[1], 0, 0);
8790 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
8791 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
8792 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
8793 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
8796 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
8798 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
8804 [(set (match_operand 0 "arith_reg_dest" "")
8805 (match_operand 1 "sh_const_vec" ""))]
8806 "TARGET_SHMEDIA && reload_completed
8807 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8808 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
8809 && XVECEXP (operands[1], 0, 0) != const0_rtx
8810 && (HOST_BITS_PER_WIDE_INT >= 64
8811 || HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (GET_MODE (operands[0]))
8812 || sh_1el_vec (operands[1], VOIDmode))"
8813 [(set (match_dup 0) (match_dup 1))]
8816 rtx v = operands[1];
8817 enum machine_mode new_mode
8818 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
8820 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
8822 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[0]), 0);
8825 (define_expand "movv2hi"
8826 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
8827 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
8829 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
8831 (define_insn "movv2hi_i"
8832 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
8833 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8835 && (register_operand (operands[0], V2HImode)
8836 || register_operand (operands[1], V2HImode))"
8843 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
8844 (set_attr "length" "4,4,16,4,4")])
8846 (define_expand "movv4hi"
8847 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
8848 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
8850 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
8852 (define_insn "movv4hi_i"
8853 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
8854 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8856 && (register_operand (operands[0], V4HImode)
8857 || register_operand (operands[1], V4HImode))"
8864 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
8865 (set_attr "length" "4,4,16,4,4")])
8867 (define_expand "movv2si"
8868 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
8869 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
8871 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
8873 (define_insn "movv2si_i"
8874 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
8875 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
8877 && (register_operand (operands[0], V2SImode)
8878 || register_operand (operands[1], V2SImode))"
8885 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
8886 (set_attr "length" "4,4,16,4,4")])
8888 ;; Multimedia Intrinsics
8890 (define_insn "absv2si2"
8891 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8892 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
8895 [(set_attr "type" "mcmp_media")])
8897 (define_insn "absv4hi2"
8898 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8899 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
8902 [(set_attr "type" "mcmp_media")])
8904 (define_insn "addv2si3"
8905 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8906 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
8907 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
8910 [(set_attr "type" "arith_media")])
8912 (define_insn "addv4hi3"
8913 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8914 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
8915 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
8918 [(set_attr "type" "arith_media")])
8920 (define_insn "ssaddv2si3"
8921 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8922 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
8923 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
8925 "madds.l %1, %2, %0"
8926 [(set_attr "type" "mcmp_media")])
8928 (define_insn "usaddv8qi3"
8929 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8930 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
8931 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
8933 "madds.ub %1, %2, %0"
8934 [(set_attr "type" "mcmp_media")])
8936 (define_insn "ssaddv4hi3"
8937 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8938 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
8939 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
8941 "madds.w %1, %2, %0"
8942 [(set_attr "type" "mcmp_media")])
8944 (define_insn "negcmpeqv8qi"
8945 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8946 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
8947 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
8949 "mcmpeq.b %N1, %N2, %0"
8950 [(set_attr "type" "mcmp_media")])
8952 (define_insn "negcmpeqv2si"
8953 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8954 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
8955 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
8957 "mcmpeq.l %N1, %N2, %0"
8958 [(set_attr "type" "mcmp_media")])
8960 (define_insn "negcmpeqv4hi"
8961 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8962 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
8963 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
8965 "mcmpeq.w %N1, %N2, %0"
8966 [(set_attr "type" "mcmp_media")])
8968 (define_insn "negcmpgtuv8qi"
8969 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
8970 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
8971 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
8973 "mcmpgt.ub %N1, %N2, %0"
8974 [(set_attr "type" "mcmp_media")])
8976 (define_insn "negcmpgtv2si"
8977 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
8978 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
8979 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
8981 "mcmpgt.l %N1, %N2, %0"
8982 [(set_attr "type" "mcmp_media")])
8984 (define_insn "negcmpgtv4hi"
8985 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
8986 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
8987 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
8989 "mcmpgt.w %N1, %N2, %0"
8990 [(set_attr "type" "mcmp_media")])
8993 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8994 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
8995 (match_operand:DI 2 "arith_reg_operand" "r"))
8996 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
8997 (not:DI (match_dup 2)))))]
9000 [(set_attr "type" "arith_media")])
9002 (define_insn "mcnvs_lw"
9003 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9005 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9006 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9008 "mcnvs.lw %N1, %N2, %0"
9009 [(set_attr "type" "mcmp_media")])
9011 (define_insn "mcnvs_wb"
9012 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9014 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9015 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9017 "mcnvs.wb %N1, %N2, %0"
9018 [(set_attr "type" "mcmp_media")])
9020 (define_insn "mcnvs_wub"
9021 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9023 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9024 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9026 "mcnvs.wub %N1, %N2, %0"
9027 [(set_attr "type" "mcmp_media")])
9029 (define_insn "mextr_rl"
9030 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9031 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9032 (match_operand:HI 3 "mextr_bit_offset" "i"))
9033 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9034 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9035 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9038 static char templ[16];
9040 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9041 (int) INTVAL (operands[3]) >> 3);
9044 [(set_attr "type" "arith_media")])
9046 (define_insn "*mextr_lr"
9047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9048 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9049 (match_operand:HI 3 "mextr_bit_offset" "i"))
9050 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9051 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9052 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9055 static char templ[16];
9057 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9058 (int) INTVAL (operands[4]) >> 3);
9061 [(set_attr "type" "arith_media")])
9063 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9064 ; vector then varies depending on endianness.
9065 (define_expand "mextr1"
9066 [(match_operand:V8QI 0 "arith_reg_dest" "")
9067 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9068 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9072 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9073 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9077 (define_expand "mextr2"
9078 [(match_operand:V8QI 0 "arith_reg_dest" "")
9079 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9080 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9084 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9085 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9089 (define_expand "mextr3"
9090 [(match_operand:V8QI 0 "arith_reg_dest" "")
9091 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9092 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9096 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9097 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9101 (define_expand "mextr4"
9102 [(match_operand:V8QI 0 "arith_reg_dest" "")
9103 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9104 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9108 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9109 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9113 (define_expand "mextr5"
9114 [(match_operand:V8QI 0 "arith_reg_dest" "")
9115 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9116 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9120 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9121 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9125 (define_expand "mextr6"
9126 [(match_operand:V8QI 0 "arith_reg_dest" "")
9127 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9128 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9132 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9133 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9137 (define_expand "mextr7"
9138 [(match_operand:V8QI 0 "arith_reg_dest" "")
9139 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9140 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9144 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[3],
9145 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9149 (define_expand "mmacfx_wl"
9150 [(match_operand:V2SI 0 "arith_reg_dest" "")
9151 (match_operand:V2HI 1 "extend_reg_operand" "")
9152 (match_operand:V2HI 2 "extend_reg_operand" "")
9153 (match_operand:V2SI 3 "arith_reg_operand" "")]
9157 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9158 operands[1], operands[2]));
9162 (define_insn "mmacfx_wl_i"
9163 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9165 (match_operand:V2SI 1 "arith_reg_operand" "0")
9170 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9171 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9174 "mmacfx.wl %2, %3, %0"
9175 [(set_attr "type" "mac_media")])
9177 (define_expand "mmacnfx_wl"
9178 [(match_operand:V2SI 0 "arith_reg_dest" "")
9179 (match_operand:V2HI 1 "extend_reg_operand" "")
9180 (match_operand:V2HI 2 "extend_reg_operand" "")
9181 (match_operand:V2SI 3 "arith_reg_operand" "")]
9185 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9186 operands[1], operands[2]));
9190 (define_insn "mmacnfx_wl_i"
9191 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9193 (match_operand:V2SI 1 "arith_reg_operand" "0")
9198 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9199 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9202 "mmacnfx.wl %2, %3, %0"
9203 [(set_attr "type" "mac_media")])
9205 (define_insn "mulv2si3"
9206 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9207 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9208 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9211 [(set_attr "type" "d2mpy_media")])
9213 (define_insn "mulv4hi3"
9214 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9215 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9216 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9219 [(set_attr "type" "dmpy_media")])
9221 (define_insn "mmulfx_l"
9222 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9226 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9227 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9230 "mmulfx.l %1, %2, %0"
9231 [(set_attr "type" "d2mpy_media")])
9233 (define_insn "mmulfx_w"
9234 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9238 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9239 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9242 "mmulfx.w %1, %2, %0"
9243 [(set_attr "type" "dmpy_media")])
9245 (define_insn "mmulfxrp_w"
9246 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9251 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9252 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9256 "mmulfxrp.w %1, %2, %0"
9257 [(set_attr "type" "dmpy_media")])
9259 (define_expand "mmulhi_wl"
9260 [(match_operand:V2SI 0 "arith_reg_dest" "")
9261 (match_operand:V4HI 1 "arith_reg_operand" "")
9262 (match_operand:V4HI 2 "arith_reg_operand" "")]
9266 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9267 (operands[0], operands[1], operands[2]));
9271 (define_expand "mmullo_wl"
9272 [(match_operand:V2SI 0 "arith_reg_dest" "")
9273 (match_operand:V4HI 1 "arith_reg_operand" "")
9274 (match_operand:V4HI 2 "arith_reg_operand" "")]
9278 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9279 (operands[0], operands[1], operands[2]));
9283 (define_insn "mmul23_wl"
9284 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9287 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9288 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9289 (const_vector [(const_int 2) (const_int 3)])))]
9291 "* return (TARGET_LITTLE_ENDIAN
9292 ? \"mmulhi.wl %1, %2, %0\"
9293 : \"mmullo.wl %1, %2, %0\");"
9294 [(set_attr "type" "dmpy_media")])
9296 (define_insn "mmul01_wl"
9297 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9300 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9301 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9302 (const_vector [(const_int 0) (const_int 1)])))]
9304 "* return (TARGET_LITTLE_ENDIAN
9305 ? \"mmullo.wl %1, %2, %0\"
9306 : \"mmulhi.wl %1, %2, %0\");"
9307 [(set_attr "type" "dmpy_media")])
9309 (define_expand "mmulsum_wq"
9310 [(match_operand:DI 0 "arith_reg_dest" "")
9311 (match_operand:V4HI 1 "arith_reg_operand" "")
9312 (match_operand:V4HI 2 "arith_reg_operand" "")
9313 (match_operand:DI 3 "arith_reg_operand" "")]
9317 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9318 operands[1], operands[2]));
9322 (define_insn "mmulsum_wq_i"
9323 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9324 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9329 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9330 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9331 (const_vector [(const_int 0)]))
9332 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9333 (sign_extend:V4DI (match_dup 3)))
9334 (const_vector [(const_int 1)])))
9336 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9337 (sign_extend:V4DI (match_dup 3)))
9338 (const_vector [(const_int 2)]))
9339 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9340 (sign_extend:V4DI (match_dup 3)))
9341 (const_vector [(const_int 3)]))))))]
9343 "mmulsum.wq %2, %3, %0"
9344 [(set_attr "type" "mac_media")])
9346 (define_expand "mperm_w"
9347 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9348 (match_operand:V4HI 1 "arith_reg_operand" "r")
9349 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9353 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9354 (operands[0], operands[1], operands[2]));
9357 ; This use of vec_select isn't exactly correct according to rtl.texi
9358 ; (because not constant), but it seems a straightforward extension.
9359 (define_insn "mperm_w_little"
9360 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9362 (match_operand:V4HI 1 "arith_reg_operand" "r")
9364 [(zero_extract (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9365 (const_int 2) (const_int 0))
9366 (zero_extract (match_dup 2) (const_int 2) (const_int 2))
9367 (zero_extract (match_dup 2) (const_int 2) (const_int 4))
9368 (zero_extract (match_dup 2) (const_int 2) (const_int 6))])))]
9369 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9370 "mperm.w %1, %N2, %0"
9371 [(set_attr "type" "arith_media")])
9373 (define_insn "mperm_w_big"
9374 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9376 (match_operand:V4HI 1 "arith_reg_operand" "r")
9378 [(zero_extract (not:QI (match_operand:QI 2
9379 "extend_reg_or_0_operand" "rU"))
9380 (const_int 2) (const_int 0))
9381 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9382 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9383 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 6))])))]
9384 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9385 "mperm.w %1, %N2, %0"
9386 [(set_attr "type" "arith_media")])
9388 (define_insn "mperm_w0"
9389 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9390 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9391 "extend_reg_operand" "r"))))]
9393 "mperm.w %1, r63, %0"
9394 [(set_attr "type" "arith_media")])
9396 (define_expand "msad_ubq"
9397 [(match_operand:DI 0 "arith_reg_dest" "")
9398 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9399 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9400 (match_operand:DI 3 "arith_reg_operand" "")]
9404 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9405 operands[1], operands[2]));
9409 (define_insn "msad_ubq_i"
9410 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9415 (match_operand:DI 1 "arith_reg_operand" "0")
9416 (abs:DI (vec_select:DI
9419 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9421 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9422 (const_vector [(const_int 0)]))))
9423 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9424 (zero_extend:V8DI (match_dup 3)))
9425 (const_vector [(const_int 1)]))))
9427 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9428 (zero_extend:V8DI (match_dup 3)))
9429 (const_vector [(const_int 2)])))
9430 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9431 (zero_extend:V8DI (match_dup 3)))
9432 (const_vector [(const_int 3)])))))
9435 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9436 (zero_extend:V8DI (match_dup 3)))
9437 (const_vector [(const_int 4)])))
9438 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9439 (zero_extend:V8DI (match_dup 3)))
9440 (const_vector [(const_int 5)]))))
9442 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9443 (zero_extend:V8DI (match_dup 3)))
9444 (const_vector [(const_int 6)])))
9445 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9446 (zero_extend:V8DI (match_dup 3)))
9447 (const_vector [(const_int 7)])))))))]
9449 "msad.ubq %N2, %N3, %0"
9450 [(set_attr "type" "mac_media")])
9452 (define_insn "mshalds_l"
9453 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9456 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9457 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9460 "mshalds.l %1, %2, %0"
9461 [(set_attr "type" "mcmp_media")])
9463 (define_insn "mshalds_w"
9464 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9467 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9468 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9471 "mshalds.w %1, %2, %0"
9472 [(set_attr "type" "mcmp_media")])
9474 (define_insn "ashrv2si3"
9475 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9476 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9477 (match_operand:DI 2 "arith_reg_operand" "r")))]
9479 "mshard.l %1, %2, %0"
9480 [(set_attr "type" "arith_media")])
9482 (define_insn "ashrv4hi3"
9483 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9484 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9485 (match_operand:DI 2 "arith_reg_operand" "r")))]
9487 "mshard.w %1, %2, %0"
9488 [(set_attr "type" "arith_media")])
9490 (define_insn "mshards_q"
9491 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9493 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9494 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9496 "mshards.q %1, %N2, %0"
9497 [(set_attr "type" "mcmp_media")])
9499 (define_expand "mshfhi_b"
9500 [(match_operand:V8QI 0 "arith_reg_dest" "")
9501 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9502 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9506 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9507 (operands[0], operands[1], operands[2]));
9510 (define_expand "mshflo_b"
9511 [(match_operand:V8QI 0 "arith_reg_dest" "")
9512 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9513 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9517 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9518 (operands[0], operands[1], operands[2]));
9521 (define_insn "mshf4_b"
9523 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9525 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9526 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9527 (const_vector [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9528 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9530 "* return (TARGET_LITTLE_ENDIAN
9531 ? \"mshfhi.b %N1, %N2, %0\"
9532 : \"mshflo.b %N1, %N2, %0\");"
9533 [(set_attr "type" "arith_media")])
9535 (define_insn "mshf0_b"
9537 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9539 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9540 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9541 (const_vector [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9542 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9544 "* return (TARGET_LITTLE_ENDIAN
9545 ? \"mshflo.b %N1, %N2, %0\"
9546 : \"mshfhi.b %N1, %N2, %0\");"
9547 [(set_attr "type" "arith_media")])
9549 (define_expand "mshfhi_l"
9550 [(match_operand:V2SI 0 "arith_reg_dest" "")
9551 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9552 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9556 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9557 (operands[0], operands[1], operands[2]));
9560 (define_expand "mshflo_l"
9561 [(match_operand:V2SI 0 "arith_reg_dest" "")
9562 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9563 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9567 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9568 (operands[0], operands[1], operands[2]));
9571 (define_insn "mshf4_l"
9572 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9574 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9575 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9576 (const_vector [(const_int 1) (const_int 3)])))]
9578 "* return (TARGET_LITTLE_ENDIAN
9579 ? \"mshfhi.l %N1, %N2, %0\"
9580 : \"mshflo.l %N1, %N2, %0\");"
9581 [(set_attr "type" "arith_media")])
9583 (define_insn "mshf0_l"
9584 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9586 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9587 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9588 (const_vector [(const_int 0) (const_int 2)])))]
9590 "* return (TARGET_LITTLE_ENDIAN
9591 ? \"mshflo.l %N1, %N2, %0\"
9592 : \"mshfhi.l %N1, %N2, %0\");"
9593 [(set_attr "type" "arith_media")])
9595 (define_expand "mshfhi_w"
9596 [(match_operand:V4HI 0 "arith_reg_dest" "")
9597 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9598 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9602 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
9603 (operands[0], operands[1], operands[2]));
9606 (define_expand "mshflo_w"
9607 [(match_operand:V4HI 0 "arith_reg_dest" "")
9608 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9609 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9613 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
9614 (operands[0], operands[1], operands[2]));
9617 (define_insn "mshf4_w"
9618 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9620 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9621 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
9622 (const_vector [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
9624 "* return (TARGET_LITTLE_ENDIAN
9625 ? \"mshfhi.w %N1, %N2, %0\"
9626 : \"mshflo.w %N1, %N2, %0\");"
9627 [(set_attr "type" "arith_media")])
9629 (define_insn "mshf0_w"
9630 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9632 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9633 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
9634 (const_vector [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
9636 "* return (TARGET_LITTLE_ENDIAN
9637 ? \"mshflo.w %N1, %N2, %0\"
9638 : \"mshfhi.w %N1, %N2, %0\");"
9639 [(set_attr "type" "arith_media")])
9641 /* These are useful to expand ANDs and as combiner patterns. */
9642 (define_insn "mshfhi_l_di"
9643 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9644 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9646 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9647 (const_int -4294967296))))]
9649 "mshfhi.l %N1, %N2, %0"
9650 [(set_attr "type" "arith_media")])
9652 (define_insn "*mshfhi_l_di_rev"
9653 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9654 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9655 (const_int -4294967296))
9656 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9659 "mshfhi.l %N2, %N1, %0"
9660 [(set_attr "type" "arith_media")])
9662 (define_insn "mshflo_l_di"
9663 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9664 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9665 (const_int 4294967295))
9666 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9670 "mshflo.l %N1, %N2, %0"
9671 [(set_attr "type" "arith_media")])
9673 (define_insn "*mshflo_l_di_rev"
9674 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9675 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9677 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9678 (const_int 4294967295))))]
9681 "mshflo.l %N2, %N1, %0"
9682 [(set_attr "type" "arith_media")])
9684 (define_insn "*mshflo_l_di_x"
9685 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9686 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand" "rU"))
9687 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9691 "mshflo.l %N1, %N2, %0"
9692 [(set_attr "type" "arith_media")])
9694 (define_insn "*mshflo_l_di_x_rev"
9695 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9696 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9698 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
9701 "mshflo.l %N2, %N1, %0"
9702 [(set_attr "type" "arith_media")])
9704 (define_insn "ashlv2si3"
9705 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9706 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9707 (match_operand:DI 2 "arith_reg_operand" "r")))]
9709 "mshlld.l %1, %2, %0"
9710 [(set_attr "type" "arith_media")])
9712 (define_insn "ashlv4hi3"
9713 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9714 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9715 (match_operand:DI 2 "arith_reg_operand" "r")))]
9717 "mshlld.w %1, %2, %0"
9718 [(set_attr "type" "arith_media")])
9720 (define_insn "lshrv2si3"
9721 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9722 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9723 (match_operand:DI 2 "arith_reg_operand" "r")))]
9725 "mshlrd.l %1, %2, %0"
9726 [(set_attr "type" "arith_media")])
9728 (define_insn "lshrv4hi3"
9729 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9730 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9731 (match_operand:DI 2 "arith_reg_operand" "r")))]
9733 "mshlrd.w %1, %2, %0"
9734 [(set_attr "type" "arith_media")])
9736 (define_insn "subv2si3"
9737 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9738 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9739 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9741 "msub.l %N1, %2, %0"
9742 [(set_attr "type" "arith_media")])
9744 (define_insn "subv4hi3"
9745 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9746 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9747 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9749 "msub.w %N1, %2, %0"
9750 [(set_attr "type" "arith_media")])
9752 (define_insn "sssubv2si3"
9753 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9754 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9755 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9757 "msubs.l %N1, %2, %0"
9758 [(set_attr "type" "mcmp_media")])
9760 (define_insn "ussubv8qi3"
9761 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9762 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
9763 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9765 "msubs.ub %1, %2, %0"
9766 [(set_attr "type" "mcmp_media")])
9768 (define_insn "sssubv4hi3"
9769 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9770 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9771 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9773 "msubs.w %N1, %2, %0"
9774 [(set_attr "type" "mcmp_media")])
9776 ;; Floating Point Intrinsics
9778 (define_insn "fcosa_s"
9779 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9780 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
9784 [(set_attr "type" "atrans_media")])
9786 (define_insn "fsina_s"
9787 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9788 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
9792 [(set_attr "type" "atrans_media")])
9795 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9796 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
9797 "fp_arith_reg_operand" "f")
9798 (match_operand:V4SF 2
9799 "fp_arith_reg_operand" "f"))
9800 (const_vector [(const_int 0)]))
9801 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9802 (const_vector [(const_int 1)])))
9803 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9804 (const_vector [(const_int 2)]))
9805 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
9806 (const_vector [(const_int 3)])))))]
9809 [(set_attr "type" "fparith_media")])
9811 (define_insn "fsrra_s"
9812 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9813 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
9817 [(set_attr "type" "atrans_media")])
9820 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
9824 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
9825 (const_vector [(const_int 0) (const_int 5)
9826 (const_int 10) (const_int 15)]))
9827 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
9829 (vec_select:V4SF (match_dup 1)
9830 (const_vector [(const_int 4) (const_int 9)
9831 (const_int 14) (const_int 3)]))
9832 (vec_select:V4SF (match_dup 2)
9833 (const_vector [(const_int 1) (const_int 2)
9834 (const_int 3) (const_int 0)]))))
9837 (vec_select:V4SF (match_dup 1)
9838 (const_vector [(const_int 8) (const_int 13)
9839 (const_int 2) (const_int 7)]))
9840 (vec_select:V4SF (match_dup 2)
9841 (const_vector [(const_int 2) (const_int 3)
9842 (const_int 0) (const_int 1)])))
9844 (vec_select:V4SF (match_dup 1)
9845 (const_vector [(const_int 12) (const_int 1)
9846 (const_int 6) (const_int 11)]))
9847 (vec_select:V4SF (match_dup 2)
9848 (const_vector [(const_int 3) (const_int 0)
9849 (const_int 1) (const_int 2)]))))))]
9852 [(set_attr "type" "fparith_media")])
9854 ;; The following description models the
9855 ;; SH4 pipeline using the DFA based scheduler.
9856 ;; The DFA based description is better way to model
9857 ;; a superscalar pipeline as compared to function unit
9858 ;; reservation model.
9859 ;; 1. The function unit based model is oriented to describe at most one
9860 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
9861 ;; pipeline units by same insn. This can be done using DFA based description.
9862 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
9863 ;; 3. Writing all unit reservations for an instruction class is more natural description
9864 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
9865 ;; old function unit based model.
9866 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
9869 ;; Two automata are defined to reduce number of states
9870 ;; which a single large automaton will have.(Factoring)
9872 (define_automaton "inst_pipeline,fpu_pipe")
9874 ;; This unit is basically the decode unit of the processor.
9875 ;; Since SH4 is a dual issue machine,it is as if there are two
9876 ;; units so that any insn can be processed by either one
9877 ;; of the decoding unit.
9879 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
9882 ;; The fixed point arithmetic calculator(?? EX Unit).
9884 (define_cpu_unit "int" "inst_pipeline")
9886 ;; f1_1 and f1_2 are floating point units.Actually there is
9887 ;; a f1 unit which can overlap with other f1 unit but
9888 ;; not another F1 unit.It is as though there were two
9891 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
9893 ;; The floating point units.
9895 (define_cpu_unit "F1,F2,F3,FS" "fpu_pipe")
9897 ;; This is basically the MA unit of SH4
9898 ;; used in LOAD/STORE pipeline.
9900 (define_cpu_unit "memory" "inst_pipeline")
9902 ;; The address calculator used for branch instructions.
9903 ;; This will be reserved with "issue" of branch instructions
9904 ;; and this is to make sure that no two branch instructions
9905 ;; can be issued in parallel.
9907 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
9909 ;; ----------------------------------------------------
9910 ;; This reservation is to simplify the dual issue description.
9912 (define_reservation "issue" "pipe_01|pipe_02")
9914 ;; This is to express the locking of D stage.
9916 (define_reservation "d_lock" "pipe_01+pipe_02")
9918 ;; This is to simplify description where F1,F2,FS
9919 ;; are used simultaneously.
9921 (define_reservation "fpu" "F1+F2+FS")
9923 ;; This is to highlight the fact that f1
9924 ;; cannot overlap with F1.
9926 (exclusion_set "f1_1,f1_2" "F1")
9928 ;; Although reg moves have a latency of zero
9929 ;; we need to highlight that they use D stage
9932 (define_insn_reservation "reg_mov" 0
9933 (eq_attr "type" "move,fmove")
9936 ;; Other MT group intructions(1 step operations)
9941 (define_insn_reservation "mt" 1
9942 (eq_attr "insn_class" "mt_group")
9945 ;; Fixed Point Arithmetic Instructions(1 step operations)
9950 (define_insn_reservation "simple_arith" 1
9951 (eq_attr "insn_class" "ex_group")
9954 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
9959 (define_insn_reservation "load_store" 2
9960 (eq_attr "type" "load,load_si,pcload,pcload_si,store")
9963 ;; Branch (BF,BF/S,BT,BT/S,BRA)
9965 ;; Latency: 2 (or 1) Actually Observed to be 5/7
9967 ;; The latency is 1 when displacement is 0.
9968 ;; This reservation can be further broken into 2
9969 ;; 1. branch_zero : One with latency 1 and in the TEST
9970 ;; part it also checks for 0 (ZERO) displacement
9971 ;; 2. branch: Latency 2.
9973 (define_insn_reservation "branch_zero" 5
9974 (and (eq_attr "type" "cbranch")
9975 (eq_attr "length" "2"))
9976 "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
9978 (define_insn_reservation "branch" 7
9979 (eq_attr "type" "cbranch")
9980 "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
9982 ;; Branch Far (JMP,RTS,BRAF)
9986 ;; Since issue stage (D stage) is blocked for 2nd cycle,
9987 ;; cpu_unit int is reserved since it might be required for far
9988 ;; address calculation.
9990 (define_insn_reservation "branch_far" 12
9991 (and (eq_attr "type" "jump,return")
9992 (eq_attr "length" "6"))
9993 "d_lock*2,int+pcr_addrcalc,pcr_addrcalc")
9999 ;; this instruction can be executed in any of the pipelines
10000 ;; and blocks the pipeline for next 4 stages.
10002 (define_insn_reservation "return_from_exp" 5
10003 (eq_attr "type" "rte")
10004 "(issue+pcr_addrcalc),d_lock*4,int+pcr_addrcalc,nothing")
10011 (define_insn_reservation "ocbwb" 5
10012 (eq_attr "insn_class" "cwb")
10013 "issue,(int+memory),memory*5")
10019 ;; The SX stage is blocked for last 2 cycles.
10021 (define_insn_reservation "lds_to_pr" 3
10022 (eq_attr "type" "prset,call,sfunc")
10023 "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+pcr_addrcalc)*2")
10029 ;; The SX unit is blocked for last 2 cycles.
10031 (define_insn_reservation "ldsmem_to_pr" 3
10032 (eq_attr "type" "pload")
10033 "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+memory+pcr_addrcalc),(int+pcr_addrcalc)")
10039 ;; The SX unit in second and third cycles.
10041 (define_insn_reservation "sts_from_pr" 2
10042 (eq_attr "type" "prget")
10043 "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+pcr_addrcalc),nothing")
10050 (define_insn_reservation "prload_mem" 2
10051 (eq_attr "type" "pstore")
10052 "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+memory+pcr_addrcalc),memory")
10058 ;; F1 is blocked for last three cycles.
10060 (define_insn_reservation "fpscr_store" 4
10061 (eq_attr "insn_class" "lds_to_fpscr")
10067 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10069 ;; F1 is blocked for last three cycles.
10071 (define_insn_reservation "fpscr_store_mem" 4
10072 (eq_attr "insn_class" "ldsmem_to_fpscr")
10073 "issue,(int+memory),(F1+memory),F1*2")
10076 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10081 (define_insn_reservation "multi" 4
10082 (eq_attr "type" "smpy,dmpy")
10083 "issue,(issue+int+f1_1),(int+f1_1),(f1_1|f1_2)*2,F2,FS")
10086 ;; Single precision floating point computation FCMP/EQ,
10087 ;; FCP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10092 (define_insn_reservation "fp_arith" 4
10093 (eq_attr "type" "fp")
10096 ;; Single Precision FDIV/SQRT
10101 (define_insn_reservation "fp_div" 13
10102 (eq_attr "type" "fdiv")
10103 "issue,F1+F3,F1+F2+F3,F3*7,F1+F3,F2,FS")
10105 ;; Double Precision floating point computation
10106 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10108 ;; Latency: (3,4)/5
10111 (define_insn_reservation "dp_float" 5
10112 (eq_attr "type" "dfp_conv")
10113 "issue,F1,F1+F2,F2+FS,FS")
10115 ;; Double-precision floating-point (FADD ,FMUL,FSUB)
10117 ;; Latency: (7,8)/9
10120 (define_insn_reservation "fp_double_arith" 9
10121 (eq_attr "type" "dfp_arith")
10122 "issue,F1,F1+F2,fpu*4,F2+FS,FS")
10124 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10129 (define_insn_reservation "fp_double_cmp" 5
10130 (eq_attr "type" "dfp_cmp")
10131 "issue,(issue+F1),F1+F2,F2+FS,FS")
10133 ;; Double precision FDIV/SQRT
10135 ;; Latency: (24,25)/26
10138 (define_insn_reservation "dp_div" 26
10139 (eq_attr "type" "dfdiv")
10140 "issue,F1+F3,F1+F2+F3,F2+F3+FS,F3*16,F1+F3,F1+F2+F3,fpu+F3,F2+FS,FS")