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 "pipe_model" "sh1,sh4,sh5media"
174 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
175 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
176 (const_string "sh1"))))
178 ;; cbranch conditional branch instructions
179 ;; jump unconditional jumps
180 ;; arith ordinary arithmetic
181 ;; arith3 a compound insn that behaves similarly to a sequence of
182 ;; three insns of type arith
183 ;; arith3b like above, but might end with a redirected branch
185 ;; load_si Likewise, SImode variant for general register.
187 ;; move register to register
188 ;; fmove register to register, floating point
189 ;; smpy word precision integer multiply
190 ;; dmpy longword or doublelongword precision integer multiply
192 ;; pload load of pr reg, which can't be put into delay slot of rts
193 ;; prset copy register to pr reg, ditto
194 ;; pstore store of pr reg, which can't be put into delay slot of jsr
195 ;; prget copy pr to register, ditto
196 ;; pcload pc relative load of constant value
197 ;; pcload_si Likewise, SImode variant for general register.
198 ;; rte return from exception
199 ;; sfunc special function call with known used registers
200 ;; call function call
202 ;; fdiv floating point divide (or square root)
203 ;; gp_fpul move between general purpose register and fpul
204 ;; dfp_arith, dfp_cmp,dfp_conv
205 ;; dfdiv double precision floating point divide (or square root)
206 ;; arith_media SHmedia arithmetic, logical, and shift instructions
207 ;; cbranch_media SHmedia conditional branch instructions
208 ;; cmp_media SHmedia compare instructions
209 ;; dfdiv_media SHmedia double precision divide and square root
210 ;; dfmul_media SHmedia double precision multiply instruction
211 ;; dfparith_media SHmedia double precision floating point arithmetic
212 ;; dfpconv_media SHmedia double precision floating point conversions
213 ;; dmpy_media SHmedia longword multiply
214 ;; fcmp_media SHmedia floating point compare instructions
215 ;; fdiv_media SHmedia single precision divide and square root
216 ;; fload_media SHmedia floating point register load instructions
217 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
218 ;; fparith_media SHmedia single precision floating point arithmetic
219 ;; fpconv_media SHmedia single precision floating point conversions
220 ;; fstore_media SHmedia floating point register store instructions
221 ;; gettr_media SHmedia gettr instruction
222 ;; invalidate_line_media SHmedia invaldiate_line sequence
223 ;; jump_media SHmedia unconditional branch instructions
224 ;; load_media SHmedia general register load instructions
225 ;; pt_media SHmedia pt instruction (expanded by assembler)
226 ;; ptabs_media SHmedia ptabs instruction
227 ;; store_media SHmedia general register store instructions
228 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
229 ;; mac_media SHmedia mac-style fixed point operations
230 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
231 ;; atrans SHmedia approximate transcendential functions
232 ;; ustore_media SHmedia unaligned stores
233 ;; nil no-op move, will be deleted.
236 "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_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
237 (const_string "other"))
239 ;; We define a new attribute namely "insn_class".We use
240 ;; this for DFA based pipeline description.
241 ;; Although the "type" attribute covers almost all insn
242 ;; classes,it is more convenient to define new attribute
243 ;; for certain reservations.
245 ;; mt_group SH4 "mt" group instructions.
247 ;; ex_group SH4 "ex" group instructions.They mostly
248 ;; overlap with arithmetic instructions but
249 ;; new attribute defined to distinguish from
250 ;; mt group instructions.
252 ;; lds_to_fpscr The "type" attribute couldn't sufficiently
253 ;; distinguish it from others.It is part of
254 ;; new attribute.Similar case with ldsmem_to_fpscr
257 (define_attr "insn_class"
258 "mt_group,ex_group,lds_to_fpscr,ldsmem_to_fpscr,cwb,none"
259 (const_string "none"))
261 ;; Indicate what precision must be selected in fpscr for this insn, if any.
263 (define_attr "fp_mode" "single,double,none" (const_string "none"))
265 ; If a conditional branch destination is within -252..258 bytes away
266 ; from the instruction it can be 2 bytes long. Something in the
267 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
268 ; branches are initially assumed to be 16 bytes long.
269 ; In machine_dependent_reorg, we split all branches that are longer than
272 ;; The maximum range used for SImode constant pool entries is 1018. A final
273 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
274 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
275 ;; instruction around the pool table, 2 bytes of alignment before the table,
276 ;; and 30 bytes of alignment after the table. That gives a maximum total
277 ;; pool size of 1058 bytes.
278 ;; Worst case code/pool content size ratio is 1:2 (using asms).
279 ;; Thus, in the worst case, there is one instruction in front of a maximum
280 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
281 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
282 ;; If we have a forward branch, the initial table will be put after the
283 ;; unconditional branch.
285 ;; ??? We could do much better by keeping track of the actual pcloads within
286 ;; the branch range and in the pcload range in front of the branch range.
288 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
290 (define_attr "short_cbranch_p" "no,yes"
291 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
293 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
295 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
297 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
299 ] (const_string "no")))
301 (define_attr "med_branch_p" "no,yes"
302 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
305 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
307 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
310 ] (const_string "no")))
312 (define_attr "med_cbranch_p" "no,yes"
313 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
316 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
321 ] (const_string "no")))
323 (define_attr "braf_branch_p" "no,yes"
324 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
326 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
329 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
331 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
334 ] (const_string "no")))
336 (define_attr "braf_cbranch_p" "no,yes"
337 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
339 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
347 ] (const_string "no")))
349 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
350 ; For wider ranges, we need a combination of a code and a data part.
351 ; If we can get a scratch register for a long range jump, the code
352 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
353 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
354 ; long; otherwise, it must be 6 bytes long.
356 ; All other instructions are two bytes long by default.
358 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
359 ;; but getattrtab doesn't understand this.
360 (define_attr "length" ""
361 (cond [(eq_attr "type" "cbranch")
362 (cond [(eq_attr "short_cbranch_p" "yes")
364 (eq_attr "med_cbranch_p" "yes")
366 (eq_attr "braf_cbranch_p" "yes")
368 ;; ??? using pc is not computed transitively.
369 (ne (match_dup 0) (match_dup 0))
371 (ne (symbol_ref ("flag_pic")) (const_int 0))
374 (eq_attr "type" "jump")
375 (cond [(eq_attr "med_branch_p" "yes")
377 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
379 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
380 (symbol_ref "code_for_indirect_jump_scratch")))
381 (if_then_else (eq_attr "braf_branch_p" "yes")
384 (eq_attr "braf_branch_p" "yes")
386 ;; ??? using pc is not computed transitively.
387 (ne (match_dup 0) (match_dup 0))
389 (ne (symbol_ref ("flag_pic")) (const_int 0))
392 (eq_attr "type" "pt_media")
393 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
394 (const_int 20) (const_int 12))
395 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
399 ;; (define_function_unit {name} {num-units} {n-users} {test}
400 ;; {ready-delay} {issue-delay} [{conflict-list}])
402 ;; Load and store instructions save a cycle if they are aligned on a
403 ;; four byte boundary. Using a function unit for stores encourages
404 ;; gcc to separate load and store instructions by one instruction,
405 ;; which makes it more likely that the linker will be able to word
406 ;; align them when relaxing.
408 ;; Loads have a latency of two.
409 ;; However, call insns can have a delay slot, so that we want one more
410 ;; insn to be scheduled between the load of the function address and the call.
411 ;; This is equivalent to a latency of three.
412 ;; We cannot use a conflict list for this, because we need to distinguish
413 ;; between the actual call address and the function arguments.
414 ;; ADJUST_COST can only properly handle reductions of the cost, so we
415 ;; use a latency of three here.
416 ;; We only do this for SImode loads of general registers, to make the work
417 ;; for ADJUST_COST easier.
418 (define_function_unit "memory" 1 0
419 (and (eq_attr "pipe_model" "sh1")
420 (eq_attr "type" "load_si,pcload_si"))
422 (define_function_unit "memory" 1 0
423 (and (eq_attr "pipe_model" "sh1")
424 (eq_attr "type" "load,pcload,pload,store,pstore"))
427 (define_function_unit "int" 1 0
428 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
430 (define_function_unit "int" 1 0
431 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
433 (define_function_unit "int" 1 0
434 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
436 ;; ??? These are approximations.
437 (define_function_unit "mpy" 1 0
438 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
439 (define_function_unit "mpy" 1 0
440 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
442 (define_function_unit "fp" 1 0
443 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
444 (define_function_unit "fp" 1 0
445 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
449 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
450 ;; costs by at least two.
451 ;; There will be single increments of the modeled that don't correspond
452 ;; to the actual target ;; whenever two insns to be issued depend one a
453 ;; single resource, and the scheduler picks to be the first one.
454 ;; If we multiplied the costs just by two, just two of these single
455 ;; increments would amount to an actual cycle. By picking a larger
456 ;; factor, we can ameliorate the effect; However, we then have to make sure
457 ;; that only two insns are modeled as issued per actual cycle.
458 ;; Moreover, we need a way to specify the latency of insns that don't
459 ;; use an actual function unit.
460 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
462 (define_function_unit "issue" 2 0
463 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "!nil,arith3"))
466 (define_function_unit "issue" 2 0
467 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith3"))
470 ;; There is no point in providing exact scheduling information about branches,
471 ;; because they are at the starts / ends of basic blocks anyways.
473 ;; Some insns cannot be issued before/after another insn in the same cycle,
474 ;; irrespective of the type of the other insn.
476 ;; default is dual-issue, but can't be paired with an insn that
477 ;; uses multiple function units.
478 (define_function_unit "single_issue" 1 0
479 (and (eq_attr "pipe_model" "sh4")
480 (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
482 [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
484 (define_function_unit "single_issue" 1 0
485 (and (eq_attr "pipe_model" "sh4")
486 (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
490 ;; arith3 insns are always pairable at the start, but not inecessarily at
491 ;; the end; however, there doesn't seem to be a way to express that.
492 (define_function_unit "single_issue" 1 0
493 (and (eq_attr "pipe_model" "sh4")
494 (eq_attr "type" "arith3"))
498 ;; arith3b insn are pairable at the end and have latency that prevents pairing
499 ;; with the following branch, but we don't want this latency be respected;
500 ;; When the following branch is immediately adjacent, we can redirect the
501 ;; internal branch, which is likly to be a larger win.
502 (define_function_unit "single_issue" 1 0
503 (and (eq_attr "pipe_model" "sh4")
504 (eq_attr "type" "arith3b"))
508 ;; calls introduce a longisch delay that is likely to flush the pipelines.
509 (define_function_unit "single_issue" 1 0
510 (and (eq_attr "pipe_model" "sh4")
511 (eq_attr "type" "call,sfunc"))
513 [(eq_attr "type" "!call") (eq_attr "type" "call")])
515 ;; Load and store instructions have no alignment peculiarities for the SH4,
516 ;; but they use the load-store unit, which they share with the fmove type
517 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
518 ;; Loads have a latency of two.
519 ;; However, call insns can only paired with a preceding insn, and have
520 ;; a delay slot, so that we want two more insns to be scheduled between the
521 ;; load of the function address and the call. This is equivalent to a
523 ;; We cannot use a conflict list for this, because we need to distinguish
524 ;; between the actual call address and the function arguments.
525 ;; ADJUST_COST can only properly handle reductions of the cost, so we
526 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
527 ;; We only do this for SImode loads of general registers, to make the work
528 ;; for ADJUST_COST easier.
530 ;; When specifying different latencies for different insns using the
531 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
532 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
533 ;; for an executing insn E and a candidate insn C.
534 ;; Therefore, we define three different function units for load_store:
535 ;; load_store, load and load_si.
537 (define_function_unit "load_si" 1 0
538 (and (eq_attr "pipe_model" "sh4")
539 (eq_attr "type" "load_si,pcload_si")) 30 10)
540 (define_function_unit "load" 1 0
541 (and (eq_attr "pipe_model" "sh4")
542 (eq_attr "type" "load,pcload,pload")) 20 10)
543 (define_function_unit "load_store" 1 0
544 (and (eq_attr "pipe_model" "sh4")
545 (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
548 (define_function_unit "int" 1 0
549 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "arith,dyn_shift")) 10 10)
551 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
552 ;; spurious FIFO constraint; the multiply instructions use the "int"
553 ;; unit actually only for two cycles.
554 (define_function_unit "int" 1 0
555 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 20 20)
557 ;; We use a fictous "mpy" unit to express the actual latency.
558 (define_function_unit "mpy" 1 0
559 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 20)
561 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
562 ;; spurious FIFO constraint.
563 (define_function_unit "int" 1 0
564 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 10 10)
566 ;; We use a fictous "gp_fpul" unit to express the actual latency.
567 (define_function_unit "gp_fpul" 1 0
568 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "gp_fpul")) 20 10)
570 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
571 ;; Thus, a simple single-precision fp operation could finish if issued in
572 ;; the very next cycle, but stalls when issued two or three cycles later.
573 ;; Similarily, a divide / sqrt can work without stalls if issued in
574 ;; the very next cycle, while it would have to block if issued two or
575 ;; three cycles later.
576 ;; There is no way to model this with gcc's function units. This problem is
577 ;; actually mentioned in md.texi. Tackling this problem requires first that
578 ;; it is possible to speak about the target in an open discussion.
580 ;; However, simple double-precision operations always conflict.
582 (define_function_unit "fp" 1 0
583 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "smpy,dmpy")) 40 40
584 [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
586 ;; The "fp" unit is for pipeline stages F1 and F2.
588 (define_function_unit "fp" 1 0
589 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fp")) 30 10)
591 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
592 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
594 (define_function_unit "fp" 1 0
595 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 30 10)
597 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
598 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
599 ;; We also use it to give the actual latency here.
600 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
601 ;; but that will hardly matter in practice for scheduling.
602 (define_function_unit "fdiv" 1 0
603 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "fdiv")) 120 100)
605 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
606 ;; that we can't express.
608 (define_function_unit "fp" 1 0
609 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
611 (define_function_unit "fp" 1 0
612 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfp_arith")) 80 60)
614 (define_function_unit "fp" 1 0
615 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 10)
617 (define_function_unit "fdiv" 1 0
618 (and (eq_attr "pipe_model" "sh4") (eq_attr "type" "dfdiv")) 230 210)
620 ;; SH-5 SHmedia scheduling
621 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
622 ;; single-issue machine. It has four pipelines, the branch unit (br),
623 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
624 ;; the floating point unit (fpu).
625 ;; Here model the instructions with a latency greater than one cycle.
627 ;; Every instruction on SH-5 occupies the issue resource for at least one
629 (define_function_unit "sh5issue" 1 0
630 (and (eq_attr "pipe_model" "sh5media")
631 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
633 ;; Specify the various types of instruction which have latency > 1
634 (define_function_unit "sh5issue" 1 0
635 (and (eq_attr "pipe_model" "sh5media")
636 (eq_attr "type" "mcmp_media")) 2 1)
638 (define_function_unit "sh5issue" 1 0
639 (and (eq_attr "pipe_model" "sh5media")
640 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
641 ;; but see sh_adjust_cost for mac_media exception.
643 (define_function_unit "sh5issue" 1 0
644 (and (eq_attr "pipe_model" "sh5media")
645 (eq_attr "type" "fload_media,fmove_media")) 4 1)
647 (define_function_unit "sh5issue" 1 0
648 (and (eq_attr "pipe_model" "sh5media")
649 (eq_attr "type" "d2mpy_media")) 4 2)
651 (define_function_unit "sh5issue" 1 0
652 (and (eq_attr "pipe_model" "sh5media")
653 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
655 (define_function_unit "sh5issue" 1 0
656 (and (eq_attr "pipe_model" "sh5media")
657 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
659 (define_function_unit "sh5issue" 1 0
660 (and (eq_attr "pipe_model" "sh5media")
661 (eq_attr "type" "invalidate_line_media")) 7 7)
663 (define_function_unit "sh5issue" 1 0
664 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
666 (define_function_unit "sh5issue" 1 0
667 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
669 ;; Floating-point divide and square-root occupy an additional resource,
670 ;; which is not internally pipelined. However, other instructions
671 ;; can continue to issue.
672 (define_function_unit "sh5fds" 1 0
673 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
675 (define_function_unit "sh5fds" 1 0
676 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
678 ; Definitions for filling branch delay slots.
680 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
682 ;; ??? This should be (nil) instead of (const_int 0)
683 (define_attr "hit_stack" "yes,no"
684 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
687 (const_string "yes")))
689 (define_attr "interrupt_function" "no,yes"
690 (const (symbol_ref "current_function_interrupt")))
692 (define_attr "in_delay_slot" "yes,no"
693 (cond [(eq_attr "type" "cbranch") (const_string "no")
694 (eq_attr "type" "pcload,pcload_si") (const_string "no")
695 (eq_attr "needs_delay_slot" "yes") (const_string "no")
696 (eq_attr "length" "2") (const_string "yes")
697 ] (const_string "no")))
699 (define_attr "is_sfunc" ""
700 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
702 (define_attr "is_mac_media" ""
703 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
706 (eq_attr "needs_delay_slot" "yes")
707 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
709 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
710 ;; and thus we can't put a pop instruction in its delay slot.
711 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
712 ;; instruction can go in the delay slot.
714 ;; Since a normal return (rts) implicitly uses the PR register,
715 ;; we can't allow PR register loads in an rts delay slot.
718 (eq_attr "type" "return")
719 [(and (eq_attr "in_delay_slot" "yes")
720 (ior (and (eq_attr "interrupt_function" "no")
721 (eq_attr "type" "!pload,prset"))
722 (and (eq_attr "interrupt_function" "yes")
724 (ne (symbol_ref "TARGET_SH3") (const_int 0))
725 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
727 ;; Since a call implicitly uses the PR register, we can't allow
728 ;; a PR register store in a jsr delay slot.
731 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
732 [(and (eq_attr "in_delay_slot" "yes")
733 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
735 ;; Say that we have annulled true branches, since this gives smaller and
736 ;; faster code when branches are predicted as not taken.
739 (and (eq_attr "type" "cbranch")
740 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
741 [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
743 ;; -------------------------------------------------------------------------
744 ;; SImode signed integer comparisons
745 ;; -------------------------------------------------------------------------
749 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
750 (match_operand:SI 1 "arith_operand" "L,r"))
754 [(set_attr "insn_class" "mt_group")])
756 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
757 ;; That would still allow reload to create cmpi instructions, but would
758 ;; perhaps allow forcing the constant into a register when that is better.
759 ;; Probably should use r0 for mem/imm compares, but force constant into a
760 ;; register for pseudo/imm compares.
762 (define_insn "cmpeqsi_t"
764 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
765 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
771 [(set_attr "insn_class" "mt_group,mt_group,mt_group")])
773 (define_insn "cmpgtsi_t"
775 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
776 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
781 [(set_attr "insn_class" "mt_group,mt_group")])
783 (define_insn "cmpgesi_t"
785 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
786 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
791 [(set_attr "insn_class" "mt_group,mt_group")])
793 ;; -------------------------------------------------------------------------
794 ;; SImode unsigned integer comparisons
795 ;; -------------------------------------------------------------------------
797 (define_insn "cmpgeusi_t"
799 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
800 (match_operand:SI 1 "arith_reg_operand" "r")))]
803 [(set_attr "insn_class" "mt_group")])
805 (define_insn "cmpgtusi_t"
807 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
808 (match_operand:SI 1 "arith_reg_operand" "r")))]
811 [(set_attr "insn_class" "mt_group")])
813 ;; We save the compare operands in the cmpxx patterns and use them when
814 ;; we generate the branch.
816 (define_expand "cmpsi"
818 (compare (match_operand:SI 0 "arith_operand" "")
819 (match_operand:SI 1 "arith_operand" "")))]
823 sh_compare_op0 = operands[0];
824 sh_compare_op1 = operands[1];
828 ;; -------------------------------------------------------------------------
829 ;; DImode signed integer comparisons
830 ;; -------------------------------------------------------------------------
832 ;; ??? Could get better scheduling by splitting the initial test from the
833 ;; rest of the insn after reload. However, the gain would hardly justify
834 ;; the sh.md size increase necessary to do that.
838 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
839 (match_operand:DI 1 "arith_operand" "r"))
842 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
844 [(set_attr "length" "6")
845 (set_attr "type" "arith3b")])
847 (define_insn "cmpeqdi_t"
849 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
850 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
853 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
854 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
855 [(set_attr "length" "6")
856 (set_attr "type" "arith3b")])
860 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
861 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
862 ;; If we applied this split when not optimizing, it would only be
863 ;; applied during the machine-dependent reorg, when no new basic blocks
865 "TARGET_SH1 && reload_completed && optimize"
866 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
867 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
868 (label_ref (match_dup 6))
870 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
875 = gen_rtx_REG (SImode,
876 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
878 = (operands[1] == const0_rtx
880 : gen_rtx_REG (SImode,
881 true_regnum (operands[1])
882 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
883 operands[4] = gen_lowpart (SImode, operands[0]);
884 operands[5] = gen_lowpart (SImode, operands[1]);
885 operands[6] = gen_label_rtx ();
888 (define_insn "cmpgtdi_t"
890 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
891 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
894 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
895 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
896 [(set_attr "length" "8")
897 (set_attr "type" "arith3")])
899 (define_insn "cmpgedi_t"
901 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
902 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
905 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
907 [(set_attr "length" "8,2")
908 (set_attr "type" "arith3,arith")])
910 ;; -------------------------------------------------------------------------
911 ;; DImode unsigned integer comparisons
912 ;; -------------------------------------------------------------------------
914 (define_insn "cmpgeudi_t"
916 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
917 (match_operand:DI 1 "arith_reg_operand" "r")))]
919 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
920 [(set_attr "length" "8")
921 (set_attr "type" "arith3")])
923 (define_insn "cmpgtudi_t"
925 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
926 (match_operand:DI 1 "arith_reg_operand" "r")))]
928 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
929 [(set_attr "length" "8")
930 (set_attr "type" "arith3")])
932 (define_insn "cmpeqdi_media"
933 [(set (match_operand:DI 0 "register_operand" "=r")
934 (eq:DI (match_operand:DI 1 "register_operand" "%r")
935 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
938 [(set_attr "type" "cmp_media")])
940 (define_insn "cmpgtdi_media"
941 [(set (match_operand:DI 0 "register_operand" "=r")
942 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
943 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
946 [(set_attr "type" "cmp_media")])
948 (define_insn "cmpgtudi_media"
949 [(set (match_operand:DI 0 "register_operand" "=r")
950 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
951 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
953 "cmpgtu %N1, %N2, %0"
954 [(set_attr "type" "cmp_media")])
956 ;; We save the compare operands in the cmpxx patterns and use them when
957 ;; we generate the branch.
959 (define_expand "cmpdi"
961 (compare (match_operand:DI 0 "arith_operand" "")
962 (match_operand:DI 1 "arith_operand" "")))]
963 "TARGET_SH2 || TARGET_SHMEDIA"
966 sh_compare_op0 = operands[0];
967 sh_compare_op1 = operands[1];
970 ;; -------------------------------------------------------------------------
971 ;; Conditional move instructions
972 ;; -------------------------------------------------------------------------
974 ;; The insn names may seem reversed, but note that cmveq performs the move
975 ;; if op1 == 0, and cmvne does it if op1 != 0.
977 (define_insn "movdicc_false"
978 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
979 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
981 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
982 (match_operand:DI 3 "arith_reg_operand" "0")))]
985 [(set_attr "type" "arith_media")])
987 (define_insn "movdicc_true"
988 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
989 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
991 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
992 (match_operand:DI 3 "arith_reg_operand" "0")))]
995 [(set_attr "type" "arith_media")])
997 (define_expand "movdicc"
998 [(set (match_operand:DI 0 "register_operand" "")
999 (if_then_else:DI (match_operand 1 "comparison_operator" "")
1000 (match_operand:DI 2 "register_operand" "")
1001 (match_operand:DI 3 "register_operand" "")))]
1005 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1006 && GET_MODE (sh_compare_op0) == DImode
1007 && sh_compare_op1 == const0_rtx)
1008 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
1009 sh_compare_op0, sh_compare_op1);
1017 tmp = gen_reg_rtx (DImode);
1019 switch (GET_CODE (operands[1]))
1022 emit_insn (gen_seq (tmp));
1023 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1027 emit_insn (gen_seq (tmp));
1028 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1032 emit_insn (gen_sgt (tmp));
1033 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1037 emit_insn (gen_slt (tmp));
1038 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1042 emit_insn (gen_slt (tmp));
1043 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1047 emit_insn (gen_sgt (tmp));
1048 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1052 emit_insn (gen_sgtu (tmp));
1053 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1057 emit_insn (gen_sltu (tmp));
1058 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1062 emit_insn (gen_sltu (tmp));
1063 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1067 emit_insn (gen_sgtu (tmp));
1068 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1072 emit_insn (gen_sunordered (tmp));
1073 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
1077 emit_insn (gen_sunordered (tmp));
1078 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
1095 ;; -------------------------------------------------------------------------
1096 ;; Addition instructions
1097 ;; -------------------------------------------------------------------------
1099 (define_expand "adddi3"
1100 [(set (match_operand:DI 0 "arith_reg_operand" "")
1101 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1102 (match_operand:DI 2 "arith_operand" "")))]
1108 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1110 operands[2] = force_reg (DImode, operands[2]);
1111 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1116 (define_insn "*adddi3_media"
1117 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1118 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1119 (match_operand:DI 2 "arith_operand" "r,P")))]
1124 [(set_attr "type" "arith_media")])
1126 (define_insn "adddi3z_media"
1127 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1129 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1130 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1132 "addz.l %1, %N2, %0"
1133 [(set_attr "type" "arith_media")])
1135 (define_insn "adddi3_compact"
1136 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1137 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1138 (match_operand:DI 2 "arith_reg_operand" "r")))
1139 (clobber (reg:SI T_REG))]
1142 [(set_attr "length" "6")])
1145 [(set (match_operand:DI 0 "arith_reg_operand" "")
1146 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1147 (match_operand:DI 2 "arith_reg_operand" "")))
1148 (clobber (reg:SI T_REG))]
1149 "TARGET_SH1 && reload_completed"
1153 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1154 high0 = gen_rtx_REG (SImode,
1155 true_regnum (operands[0])
1156 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1157 high2 = gen_rtx_REG (SImode,
1158 true_regnum (operands[2])
1159 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1160 emit_insn (gen_clrt ());
1161 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1162 emit_insn (gen_addc1 (high0, high0, high2));
1167 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169 (match_operand:SI 2 "arith_reg_operand" "r"))
1172 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1175 [(set_attr "type" "arith")
1176 (set_attr "insn_class" "ex_group")])
1178 (define_insn "addc1"
1179 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1180 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1181 (match_operand:SI 2 "arith_reg_operand" "r"))
1183 (clobber (reg:SI T_REG))]
1186 [(set_attr "type" "arith")
1187 (set_attr "insn_class" "ex_group")])
1189 (define_expand "addsi3"
1190 [(set (match_operand:SI 0 "arith_reg_operand" "")
1191 (plus:SI (match_operand:SI 1 "arith_operand" "")
1192 (match_operand:SI 2 "arith_operand" "")))]
1197 operands[1] = force_reg (SImode, operands[1]);
1200 (define_insn "addsi3_media"
1201 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1202 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1203 (match_operand:SI 2 "arith_operand" "r,P")))]
1208 [(set_attr "type" "arith_media")])
1210 (define_insn "*addsi3_compact"
1211 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1212 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1213 (match_operand:SI 2 "arith_operand" "rI")))]
1216 [(set_attr "type" "arith")
1217 (set_attr "insn_class" "ex_group")])
1219 ;; -------------------------------------------------------------------------
1220 ;; Subtraction instructions
1221 ;; -------------------------------------------------------------------------
1223 (define_expand "subdi3"
1224 [(set (match_operand:DI 0 "arith_reg_operand" "")
1225 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1226 (match_operand:DI 2 "arith_reg_operand" "")))]
1232 operands[1] = force_reg (DImode, operands[1]);
1233 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1238 (define_insn "*subdi3_media"
1239 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1240 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1241 (match_operand:DI 2 "arith_reg_operand" "r")))]
1244 [(set_attr "type" "arith_media")])
1246 (define_insn "subdi3_compact"
1247 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1248 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1249 (match_operand:DI 2 "arith_reg_operand" "r")))
1250 (clobber (reg:SI T_REG))]
1253 [(set_attr "length" "6")])
1256 [(set (match_operand:DI 0 "arith_reg_operand" "")
1257 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258 (match_operand:DI 2 "arith_reg_operand" "")))
1259 (clobber (reg:SI T_REG))]
1260 "TARGET_SH1 && reload_completed"
1264 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1265 high0 = gen_rtx_REG (SImode,
1266 true_regnum (operands[0])
1267 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1268 high2 = gen_rtx_REG (SImode,
1269 true_regnum (operands[2])
1270 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1271 emit_insn (gen_clrt ());
1272 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1273 emit_insn (gen_subc1 (high0, high0, high2));
1278 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1279 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1280 (match_operand:SI 2 "arith_reg_operand" "r"))
1283 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1286 [(set_attr "type" "arith")
1287 (set_attr "insn_class" "ex_group")])
1289 (define_insn "subc1"
1290 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1291 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1292 (match_operand:SI 2 "arith_reg_operand" "r"))
1294 (clobber (reg:SI T_REG))]
1297 [(set_attr "type" "arith")
1298 (set_attr "insn_class" "ex_group")])
1300 (define_insn "*subsi3_internal"
1301 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1302 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1303 (match_operand:SI 2 "arith_reg_operand" "r")))]
1306 [(set_attr "type" "arith")
1307 (set_attr "insn_class" "ex_group")])
1309 (define_insn "*subsi3_media"
1310 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1311 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1312 (match_operand:SI 2 "extend_reg_operand" "r")))]
1315 [(set_attr "type" "arith_media")])
1317 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1318 ;; will sometimes save one instruction. Otherwise we might get
1319 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1322 (define_expand "subsi3"
1323 [(set (match_operand:SI 0 "arith_reg_operand" "")
1324 (minus:SI (match_operand:SI 1 "arith_operand" "")
1325 (match_operand:SI 2 "arith_reg_operand" "")))]
1329 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1331 emit_insn (gen_negsi2 (operands[0], operands[2]));
1332 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1337 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1339 if (operands[1] != const0_rtx)
1340 operands[1] = force_reg (SImode, operands[1]);
1344 ;; -------------------------------------------------------------------------
1345 ;; Division instructions
1346 ;; -------------------------------------------------------------------------
1348 ;; We take advantage of the library routines which don't clobber as many
1349 ;; registers as a normal function call would.
1351 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1352 ;; also has an effect on the register that holds the address of the sfunc.
1353 ;; To make this work, we have an extra dummy insn that shows the use
1354 ;; of this register for reorg.
1356 (define_insn "use_sfunc_addr"
1357 [(set (reg:SI PR_REG)
1358 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1361 [(set_attr "length" "0")])
1363 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1364 ;; hard register 0. If we used hard register 0, then the next instruction
1365 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1366 ;; gets allocated to a stack slot that needs its address reloaded, then
1367 ;; there is nothing to prevent reload from using r0 to reload the address.
1368 ;; This reload would clobber the value in r0 we are trying to store.
1369 ;; If we let reload allocate r0, then this problem can never happen.
1371 (define_insn "udivsi3_i1"
1372 [(set (match_operand:SI 0 "register_operand" "=z")
1373 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1374 (clobber (reg:SI T_REG))
1375 (clobber (reg:SI PR_REG))
1376 (clobber (reg:SI R4_REG))
1377 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1378 "TARGET_SH1 && ! TARGET_SH4"
1380 [(set_attr "type" "sfunc")
1381 (set_attr "needs_delay_slot" "yes")])
1383 ; Since shmedia-nofpu code could be linked against shcompact code, and
1384 ; the udivsi3 libcall has the same name, we must consider all registers
1385 ; clobbered that are in the union of the registers clobbered by the
1386 ; shmedia and the shcompact implementation. Note, if the shcompact
1387 ; implemenation actually used shcompact code, we'd need to clobber
1388 ; also r23 and fr23.
1389 (define_insn "udivsi3_i1_media"
1390 [(set (match_operand:SI 0 "register_operand" "=z")
1391 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1392 (clobber (reg:SI T_MEDIA_REG))
1393 (clobber (reg:SI PR_MEDIA_REG))
1394 (clobber (reg:SI R20_REG))
1395 (clobber (reg:SI R21_REG))
1396 (clobber (reg:SI R22_REG))
1397 (clobber (reg:DI TR0_REG))
1398 (clobber (reg:DI TR1_REG))
1399 (clobber (reg:DI TR2_REG))
1400 (use (match_operand:DI 1 "target_operand" "b"))]
1401 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1403 [(set_attr "type" "sfunc")
1404 (set_attr "needs_delay_slot" "yes")])
1406 (define_expand "udivsi3_i4_media"
1408 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1410 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1411 (set (match_dup 5) (float:DF (match_dup 3)))
1412 (set (match_dup 6) (float:DF (match_dup 4)))
1413 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1414 (set (match_dup 8) (fix:DI (match_dup 7)))
1415 (set (match_operand:SI 0 "register_operand" "")
1416 (truncate:SI (match_dup 8)))]
1417 "TARGET_SHMEDIA_FPU"
1420 operands[3] = gen_reg_rtx (DImode);
1421 operands[4] = gen_reg_rtx (DImode);
1422 operands[5] = gen_reg_rtx (DFmode);
1423 operands[6] = gen_reg_rtx (DFmode);
1424 operands[7] = gen_reg_rtx (DFmode);
1425 operands[8] = gen_reg_rtx (DImode);
1428 (define_insn "udivsi3_i4"
1429 [(set (match_operand:SI 0 "register_operand" "=y")
1430 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1431 (clobber (reg:SI T_REG))
1432 (clobber (reg:SI PR_REG))
1433 (clobber (reg:DF DR0_REG))
1434 (clobber (reg:DF DR2_REG))
1435 (clobber (reg:DF DR4_REG))
1436 (clobber (reg:SI R0_REG))
1437 (clobber (reg:SI R1_REG))
1438 (clobber (reg:SI R4_REG))
1439 (clobber (reg:SI R5_REG))
1440 (use (reg:PSI FPSCR_REG))
1441 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1442 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1444 [(set_attr "type" "sfunc")
1445 (set_attr "fp_mode" "double")
1446 (set_attr "needs_delay_slot" "yes")])
1448 (define_insn "udivsi3_i4_single"
1449 [(set (match_operand:SI 0 "register_operand" "=y")
1450 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1451 (clobber (reg:SI T_REG))
1452 (clobber (reg:SI PR_REG))
1453 (clobber (reg:DF DR0_REG))
1454 (clobber (reg:DF DR2_REG))
1455 (clobber (reg:DF DR4_REG))
1456 (clobber (reg:SI R0_REG))
1457 (clobber (reg:SI R1_REG))
1458 (clobber (reg:SI R4_REG))
1459 (clobber (reg:SI R5_REG))
1460 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1461 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1463 [(set_attr "type" "sfunc")
1464 (set_attr "needs_delay_slot" "yes")])
1466 (define_expand "udivsi3"
1467 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1468 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1469 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1470 (parallel [(set (match_operand:SI 0 "register_operand" "")
1471 (udiv:SI (reg:SI R4_REG)
1473 (clobber (reg:SI T_REG))
1474 (clobber (reg:SI PR_REG))
1475 (clobber (reg:SI R4_REG))
1476 (use (match_dup 3))])]
1480 rtx first = 0, last;
1482 operands[3] = gen_reg_rtx (Pmode);
1483 /* Emit the move of the address to a pseudo outside of the libcall. */
1484 if (TARGET_HARD_SH4 && TARGET_SH3E)
1486 emit_move_insn (operands[3],
1487 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1488 if (TARGET_FPU_SINGLE)
1489 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1491 last = gen_udivsi3_i4 (operands[0], operands[3]);
1493 else if (TARGET_SHMEDIA_FPU)
1495 operands[1] = force_reg (SImode, operands[1]);
1496 operands[2] = force_reg (SImode, operands[2]);
1497 last = gen_udivsi3_i4_media (operands[0], operands[1], operands[2]);
1500 else if (TARGET_SH5)
1502 emit_move_insn (operands[3],
1503 gen_rtx_SYMBOL_REF (Pmode,
1509 last = gen_udivsi3_i1_media (operands[0],
1512 : gen_rtx_SUBREG (DImode, operands[3],
1514 else if (TARGET_FPU_ANY)
1515 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1517 last = gen_udivsi3_i1 (operands[0], operands[3]);
1521 emit_move_insn (operands[3],
1522 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1523 last = gen_udivsi3_i1 (operands[0], operands[3]);
1527 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1528 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1530 last = emit_insn (last);
1531 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1532 invariant code motion can move it. */
1533 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1534 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1538 (define_insn "divsi3_i1"
1539 [(set (match_operand:SI 0 "register_operand" "=z")
1540 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1541 (clobber (reg:SI T_REG))
1542 (clobber (reg:SI PR_REG))
1543 (clobber (reg:SI R1_REG))
1544 (clobber (reg:SI R2_REG))
1545 (clobber (reg:SI R3_REG))
1546 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1547 "TARGET_SH1 && ! TARGET_SH4"
1549 [(set_attr "type" "sfunc")
1550 (set_attr "needs_delay_slot" "yes")])
1552 ; Since shmedia-nofpu code could be linked against shcompact code, and
1553 ; the sdivsi3 libcall has the same name, we must consider all registers
1554 ; clobbered that are in the union of the registers clobbered by the
1555 ; shmedia and the shcompact implementation. Note, if the shcompact
1556 ; implemenation actually used shcompact code, we'd need to clobber
1557 ; also r22, r23 and fr23.
1558 (define_insn "divsi3_i1_media"
1559 [(set (match_operand:SI 0 "register_operand" "=z")
1560 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1561 (clobber (reg:SI T_MEDIA_REG))
1562 (clobber (reg:SI PR_MEDIA_REG))
1563 (clobber (reg:SI R1_REG))
1564 (clobber (reg:SI R2_REG))
1565 (clobber (reg:SI R3_REG))
1566 (clobber (reg:SI R20_REG))
1567 (clobber (reg:SI R21_REG))
1568 (clobber (reg:DI TR0_REG))
1569 (clobber (reg:DI TR1_REG))
1570 (clobber (reg:DI TR2_REG))
1571 (use (match_operand:DI 1 "target_operand" "b"))]
1572 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1574 [(set_attr "type" "sfunc")])
1576 (define_expand "divsi3_i4_media"
1577 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1578 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1579 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1580 (set (match_operand:SI 0 "register_operand" "=r")
1581 (fix:SI (match_dup 5)))]
1582 "TARGET_SHMEDIA_FPU"
1585 operands[3] = gen_reg_rtx (DFmode);
1586 operands[4] = gen_reg_rtx (DFmode);
1587 operands[5] = gen_reg_rtx (DFmode);
1590 (define_insn "divsi3_i4"
1591 [(set (match_operand:SI 0 "register_operand" "=y")
1592 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1593 (clobber (reg:SI PR_REG))
1594 (clobber (reg:DF DR0_REG))
1595 (clobber (reg:DF DR2_REG))
1596 (use (reg:PSI FPSCR_REG))
1597 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1598 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1600 [(set_attr "type" "sfunc")
1601 (set_attr "fp_mode" "double")
1602 (set_attr "needs_delay_slot" "yes")])
1604 (define_insn "divsi3_i4_single"
1605 [(set (match_operand:SI 0 "register_operand" "=y")
1606 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1607 (clobber (reg:SI PR_REG))
1608 (clobber (reg:DF DR0_REG))
1609 (clobber (reg:DF DR2_REG))
1610 (clobber (reg:SI R2_REG))
1611 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1612 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1614 [(set_attr "type" "sfunc")
1615 (set_attr "needs_delay_slot" "yes")])
1617 (define_expand "divsi3"
1618 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1619 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1620 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1621 (parallel [(set (match_operand:SI 0 "register_operand" "")
1622 (div:SI (reg:SI R4_REG)
1624 (clobber (reg:SI T_REG))
1625 (clobber (reg:SI PR_REG))
1626 (clobber (reg:SI R1_REG))
1627 (clobber (reg:SI R2_REG))
1628 (clobber (reg:SI R3_REG))
1629 (use (match_dup 3))])]
1633 rtx first = 0, last;
1635 operands[3] = gen_reg_rtx (Pmode);
1636 /* Emit the move of the address to a pseudo outside of the libcall. */
1637 if (TARGET_HARD_SH4 && TARGET_SH3E)
1639 emit_move_insn (operands[3],
1640 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1641 if (TARGET_FPU_SINGLE)
1642 last = gen_divsi3_i4_single (operands[0], operands[3]);
1644 last = gen_divsi3_i4 (operands[0], operands[3]);
1646 else if (TARGET_SHMEDIA_FPU)
1648 operands[1] = force_reg (SImode, operands[1]);
1649 operands[2] = force_reg (SImode, operands[2]);
1650 last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1653 else if (TARGET_SH5)
1655 emit_move_insn (operands[3],
1656 gen_rtx_SYMBOL_REF (Pmode,
1662 last = gen_divsi3_i1_media (operands[0],
1665 : gen_rtx_SUBREG (DImode, operands[3],
1667 else if (TARGET_FPU_ANY)
1668 last = gen_divsi3_i4_single (operands[0], operands[3]);
1670 last = gen_divsi3_i1 (operands[0], operands[3]);
1674 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1675 last = gen_divsi3_i1 (operands[0], operands[3]);
1679 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1680 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1682 last = emit_insn (last);
1683 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1684 invariant code motion can move it. */
1685 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1686 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1690 ;; -------------------------------------------------------------------------
1691 ;; Multiplication instructions
1692 ;; -------------------------------------------------------------------------
1694 (define_insn "umulhisi3_i"
1695 [(set (reg:SI MACL_REG)
1696 (mult:SI (zero_extend:SI
1697 (match_operand:HI 0 "arith_reg_operand" "r"))
1699 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1702 [(set_attr "type" "smpy")])
1704 (define_insn "mulhisi3_i"
1705 [(set (reg:SI MACL_REG)
1706 (mult:SI (sign_extend:SI
1707 (match_operand:HI 0 "arith_reg_operand" "r"))
1709 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1712 [(set_attr "type" "smpy")])
1714 (define_expand "mulhisi3"
1715 [(set (reg:SI MACL_REG)
1716 (mult:SI (sign_extend:SI
1717 (match_operand:HI 1 "arith_reg_operand" ""))
1719 (match_operand:HI 2 "arith_reg_operand" ""))))
1720 (set (match_operand:SI 0 "arith_reg_operand" "")
1727 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1728 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1729 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1730 invariant code motion can move it. */
1731 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1732 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1736 (define_expand "umulhisi3"
1737 [(set (reg:SI MACL_REG)
1738 (mult:SI (zero_extend:SI
1739 (match_operand:HI 1 "arith_reg_operand" ""))
1741 (match_operand:HI 2 "arith_reg_operand" ""))))
1742 (set (match_operand:SI 0 "arith_reg_operand" "")
1749 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1750 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1751 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1752 invariant code motion can move it. */
1753 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1754 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1758 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1759 ;; a call to a routine which clobbers known registers.
1762 [(set (match_operand:SI 1 "register_operand" "=z")
1763 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1764 (clobber (reg:SI MACL_REG))
1765 (clobber (reg:SI T_REG))
1766 (clobber (reg:SI PR_REG))
1767 (clobber (reg:SI R3_REG))
1768 (clobber (reg:SI R2_REG))
1769 (clobber (reg:SI R1_REG))
1770 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1773 [(set_attr "type" "sfunc")
1774 (set_attr "needs_delay_slot" "yes")])
1776 (define_expand "mulsi3_call"
1777 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1778 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1779 (parallel[(set (match_operand:SI 0 "register_operand" "")
1780 (mult:SI (reg:SI R4_REG)
1782 (clobber (reg:SI MACL_REG))
1783 (clobber (reg:SI T_REG))
1784 (clobber (reg:SI PR_REG))
1785 (clobber (reg:SI R3_REG))
1786 (clobber (reg:SI R2_REG))
1787 (clobber (reg:SI R1_REG))
1788 (use (match_operand:SI 3 "register_operand" ""))])]
1792 (define_insn "mul_l"
1793 [(set (reg:SI MACL_REG)
1794 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1795 (match_operand:SI 1 "arith_reg_operand" "r")))]
1798 [(set_attr "type" "dmpy")])
1800 (define_expand "mulsi3"
1801 [(set (reg:SI MACL_REG)
1802 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1803 (match_operand:SI 2 "arith_reg_operand" "")))
1804 (set (match_operand:SI 0 "arith_reg_operand" "")
1813 /* The address must be set outside the libcall,
1814 since it goes into a pseudo. */
1815 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1816 rtx addr = force_reg (SImode, sym);
1817 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1820 last = emit_insn (insns);
1824 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1826 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1827 /* consec_sets_giv can only recognize the first insn that sets a
1828 giv as the giv insn. So we must tag this also with a REG_EQUAL
1830 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1832 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1833 invariant code motion can move it. */
1834 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1835 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1839 (define_insn "mulsidi3_i"
1840 [(set (reg:SI MACH_REG)
1844 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1845 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1847 (set (reg:SI MACL_REG)
1848 (mult:SI (match_dup 0)
1852 [(set_attr "type" "dmpy")])
1854 (define_expand "mulsidi3"
1855 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1856 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1857 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1858 "TARGET_SH2 || TARGET_SHMEDIA"
1863 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1869 (define_insn "mulsidi3_media"
1870 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1871 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1872 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1875 [(set_attr "type" "dmpy_media")])
1877 (define_insn "mulsidi3_compact"
1878 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1880 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1881 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1882 (clobber (reg:SI MACH_REG))
1883 (clobber (reg:SI MACL_REG))]
1888 [(set (match_operand:DI 0 "arith_reg_operand" "")
1890 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1891 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1892 (clobber (reg:SI MACH_REG))
1893 (clobber (reg:SI MACL_REG))]
1898 rtx low_dst = gen_lowpart (SImode, operands[0]);
1899 rtx high_dst = gen_highpart (SImode, operands[0]);
1901 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1903 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1904 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1905 /* We need something to tag the possible REG_EQUAL notes on to. */
1906 emit_move_insn (operands[0], operands[0]);
1910 (define_insn "umulsidi3_i"
1911 [(set (reg:SI MACH_REG)
1915 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1916 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1918 (set (reg:SI MACL_REG)
1919 (mult:SI (match_dup 0)
1923 [(set_attr "type" "dmpy")])
1925 (define_expand "umulsidi3"
1926 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1927 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1928 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1929 "TARGET_SH2 || TARGET_SHMEDIA"
1934 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1940 (define_insn "umulsidi3_media"
1941 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1942 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1943 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1946 [(set_attr "type" "dmpy_media")])
1948 (define_insn "umulsidi3_compact"
1949 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1951 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1952 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1953 (clobber (reg:SI MACH_REG))
1954 (clobber (reg:SI MACL_REG))]
1959 [(set (match_operand:DI 0 "arith_reg_operand" "")
1960 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1961 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1962 (clobber (reg:SI MACH_REG))
1963 (clobber (reg:SI MACL_REG))]
1968 rtx low_dst = gen_lowpart (SImode, operands[0]);
1969 rtx high_dst = gen_highpart (SImode, operands[0]);
1971 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1973 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1974 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1975 /* We need something to tag the possible REG_EQUAL notes on to. */
1976 emit_move_insn (operands[0], operands[0]);
1980 (define_insn "smulsi3_highpart_i"
1981 [(set (reg:SI MACH_REG)
1985 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1986 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1988 (clobber (reg:SI MACL_REG))]
1991 [(set_attr "type" "dmpy")])
1993 (define_expand "smulsi3_highpart"
1995 [(set (reg:SI MACH_REG)
1999 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2000 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2002 (clobber (reg:SI MACL_REG))])
2003 (set (match_operand:SI 0 "arith_reg_operand" "")
2010 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2011 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2012 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2013 invariant code motion can move it. */
2014 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2015 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2016 /* expand_binop can't find a suitable code in mul_highpart_optab to
2017 make a REG_EQUAL note from, so make one here.
2018 ??? Alternatively, we could put this at the calling site of expand_binop,
2019 i.e. expand_mult_highpart. */
2021 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2026 (define_insn "umulsi3_highpart_i"
2027 [(set (reg:SI MACH_REG)
2031 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2032 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2034 (clobber (reg:SI MACL_REG))]
2037 [(set_attr "type" "dmpy")])
2039 (define_expand "umulsi3_highpart"
2041 [(set (reg:SI MACH_REG)
2045 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2046 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2048 (clobber (reg:SI MACL_REG))])
2049 (set (match_operand:SI 0 "arith_reg_operand" "")
2056 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2057 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2058 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2059 invariant code motion can move it. */
2060 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2061 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2065 ;; -------------------------------------------------------------------------
2066 ;; Logical operations
2067 ;; -------------------------------------------------------------------------
2069 (define_insn "*andsi3_compact"
2070 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2071 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2072 (match_operand:SI 2 "logical_operand" "r,L")))]
2075 [(set_attr "type" "arith")
2076 (set_attr "insn_class" "ex_group")])
2078 ;; If the constant is 255, then emit a extu.b instruction instead of an
2079 ;; and, since that will give better code.
2081 (define_expand "andsi3"
2082 [(set (match_operand:SI 0 "arith_reg_operand" "")
2083 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
2084 (match_operand:SI 2 "logical_operand" "")))]
2088 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
2090 emit_insn (gen_zero_extendqisi2 (operands[0],
2091 gen_lowpart (QImode, operands[1])));
2096 (define_insn_and_split "anddi3"
2097 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
2098 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
2099 (match_operand:DI 2 "and_operand" "r,P,n")))]
2106 && ! logical_operand (operands[2], DImode)"
2110 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2111 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2113 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2116 [(set_attr "type" "arith_media")])
2118 (define_insn "andcdi3"
2119 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2120 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2121 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2124 [(set_attr "type" "arith_media")])
2126 (define_insn "iorsi3"
2127 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2128 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2129 (match_operand:SI 2 "logical_operand" "r,L")))]
2132 [(set_attr "type" "arith")
2133 (set_attr "insn_class" "ex_group")])
2135 (define_insn "iordi3"
2136 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2137 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2138 (match_operand:DI 2 "logical_operand" "r,P")))]
2143 [(set_attr "type" "arith_media")])
2145 (define_insn "xorsi3"
2146 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2147 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2148 (match_operand:SI 2 "logical_operand" "L,r")))]
2151 [(set_attr "type" "arith")
2152 (set_attr "insn_class" "ex_group")])
2154 (define_insn "xordi3"
2155 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2156 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2157 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2162 [(set_attr "type" "arith_media")])
2164 ;; -------------------------------------------------------------------------
2165 ;; Shifts and rotates
2166 ;; -------------------------------------------------------------------------
2168 (define_expand "rotldi3"
2169 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2170 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2171 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2173 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2175 (define_insn "rotldi3_mextr"
2176 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2177 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2178 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2182 static char templ[16];
2184 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2185 8 - (int) (INTVAL (operands[2]) >> 3));
2188 [(set_attr "type" "arith_media")])
2190 (define_expand "rotrdi3"
2191 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2192 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2193 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2195 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2197 (define_insn "rotrdi3_mextr"
2198 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2199 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2200 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2204 static char templ[16];
2206 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2209 [(set_attr "type" "arith_media")])
2211 (define_insn "rotlsi3_1"
2212 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2213 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2216 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2219 [(set_attr "type" "arith")
2220 (set_attr "insn_class" "ex_group")])
2222 (define_insn "rotlsi3_31"
2223 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2224 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2226 (clobber (reg:SI T_REG))]
2229 [(set_attr "type" "arith")
2230 (set_attr "insn_class" "ex_group")])
2232 (define_insn "rotlsi3_16"
2233 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2234 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2238 [(set_attr "type" "arith")
2239 (set_attr "insn_class" "ex_group")])
2241 (define_expand "rotlsi3"
2242 [(set (match_operand:SI 0 "arith_reg_operand" "")
2243 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2244 (match_operand:SI 2 "immediate_operand" "")))]
2248 static const char rot_tab[] = {
2249 000, 000, 000, 000, 000, 000, 010, 001,
2250 001, 001, 011, 013, 003, 003, 003, 003,
2251 003, 003, 003, 003, 003, 013, 012, 002,
2252 002, 002, 010, 000, 000, 000, 000, 000,
2257 if (GET_CODE (operands[2]) != CONST_INT)
2259 count = INTVAL (operands[2]);
2260 choice = rot_tab[count];
2261 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2267 emit_move_insn (operands[0], operands[1]);
2268 count -= (count & 16) * 2;
2271 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2278 parts[0] = gen_reg_rtx (SImode);
2279 parts[1] = gen_reg_rtx (SImode);
2280 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2281 parts[choice-1] = operands[1];
2282 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2283 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2284 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2285 count = (count & ~16) - 8;
2289 for (; count > 0; count--)
2290 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2291 for (; count < 0; count++)
2292 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2297 (define_insn "*rotlhi3_8"
2298 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2299 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2303 [(set_attr "type" "arith")
2304 (set_attr "insn_class" "ex_group")])
2306 (define_expand "rotlhi3"
2307 [(set (match_operand:HI 0 "arith_reg_operand" "")
2308 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2309 (match_operand:HI 2 "immediate_operand" "")))]
2313 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2320 ;; This pattern is used by init_expmed for computing the costs of shift
2323 (define_insn_and_split "ashlsi3_std"
2324 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2325 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2326 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2327 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2329 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2330 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2338 && GET_CODE (operands[2]) == CONST_INT
2339 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2340 [(set (match_dup 3) (match_dup 2))
2342 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2343 (clobber (match_dup 4))])]
2344 "operands[4] = gen_rtx_SCRATCH (SImode);"
2345 [(set_attr "length" "*,*,*,4")
2346 (set_attr "type" "dyn_shift,arith,arith,arith")
2347 (set_attr "insn_class" "ex_group,ex_group,ex_group,ex_group")])
2349 (define_insn "ashlhi3_k"
2350 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2351 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2352 (match_operand:HI 2 "const_int_operand" "M,K")))]
2353 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2357 [(set_attr "type" "arith")
2358 (set_attr "insn_class" "ex_group")])
2360 (define_insn "ashlsi3_n"
2361 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2362 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2363 (match_operand:SI 2 "const_int_operand" "n")))
2364 (clobber (reg:SI T_REG))]
2365 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2367 [(set (attr "length")
2368 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2370 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2372 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2374 (const_string "8")))
2375 (set_attr "type" "arith")
2376 (set_attr "insn_class" "ex_group")])
2379 [(set (match_operand:SI 0 "arith_reg_operand" "")
2380 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2381 (match_operand:SI 2 "const_int_operand" "")))
2382 (clobber (reg:SI T_REG))]
2383 "TARGET_SH1 && reload_completed"
2384 [(use (reg:SI R0_REG))]
2387 gen_shifty_op (ASHIFT, operands);
2391 (define_insn "ashlsi3_media"
2392 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2393 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2394 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2399 [(set_attr "type" "arith_media")])
2401 (define_expand "ashlsi3"
2402 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2403 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2404 (match_operand:SI 2 "nonmemory_operand" "")))
2405 (clobber (reg:SI T_REG))])]
2411 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2414 if (GET_CODE (operands[2]) == CONST_INT
2415 && sh_dynamicalize_shift_p (operands[2]))
2416 operands[2] = force_reg (SImode, operands[2]);
2419 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2422 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2426 (define_insn "ashlhi3"
2427 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2428 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2429 (match_operand:HI 2 "const_int_operand" "n")))
2430 (clobber (reg:SI T_REG))]
2433 [(set (attr "length")
2434 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2436 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2438 (const_string "6")))
2439 (set_attr "type" "arith")])
2442 [(set (match_operand:HI 0 "arith_reg_operand" "")
2443 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2444 (match_operand:HI 2 "const_int_operand" "")))
2445 (clobber (reg:SI T_REG))]
2446 "TARGET_SH1 && reload_completed"
2447 [(use (reg:SI R0_REG))]
2450 gen_shifty_hi_op (ASHIFT, operands);
2455 ; arithmetic shift right
2458 (define_insn "ashrsi3_k"
2459 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2460 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2461 (match_operand:SI 2 "const_int_operand" "M")))
2462 (clobber (reg:SI T_REG))]
2463 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2465 [(set_attr "type" "arith")
2466 (set_attr "insn_class" "ex_group")])
2468 ;; We can't do HImode right shifts correctly unless we start out with an
2469 ;; explicit zero / sign extension; doing that would result in worse overall
2470 ;; code, so just let the machine independent code widen the mode.
2471 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2474 ;; ??? This should be a define expand.
2476 (define_insn "ashrsi2_16"
2477 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2482 [(set_attr "length" "4")])
2485 [(set (match_operand:SI 0 "arith_reg_operand" "")
2486 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2489 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2490 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2491 "operands[2] = gen_lowpart (HImode, operands[0]);")
2493 ;; ??? This should be a define expand.
2495 (define_insn "ashrsi2_31"
2496 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2497 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2499 (clobber (reg:SI T_REG))]
2502 [(set_attr "length" "4")])
2505 [(set (match_operand:SI 0 "arith_reg_operand" "")
2506 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2508 (clobber (reg:SI T_REG))]
2513 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2514 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2518 (define_insn "ashlsi_c"
2519 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2520 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2522 (lt:SI (match_dup 1) (const_int 0)))]
2525 [(set_attr "type" "arith")
2526 (set_attr "insn_class" "ex_group")])
2528 (define_insn "ashrsi3_d"
2529 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2530 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2531 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2534 [(set_attr "type" "dyn_shift")
2535 (set_attr "insn_class" "ex_group")])
2537 (define_insn "ashrsi3_n"
2538 [(set (reg:SI R4_REG)
2539 (ashiftrt:SI (reg:SI R4_REG)
2540 (match_operand:SI 0 "const_int_operand" "i")))
2541 (clobber (reg:SI T_REG))
2542 (clobber (reg:SI PR_REG))
2543 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2546 [(set_attr "type" "sfunc")
2547 (set_attr "needs_delay_slot" "yes")])
2549 (define_insn "ashrsi3_media"
2550 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2551 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2552 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2557 [(set_attr "type" "arith_media")])
2559 (define_expand "ashrsi3"
2560 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2561 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2562 (match_operand:SI 2 "nonmemory_operand" "")))
2563 (clobber (reg:SI T_REG))])]
2569 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2572 if (expand_ashiftrt (operands))
2578 ;; logical shift right
2580 (define_insn "lshrsi3_d"
2581 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2582 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2583 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2586 [(set_attr "type" "dyn_shift")
2587 (set_attr "insn_class" "ex_group")])
2589 ;; Only the single bit shift clobbers the T bit.
2591 (define_insn "lshrsi3_m"
2592 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2593 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2594 (match_operand:SI 2 "const_int_operand" "M")))
2595 (clobber (reg:SI T_REG))]
2596 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2598 [(set_attr "type" "arith")
2599 (set_attr "insn_class" "ex_group")])
2601 (define_insn "lshrsi3_k"
2602 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2603 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2604 (match_operand:SI 2 "const_int_operand" "K")))]
2605 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2606 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2608 [(set_attr "type" "arith")
2609 (set_attr "insn_class" "ex_group")])
2611 (define_insn "lshrsi3_n"
2612 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2613 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2614 (match_operand:SI 2 "const_int_operand" "n")))
2615 (clobber (reg:SI T_REG))]
2616 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2618 [(set (attr "length")
2619 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2621 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2623 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2625 (const_string "8")))
2626 (set_attr "type" "arith")])
2629 [(set (match_operand:SI 0 "arith_reg_operand" "")
2630 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2631 (match_operand:SI 2 "const_int_operand" "")))
2632 (clobber (reg:SI T_REG))]
2633 "TARGET_SH1 && reload_completed"
2634 [(use (reg:SI R0_REG))]
2637 gen_shifty_op (LSHIFTRT, operands);
2641 (define_insn "lshrsi3_media"
2642 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2643 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2644 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2649 [(set_attr "type" "arith_media")])
2651 (define_expand "lshrsi3"
2652 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2653 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2654 (match_operand:SI 2 "nonmemory_operand" "")))
2655 (clobber (reg:SI T_REG))])]
2661 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2664 if (GET_CODE (operands[2]) == CONST_INT
2665 && sh_dynamicalize_shift_p (operands[2]))
2666 operands[2] = force_reg (SImode, operands[2]);
2667 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2669 rtx count = copy_to_mode_reg (SImode, operands[2]);
2670 emit_insn (gen_negsi2 (count, count));
2671 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2674 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2678 ;; ??? This should be a define expand.
2680 (define_insn "ashldi3_k"
2681 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2682 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2684 (clobber (reg:SI T_REG))]
2686 "shll %R0\;rotcl %S0"
2687 [(set_attr "length" "4")
2688 (set_attr "type" "arith")
2689 (set_attr "insn_class" "ex_group")])
2691 (define_insn "ashldi3_media"
2692 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2693 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2694 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2699 [(set_attr "type" "arith_media")])
2701 (define_expand "ashldi3"
2702 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2703 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2704 (match_operand:DI 2 "immediate_operand" "")))
2705 (clobber (reg:SI T_REG))])]
2711 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2714 if (GET_CODE (operands[2]) != CONST_INT
2715 || INTVAL (operands[2]) != 1)
2719 ;; ??? This should be a define expand.
2721 (define_insn "lshrdi3_k"
2722 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2723 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2725 (clobber (reg:SI T_REG))]
2727 "shlr %S0\;rotcr %R0"
2728 [(set_attr "length" "4")
2729 (set_attr "type" "arith")
2730 (set_attr "insn_class" "ex_group")])
2732 (define_insn "lshrdi3_media"
2733 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2734 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2735 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2740 [(set_attr "type" "arith_media")])
2742 (define_expand "lshrdi3"
2743 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2744 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2745 (match_operand:DI 2 "immediate_operand" "")))
2746 (clobber (reg:SI T_REG))])]
2752 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2755 if (GET_CODE (operands[2]) != CONST_INT
2756 || INTVAL (operands[2]) != 1)
2760 ;; ??? This should be a define expand.
2762 (define_insn "ashrdi3_k"
2763 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2764 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2766 (clobber (reg:SI T_REG))]
2768 "shar %S0\;rotcr %R0"
2769 [(set_attr "length" "4")
2770 (set_attr "type" "arith")
2771 (set_attr "insn_class" "ex_group")])
2773 (define_insn "ashrdi3_media"
2774 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2775 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2776 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2781 [(set_attr "type" "arith_media")])
2783 (define_expand "ashrdi3"
2784 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2785 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2786 (match_operand:DI 2 "immediate_operand" "")))
2787 (clobber (reg:SI T_REG))])]
2793 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2796 if (GET_CODE (operands[2]) != CONST_INT
2797 || INTVAL (operands[2]) != 1)
2801 ;; combined left/right shift
2804 [(set (match_operand:SI 0 "register_operand" "")
2805 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2806 (match_operand:SI 2 "const_int_operand" ""))
2807 (match_operand:SI 3 "const_int_operand" "")))]
2808 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2809 [(use (reg:SI R0_REG))]
2810 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2814 [(set (match_operand:SI 0 "register_operand" "")
2815 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2816 (match_operand:SI 2 "const_int_operand" ""))
2817 (match_operand:SI 3 "const_int_operand" "")))
2818 (clobber (reg:SI T_REG))]
2819 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2820 [(use (reg:SI R0_REG))]
2821 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2825 [(set (match_operand:SI 0 "register_operand" "=r")
2826 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2827 (match_operand:SI 2 "const_int_operand" "n"))
2828 (match_operand:SI 3 "const_int_operand" "n")))
2829 (clobber (reg:SI T_REG))]
2830 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2832 [(set (attr "length")
2833 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2835 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2837 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2839 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2841 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2843 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2845 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2846 (const_string "16")]
2847 (const_string "18")))
2848 (set_attr "type" "arith")])
2851 [(set (match_operand:SI 0 "register_operand" "=z")
2852 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2853 (match_operand:SI 2 "const_int_operand" "n"))
2854 (match_operand:SI 3 "const_int_operand" "n")))
2855 (clobber (reg:SI T_REG))]
2856 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2858 [(set (attr "length")
2859 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2861 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2863 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2865 (const_string "10")))
2866 (set_attr "type" "arith")])
2868 ;; shift left / and combination with a scratch register: The combine pass
2869 ;; does not accept the individual instructions, even though they are
2870 ;; cheap. But it needs a precise description so that it is usable after
2872 (define_insn "and_shl_scratch"
2873 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2877 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2878 (match_operand:SI 2 "const_int_operand" "N,n"))
2879 (match_operand:SI 3 "" "0,r"))
2880 (match_operand:SI 4 "const_int_operand" "n,n"))
2881 (match_operand:SI 5 "const_int_operand" "n,n")))
2882 (clobber (reg:SI T_REG))]
2885 [(set (attr "length")
2886 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2888 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2890 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2892 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2893 (const_string "10")]
2894 (const_string "12")))
2895 (set_attr "type" "arith")])
2898 [(set (match_operand:SI 0 "register_operand" "")
2902 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2903 (match_operand:SI 2 "const_int_operand" ""))
2904 (match_operand:SI 3 "register_operand" ""))
2905 (match_operand:SI 4 "const_int_operand" ""))
2906 (match_operand:SI 5 "const_int_operand" "")))
2907 (clobber (reg:SI T_REG))]
2909 [(use (reg:SI R0_REG))]
2912 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2914 if (INTVAL (operands[2]))
2916 gen_shifty_op (LSHIFTRT, operands);
2918 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2919 operands[2] = operands[4];
2920 gen_shifty_op (ASHIFT, operands);
2921 if (INTVAL (operands[5]))
2923 operands[2] = operands[5];
2924 gen_shifty_op (LSHIFTRT, operands);
2929 ;; signed left/right shift combination.
2931 [(set (match_operand:SI 0 "register_operand" "")
2933 (ashift:SI (match_operand:SI 1 "register_operand" "")
2934 (match_operand:SI 2 "const_int_operand" ""))
2935 (match_operand:SI 3 "const_int_operand" "")
2937 (clobber (reg:SI T_REG))]
2939 [(use (reg:SI R0_REG))]
2940 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2943 (define_insn "shl_sext_ext"
2944 [(set (match_operand:SI 0 "register_operand" "=r")
2946 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2947 (match_operand:SI 2 "const_int_operand" "n"))
2948 (match_operand:SI 3 "const_int_operand" "n")
2950 (clobber (reg:SI T_REG))]
2951 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2953 [(set (attr "length")
2954 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2956 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2958 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2960 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2962 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2964 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2966 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2968 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2969 (const_string "16")]
2970 (const_string "18")))
2971 (set_attr "type" "arith")])
2973 (define_insn "shl_sext_sub"
2974 [(set (match_operand:SI 0 "register_operand" "=z")
2976 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2977 (match_operand:SI 2 "const_int_operand" "n"))
2978 (match_operand:SI 3 "const_int_operand" "n")
2980 (clobber (reg:SI T_REG))]
2981 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2983 [(set (attr "length")
2984 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2986 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2988 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2990 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2991 (const_string "12")]
2992 (const_string "14")))
2993 (set_attr "type" "arith")])
2995 ;; These patterns are found in expansions of DImode shifts by 16, and
2996 ;; allow the xtrct instruction to be generated from C source.
2998 (define_insn "xtrct_left"
2999 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3000 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
3002 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
3006 [(set_attr "type" "arith")
3007 (set_attr "insn_class" "ex_group")])
3009 (define_insn "xtrct_right"
3010 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3011 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3013 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
3017 [(set_attr "type" "arith")
3018 (set_attr "insn_class" "ex_group")])
3020 ;; -------------------------------------------------------------------------
3022 ;; -------------------------------------------------------------------------
3025 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3026 (neg:SI (plus:SI (reg:SI T_REG)
3027 (match_operand:SI 1 "arith_reg_operand" "r"))))
3029 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
3033 [(set_attr "type" "arith")
3034 (set_attr "insn_class" "ex_group")])
3036 (define_insn "*negdi_media"
3037 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3038 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
3041 [(set_attr "type" "arith_media")])
3043 (define_expand "negdi2"
3044 [(set (match_operand:DI 0 "arith_reg_operand" "")
3045 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
3051 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3052 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3054 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3055 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3057 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
3058 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
3060 emit_insn (gen_clrt ());
3061 emit_insn (gen_negc (low_dst, low_src));
3062 emit_insn (gen_negc (high_dst, high_src));
3067 (define_insn "negsi2"
3068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3069 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
3072 [(set_attr "type" "arith")
3073 (set_attr "insn_class" "ex_group")])
3075 (define_insn "one_cmplsi2"
3076 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3077 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
3080 [(set_attr "type" "arith")
3081 (set_attr "insn_class" "ex_group")])
3083 (define_expand "one_cmpldi2"
3084 [(set (match_operand:DI 0 "arith_reg_operand" "")
3085 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
3087 "TARGET_SHMEDIA" "")
3089 ;; -------------------------------------------------------------------------
3090 ;; Zero extension instructions
3091 ;; -------------------------------------------------------------------------
3093 (define_insn "zero_extendsidi2"
3094 [(set (match_operand:DI 0 "register_operand" "=r")
3095 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
3097 "addz.l %1, r63, %0"
3098 [(set_attr "type" "arith_media")])
3100 (define_insn "zero_extendhidi2"
3101 [(set (match_operand:DI 0 "register_operand" "=r,r")
3102 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3107 [(set_attr "type" "*,load_media")])
3110 [(set (match_operand:DI 0 "register_operand" "")
3111 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3112 "TARGET_SHMEDIA && reload_completed"
3113 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3114 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3117 if (GET_CODE (operands[1]) == TRUNCATE)
3118 operands[1] = XEXP (operands[1], 0);
3121 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3122 ;; reload the entrire truncate expression.
3123 (define_insn_and_split "*loaddi_trunc"
3124 [(set (match_operand 0 "int_gpr_dest" "=r")
3125 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3126 "TARGET_SHMEDIA && reload_completed"
3128 "TARGET_SHMEDIA && reload_completed"
3129 [(set (match_dup 0) (match_dup 1))]
3130 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3132 (define_insn "zero_extendqidi2"
3133 [(set (match_operand:DI 0 "register_operand" "=r,r")
3134 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3139 [(set_attr "type" "arith_media,load_media")])
3141 (define_expand "zero_extendhisi2"
3142 [(set (match_operand:SI 0 "arith_reg_operand" "")
3143 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3147 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3148 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3151 (define_insn "*zero_extendhisi2_compact"
3152 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3153 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3156 [(set_attr "type" "arith")
3157 (set_attr "insn_class" "ex_group")])
3159 (define_insn "*zero_extendhisi2_media"
3160 [(set (match_operand:SI 0 "register_operand" "=r,r")
3161 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3166 [(set_attr "type" "arith_media,load_media")])
3169 [(set (match_operand:SI 0 "register_operand" "")
3170 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3171 "TARGET_SHMEDIA && reload_completed"
3172 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3173 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3176 if (GET_CODE (operands[1]) == TRUNCATE)
3177 operands[1] = XEXP (operands[1], 0);
3180 (define_expand "zero_extendqisi2"
3181 [(set (match_operand:SI 0 "arith_reg_operand" "")
3182 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3186 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3187 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3190 (define_insn "*zero_extendqisi2_compact"
3191 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3192 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3195 [(set_attr "type" "arith")
3196 (set_attr "insn_class" "ex_group")])
3198 (define_insn "*zero_extendqisi2_media"
3199 [(set (match_operand:SI 0 "register_operand" "=r,r")
3200 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3205 [(set_attr "type" "arith_media,load_media")])
3207 (define_insn "zero_extendqihi2"
3208 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3209 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3212 [(set_attr "type" "arith")
3213 (set_attr "insn_class" "ex_group")])
3215 ;; -------------------------------------------------------------------------
3216 ;; Sign extension instructions
3217 ;; -------------------------------------------------------------------------
3219 ;; ??? This should be a define expand.
3220 ;; ??? Or perhaps it should be dropped?
3222 ;; convert_move generates good code for SH[1-4].
3223 (define_insn "extendsidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r,r")
3225 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3230 [(set_attr "type" "arith_media,load_media")])
3232 (define_insn "extendhidi2"
3233 [(set (match_operand:DI 0 "register_operand" "=r,r")
3234 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3239 [(set_attr "type" "*,load_media")])
3242 [(set (match_operand:DI 0 "register_operand" "")
3243 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3244 "TARGET_SHMEDIA && reload_completed"
3245 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3246 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3249 if (GET_CODE (operands[1]) == TRUNCATE)
3250 operands[1] = XEXP (operands[1], 0);
3253 (define_insn "extendqidi2"
3254 [(set (match_operand:DI 0 "register_operand" "=r,r")
3255 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3260 [(set_attr "type" "*,load_media")])
3263 [(set (match_operand:DI 0 "register_operand" "")
3264 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3265 "TARGET_SHMEDIA && reload_completed"
3266 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3267 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3270 if (GET_CODE (operands[1]) == TRUNCATE)
3271 operands[1] = XEXP (operands[1], 0);
3274 (define_expand "extendhisi2"
3275 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3276 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3280 (define_insn "*extendhisi2_compact"
3281 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3282 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3287 [(set_attr "type" "arith,load")
3288 (set_attr "insn_class" "ex_group,*")])
3290 (define_insn "*extendhisi2_media"
3291 [(set (match_operand:SI 0 "register_operand" "=r,r")
3292 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3297 [(set_attr "type" "arith_media,load_media")])
3300 [(set (match_operand:SI 0 "register_operand" "")
3301 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3302 "TARGET_SHMEDIA && reload_completed"
3303 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3304 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3307 if (GET_CODE (operands[1]) == TRUNCATE)
3308 operands[1] = XEXP (operands[1], 0);
3311 (define_expand "extendqisi2"
3312 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3313 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3317 (define_insn "*extendqisi2_compact"
3318 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3319 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3324 [(set_attr "type" "arith,load")
3325 (set_attr "insn_class" "ex_group,*")])
3327 (define_insn "*extendqisi2_media"
3328 [(set (match_operand:SI 0 "register_operand" "=r,r")
3329 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3334 [(set_attr "type" "arith_media,load_media")])
3337 [(set (match_operand:SI 0 "register_operand" "")
3338 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3339 "TARGET_SHMEDIA && reload_completed"
3340 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3341 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3344 if (GET_CODE (operands[1]) == TRUNCATE)
3345 operands[1] = XEXP (operands[1], 0);
3348 (define_insn "extendqihi2"
3349 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3350 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3355 [(set_attr "type" "arith,load")
3356 (set_attr "insn_class" "ex_group,*")])
3358 /* It would seem useful to combine the truncXi patterns into the movXi
3359 patterns, but unary operators are ignored when matching constraints,
3360 so we need separate patterns. */
3361 (define_insn "truncdisi2"
3362 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3363 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3372 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3375 (define_insn "truncdihi2"
3376 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3377 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3380 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3382 [(set_attr "type" "arith_media,store_media")
3383 (set_attr "length" "8,4")])
3385 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3386 ; Because we use zero extension, we can't provide signed QImode compares
3387 ; using a simple compare or conditional banch insn.
3388 (define_insn "truncdiqi2"
3389 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3390 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3395 [(set_attr "type" "arith_media,store")])
3397 ;; -------------------------------------------------------------------------
3398 ;; Move instructions
3399 ;; -------------------------------------------------------------------------
3401 ;; define push and pop so it is easy for sh.c
3402 ;; We can't use push and pop on SHcompact because the stack must always
3403 ;; be 8-byte aligned.
3405 (define_expand "push"
3406 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3407 (match_operand:SI 0 "register_operand" "r,l,x"))]
3408 "TARGET_SH1 && ! TARGET_SH5"
3411 (define_expand "pop"
3412 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3413 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3414 "TARGET_SH1 && ! TARGET_SH5"
3417 (define_expand "push_e"
3418 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3419 (match_operand:SF 0 "" ""))
3420 (use (reg:PSI FPSCR_REG))
3421 (clobber (scratch:SI))])]
3422 "TARGET_SH1 && ! TARGET_SH5"
3425 (define_insn "push_fpul"
3426 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3427 "TARGET_SH3E && ! TARGET_SH5"
3429 [(set_attr "type" "store")
3430 (set_attr "hit_stack" "yes")])
3432 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3434 (define_expand "push_4"
3435 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3436 (match_operand:DF 0 "" ""))
3437 (use (reg:PSI FPSCR_REG))
3438 (clobber (scratch:SI))])]
3439 "TARGET_SH1 && ! TARGET_SH5"
3442 (define_expand "pop_e"
3443 [(parallel [(set (match_operand:SF 0 "" "")
3444 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3445 (use (reg:PSI FPSCR_REG))
3446 (clobber (scratch:SI))])]
3447 "TARGET_SH1 && ! TARGET_SH5"
3450 (define_insn "pop_fpul"
3451 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3452 "TARGET_SH3E && ! TARGET_SH5"
3454 [(set_attr "type" "load")
3455 (set_attr "hit_stack" "yes")])
3457 (define_expand "pop_4"
3458 [(parallel [(set (match_operand:DF 0 "" "")
3459 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3460 (use (reg:PSI FPSCR_REG))
3461 (clobber (scratch:SI))])]
3462 "TARGET_SH1 && ! TARGET_SH5"
3465 ;; These two patterns can happen as the result of optimization, when
3466 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3467 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3470 [(set (reg:SI T_REG) (const_int 0))]
3475 [(set (reg:SI T_REG) (const_int 1))]
3479 ;; t/r must come after r/r, lest reload will try to reload stuff like
3480 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3481 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3482 (define_insn "movsi_i"
3483 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3484 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3487 && (register_operand (operands[0], SImode)
3488 || register_operand (operands[1], SImode))"
3505 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3506 (set_attr "insn_class" "*,*,mt_group,*,*,*,*,*,*,*,*,*,*,*,*")
3507 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3509 ;; t/r must come after r/r, lest reload will try to reload stuff like
3510 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3511 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3512 ;; will require a reload.
3513 (define_insn "movsi_ie"
3514 [(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")
3515 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3517 && (register_operand (operands[0], SImode)
3518 || register_operand (operands[1], SImode))"
3539 ! move optimized away"
3540 [(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")
3541 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3543 (define_insn "movsi_i_lowpart"
3544 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3545 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3547 && (register_operand (operands[0], SImode)
3548 || register_operand (operands[1], SImode))"
3558 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3560 (define_insn "*movsi_media"
3561 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3562 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3564 && (register_operand (operands[0], SImode)
3565 || register_operand (operands[1], SImode))"
3580 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3581 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3583 (define_insn "*movsi_media_nofpu"
3584 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3585 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3587 && (register_operand (operands[0], SImode)
3588 || register_operand (operands[1], SImode))"
3598 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3599 (set_attr "length" "4,4,8,4,4,4,4,12")])
3602 [(set (match_operand:SI 0 "arith_reg_operand" "")
3603 (match_operand:SI 1 "immediate_operand" ""))]
3604 "TARGET_SHMEDIA && reload_completed
3605 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3606 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3609 operands[2] = shallow_copy_rtx (operands[1]);
3610 PUT_MODE (operands[2], DImode);
3614 [(set (match_operand:SI 0 "register_operand" "")
3615 (match_operand:SI 1 "immediate_operand" ""))]
3616 "TARGET_SHMEDIA && reload_completed
3617 && ((GET_CODE (operands[1]) == CONST_INT
3618 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3619 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3620 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3622 (define_expand "movsi"
3623 [(set (match_operand:SI 0 "general_movdst_operand" "")
3624 (match_operand:SI 1 "general_movsrc_operand" ""))]
3626 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3628 (define_expand "ic_invalidate_line"
3629 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3630 (match_dup 1)] UNSPEC_ICACHE)
3631 (clobber (scratch:SI))])]
3632 "TARGET_HARD_SH4 || TARGET_SH5"
3637 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3640 else if (TARGET_SHCOMPACT)
3642 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3643 operands[1] = force_reg (Pmode, operands[1]);
3644 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3647 operands[0] = force_reg (Pmode, operands[0]);
3648 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3652 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3653 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3654 ;; the requirement *1*00 for associative address writes. The alignment of
3655 ;; %0 implies that its least significant bit is cleared,
3656 ;; thus we clear the V bit of a matching entry if there is one.
3657 (define_insn "ic_invalidate_line_i"
3658 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3659 (match_operand:SI 1 "register_operand" "r")]
3661 (clobber (match_scratch:SI 2 "=&r"))]
3663 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3664 [(set_attr "length" "8")
3665 (set_attr "insn_class" "cwb")])
3667 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3668 ;; an add in the code that calculates the address.
3669 (define_insn "ic_invalidate_line_media"
3670 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3673 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3674 [(set_attr "length" "16")
3675 (set_attr "type" "invalidate_line_media")])
3677 (define_insn "ic_invalidate_line_compact"
3678 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3679 (match_operand:SI 1 "register_operand" "r")]
3681 (clobber (reg:SI PR_REG))]
3684 [(set_attr "type" "sfunc")
3685 (set_attr "needs_delay_slot" "yes")])
3687 (define_expand "initialize_trampoline"
3688 [(match_operand:SI 0 "" "")
3689 (match_operand:SI 1 "" "")
3690 (match_operand:SI 2 "" "")]
3696 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3697 tramp = gen_rtx_REG (SImode, R0_REG);
3698 emit_move_insn (tramp, operands[0]);
3699 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3700 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3702 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3706 (define_insn "initialize_trampoline_compact"
3707 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3708 (match_operand:SI 1 "register_operand" "r")
3709 (reg:SI R2_REG) (reg:SI R3_REG)]
3712 (clobber (reg:SI PR_REG))]
3715 [(set_attr "type" "sfunc")
3716 (set_attr "needs_delay_slot" "yes")])
3718 (define_insn "movqi_i"
3719 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3720 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3722 && (arith_reg_operand (operands[0], QImode)
3723 || arith_reg_operand (operands[1], QImode))"
3731 [(set_attr "type" "move,load,store,move,move,move")])
3733 (define_insn "*movqi_media"
3734 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3735 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3737 && (arith_reg_operand (operands[0], QImode)
3738 || arith_reg_operand (operands[1], QImode))"
3744 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3746 (define_expand "movqi"
3747 [(set (match_operand:QI 0 "general_operand" "")
3748 (match_operand:QI 1 "general_operand" ""))]
3750 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3752 (define_expand "reload_inqi"
3753 [(set (match_operand:SI 2 "" "=&r")
3754 (match_operand:QI 1 "inqhi_operand" ""))
3755 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3756 (truncate:HI (match_dup 3)))]
3760 rtx inner = XEXP (operands[1], 0);
3761 int regno = REGNO (inner);
3763 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3764 operands[1] = gen_rtx_REG (SImode, regno);
3765 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3768 (define_insn "movhi_i"
3769 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3770 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3772 && (arith_reg_operand (operands[0], HImode)
3773 || arith_reg_operand (operands[1], HImode))"
3783 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3785 (define_insn "*movhi_media"
3786 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3787 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3789 && (arith_reg_operand (operands[0], HImode)
3790 || arith_reg_operand (operands[1], HImode))"
3797 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3800 [(set (match_operand:HI 0 "register_operand" "")
3801 (match_operand:HI 1 "immediate_operand" ""))]
3802 "TARGET_SHMEDIA && reload_completed
3803 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3804 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3806 (define_expand "movhi"
3807 [(set (match_operand:HI 0 "general_movdst_operand" "")
3808 (match_operand:HI 1 "general_movsrc_operand" ""))]
3810 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3812 (define_expand "reload_inhi"
3813 [(set (match_operand:SI 2 "" "=&r")
3814 (match_operand:HI 1 "inqhi_operand" ""))
3815 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3816 (truncate:HI (match_dup 3)))]
3820 rtx inner = XEXP (operands[1], 0);
3821 int regno = REGNO (inner);
3823 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3824 operands[1] = gen_rtx_REG (SImode, regno);
3825 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3828 ;; ??? This should be a define expand.
3830 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3831 ;; compiled with -m2 -ml -O3 -funroll-loops
3833 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3834 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3836 && (arith_reg_operand (operands[0], DImode)
3837 || arith_reg_operand (operands[1], DImode))"
3838 "* return output_movedouble (insn, operands, DImode);"
3839 [(set_attr "length" "4")
3840 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3842 ;; If the output is a register and the input is memory or a register, we have
3843 ;; to be careful and see which word needs to be loaded first.
3846 [(set (match_operand:DI 0 "general_movdst_operand" "")
3847 (match_operand:DI 1 "general_movsrc_operand" ""))]
3848 "TARGET_SH1 && reload_completed"
3849 [(set (match_dup 2) (match_dup 3))
3850 (set (match_dup 4) (match_dup 5))]
3855 if ((GET_CODE (operands[0]) == MEM
3856 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3857 || (GET_CODE (operands[1]) == MEM
3858 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3861 if (GET_CODE (operands[0]) == REG)
3862 regno = REGNO (operands[0]);
3863 else if (GET_CODE (operands[0]) == SUBREG)
3864 regno = subreg_regno (operands[0]);
3865 else if (GET_CODE (operands[0]) == MEM)
3871 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3873 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3874 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3875 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3876 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3880 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3881 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3882 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3883 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3886 if (operands[2] == 0 || operands[3] == 0
3887 || operands[4] == 0 || operands[5] == 0)
3891 (define_insn "*movdi_media"
3892 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3893 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3895 && (register_operand (operands[0], DImode)
3896 || register_operand (operands[1], DImode))"
3911 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3912 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3914 (define_insn "*movdi_media_nofpu"
3915 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3916 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3918 && (register_operand (operands[0], DImode)
3919 || register_operand (operands[1], DImode))"
3929 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3930 (set_attr "length" "4,4,16,4,4,4,4,*")])
3933 [(set (match_operand:DI 0 "arith_reg_operand" "")
3934 (match_operand:DI 1 "immediate_operand" ""))]
3935 "TARGET_SHMEDIA && reload_completed
3936 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3937 [(set (match_dup 0) (match_dup 1))]
3942 if (TARGET_SHMEDIA64)
3943 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3945 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3947 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3953 (define_expand "movdi_const"
3954 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3955 (const:DI (sign_extend:DI
3958 (match_operand:DI 1 "immediate_operand" "s")
3961 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3969 (const_int 32)))))))))
3971 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3979 (const_int 16)))))))))
3981 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3987 (match_dup 1))))))))]
3988 "TARGET_SHMEDIA64 && reload_completed
3989 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3992 if (GET_CODE (operands[1]) == LABEL_REF
3993 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3994 LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3995 else if (GOTOFF_P (operands[1])
3996 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3997 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3999 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
4002 (define_expand "movdi_const_32bit"
4003 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4004 (const:DI (sign_extend:DI
4007 (match_operand:DI 1 "immediate_operand" "s")
4010 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4016 (match_dup 1))))))))]
4017 "TARGET_SHMEDIA32 && reload_completed
4018 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4021 if (GET_CODE (operands[1]) == LABEL_REF
4022 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4023 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4024 else if (GOTOFF_P (operands[1])
4025 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
4026 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
4028 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
4031 (define_expand "movdi_const_16bit"
4032 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
4033 (const:DI (sign_extend:DI
4035 (match_operand:DI 1 "immediate_operand" "s")))))]
4036 "TARGET_SHMEDIA && flag_pic && reload_completed
4037 && GET_CODE (operands[1]) == SYMBOL_REF"
4041 [(set (match_operand:DI 0 "arith_reg_operand" "")
4042 (match_operand:DI 1 "immediate_operand" ""))]
4043 "TARGET_SHMEDIA && reload_completed
4044 && GET_CODE (operands[1]) == CONST_INT
4045 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
4046 [(set (match_dup 0) (match_dup 2))
4050 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
4051 unsigned HOST_WIDE_INT low = val;
4052 unsigned HOST_WIDE_INT high = val;
4053 unsigned HOST_WIDE_INT sign;
4054 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
4056 /* Sign-extend the 16 least-significant bits. */
4061 /* Arithmetic shift right the word by 16 bits. */
4064 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4069 /* If we can't generate the constant with a two-insn movi / shori
4070 sequence, try some other strategies. */
4071 if (! CONST_OK_FOR_J (high))
4073 /* Try constant load / left shift. We know VAL != 0. */
4074 val2 = val ^ (val-1);
4077 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4079 if (CONST_OK_FOR_J (val >> trailing_zeroes)
4080 || (! CONST_OK_FOR_J (high >> 16)
4081 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
4083 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4084 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4085 GEN_INT (trailing_zeroes));
4089 /* Try constant load / right shift. */
4090 val2 = (val >> 15) + 1;
4091 if (val2 == (val2 & -val2))
4093 int shift = 49 - exact_log2 (val2);
4095 val2 = trunc_int_for_mode (val << shift, DImode);
4096 if (CONST_OK_FOR_J (val2))
4098 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4104 val2 = val & 0xffff;
4105 if ((val >> 16 & 0xffff) == val2
4106 && (val >> 32 & 0xffff) == val2
4107 && (val >> 48 & 0xffff) == val2)
4109 val2 = (HOST_WIDE_INT) val >> 48;
4110 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4111 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4114 /* Try movi / mshflo.l */
4115 val2 = (HOST_WIDE_INT) val >> 32;
4116 if (val2 == trunc_int_for_mode (val, SImode))
4118 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4122 /* Try movi / mshflo.l w/ r63. */
4123 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4124 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4126 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4132 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4135 operands[2] = GEN_INT (val2);
4139 [(set (match_operand:DI 0 "arith_reg_operand" "")
4140 (match_operand:DI 1 "immediate_operand" ""))]
4141 "TARGET_SHMEDIA && reload_completed
4142 && GET_CODE (operands[1]) == CONST_DOUBLE"
4143 [(set (match_dup 0) (match_dup 2))
4145 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4146 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4149 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4150 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4151 unsigned HOST_WIDE_INT val = low;
4152 unsigned HOST_WIDE_INT sign;
4154 /* Sign-extend the 16 least-significant bits. */
4158 operands[1] = GEN_INT (val);
4160 /* Arithmetic shift right the double-word by 16 bits. */
4162 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4165 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4169 /* This will only be true if high is a sign-extension of low, i.e.,
4170 it must be either 0 or (unsigned)-1, and be zero iff the
4171 most-significant bit of low is set. */
4172 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4173 operands[2] = GEN_INT (low);
4175 operands[2] = immed_double_const (low, high, DImode);
4178 (define_insn "shori_media"
4179 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4180 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4184 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4189 [(set_attr "type" "arith_media,*")])
4191 (define_expand "movdi"
4192 [(set (match_operand:DI 0 "general_movdst_operand" "")
4193 (match_operand:DI 1 "general_movsrc_operand" ""))]
4195 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4197 (define_insn "movdf_media"
4198 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4199 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4201 && (register_operand (operands[0], DFmode)
4202 || register_operand (operands[1], DFmode))"
4213 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4215 (define_insn "movdf_media_nofpu"
4216 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4217 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4219 && (register_operand (operands[0], DFmode)
4220 || register_operand (operands[1], DFmode))"
4226 [(set_attr "type" "arith_media,*,load_media,store_media")])
4229 [(set (match_operand:DF 0 "arith_reg_operand" "")
4230 (match_operand:DF 1 "immediate_operand" ""))]
4231 "TARGET_SHMEDIA && reload_completed"
4232 [(set (match_dup 3) (match_dup 2))]
4235 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4237 REAL_VALUE_TYPE value;
4239 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4240 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4242 if (HOST_BITS_PER_WIDE_INT >= 64)
4243 operands[2] = immed_double_const ((unsigned long) values[endian]
4244 | ((HOST_WIDE_INT) values[1 - endian]
4246 else if (HOST_BITS_PER_WIDE_INT == 32)
4247 operands[2] = immed_double_const (values[endian], values[1 - endian],
4252 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4255 ;; ??? This should be a define expand.
4257 (define_insn "movdf_k"
4258 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4259 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4261 && (! TARGET_SH4 || reload_completed
4262 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4263 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4264 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4265 && (arith_reg_operand (operands[0], DFmode)
4266 || arith_reg_operand (operands[1], DFmode))"
4267 "* return output_movedouble (insn, operands, DFmode);"
4268 [(set_attr "length" "4")
4269 (set_attr "type" "move,pcload,load,store")])
4271 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4272 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4273 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4274 ;; the d/m/c/X alternative, which is split later into single-precision
4275 ;; instructions. And when not optimizing, no splits are done before fixing
4276 ;; up pcloads, so we need usable length information for that.
4277 (define_insn "movdf_i4"
4278 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4279 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4280 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4281 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4283 && (arith_reg_operand (operands[0], DFmode)
4284 || arith_reg_operand (operands[1], DFmode))"
4296 [(set_attr_alternative "length"
4297 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4299 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4300 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4301 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4303 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4304 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4305 ;; increment or decrement r15 explicitly.
4307 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4308 (const_int 10) (const_int 8))
4310 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4311 (const_int 10) (const_int 8))])
4312 (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
4313 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4314 (const_string "double")
4315 (const_string "none")))])
4317 ;; Moving DFmode between fp/general registers through memory
4318 ;; (the top of the stack) is faster than moving through fpul even for
4319 ;; little endian. Because the type of an instruction is important for its
4320 ;; scheduling, it is beneficial to split these operations, rather than
4321 ;; emitting them in one single chunk, even if this will expose a stack
4322 ;; use that will prevent scheduling of other stack accesses beyond this
4325 [(set (match_operand:DF 0 "register_operand" "")
4326 (match_operand:DF 1 "register_operand" ""))
4327 (use (match_operand:PSI 2 "fpscr_operand" ""))
4328 (clobber (match_scratch:SI 3 "=X"))]
4329 "TARGET_SH4 && reload_completed
4330 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4336 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4338 emit_move_insn (stack_pointer_rtx,
4339 plus_constant (stack_pointer_rtx, -8));
4340 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4343 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4344 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4345 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4346 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4347 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4348 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4350 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4351 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4352 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4353 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4355 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4359 ;; local-alloc sometimes allocates scratch registers even when not required,
4360 ;; so we must be prepared to handle these.
4362 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4364 [(set (match_operand:DF 0 "general_movdst_operand" "")
4365 (match_operand:DF 1 "general_movsrc_operand" ""))
4366 (use (match_operand:PSI 2 "fpscr_operand" ""))
4367 (clobber (match_scratch:SI 3 ""))]
4370 && true_regnum (operands[0]) < 16
4371 && true_regnum (operands[1]) < 16"
4372 [(set (match_dup 0) (match_dup 1))]
4375 /* If this was a reg <-> mem operation with base + index reg addressing,
4376 we have to handle this in a special way. */
4377 rtx mem = operands[0];
4379 if (! memory_operand (mem, DFmode))
4384 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4385 mem = SUBREG_REG (mem);
4386 if (GET_CODE (mem) == MEM)
4388 rtx addr = XEXP (mem, 0);
4389 if (GET_CODE (addr) == PLUS
4390 && GET_CODE (XEXP (addr, 0)) == REG
4391 && GET_CODE (XEXP (addr, 1)) == REG)
4394 rtx reg0 = gen_rtx (REG, Pmode, 0);
4395 rtx regop = operands[store_p], word0 ,word1;
4397 if (GET_CODE (regop) == SUBREG)
4398 alter_subreg (®op);
4399 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4403 mem = copy_rtx (mem);
4404 PUT_MODE (mem, SImode);
4405 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4406 alter_subreg (&word0);
4407 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4408 alter_subreg (&word1);
4409 if (store_p || ! refers_to_regno_p (REGNO (word0),
4410 REGNO (word0) + 1, addr, 0))
4413 ? gen_movsi_ie (mem, word0)
4414 : gen_movsi_ie (word0, mem));
4415 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4416 mem = copy_rtx (mem);
4418 ? gen_movsi_ie (mem, word1)
4419 : gen_movsi_ie (word1, mem));
4420 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4424 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4425 emit_insn (gen_movsi_ie (word1, mem));
4426 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4427 mem = copy_rtx (mem);
4428 emit_insn (gen_movsi_ie (word0, mem));
4435 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4437 [(set (match_operand:DF 0 "register_operand" "")
4438 (match_operand:DF 1 "memory_operand" ""))
4439 (use (match_operand:PSI 2 "fpscr_operand" ""))
4440 (clobber (reg:SI R0_REG))]
4441 "TARGET_SH4 && reload_completed"
4442 [(parallel [(set (match_dup 0) (match_dup 1))
4444 (clobber (scratch:SI))])]
4447 (define_expand "reload_indf"
4448 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4449 (match_operand:DF 1 "immediate_operand" "FQ"))
4450 (use (reg:PSI FPSCR_REG))
4451 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4455 (define_expand "reload_outdf"
4456 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4457 (match_operand:DF 1 "register_operand" "af,r"))
4458 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4462 ;; Simplify no-op moves.
4464 [(set (match_operand:SF 0 "register_operand" "")
4465 (match_operand:SF 1 "register_operand" ""))
4466 (use (match_operand:PSI 2 "fpscr_operand" ""))
4467 (clobber (match_scratch:SI 3 "X"))]
4468 "TARGET_SH3E && reload_completed
4469 && true_regnum (operands[0]) == true_regnum (operands[1])"
4470 [(set (match_dup 0) (match_dup 0))]
4473 ;; fmovd substitute post-reload splits
4475 [(set (match_operand:DF 0 "register_operand" "")
4476 (match_operand:DF 1 "register_operand" ""))
4477 (use (match_operand:PSI 2 "fpscr_operand" ""))
4478 (clobber (match_scratch:SI 3 "X"))]
4479 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4480 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4481 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4485 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4486 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4487 gen_rtx (REG, SFmode, src), operands[2]));
4488 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4489 gen_rtx (REG, SFmode, src + 1), operands[2]));
4494 [(set (match_operand:DF 0 "register_operand" "")
4495 (mem:DF (match_operand:SI 1 "register_operand" "")))
4496 (use (match_operand:PSI 2 "fpscr_operand" ""))
4497 (clobber (match_scratch:SI 3 ""))]
4498 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4499 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4500 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4504 int regno = true_regnum (operands[0]);
4506 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4508 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4509 regno + !! TARGET_LITTLE_ENDIAN),
4510 mem2, operands[2]));
4511 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4512 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4513 regno + ! TARGET_LITTLE_ENDIAN),
4514 gen_rtx (MEM, SFmode, operands[1]),
4520 [(set (match_operand:DF 0 "register_operand" "")
4521 (match_operand:DF 1 "memory_operand" ""))
4522 (use (match_operand:PSI 2 "fpscr_operand" ""))
4523 (clobber (match_scratch:SI 3 ""))]
4524 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4525 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4529 int regno = true_regnum (operands[0]);
4530 rtx addr, insn, adjust = NULL_RTX;
4531 rtx mem2 = copy_rtx (operands[1]);
4532 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4533 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4535 PUT_MODE (mem2, SFmode);
4536 operands[1] = copy_rtx (mem2);
4537 addr = XEXP (mem2, 0);
4538 if (GET_CODE (addr) != POST_INC)
4540 /* If we have to modify the stack pointer, the value that we have
4541 read with post-increment might be modified by an interrupt,
4542 so write it back. */
4543 if (REGNO (addr) == STACK_POINTER_REGNUM)
4544 adjust = gen_push_e (reg0);
4546 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4547 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4549 addr = XEXP (addr, 0);
4550 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4551 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4552 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4556 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4561 [(set (match_operand:DF 0 "memory_operand" "")
4562 (match_operand:DF 1 "register_operand" ""))
4563 (use (match_operand:PSI 2 "fpscr_operand" ""))
4564 (clobber (match_scratch:SI 3 ""))]
4565 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4566 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4570 int regno = true_regnum (operands[1]);
4571 rtx insn, addr, adjust = NULL_RTX;
4573 operands[0] = copy_rtx (operands[0]);
4574 PUT_MODE (operands[0], SFmode);
4575 insn = emit_insn (gen_movsf_ie (operands[0],
4576 gen_rtx (REG, SFmode,
4577 regno + ! TARGET_LITTLE_ENDIAN),
4579 operands[0] = copy_rtx (operands[0]);
4580 addr = XEXP (operands[0], 0);
4581 if (GET_CODE (addr) != PRE_DEC)
4583 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4584 emit_insn_before (adjust, insn);
4585 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4587 addr = XEXP (addr, 0);
4589 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4590 insn = emit_insn (gen_movsf_ie (operands[0],
4591 gen_rtx (REG, SFmode,
4592 regno + !! TARGET_LITTLE_ENDIAN),
4594 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4598 ;; If the output is a register and the input is memory or a register, we have
4599 ;; to be careful and see which word needs to be loaded first.
4602 [(set (match_operand:DF 0 "general_movdst_operand" "")
4603 (match_operand:DF 1 "general_movsrc_operand" ""))]
4604 "TARGET_SH1 && reload_completed"
4605 [(set (match_dup 2) (match_dup 3))
4606 (set (match_dup 4) (match_dup 5))]
4611 if ((GET_CODE (operands[0]) == MEM
4612 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4613 || (GET_CODE (operands[1]) == MEM
4614 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4617 if (GET_CODE (operands[0]) == REG)
4618 regno = REGNO (operands[0]);
4619 else if (GET_CODE (operands[0]) == SUBREG)
4620 regno = subreg_regno (operands[0]);
4621 else if (GET_CODE (operands[0]) == MEM)
4627 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4629 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4630 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4631 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4632 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4636 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4637 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4638 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4639 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4642 if (operands[2] == 0 || operands[3] == 0
4643 || operands[4] == 0 || operands[5] == 0)
4647 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4648 ;; used only once, let combine add in the index again.
4651 [(set (match_operand:SI 0 "register_operand" "")
4652 (match_operand:SI 1 "" ""))
4653 (clobber (match_operand 2 "register_operand" ""))]
4654 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4655 [(use (reg:SI R0_REG))]
4658 rtx addr, reg, const_int;
4660 if (GET_CODE (operands[1]) != MEM)
4662 addr = XEXP (operands[1], 0);
4663 if (GET_CODE (addr) != PLUS)
4665 reg = XEXP (addr, 0);
4666 const_int = XEXP (addr, 1);
4667 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4668 && GET_CODE (const_int) == CONST_INT))
4670 emit_move_insn (operands[2], const_int);
4671 emit_move_insn (operands[0],
4672 change_address (operands[1], VOIDmode,
4673 gen_rtx_PLUS (SImode, reg, operands[2])));
4678 [(set (match_operand:SI 1 "" "")
4679 (match_operand:SI 0 "register_operand" ""))
4680 (clobber (match_operand 2 "register_operand" ""))]
4681 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4682 [(use (reg:SI R0_REG))]
4685 rtx addr, reg, const_int;
4687 if (GET_CODE (operands[1]) != MEM)
4689 addr = XEXP (operands[1], 0);
4690 if (GET_CODE (addr) != PLUS)
4692 reg = XEXP (addr, 0);
4693 const_int = XEXP (addr, 1);
4694 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4695 && GET_CODE (const_int) == CONST_INT))
4697 emit_move_insn (operands[2], const_int);
4698 emit_move_insn (change_address (operands[1], VOIDmode,
4699 gen_rtx_PLUS (SImode, reg, operands[2])),
4704 (define_expand "movdf"
4705 [(set (match_operand:DF 0 "general_movdst_operand" "")
4706 (match_operand:DF 1 "general_movsrc_operand" ""))]
4710 if (prepare_move_operands (operands, DFmode)) DONE;
4713 if (TARGET_SHMEDIA_FPU)
4714 emit_insn (gen_movdf_media (operands[0], operands[1]));
4716 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4721 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4726 ;;This is incompatible with the way gcc uses subregs.
4727 ;;(define_insn "movv2sf_i"
4728 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4729 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4730 ;; "TARGET_SHMEDIA_FPU
4731 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4732 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4736 ;; fst%M0.p %m0, %1"
4737 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4739 (define_insn_and_split "movv2sf_i"
4740 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4741 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4742 "TARGET_SHMEDIA_FPU"
4744 "TARGET_SHMEDIA_FPU && reload_completed"
4745 [(set (match_dup 0) (match_dup 1))]
4748 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4749 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4752 (define_expand "movv2sf"
4753 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4754 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4755 "TARGET_SHMEDIA_FPU"
4758 if (prepare_move_operands (operands, V2SFmode))
4762 (define_expand "addv2sf3"
4763 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4764 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4765 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4766 "TARGET_SHMEDIA_FPU"
4769 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4773 (define_expand "subv2sf3"
4774 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4775 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4776 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4777 "TARGET_SHMEDIA_FPU"
4780 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4784 (define_expand "mulv2sf3"
4785 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4786 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4787 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4788 "TARGET_SHMEDIA_FPU"
4791 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4795 (define_expand "divv2sf3"
4796 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4797 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4798 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4799 "TARGET_SHMEDIA_FPU"
4802 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4806 (define_insn_and_split "*movv4sf_i"
4807 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4808 (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4809 "TARGET_SHMEDIA_FPU"
4811 "&& reload_completed"
4817 for (i = 0; i < 4/2; i++)
4821 if (GET_CODE (operands[0]) == MEM)
4822 x = gen_rtx_MEM (V2SFmode,
4823 plus_constant (XEXP (operands[0], 0),
4824 i * GET_MODE_SIZE (V2SFmode)));
4826 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4828 if (GET_CODE (operands[1]) == MEM)
4829 y = gen_rtx_MEM (V2SFmode,
4830 plus_constant (XEXP (operands[1], 0),
4831 i * GET_MODE_SIZE (V2SFmode)));
4833 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4835 emit_insn (gen_movv2sf_i (x, y));
4840 [(set_attr "length" "8")])
4842 (define_expand "movv4sf"
4843 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4844 (match_operand:V4SF 1 "general_operand" ""))]
4845 "TARGET_SHMEDIA_FPU"
4848 if (prepare_move_operands (operands, V4SFmode))
4852 (define_insn_and_split "*movv16sf_i"
4853 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4854 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4855 "TARGET_SHMEDIA_FPU"
4857 "&& reload_completed"
4863 for (i = 0; i < 16/2; i++)
4867 if (GET_CODE (operands[0]) == MEM)
4868 x = gen_rtx_MEM (V2SFmode,
4869 plus_constant (XEXP (operands[0], 0),
4870 i * GET_MODE_SIZE (V2SFmode)));
4873 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4877 if (GET_CODE (operands[1]) == MEM)
4878 y = gen_rtx_MEM (V2SFmode,
4879 plus_constant (XEXP (operands[1], 0),
4880 i * GET_MODE_SIZE (V2SFmode)));
4883 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4887 emit_insn (gen_movv2sf_i (x, y));
4892 [(set_attr "length" "32")])
4894 (define_expand "movv16sf"
4895 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4896 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4897 "TARGET_SHMEDIA_FPU"
4900 if (prepare_move_operands (operands, V16SFmode))
4904 (define_insn "movsf_media"
4905 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4906 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4908 && (register_operand (operands[0], SFmode)
4909 || register_operand (operands[1], SFmode))"
4920 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4922 (define_insn "movsf_media_nofpu"
4923 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4924 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4926 && (register_operand (operands[0], SFmode)
4927 || register_operand (operands[1], SFmode))"
4933 [(set_attr "type" "arith_media,*,load_media,store_media")])
4936 [(set (match_operand:SF 0 "arith_reg_operand" "")
4937 (match_operand:SF 1 "immediate_operand" ""))]
4938 "TARGET_SHMEDIA && reload_completed
4939 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4940 [(set (match_dup 3) (match_dup 2))]
4944 REAL_VALUE_TYPE value;
4946 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4947 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4948 operands[2] = GEN_INT (values);
4950 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4953 (define_insn "movsf_i"
4954 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4955 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4958 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4959 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4960 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4961 && (arith_reg_operand (operands[0], SFmode)
4962 || arith_reg_operand (operands[1], SFmode))"
4971 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4973 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4974 ;; update_flow_info would not know where to put REG_EQUAL notes
4975 ;; when the destination changes mode.
4976 (define_insn "movsf_ie"
4977 [(set (match_operand:SF 0 "general_movdst_operand"
4978 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4979 (match_operand:SF 1 "general_movsrc_operand"
4980 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4981 (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"))
4982 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4985 && (arith_reg_operand (operands[0], SFmode)
4986 || arith_reg_operand (operands[1], SFmode)
4987 || arith_reg_operand (operands[3], SImode)
4988 || (fpul_operand (operands[0], SFmode)
4989 && memory_operand (operands[1], SFmode)
4990 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4991 || (fpul_operand (operands[1], SFmode)
4992 && memory_operand (operands[0], SFmode)
4993 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
5013 ! move optimized away"
5014 [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
5015 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
5016 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5017 (const_string "single")
5018 (const_string "none")))])
5021 [(set (match_operand:SF 0 "register_operand" "")
5022 (match_operand:SF 1 "register_operand" ""))
5023 (use (match_operand:PSI 2 "fpscr_operand" ""))
5024 (clobber (reg:SI FPUL_REG))]
5026 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
5028 (clobber (scratch:SI))])
5029 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
5031 (clobber (scratch:SI))])]
5034 (define_expand "movsf"
5035 [(set (match_operand:SF 0 "general_movdst_operand" "")
5036 (match_operand:SF 1 "general_movsrc_operand" ""))]
5040 if (prepare_move_operands (operands, SFmode))
5044 if (TARGET_SHMEDIA_FPU)
5045 emit_insn (gen_movsf_media (operands[0], operands[1]));
5047 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
5052 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
5057 (define_insn "mov_nop"
5058 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
5061 [(set_attr "length" "0")
5062 (set_attr "type" "nil")])
5064 (define_expand "reload_insf"
5065 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5066 (match_operand:SF 1 "immediate_operand" "FQ"))
5067 (use (reg:PSI FPSCR_REG))
5068 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5072 (define_expand "reload_insi"
5073 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5074 (match_operand:SF 1 "immediate_operand" "FQ"))
5075 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5079 (define_insn "*movsi_y"
5080 [(set (match_operand:SI 0 "register_operand" "=y,y")
5081 (match_operand:SI 1 "immediate_operand" "Qi,I"))
5082 (clobber (match_scratch:SI 2 "=&z,r"))]
5084 && (reload_in_progress || reload_completed)"
5086 [(set_attr "length" "4")
5087 (set_attr "type" "pcload,move")])
5090 [(set (match_operand:SI 0 "register_operand" "")
5091 (match_operand:SI 1 "immediate_operand" ""))
5092 (clobber (match_operand:SI 2 "register_operand" ""))]
5094 [(set (match_dup 2) (match_dup 1))
5095 (set (match_dup 0) (match_dup 2))]
5099 [(set (match_operand:SI 0 "register_operand" "")
5100 (match_operand:SI 1 "memory_operand" ""))
5101 (clobber (reg:SI R0_REG))]
5103 [(set (match_dup 0) (match_dup 1))]
5106 ;; ------------------------------------------------------------------------
5107 ;; Define the real conditional branch instructions.
5108 ;; ------------------------------------------------------------------------
5110 (define_insn "branch_true"
5111 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5112 (label_ref (match_operand 0 "" ""))
5115 "* return output_branch (1, insn, operands);"
5116 [(set_attr "type" "cbranch")])
5118 (define_insn "branch_false"
5119 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5120 (label_ref (match_operand 0 "" ""))
5123 "* return output_branch (0, insn, operands);"
5124 [(set_attr "type" "cbranch")])
5126 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5127 ;; which destination is too far away.
5128 ;; The const_int_operand is distinct for each branch target; it avoids
5129 ;; unwanted matches with redundant_insn.
5130 (define_insn "block_branch_redirect"
5131 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5134 [(set_attr "length" "0")])
5136 ;; This one has the additional purpose to record a possible scratch register
5137 ;; for the following branch.
5138 (define_insn "indirect_jump_scratch"
5139 [(set (match_operand:SI 0 "register_operand" "=r")
5140 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5143 [(set_attr "length" "0")])
5145 ;; Conditional branch insns
5147 (define_expand "beq_media"
5149 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5150 (match_operand:DI 2 "arith_operand" "r,O"))
5151 (label_ref:DI (match_operand 0 "" ""))
5156 (define_insn "*beq_media_i"
5158 (if_then_else (match_operator 3 "equality_comparison_operator"
5159 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5160 (match_operand:DI 2 "arith_operand" "r,O")])
5161 (match_operand:DI 0 "target_operand" "b,b")
5167 [(set_attr "type" "cbranch_media")])
5169 (define_expand "bne_media"
5171 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5172 (match_operand:DI 2 "arith_operand" "r,O"))
5173 (label_ref:DI (match_operand 0 "" ""))
5178 (define_expand "bgt_media"
5180 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5181 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5182 (label_ref:DI (match_operand 0 "" ""))
5187 (define_expand "bge_media"
5189 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5190 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5191 (label_ref:DI (match_operand 0 "" ""))
5196 (define_expand "bgtu_media"
5198 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5199 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5200 (label_ref:DI (match_operand 0 "" ""))
5205 (define_expand "bgeu_media"
5207 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5208 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5209 (label_ref:DI (match_operand 0 "" ""))
5214 (define_insn "*bgt_media_i"
5216 (if_then_else (match_operator 3 "greater_comparison_operator"
5217 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5218 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5219 (match_operand:DI 0 "target_operand" "b")
5222 "b%o3%' %N1, %N2, %0"
5223 [(set_attr "type" "cbranch_media")])
5225 ;; These are only needed to make invert_jump() happy.
5226 (define_insn "*blt_media_i"
5228 (if_then_else (match_operator 3 "less_comparison_operator"
5229 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5230 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5231 (match_operand:DI 0 "target_operand" "b")
5234 "b%o3%' %N2, %N1, %0"
5235 [(set_attr "type" "cbranch_media")])
5237 (define_expand "beq"
5239 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5240 (label_ref (match_operand 0 "" ""))
5247 if (GET_MODE (sh_compare_op0) != DImode)
5249 rtx tmp = gen_reg_rtx (DImode);
5251 emit_insn (gen_seq (tmp));
5252 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5256 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5257 emit_jump_insn (gen_beq_media (operands[0],
5258 sh_compare_op0, sh_compare_op1));
5262 from_compare (operands, EQ);
5265 (define_expand "bne"
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5275 if (GET_MODE (sh_compare_op0) != DImode)
5277 rtx tmp = gen_reg_rtx (DImode);
5279 emit_insn (gen_seq (tmp));
5280 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5284 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5285 emit_jump_insn (gen_bne_media (operands[0],
5286 sh_compare_op0, sh_compare_op1));
5290 from_compare (operands, EQ);
5293 (define_expand "bgt"
5295 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5296 (label_ref (match_operand 0 "" ""))
5303 if (GET_MODE (sh_compare_op0) != DImode)
5305 rtx tmp = gen_reg_rtx (DImode);
5307 emit_insn (gen_sgt (tmp));
5308 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5312 if (sh_compare_op0 != const0_rtx)
5313 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5314 if (sh_compare_op1 != const0_rtx)
5315 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5316 emit_jump_insn (gen_bgt_media (operands[0],
5317 sh_compare_op0, sh_compare_op1));
5321 from_compare (operands, GT);
5324 (define_expand "blt"
5326 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5327 (label_ref (match_operand 0 "" ""))
5334 if (GET_MODE (sh_compare_op0) != DImode)
5336 rtx tmp = gen_reg_rtx (DImode);
5338 emit_insn (gen_slt (tmp));
5339 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5343 if (sh_compare_op0 != const0_rtx)
5344 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5345 if (sh_compare_op1 != const0_rtx)
5346 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5347 emit_jump_insn (gen_bgt_media (operands[0],
5348 sh_compare_op1, sh_compare_op0));
5352 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5354 rtx tmp = sh_compare_op0;
5355 sh_compare_op0 = sh_compare_op1;
5356 sh_compare_op1 = tmp;
5357 emit_insn (gen_bgt (operands[0]));
5360 from_compare (operands, GE);
5363 (define_expand "ble"
5365 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5366 (label_ref (match_operand 0 "" ""))
5373 if (GET_MODE (sh_compare_op0) != DImode)
5375 rtx tmp = gen_reg_rtx (DImode);
5377 emit_insn (gen_sle (tmp));
5378 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5382 if (sh_compare_op0 != const0_rtx)
5383 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5384 if (sh_compare_op1 != const0_rtx)
5385 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5386 emit_jump_insn (gen_bge_media (operands[0],
5387 sh_compare_op1, sh_compare_op0));
5393 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5395 rtx tmp = sh_compare_op0;
5396 sh_compare_op0 = sh_compare_op1;
5397 sh_compare_op1 = tmp;
5398 emit_insn (gen_bge (operands[0]));
5401 from_compare (operands, GT);
5404 (define_expand "bge"
5406 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5407 (label_ref (match_operand 0 "" ""))
5414 if (GET_MODE (sh_compare_op0) != DImode)
5416 rtx tmp = gen_reg_rtx (DImode);
5418 emit_insn (gen_sge (tmp));
5419 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5423 if (sh_compare_op0 != const0_rtx)
5424 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425 if (sh_compare_op1 != const0_rtx)
5426 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5427 emit_jump_insn (gen_bge_media (operands[0],
5428 sh_compare_op0, sh_compare_op1));
5434 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5436 rtx tmp = sh_compare_op0;
5437 sh_compare_op0 = sh_compare_op1;
5438 sh_compare_op1 = tmp;
5439 emit_insn (gen_ble (operands[0]));
5442 from_compare (operands, GE);
5445 (define_expand "bgtu"
5447 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5448 (label_ref (match_operand 0 "" ""))
5455 if (sh_compare_op0 != const0_rtx)
5456 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5457 if (sh_compare_op1 != const0_rtx)
5458 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5459 emit_jump_insn (gen_bgtu_media (operands[0],
5460 sh_compare_op0, sh_compare_op1));
5464 from_compare (operands, GTU);
5467 (define_expand "bltu"
5469 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5470 (label_ref (match_operand 0 "" ""))
5477 if (sh_compare_op0 != const0_rtx)
5478 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5479 if (sh_compare_op1 != const0_rtx)
5480 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5481 emit_jump_insn (gen_bgtu_media (operands[0],
5482 sh_compare_op1, sh_compare_op0));
5486 from_compare (operands, GEU);
5489 (define_expand "bgeu"
5491 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5492 (label_ref (match_operand 0 "" ""))
5499 if (sh_compare_op0 != const0_rtx)
5500 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5501 if (sh_compare_op1 != const0_rtx)
5502 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5503 emit_jump_insn (gen_bgeu_media (operands[0],
5504 sh_compare_op0, sh_compare_op1));
5508 from_compare (operands, GEU);
5511 (define_expand "bleu"
5513 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5514 (label_ref (match_operand 0 "" ""))
5521 if (sh_compare_op0 != const0_rtx)
5522 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5523 if (sh_compare_op1 != const0_rtx)
5524 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5525 emit_jump_insn (gen_bgeu_media (operands[0],
5526 sh_compare_op1, sh_compare_op0));
5530 from_compare (operands, GTU);
5533 (define_expand "bunordered"
5534 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5536 (if_then_else (ne (match_dup 1) (const_int 0))
5537 (label_ref:DI (match_operand 0 "" ""))
5542 operands[1] = gen_reg_rtx (DImode);
5543 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5544 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5547 ;; ------------------------------------------------------------------------
5548 ;; Jump and linkage insns
5549 ;; ------------------------------------------------------------------------
5551 (define_insn "jump_compact"
5553 (label_ref (match_operand 0 "" "")))]
5557 /* The length is 16 if the delay slot is unfilled. */
5558 if (get_attr_length(insn) > 4)
5559 return output_far_jump(insn, operands[0]);
5561 return \"bra %l0%#\";
5563 [(set_attr "type" "jump")
5564 (set_attr "needs_delay_slot" "yes")])
5566 (define_insn "jump_media"
5568 (match_operand:DI 0 "target_operand" "b"))]
5571 [(set_attr "type" "jump_media")])
5573 (define_expand "jump"
5575 (label_ref (match_operand 0 "" "")))]
5580 emit_jump_insn (gen_jump_compact (operands[0]));
5581 else if (TARGET_SHMEDIA)
5583 if (reload_in_progress || reload_completed)
5585 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5591 (define_insn "force_mode_for_call"
5592 [(use (reg:PSI FPSCR_REG))]
5595 [(set_attr "length" "0")
5596 (set (attr "fp_mode")
5597 (if_then_else (eq_attr "fpu_single" "yes")
5598 (const_string "single") (const_string "double")))])
5600 (define_insn "calli"
5601 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5602 (match_operand 1 "" ""))
5603 (use (reg:PSI FPSCR_REG))
5604 (clobber (reg:SI PR_REG))]
5607 [(set_attr "type" "call")
5608 (set (attr "fp_mode")
5609 (if_then_else (eq_attr "fpu_single" "yes")
5610 (const_string "single") (const_string "double")))
5611 (set_attr "needs_delay_slot" "yes")])
5613 ;; This is a pc-rel call, using bsrf, for use with PIC.
5615 (define_insn "calli_pcrel"
5616 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5617 (match_operand 1 "" ""))
5618 (use (reg:PSI FPSCR_REG))
5619 (use (reg:SI PIC_REG))
5620 (use (match_operand 2 "" ""))
5621 (clobber (reg:SI PR_REG))]
5624 [(set_attr "type" "call")
5625 (set (attr "fp_mode")
5626 (if_then_else (eq_attr "fpu_single" "yes")
5627 (const_string "single") (const_string "double")))
5628 (set_attr "needs_delay_slot" "yes")])
5630 (define_insn_and_split "call_pcrel"
5631 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5632 (match_operand 1 "" ""))
5633 (use (reg:PSI FPSCR_REG))
5634 (use (reg:SI PIC_REG))
5635 (clobber (reg:SI PR_REG))
5636 (clobber (match_scratch:SI 2 "=r"))]
5643 rtx lab = PATTERN (gen_call_site ());
5645 if (SYMBOL_REF_FLAG (operands[0]))
5646 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5648 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5649 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5652 [(set_attr "type" "call")
5653 (set (attr "fp_mode")
5654 (if_then_else (eq_attr "fpu_single" "yes")
5655 (const_string "single") (const_string "double")))
5656 (set_attr "needs_delay_slot" "yes")])
5658 (define_insn "call_compact"
5659 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5660 (match_operand 1 "" ""))
5661 (match_operand 2 "immediate_operand" "n")
5662 (use (reg:SI R0_REG))
5663 (use (reg:SI R1_REG))
5664 (use (reg:PSI FPSCR_REG))
5665 (clobber (reg:SI PR_REG))]
5666 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5668 [(set_attr "type" "call")
5669 (set (attr "fp_mode")
5670 (if_then_else (eq_attr "fpu_single" "yes")
5671 (const_string "single") (const_string "double")))
5672 (set_attr "needs_delay_slot" "yes")])
5674 (define_insn "call_compact_rettramp"
5675 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5676 (match_operand 1 "" ""))
5677 (match_operand 2 "immediate_operand" "n")
5678 (use (reg:SI R0_REG))
5679 (use (reg:SI R1_REG))
5680 (use (reg:PSI FPSCR_REG))
5681 (clobber (reg:SI R10_REG))
5682 (clobber (reg:SI PR_REG))]
5683 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5685 [(set_attr "type" "call")
5686 (set (attr "fp_mode")
5687 (if_then_else (eq_attr "fpu_single" "yes")
5688 (const_string "single") (const_string "double")))
5689 (set_attr "needs_delay_slot" "yes")])
5691 (define_insn "call_media"
5692 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5693 (match_operand 1 "" ""))
5694 (clobber (reg:DI PR_MEDIA_REG))]
5697 [(set_attr "type" "jump_media")])
5699 (define_insn "call_valuei"
5700 [(set (match_operand 0 "" "=rf")
5701 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5702 (match_operand 2 "" "")))
5703 (use (reg:PSI FPSCR_REG))
5704 (clobber (reg:SI PR_REG))]
5707 [(set_attr "type" "call")
5708 (set (attr "fp_mode")
5709 (if_then_else (eq_attr "fpu_single" "yes")
5710 (const_string "single") (const_string "double")))
5711 (set_attr "needs_delay_slot" "yes")])
5713 (define_insn "call_valuei_pcrel"
5714 [(set (match_operand 0 "" "=rf")
5715 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5716 (match_operand 2 "" "")))
5717 (use (reg:PSI FPSCR_REG))
5718 (use (reg:SI PIC_REG))
5719 (use (match_operand 3 "" ""))
5720 (clobber (reg:SI PR_REG))]
5723 [(set_attr "type" "call")
5724 (set (attr "fp_mode")
5725 (if_then_else (eq_attr "fpu_single" "yes")
5726 (const_string "single") (const_string "double")))
5727 (set_attr "needs_delay_slot" "yes")])
5729 (define_insn_and_split "call_value_pcrel"
5730 [(set (match_operand 0 "" "=rf")
5731 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5732 (match_operand 2 "" "")))
5733 (use (reg:PSI FPSCR_REG))
5734 (use (reg:SI PIC_REG))
5735 (clobber (reg:SI PR_REG))
5736 (clobber (match_scratch:SI 3 "=r"))]
5743 rtx lab = PATTERN (gen_call_site ());
5745 if (SYMBOL_REF_FLAG (operands[1]))
5746 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5748 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5749 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5753 [(set_attr "type" "call")
5754 (set (attr "fp_mode")
5755 (if_then_else (eq_attr "fpu_single" "yes")
5756 (const_string "single") (const_string "double")))
5757 (set_attr "needs_delay_slot" "yes")])
5759 (define_insn "call_value_compact"
5760 [(set (match_operand 0 "" "=rf")
5761 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5762 (match_operand 2 "" "")))
5763 (match_operand 3 "immediate_operand" "n")
5764 (use (reg:SI R0_REG))
5765 (use (reg:SI R1_REG))
5766 (use (reg:PSI FPSCR_REG))
5767 (clobber (reg:SI PR_REG))]
5768 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5770 [(set_attr "type" "call")
5771 (set (attr "fp_mode")
5772 (if_then_else (eq_attr "fpu_single" "yes")
5773 (const_string "single") (const_string "double")))
5774 (set_attr "needs_delay_slot" "yes")])
5776 (define_insn "call_value_compact_rettramp"
5777 [(set (match_operand 0 "" "=rf")
5778 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5779 (match_operand 2 "" "")))
5780 (match_operand 3 "immediate_operand" "n")
5781 (use (reg:SI R0_REG))
5782 (use (reg:SI R1_REG))
5783 (use (reg:PSI FPSCR_REG))
5784 (clobber (reg:SI R10_REG))
5785 (clobber (reg:SI PR_REG))]
5786 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5788 [(set_attr "type" "call")
5789 (set (attr "fp_mode")
5790 (if_then_else (eq_attr "fpu_single" "yes")
5791 (const_string "single") (const_string "double")))
5792 (set_attr "needs_delay_slot" "yes")])
5794 (define_insn "call_value_media"
5795 [(set (match_operand 0 "" "=rf")
5796 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5797 (match_operand 2 "" "")))
5798 (clobber (reg:DI PR_MEDIA_REG))]
5801 [(set_attr "type" "jump_media")])
5803 (define_expand "call"
5804 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5805 (match_operand 1 "" ""))
5806 (match_operand 2 "" "")
5807 (use (reg:PSI FPSCR_REG))
5808 (clobber (reg:SI PR_REG))])]
5814 operands[0] = XEXP (operands[0], 0);
5815 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5817 if (! SYMBOL_REF_FLAG (operands[0]))
5819 rtx reg = gen_reg_rtx (Pmode);
5821 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5826 operands[0] = gen_sym2PIC (operands[0]);
5827 PUT_MODE (operands[0], Pmode);
5830 if (GET_MODE (operands[0]) == SImode)
5832 if (GET_CODE (operands[0]) == REG)
5833 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5834 else if (GET_CODE (operands[0]) == SUBREG)
5836 operands[0] = SUBREG_REG (operands[0]);
5837 if (GET_MODE (operands[0]) != DImode)
5838 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5842 operands[0] = shallow_copy_rtx (operands[0]);
5843 PUT_MODE (operands[0], DImode);
5846 if (! target_reg_operand (operands[0], DImode))
5847 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5848 emit_call_insn (gen_call_media (operands[0], operands[1]));
5851 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5853 rtx cookie_rtx = operands[2];
5854 long cookie = INTVAL (cookie_rtx);
5855 rtx func = XEXP (operands[0], 0);
5860 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5862 rtx reg = gen_reg_rtx (Pmode);
5864 emit_insn (gen_symGOTPLT2reg (reg, func));
5868 func = legitimize_pic_address (func, Pmode, 0);
5871 r0 = gen_rtx_REG (SImode, R0_REG);
5872 r1 = gen_rtx_REG (SImode, R1_REG);
5874 /* Since such a call function may use all call-clobbered
5875 registers, we force a mode switch earlier, so that we don't
5876 run out of registers when adjusting fpscr for the call. */
5877 emit_insn (gen_force_mode_for_call ());
5879 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5880 \"__GCC_shcompact_call_trampoline\");
5883 rtx reg = gen_reg_rtx (Pmode);
5885 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5888 operands[0] = force_reg (SImode, operands[0]);
5890 emit_move_insn (r0, func);
5891 emit_move_insn (r1, cookie_rtx);
5893 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5894 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5897 emit_call_insn (gen_call_compact (operands[0], operands[1],
5902 else if (TARGET_SHCOMPACT && flag_pic
5903 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5904 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5906 rtx reg = gen_reg_rtx (Pmode);
5908 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5909 XEXP (operands[0], 0) = reg;
5911 if (flag_pic && TARGET_SH2
5912 && GET_CODE (operands[0]) == MEM
5913 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5915 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5919 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5921 emit_call_insn (gen_calli (operands[0], operands[1]));
5925 (define_insn "call_pop_compact"
5926 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5927 (match_operand 1 "" ""))
5928 (match_operand 2 "immediate_operand" "n")
5929 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5930 (match_operand 3 "immediate_operand" "n")))
5931 (use (reg:SI R0_REG))
5932 (use (reg:SI R1_REG))
5933 (use (reg:PSI FPSCR_REG))
5934 (clobber (reg:SI PR_REG))]
5935 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5937 [(set_attr "type" "call")
5938 (set (attr "fp_mode")
5939 (if_then_else (eq_attr "fpu_single" "yes")
5940 (const_string "single") (const_string "double")))
5941 (set_attr "needs_delay_slot" "yes")])
5943 (define_insn "call_pop_compact_rettramp"
5944 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5945 (match_operand 1 "" ""))
5946 (match_operand 2 "immediate_operand" "n")
5947 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5948 (match_operand 3 "immediate_operand" "n")))
5949 (use (reg:SI R0_REG))
5950 (use (reg:SI R1_REG))
5951 (use (reg:PSI FPSCR_REG))
5952 (clobber (reg:SI R10_REG))
5953 (clobber (reg:SI PR_REG))]
5954 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5956 [(set_attr "type" "call")
5957 (set (attr "fp_mode")
5958 (if_then_else (eq_attr "fpu_single" "yes")
5959 (const_string "single") (const_string "double")))
5960 (set_attr "needs_delay_slot" "yes")])
5962 (define_expand "call_pop"
5963 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5964 (match_operand 1 "" ""))
5965 (match_operand 2 "" "")
5966 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5967 (match_operand 3 "" "")))])]
5971 if (operands[2] && INTVAL (operands[2]))
5973 rtx cookie_rtx = operands[2];
5974 long cookie = INTVAL (cookie_rtx);
5975 rtx func = XEXP (operands[0], 0);
5980 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5982 rtx reg = gen_reg_rtx (Pmode);
5984 emit_insn (gen_symGOTPLT2reg (reg, func));
5988 func = legitimize_pic_address (func, Pmode, 0);
5991 r0 = gen_rtx_REG (SImode, R0_REG);
5992 r1 = gen_rtx_REG (SImode, R1_REG);
5994 /* Since such a call function may use all call-clobbered
5995 registers, we force a mode switch earlier, so that we don't
5996 run out of registers when adjusting fpscr for the call. */
5997 emit_insn (gen_force_mode_for_call ());
5999 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6000 \"__GCC_shcompact_call_trampoline\");
6003 rtx reg = gen_reg_rtx (Pmode);
6005 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
6008 operands[0] = force_reg (SImode, operands[0]);
6010 emit_move_insn (r0, func);
6011 emit_move_insn (r1, cookie_rtx);
6013 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6014 emit_call_insn (gen_call_pop_compact_rettramp
6015 (operands[0], operands[1], operands[2], operands[3]));
6017 emit_call_insn (gen_call_pop_compact
6018 (operands[0], operands[1], operands[2], operands[3]));
6026 (define_expand "call_value"
6027 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6028 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6029 (match_operand 2 "" "")))
6030 (match_operand 3 "" "")
6031 (use (reg:PSI FPSCR_REG))
6032 (clobber (reg:SI PR_REG))])]
6038 operands[1] = XEXP (operands[1], 0);
6039 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6041 if (! SYMBOL_REF_FLAG (operands[1]))
6043 rtx reg = gen_reg_rtx (Pmode);
6045 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6050 operands[1] = gen_sym2PIC (operands[1]);
6051 PUT_MODE (operands[1], Pmode);
6054 if (GET_MODE (operands[1]) == SImode)
6056 if (GET_CODE (operands[1]) == REG)
6057 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6058 else if (GET_CODE (operands[1]) == SUBREG)
6060 operands[1] = SUBREG_REG (operands[1]);
6061 if (GET_MODE (operands[1]) != DImode)
6062 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6066 operands[1] = shallow_copy_rtx (operands[1]);
6067 PUT_MODE (operands[1], DImode);
6070 if (! target_reg_operand (operands[1], DImode))
6071 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6072 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6076 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6078 rtx cookie_rtx = operands[3];
6079 long cookie = INTVAL (cookie_rtx);
6080 rtx func = XEXP (operands[1], 0);
6085 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6087 rtx reg = gen_reg_rtx (Pmode);
6089 emit_insn (gen_symGOTPLT2reg (reg, func));
6093 func = legitimize_pic_address (func, Pmode, 0);
6096 r0 = gen_rtx_REG (SImode, R0_REG);
6097 r1 = gen_rtx_REG (SImode, R1_REG);
6099 /* Since such a call function may use all call-clobbered
6100 registers, we force a mode switch earlier, so that we don't
6101 run out of registers when adjusting fpscr for the call. */
6102 emit_insn (gen_force_mode_for_call ());
6104 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6105 \"__GCC_shcompact_call_trampoline\");
6108 rtx reg = gen_reg_rtx (Pmode);
6110 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6113 operands[1] = force_reg (SImode, operands[1]);
6115 emit_move_insn (r0, func);
6116 emit_move_insn (r1, cookie_rtx);
6118 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6119 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6124 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6125 operands[2], operands[3]));
6129 else if (TARGET_SHCOMPACT && flag_pic
6130 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6131 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6133 rtx reg = gen_reg_rtx (Pmode);
6135 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6136 XEXP (operands[1], 0) = reg;
6138 if (flag_pic && TARGET_SH2
6139 && GET_CODE (operands[1]) == MEM
6140 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6142 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6147 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6149 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6153 (define_insn "sibcalli"
6154 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6155 (match_operand 1 "" ""))
6156 (use (reg:PSI FPSCR_REG))
6160 [(set_attr "needs_delay_slot" "yes")
6161 (set (attr "fp_mode")
6162 (if_then_else (eq_attr "fpu_single" "yes")
6163 (const_string "single") (const_string "double")))
6164 (set_attr "type" "jump_ind")])
6166 (define_insn "sibcalli_pcrel"
6167 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6168 (match_operand 1 "" ""))
6169 (use (match_operand 2 "" ""))
6170 (use (reg:PSI FPSCR_REG))
6174 [(set_attr "needs_delay_slot" "yes")
6175 (set (attr "fp_mode")
6176 (if_then_else (eq_attr "fpu_single" "yes")
6177 (const_string "single") (const_string "double")))
6178 (set_attr "type" "jump_ind")])
6180 (define_insn_and_split "sibcall_pcrel"
6181 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6182 (match_operand 1 "" ""))
6183 (use (reg:PSI FPSCR_REG))
6184 (clobber (match_scratch:SI 2 "=k"))
6192 rtx lab = PATTERN (gen_call_site ());
6195 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6196 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6198 SIBLING_CALL_P (call_insn) = 1;
6201 [(set_attr "needs_delay_slot" "yes")
6202 (set (attr "fp_mode")
6203 (if_then_else (eq_attr "fpu_single" "yes")
6204 (const_string "single") (const_string "double")))
6205 (set_attr "type" "jump_ind")])
6207 (define_insn "sibcall_compact"
6208 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6209 (match_operand 1 "" ""))
6211 (use (match_operand:SI 2 "register_operand" "z,x"))
6212 (use (reg:SI R1_REG))
6213 (use (reg:PSI FPSCR_REG))
6214 ;; We want to make sure the `x' above will only match MACH_REG
6215 ;; because sibcall_epilogue may clobber MACL_REG.
6216 (clobber (reg:SI MACL_REG))]
6220 jmp @%0\\n sts %2, r0"
6221 [(set_attr "needs_delay_slot" "yes,no")
6222 (set_attr "length" "2,4")
6223 (set (attr "fp_mode") (const_string "single"))
6224 (set_attr "type" "jump_ind")])
6226 (define_insn "sibcall_media"
6227 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6228 (match_operand 1 "" ""))
6232 [(set_attr "type" "jump_media")])
6234 (define_expand "sibcall"
6236 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6237 (match_operand 1 "" ""))
6238 (match_operand 2 "" "")
6239 (use (reg:PSI FPSCR_REG))
6246 operands[0] = XEXP (operands[0], 0);
6247 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6249 if (! SYMBOL_REF_FLAG (operands[0]))
6251 rtx reg = gen_reg_rtx (Pmode);
6253 /* We must not use GOTPLT for sibcalls, because PIC_REG
6254 must be restored before the PLT code gets to run. */
6255 emit_insn (gen_symGOT2reg (reg, operands[0]));
6260 operands[0] = gen_sym2PIC (operands[0]);
6261 PUT_MODE (operands[0], Pmode);
6264 if (GET_MODE (operands[0]) == SImode)
6266 if (GET_CODE (operands[0]) == REG)
6267 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6268 else if (GET_CODE (operands[0]) == SUBREG)
6270 operands[0] = SUBREG_REG (operands[0]);
6271 if (GET_MODE (operands[0]) != DImode)
6272 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6276 operands[0] = shallow_copy_rtx (operands[0]);
6277 PUT_MODE (operands[0], DImode);
6280 if (! target_reg_operand (operands[0], DImode))
6281 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6282 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6285 else if (TARGET_SHCOMPACT && operands[2]
6286 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6288 rtx cookie_rtx = operands[2];
6289 long cookie = INTVAL (cookie_rtx);
6290 rtx func = XEXP (operands[0], 0);
6295 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6297 rtx reg = gen_reg_rtx (Pmode);
6299 emit_insn (gen_symGOT2reg (reg, func));
6303 func = legitimize_pic_address (func, Pmode, 0);
6306 /* FIXME: if we could tell whether all argument registers are
6307 already taken, we could decide whether to force the use of
6308 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6309 simple way to tell. We could use the CALL_COOKIE, but we
6310 can't currently tell a register used for regular argument
6311 passing from one that is unused. If we leave it up to reload
6312 to decide which register to use, it seems to always choose
6313 R0_REG, which leaves no available registers in SIBCALL_REGS
6314 to hold the address of the trampoline. */
6315 mach = gen_rtx_REG (SImode, MACH_REG);
6316 r1 = gen_rtx_REG (SImode, R1_REG);
6318 /* Since such a call function may use all call-clobbered
6319 registers, we force a mode switch earlier, so that we don't
6320 run out of registers when adjusting fpscr for the call. */
6321 emit_insn (gen_force_mode_for_call ());
6323 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6324 \"__GCC_shcompact_call_trampoline\");
6327 rtx reg = gen_reg_rtx (Pmode);
6329 emit_insn (gen_symGOT2reg (reg, operands[0]));
6332 operands[0] = force_reg (SImode, operands[0]);
6334 /* We don't need a return trampoline, since the callee will
6335 return directly to the upper caller. */
6336 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6338 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6339 cookie_rtx = GEN_INT (cookie);
6342 emit_move_insn (mach, func);
6343 emit_move_insn (r1, cookie_rtx);
6345 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6348 else if (TARGET_SHCOMPACT && flag_pic
6349 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6350 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6352 rtx reg = gen_reg_rtx (Pmode);
6354 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6355 XEXP (operands[0], 0) = reg;
6357 if (flag_pic && TARGET_SH2
6358 && GET_CODE (operands[0]) == MEM
6359 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6360 /* The PLT needs the PIC register, but the epilogue would have
6361 to restore it, so we can only use PC-relative PIC calls for
6362 static functions. */
6363 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6365 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6369 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6371 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6375 (define_expand "sibcall_value"
6376 [(set (match_operand 0 "" "")
6377 (call (match_operand 1 "" "")
6378 (match_operand 2 "" "")))
6379 (match_operand 3 "" "")]
6383 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6387 (define_insn "call_value_pop_compact"
6388 [(set (match_operand 0 "" "=rf")
6389 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6390 (match_operand 2 "" "")))
6391 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392 (match_operand 4 "immediate_operand" "n")))
6393 (match_operand 3 "immediate_operand" "n")
6394 (use (reg:SI R0_REG))
6395 (use (reg:SI R1_REG))
6396 (use (reg:PSI FPSCR_REG))
6397 (clobber (reg:SI PR_REG))]
6398 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6400 [(set_attr "type" "call")
6401 (set (attr "fp_mode")
6402 (if_then_else (eq_attr "fpu_single" "yes")
6403 (const_string "single") (const_string "double")))
6404 (set_attr "needs_delay_slot" "yes")])
6406 (define_insn "call_value_pop_compact_rettramp"
6407 [(set (match_operand 0 "" "=rf")
6408 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6409 (match_operand 2 "" "")))
6410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6411 (match_operand 4 "immediate_operand" "n")))
6412 (match_operand 3 "immediate_operand" "n")
6413 (use (reg:SI R0_REG))
6414 (use (reg:SI R1_REG))
6415 (use (reg:PSI FPSCR_REG))
6416 (clobber (reg:SI R10_REG))
6417 (clobber (reg:SI PR_REG))]
6418 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6420 [(set_attr "type" "call")
6421 (set (attr "fp_mode")
6422 (if_then_else (eq_attr "fpu_single" "yes")
6423 (const_string "single") (const_string "double")))
6424 (set_attr "needs_delay_slot" "yes")])
6426 (define_expand "call_value_pop"
6427 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6428 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6429 (match_operand 2 "" "")))
6430 (match_operand 3 "" "")
6431 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6432 (match_operand 4 "" "")))])]
6436 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6438 rtx cookie_rtx = operands[3];
6439 long cookie = INTVAL (cookie_rtx);
6440 rtx func = XEXP (operands[1], 0);
6445 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6447 rtx reg = gen_reg_rtx (Pmode);
6449 emit_insn (gen_symGOTPLT2reg (reg, func));
6453 func = legitimize_pic_address (func, Pmode, 0);
6456 r0 = gen_rtx_REG (SImode, R0_REG);
6457 r1 = gen_rtx_REG (SImode, R1_REG);
6459 /* Since such a call function may use all call-clobbered
6460 registers, we force a mode switch earlier, so that we don't
6461 run out of registers when adjusting fpscr for the call. */
6462 emit_insn (gen_force_mode_for_call ());
6464 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6465 \"__GCC_shcompact_call_trampoline\");
6468 rtx reg = gen_reg_rtx (Pmode);
6470 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6473 operands[1] = force_reg (SImode, operands[1]);
6475 emit_move_insn (r0, func);
6476 emit_move_insn (r1, cookie_rtx);
6478 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6479 emit_call_insn (gen_call_value_pop_compact_rettramp
6480 (operands[0], operands[1], operands[2],
6481 operands[3], operands[4]));
6483 emit_call_insn (gen_call_value_pop_compact
6484 (operands[0], operands[1], operands[2],
6485 operands[3], operands[4]));
6493 (define_expand "sibcall_epilogue"
6498 sh_expand_epilogue ();
6499 if (TARGET_SHCOMPACT)
6503 /* If epilogue clobbers r0, preserve it in macl. */
6504 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6505 if ((set = single_set (insn))
6506 && GET_CODE (SET_DEST (set)) == REG
6507 && REGNO (SET_DEST (set)) == R0_REG)
6509 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6510 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6513 /* We can't tell at this point whether the sibcall is a
6514 sibcall_compact and, if it is, whether it uses r0 or
6515 mach as operand 2, so let the instructions that
6516 preserve r0 be optimized away if r0 turns out to be
6518 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6519 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6521 i = emit_move_insn (r0, tmp);
6522 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6530 (define_insn "indirect_jump_compact"
6532 (match_operand:SI 0 "arith_reg_operand" "r"))]
6535 [(set_attr "needs_delay_slot" "yes")
6536 (set_attr "type" "jump_ind")])
6538 (define_expand "indirect_jump"
6540 (match_operand 0 "register_operand" ""))]
6544 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6545 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6548 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6549 ;; which can be present in structured code from indirect jumps which can not
6550 ;; be present in structured code. This allows -fprofile-arcs to work.
6552 ;; For SH1 processors.
6553 (define_insn "casesi_jump_1"
6555 (match_operand:SI 0 "register_operand" "r"))
6556 (use (label_ref (match_operand 1 "" "")))]
6559 [(set_attr "needs_delay_slot" "yes")
6560 (set_attr "type" "jump_ind")])
6562 ;; For all later processors.
6563 (define_insn "casesi_jump_2"
6564 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6565 (label_ref (match_operand 1 "" ""))))
6566 (use (label_ref (match_operand 2 "" "")))]
6568 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6570 [(set_attr "needs_delay_slot" "yes")
6571 (set_attr "type" "jump_ind")])
6573 (define_insn "casesi_jump_media"
6574 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6575 (use (label_ref (match_operand 1 "" "")))]
6578 [(set_attr "type" "jump_media")])
6580 ;; Call subroutine returning any type.
6581 ;; ??? This probably doesn't work.
6583 (define_expand "untyped_call"
6584 [(parallel [(call (match_operand 0 "" "")
6586 (match_operand 1 "" "")
6587 (match_operand 2 "" "")])]
6588 "TARGET_SH3E || TARGET_SHMEDIA"
6593 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6595 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6597 rtx set = XVECEXP (operands[2], 0, i);
6598 emit_move_insn (SET_DEST (set), SET_SRC (set));
6601 /* The optimizer does not know that the call sets the function value
6602 registers we stored in the result block. We avoid problems by
6603 claiming that all hard registers are used and clobbered at this
6605 emit_insn (gen_blockage ());
6610 ;; ------------------------------------------------------------------------
6612 ;; ------------------------------------------------------------------------
6615 [(set (reg:SI T_REG)
6616 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6617 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6620 [(set_attr "type" "arith")])
6627 ;; Load address of a label. This is only generated by the casesi expand,
6628 ;; and by machine_dependent_reorg (fixing up fp moves).
6629 ;; This must use unspec, because this only works for labels that are
6633 [(set (reg:SI R0_REG)
6634 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6637 [(set_attr "in_delay_slot" "no")
6638 (set_attr "type" "arith")])
6640 ;; machine_dependent_reorg() will make this a `mova'.
6641 (define_insn "mova_const"
6642 [(set (reg:SI R0_REG)
6643 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6646 [(set_attr "in_delay_slot" "no")
6647 (set_attr "type" "arith")])
6649 (define_expand "GOTaddr2picreg"
6650 [(set (reg:SI R0_REG)
6651 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6653 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6654 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6657 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6658 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6661 operands[1] = gen_datalabel_ref (operands[1]);
6665 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6666 rtx dipic = operands[0];
6667 rtx lab = PATTERN (gen_call_site ());
6670 equiv = operands[1];
6671 operands[1] = gen_rtx_MINUS (DImode,
6675 gen_rtx_MINUS (DImode,
6676 gen_rtx_CONST (DImode,
6679 operands[1] = gen_sym2PIC (operands[1]);
6680 PUT_MODE (operands[1], DImode);
6682 if (GET_MODE (dipic) != DImode)
6683 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6685 if (TARGET_SHMEDIA64)
6686 emit_insn (gen_movdi_const (dipic, operands[1]));
6688 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6690 emit_insn (gen_ptrel (tr, dipic, lab));
6692 if (GET_MODE (operands[0]) != GET_MODE (tr))
6693 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6695 insn = emit_move_insn (operands[0], tr);
6697 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6705 ;; When generating PIC, we must match label_refs especially, because
6706 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6707 ;; them to do, because they can't be loaded directly into
6708 ;; non-branch-target registers.
6710 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6711 (match_operand:DI 1 "" "T"))]
6712 "TARGET_SHMEDIA && flag_pic
6713 && EXTRA_CONSTRAINT_T (operands[1])"
6715 [(set_attr "type" "pt_media")
6716 (set_attr "length" "*")])
6719 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6720 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6721 UNSPEC_DATALABEL)))]
6722 "TARGET_SHMEDIA && flag_pic
6723 && EXTRA_CONSTRAINT_T (operands[1])"
6724 "ptb/u datalabel %1, %0"
6725 [(set_attr "type" "pt_media")
6726 (set_attr "length" "*")])
6728 (define_insn "ptrel"
6729 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6730 (plus:DI (match_operand:DI 1 "register_operand" "r")
6732 (match_operand:DI 2 "" "")]
6734 "%O2: ptrel/u %1, %0"
6735 [(set_attr "type" "ptabs_media")])
6737 (define_expand "builtin_setjmp_receiver"
6738 [(match_operand 0 "" "")]
6742 emit_insn (gen_GOTaddr2picreg ());
6746 (define_expand "call_site"
6747 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6751 static HOST_WIDE_INT i = 0;
6752 operands[0] = GEN_INT (i);
6756 (define_expand "sym_label2reg"
6757 [(set (match_operand:SI 0 "" "")
6760 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6763 (match_operand:SI 2 "" "")
6767 (define_expand "symGOT_load"
6768 [(set (match_dup 2) (match_operand 1 "" ""))
6769 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6770 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6776 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6777 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6781 rtx reg = operands[2];
6783 if (GET_MODE (reg) != DImode)
6784 reg = gen_rtx_SUBREG (DImode, reg, 0);
6787 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6789 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6792 emit_move_insn (operands[2], operands[1]);
6794 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6796 gen_rtx_REG (Pmode, PIC_REG)));
6798 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6800 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6807 (define_expand "sym2GOT"
6808 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6812 (define_expand "symGOT2reg"
6813 [(match_operand 0 "" "") (match_operand 1 "" "")]
6819 gotsym = gen_sym2GOT (operands[1]);
6820 PUT_MODE (gotsym, Pmode);
6821 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6823 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6828 (define_expand "sym2GOTPLT"
6829 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6833 (define_expand "symGOTPLT2reg"
6834 [(match_operand 0 "" "") (match_operand 1 "" "")]
6838 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6842 (define_expand "sym2GOTOFF"
6843 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6847 (define_expand "symGOTOFF2reg"
6848 [(match_operand 0 "" "") (match_operand 1 "" "")]
6852 rtx gotoffsym, insn;
6853 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6855 gotoffsym = gen_sym2GOTOFF (operands[1]);
6856 PUT_MODE (gotoffsym, Pmode);
6857 emit_move_insn (t, gotoffsym);
6858 insn = emit_move_insn (operands[0],
6859 gen_rtx_PLUS (Pmode, t,
6860 gen_rtx_REG (Pmode, PIC_REG)));
6862 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6868 (define_expand "symPLT_label2reg"
6869 [(set (match_operand:SI 0 "" "")
6872 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6876 (match_operand:SI 2 "" "")
6878 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6879 ;; Even though the PIC register is not really used by the call
6880 ;; sequence in which this is expanded, the PLT code assumes the PIC
6881 ;; register is set, so we must not skip its initialization. Since
6882 ;; we only use this expand as part of calling sequences, and never
6883 ;; to take the address of a function, this is the best point to
6884 ;; insert the (use). Using the PLT to take the address of a
6885 ;; function would be wrong, not only because the PLT entry could
6886 ;; then be called from a function that doesn't initialize the PIC
6887 ;; register to the proper GOT, but also because pointers to the
6888 ;; same function might not compare equal, should they be set by
6889 ;; different shared libraries.
6890 (use (reg:SI PIC_REG))]
6894 (define_expand "sym2PIC"
6895 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6899 ;; case instruction for switch statements.
6901 ;; Operand 0 is index
6902 ;; operand 1 is the minimum bound
6903 ;; operand 2 is the maximum bound - minimum bound + 1
6904 ;; operand 3 is CODE_LABEL for the table;
6905 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6907 (define_expand "casesi"
6908 [(match_operand:SI 0 "arith_reg_operand" "")
6909 (match_operand:SI 1 "arith_reg_operand" "")
6910 (match_operand:SI 2 "arith_reg_operand" "")
6911 (match_operand 3 "" "") (match_operand 4 "" "")]
6915 rtx reg = gen_reg_rtx (SImode);
6916 rtx reg2 = gen_reg_rtx (SImode);
6919 rtx reg = gen_reg_rtx (DImode);
6920 rtx reg2 = gen_reg_rtx (DImode);
6921 rtx reg3 = gen_reg_rtx (DImode);
6922 rtx reg4 = gen_reg_rtx (DImode);
6923 rtx reg5 = gen_reg_rtx (DImode);
6925 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6926 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6927 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6929 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6930 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6931 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6932 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6933 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6934 (DImode, operands[3])));
6935 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6936 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6937 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6941 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6942 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6943 /* If optimizing, casesi_worker depends on the mode of the instruction
6944 before label it 'uses' - operands[3]. */
6945 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6947 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6949 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6951 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6952 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6953 operands[3], but to lab. We will fix this up in
6954 machine_dependent_reorg. */
6959 (define_expand "casesi_0"
6960 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6961 (set (match_dup 4) (minus:SI (match_dup 4)
6962 (match_operand:SI 1 "arith_operand" "")))
6964 (gtu:SI (match_dup 4)
6965 (match_operand:SI 2 "arith_reg_operand" "")))
6967 (if_then_else (ne (reg:SI T_REG)
6969 (label_ref (match_operand 3 "" ""))
6974 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6975 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6976 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6978 (define_insn "casesi_worker_0"
6979 [(set (match_operand:SI 0 "register_operand" "=r,r")
6980 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6981 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6982 (clobber (match_scratch:SI 3 "=X,1"))
6983 (clobber (match_scratch:SI 4 "=&z,z"))]
6988 [(set (match_operand:SI 0 "register_operand" "")
6989 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6990 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6991 (clobber (match_scratch:SI 3 ""))
6992 (clobber (match_scratch:SI 4 ""))]
6993 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6994 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6995 (parallel [(set (match_dup 0)
6996 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6997 (label_ref (match_dup 2))] UNSPEC_CASESI))
6998 (clobber (match_dup 3))])
6999 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7000 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7003 [(set (match_operand:SI 0 "register_operand" "")
7004 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7005 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7006 (clobber (match_scratch:SI 3 ""))
7007 (clobber (match_scratch:SI 4 ""))]
7008 "TARGET_SH2 && reload_completed"
7009 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7010 (parallel [(set (match_dup 0)
7011 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7012 (label_ref (match_dup 2))] UNSPEC_CASESI))
7013 (clobber (match_dup 3))])]
7014 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7016 (define_insn "*casesi_worker"
7017 [(set (match_operand:SI 0 "register_operand" "=r,r")
7018 (unspec:SI [(reg:SI R0_REG)
7019 (match_operand:SI 1 "register_operand" "0,r")
7020 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7021 (clobber (match_scratch:SI 3 "=X,1"))]
7025 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7027 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7030 switch (GET_MODE (diff_vec))
7033 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7035 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7037 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7038 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7039 return \"mov.b @(r0,%1),%0\";
7044 [(set_attr "length" "4")])
7046 (define_insn "casesi_shift_media"
7047 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7048 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7049 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7054 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7056 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7059 switch (GET_MODE (diff_vec))
7062 return \"shlli %1, 2, %0\";
7064 return \"shlli %1, 1, %0\";
7066 if (rtx_equal_p (operands[0], operands[1]))
7068 return \"add %1, r63, %0\";
7073 [(set_attr "type" "arith_media")])
7075 (define_insn "casesi_load_media"
7076 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7077 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7078 (match_operand 2 "arith_reg_operand" "r")
7079 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7083 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7085 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7088 switch (GET_MODE (diff_vec))
7091 return \"ldx.l %1, %2, %0\";
7094 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7095 return \"ldx.uw %1, %2, %0\";
7097 return \"ldx.w %1, %2, %0\";
7099 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7100 return \"ldx.ub %1, %2, %0\";
7101 return \"ldx.b %1, %2, %0\";
7106 [(set_attr "type" "load_media")])
7108 (define_expand "return"
7110 "reload_completed && ! sh_need_epilogue ()"
7115 emit_jump_insn (gen_return_media ());
7119 if (TARGET_SHCOMPACT
7120 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7122 emit_jump_insn (gen_shcompact_return_tramp ());
7127 (define_insn "*return_i"
7129 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7130 && (current_function_args_info.call_cookie
7131 & CALL_COOKIE_RET_TRAMP (1)))
7132 && reload_completed"
7134 [(set_attr "type" "return")
7135 (set_attr "needs_delay_slot" "yes")])
7137 (define_expand "shcompact_return_tramp"
7140 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7143 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7144 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7145 \"__GCC_shcompact_return_trampoline\");
7148 emit_insn (gen_symGOTPLT2reg (reg, sym));
7150 emit_move_insn (reg, sym);
7152 emit_jump_insn (gen_shcompact_return_tramp_i ());
7156 (define_insn "shcompact_return_tramp_i"
7157 [(parallel [(return) (use (reg:SI R0_REG))])]
7159 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7161 [(set_attr "type" "jump_ind")
7162 (set_attr "needs_delay_slot" "yes")])
7164 (define_insn "return_media_i"
7165 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7166 "TARGET_SHMEDIA && reload_completed"
7168 [(set_attr "type" "jump_media")])
7170 (define_expand "return_media"
7172 "TARGET_SHMEDIA && reload_completed"
7175 int tr_regno = sh_media_register_for_return ();
7180 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7183 tr = gen_rtx_REG (DImode, tr_regno);
7184 emit_move_insn (tr, r18);
7187 tr = gen_rtx_REG (DImode, tr_regno);
7189 emit_jump_insn (gen_return_media_i (tr));
7193 (define_insn "shcompact_preserve_incoming_args"
7194 [(set (match_operand:SI 0 "register_operand" "+r")
7195 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7198 [(set_attr "length" "0")])
7200 (define_insn "shcompact_incoming_args"
7201 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7202 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7203 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7204 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7205 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7206 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7207 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7208 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7209 (set (mem:BLK (reg:SI MACL_REG))
7210 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7211 (use (reg:SI R0_REG))
7212 (clobber (reg:SI R0_REG))
7213 (clobber (reg:SI MACL_REG))
7214 (clobber (reg:SI MACH_REG))
7215 (clobber (reg:SI PR_REG))]
7218 [(set_attr "needs_delay_slot" "yes")])
7220 (define_insn "shmedia_save_restore_regs_compact"
7221 [(set (reg:SI SP_REG)
7222 (plus:SI (reg:SI SP_REG)
7223 (match_operand:SI 0 "immediate_operand" "i")))
7224 (use (reg:SI R0_REG))
7225 (clobber (reg:SI PR_REG))]
7227 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7228 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7230 [(set_attr "needs_delay_slot" "yes")])
7232 (define_expand "prologue"
7235 "sh_expand_prologue (); DONE;")
7237 (define_expand "epilogue"
7242 sh_expand_epilogue ();
7243 emit_jump_insn (gen_return ());
7247 (define_insn "blockage"
7248 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7251 [(set_attr "length" "0")])
7253 ;; ------------------------------------------------------------------------
7255 ;; ------------------------------------------------------------------------
7258 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7259 (eq:SI (reg:SI T_REG) (const_int 1)))]
7262 [(set_attr "type" "arith")])
7264 (define_expand "seq"
7265 [(set (match_operand:SI 0 "arith_reg_operand" "")
7272 if (GET_MODE (operands[0]) != DImode)
7273 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7274 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7275 if (sh_compare_op1 != const0_rtx)
7276 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7277 ? GET_MODE (sh_compare_op0)
7278 : GET_MODE (sh_compare_op1),
7281 switch (GET_MODE (sh_compare_op0))
7284 emit_insn (gen_cmpeqdi_media (operands[0],
7285 sh_compare_op0, sh_compare_op1));
7289 if (! TARGET_SHMEDIA_FPU)
7291 emit_insn (gen_cmpeqsf_media (operands[0],
7292 sh_compare_op0, sh_compare_op1));
7296 if (! TARGET_SHMEDIA_FPU)
7298 emit_insn (gen_cmpeqdf_media (operands[0],
7299 sh_compare_op0, sh_compare_op1));
7307 operands[1] = prepare_scc_operands (EQ);
7310 (define_expand "slt"
7311 [(set (match_operand:SI 0 "arith_reg_operand" "")
7318 if (GET_MODE (operands[0]) != DImode)
7319 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7320 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7321 if (sh_compare_op1 != const0_rtx)
7322 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7323 ? GET_MODE (sh_compare_op0)
7324 : GET_MODE (sh_compare_op1),
7327 switch (GET_MODE (sh_compare_op0))
7330 emit_insn (gen_cmpgtdi_media (operands[0],
7331 sh_compare_op1, sh_compare_op0));
7335 if (! TARGET_SHMEDIA_FPU)
7337 emit_insn (gen_cmpgtsf_media (operands[0],
7338 sh_compare_op1, sh_compare_op0));
7342 if (! TARGET_SHMEDIA_FPU)
7344 emit_insn (gen_cmpgtdf_media (operands[0],
7345 sh_compare_op1, sh_compare_op0));
7353 operands[1] = prepare_scc_operands (LT);
7356 (define_expand "sle"
7357 [(match_operand:SI 0 "arith_reg_operand" "")]
7361 rtx tmp = sh_compare_op0;
7365 if (GET_MODE (operands[0]) != DImode)
7366 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7367 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7368 if (sh_compare_op1 != const0_rtx)
7369 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7370 ? GET_MODE (sh_compare_op0)
7371 : GET_MODE (sh_compare_op1),
7374 switch (GET_MODE (sh_compare_op0))
7378 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7380 emit_insn (gen_cmpgtdi_media (tmp,
7381 sh_compare_op0, sh_compare_op1));
7382 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7387 if (! TARGET_SHMEDIA_FPU)
7389 emit_insn (gen_cmpgesf_media (operands[0],
7390 sh_compare_op1, sh_compare_op0));
7394 if (! TARGET_SHMEDIA_FPU)
7396 emit_insn (gen_cmpgedf_media (operands[0],
7397 sh_compare_op1, sh_compare_op0));
7406 sh_compare_op0 = sh_compare_op1;
7407 sh_compare_op1 = tmp;
7408 emit_insn (gen_sge (operands[0]));
7412 (define_expand "sgt"
7413 [(set (match_operand:SI 0 "arith_reg_operand" "")
7420 if (GET_MODE (operands[0]) != DImode)
7421 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7422 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7423 if (sh_compare_op1 != const0_rtx)
7424 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7425 ? GET_MODE (sh_compare_op0)
7426 : GET_MODE (sh_compare_op1),
7429 switch (GET_MODE (sh_compare_op0))
7432 emit_insn (gen_cmpgtdi_media (operands[0],
7433 sh_compare_op0, sh_compare_op1));
7437 if (! TARGET_SHMEDIA_FPU)
7439 emit_insn (gen_cmpgtsf_media (operands[0],
7440 sh_compare_op0, sh_compare_op1));
7444 if (! TARGET_SHMEDIA_FPU)
7446 emit_insn (gen_cmpgtdf_media (operands[0],
7447 sh_compare_op0, sh_compare_op1));
7455 operands[1] = prepare_scc_operands (GT);
7458 (define_expand "sge"
7459 [(set (match_operand:SI 0 "arith_reg_operand" "")
7466 if (GET_MODE (operands[0]) != DImode)
7467 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7468 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7469 if (sh_compare_op1 != const0_rtx)
7470 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7471 ? GET_MODE (sh_compare_op0)
7472 : GET_MODE (sh_compare_op1),
7475 switch (GET_MODE (sh_compare_op0))
7479 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7481 emit_insn (gen_cmpgtdi_media (tmp,
7482 sh_compare_op1, sh_compare_op0));
7483 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7488 if (! TARGET_SHMEDIA_FPU)
7490 emit_insn (gen_cmpgesf_media (operands[0],
7491 sh_compare_op0, sh_compare_op1));
7495 if (! TARGET_SHMEDIA_FPU)
7497 emit_insn (gen_cmpgedf_media (operands[0],
7498 sh_compare_op0, sh_compare_op1));
7507 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7511 rtx lab = gen_label_rtx ();
7512 prepare_scc_operands (EQ);
7513 emit_jump_insn (gen_branch_true (lab));
7514 prepare_scc_operands (GT);
7516 emit_insn (gen_movt (operands[0]));
7519 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7522 operands[1] = prepare_scc_operands (GE);
7525 (define_expand "sgtu"
7526 [(set (match_operand:SI 0 "arith_reg_operand" "")
7533 if (GET_MODE (operands[0]) != DImode)
7534 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7535 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7536 if (sh_compare_op1 != const0_rtx)
7537 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7538 ? GET_MODE (sh_compare_op0)
7539 : GET_MODE (sh_compare_op1),
7542 emit_insn (gen_cmpgtudi_media (operands[0],
7543 sh_compare_op0, sh_compare_op1));
7546 operands[1] = prepare_scc_operands (GTU);
7549 (define_expand "sltu"
7550 [(set (match_operand:SI 0 "arith_reg_operand" "")
7557 if (GET_MODE (operands[0]) != DImode)
7558 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7559 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7560 if (sh_compare_op1 != const0_rtx)
7561 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7562 ? GET_MODE (sh_compare_op0)
7563 : GET_MODE (sh_compare_op1),
7566 emit_insn (gen_cmpgtudi_media (operands[0],
7567 sh_compare_op1, sh_compare_op0));
7570 operands[1] = prepare_scc_operands (LTU);
7573 (define_expand "sleu"
7574 [(set (match_operand:SI 0 "arith_reg_operand" "")
7583 if (GET_MODE (operands[0]) != DImode)
7584 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7585 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7586 if (sh_compare_op1 != const0_rtx)
7587 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7588 ? GET_MODE (sh_compare_op0)
7589 : GET_MODE (sh_compare_op1),
7592 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7594 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7595 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7599 operands[1] = prepare_scc_operands (LEU);
7602 (define_expand "sgeu"
7603 [(set (match_operand:SI 0 "arith_reg_operand" "")
7612 if (GET_MODE (operands[0]) != DImode)
7613 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7614 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7615 if (sh_compare_op1 != const0_rtx)
7616 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7617 ? GET_MODE (sh_compare_op0)
7618 : GET_MODE (sh_compare_op1),
7621 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7623 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7624 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7629 operands[1] = prepare_scc_operands (GEU);
7632 ;; sne moves the complement of the T reg to DEST like this:
7636 ;; This is better than xoring compare result with 1 because it does
7637 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7640 (define_expand "sne"
7641 [(set (match_dup 2) (const_int -1))
7642 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7643 (neg:SI (plus:SI (match_dup 1)
7646 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7655 if (GET_MODE (operands[0]) != DImode)
7656 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7658 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7661 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7662 if (sh_compare_op1 != const0_rtx)
7663 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7664 ? GET_MODE (sh_compare_op0)
7665 : GET_MODE (sh_compare_op1),
7668 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7670 emit_insn (gen_seq (tmp));
7671 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7676 operands[1] = prepare_scc_operands (EQ);
7677 operands[2] = gen_reg_rtx (SImode);
7680 (define_expand "sunordered"
7681 [(set (match_operand:DI 0 "arith_reg_operand" "")
7682 (unordered:DI (match_dup 1) (match_dup 2)))]
7683 "TARGET_SHMEDIA_FPU"
7686 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7687 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7690 ;; Use the same trick for FP sle / sge
7691 (define_expand "movnegt"
7692 [(set (match_dup 2) (const_int -1))
7693 (parallel [(set (match_operand 0 "" "")
7694 (neg:SI (plus:SI (match_dup 1)
7697 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7700 "operands[2] = gen_reg_rtx (SImode);")
7702 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7703 ;; This prevents a regression that occurred when we switched from xor to
7707 [(set (match_operand:SI 0 "arith_reg_operand" "")
7708 (plus:SI (reg:SI T_REG)
7711 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7712 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7715 ;; -------------------------------------------------------------------------
7716 ;; Instructions to cope with inline literal tables
7717 ;; -------------------------------------------------------------------------
7719 ; 2 byte integer in line
7721 (define_insn "consttable_2"
7722 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7723 (match_operand 1 "" "")]
7728 if (operands[1] != const0_rtx)
7729 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7732 [(set_attr "length" "2")
7733 (set_attr "in_delay_slot" "no")])
7735 ; 4 byte integer in line
7737 (define_insn "consttable_4"
7738 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7739 (match_operand 1 "" "")]
7744 if (operands[1] != const0_rtx)
7745 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7748 [(set_attr "length" "4")
7749 (set_attr "in_delay_slot" "no")])
7751 ; 8 byte integer in line
7753 (define_insn "consttable_8"
7754 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7755 (match_operand 1 "" "")]
7760 if (operands[1] != const0_rtx)
7761 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7764 [(set_attr "length" "8")
7765 (set_attr "in_delay_slot" "no")])
7767 ; 4 byte floating point
7769 (define_insn "consttable_sf"
7770 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7771 (match_operand 1 "" "")]
7776 if (operands[1] != const0_rtx)
7779 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7780 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7784 [(set_attr "length" "4")
7785 (set_attr "in_delay_slot" "no")])
7787 ; 8 byte floating point
7789 (define_insn "consttable_df"
7790 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7791 (match_operand 1 "" "")]
7796 if (operands[1] != const0_rtx)
7799 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7800 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7804 [(set_attr "length" "8")
7805 (set_attr "in_delay_slot" "no")])
7807 ;; Alignment is needed for some constant tables; it may also be added for
7808 ;; Instructions at the start of loops, or after unconditional branches.
7809 ;; ??? We would get more accurate lengths if we did instruction
7810 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7811 ;; here is too conservative.
7813 ; align to a two byte boundary
7815 (define_expand "align_2"
7816 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7820 ; align to a four byte boundary
7821 ;; align_4 and align_log are instructions for the starts of loops, or
7822 ;; after unconditional branches, which may take up extra room.
7824 (define_expand "align_4"
7825 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7829 ; align to a cache line boundary
7831 (define_insn "align_log"
7832 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7835 [(set_attr "length" "0")
7836 (set_attr "in_delay_slot" "no")])
7838 ; emitted at the end of the literal table, used to emit the
7839 ; 32bit branch labels if needed.
7841 (define_insn "consttable_end"
7842 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7844 "* return output_jump_label_table ();"
7845 [(set_attr "in_delay_slot" "no")])
7847 ; emitted at the end of the window in the literal table.
7849 (define_insn "consttable_window_end"
7850 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7853 [(set_attr "length" "0")
7854 (set_attr "in_delay_slot" "no")])
7856 ;; -------------------------------------------------------------------------
7858 ;; -------------------------------------------------------------------------
7860 ;; String/block move insn.
7862 (define_expand "movstrsi"
7863 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7864 (mem:BLK (match_operand:BLK 1 "" "")))
7865 (use (match_operand:SI 2 "nonmemory_operand" ""))
7866 (use (match_operand:SI 3 "immediate_operand" ""))
7867 (clobber (reg:SI PR_REG))
7868 (clobber (reg:SI R4_REG))
7869 (clobber (reg:SI R5_REG))
7870 (clobber (reg:SI R0_REG))])]
7871 "TARGET_SH1 && ! TARGET_SH5"
7874 if(expand_block_move (operands))
7879 (define_insn "block_move_real"
7880 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7881 (mem:BLK (reg:SI R5_REG)))
7882 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7883 (clobber (reg:SI PR_REG))
7884 (clobber (reg:SI R0_REG))])]
7885 "TARGET_SH1 && ! TARGET_HARD_SH4"
7887 [(set_attr "type" "sfunc")
7888 (set_attr "needs_delay_slot" "yes")])
7890 (define_insn "block_lump_real"
7891 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7892 (mem:BLK (reg:SI R5_REG)))
7893 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7894 (use (reg:SI R6_REG))
7895 (clobber (reg:SI PR_REG))
7896 (clobber (reg:SI T_REG))
7897 (clobber (reg:SI R4_REG))
7898 (clobber (reg:SI R5_REG))
7899 (clobber (reg:SI R6_REG))
7900 (clobber (reg:SI R0_REG))])]
7901 "TARGET_SH1 && ! TARGET_HARD_SH4"
7903 [(set_attr "type" "sfunc")
7904 (set_attr "needs_delay_slot" "yes")])
7906 (define_insn "block_move_real_i4"
7907 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7908 (mem:BLK (reg:SI R5_REG)))
7909 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7910 (clobber (reg:SI PR_REG))
7911 (clobber (reg:SI R0_REG))
7912 (clobber (reg:SI R1_REG))
7913 (clobber (reg:SI R2_REG))])]
7916 [(set_attr "type" "sfunc")
7917 (set_attr "needs_delay_slot" "yes")])
7919 (define_insn "block_lump_real_i4"
7920 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7921 (mem:BLK (reg:SI R5_REG)))
7922 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7923 (use (reg:SI R6_REG))
7924 (clobber (reg:SI PR_REG))
7925 (clobber (reg:SI T_REG))
7926 (clobber (reg:SI R4_REG))
7927 (clobber (reg:SI R5_REG))
7928 (clobber (reg:SI R6_REG))
7929 (clobber (reg:SI R0_REG))
7930 (clobber (reg:SI R1_REG))
7931 (clobber (reg:SI R2_REG))
7932 (clobber (reg:SI R3_REG))])]
7935 [(set_attr "type" "sfunc")
7936 (set_attr "needs_delay_slot" "yes")])
7938 ;; -------------------------------------------------------------------------
7939 ;; Floating point instructions.
7940 ;; -------------------------------------------------------------------------
7942 ;; ??? All patterns should have a type attribute.
7944 (define_expand "fpu_switch0"
7945 [(set (match_operand:SI 0 "" "") (match_dup 2))
7946 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7950 operands[1] = get_fpscr_rtx ();
7951 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7953 operands[2] = legitimize_pic_address (operands[2], SImode,
7954 no_new_pseudos ? operands[0] : 0);
7957 (define_expand "fpu_switch1"
7958 [(set (match_operand:SI 0 "" "") (match_dup 2))
7959 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7960 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7964 operands[1] = get_fpscr_rtx ();
7965 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7967 operands[2] = legitimize_pic_address (operands[2], SImode,
7968 no_new_pseudos ? operands[0] : 0);
7969 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7972 (define_expand "movpsi"
7973 [(set (match_operand:PSI 0 "register_operand" "")
7974 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7978 ;; The c / m alternative is a fake to guide reload to load directly into
7979 ;; fpscr, since reload doesn't know how to use post-increment.
7980 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7981 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7982 ;; predicate after reload.
7983 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
7984 ;; like a gpr <-> fpul move.
7985 (define_insn "fpu_switch"
7986 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7987 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7989 && (! reload_completed
7990 || true_regnum (operands[0]) != FPSCR_REG
7991 || GET_CODE (operands[1]) != MEM
7992 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7994 ! precision stays the same
8002 [(set_attr "length" "0,2,2,4,2,2,2,2")
8003 (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")
8004 (set_attr "insn_class" "ldsmem_to_fpscr,*,*,lds_to_fpscr,*,*,*,*")])
8007 [(set (reg:PSI FPSCR_REG)
8008 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8009 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8010 [(set (match_dup 0) (match_dup 0))]
8013 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8014 gen_rtx (MEM, PSImode,
8015 gen_rtx (POST_INC, Pmode,
8017 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8021 [(set (reg:PSI FPSCR_REG)
8022 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8024 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8027 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8028 gen_rtx (MEM, PSImode,
8029 gen_rtx (POST_INC, Pmode,
8031 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8034 ;; ??? This uses the fp unit, but has no type indicating that.
8035 ;; If we did that, this would either give a bogus latency or introduce
8036 ;; a bogus FIFO constraint.
8037 ;; Since this insn is currently only used for prologues/epilogues,
8038 ;; it is probably best to claim no function unit, which matches the
8040 (define_insn "toggle_sz"
8041 [(set (reg:PSI FPSCR_REG)
8042 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8046 (define_expand "addsf3"
8047 [(set (match_operand:SF 0 "arith_reg_operand" "")
8048 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8049 (match_operand:SF 2 "arith_reg_operand" "")))]
8050 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8055 expand_sf_binop (&gen_addsf3_i, operands);
8060 (define_insn "*addsf3_media"
8061 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8062 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8063 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8064 "TARGET_SHMEDIA_FPU"
8066 [(set_attr "type" "fparith_media")])
8068 (define_insn_and_split "unary_sf_op"
8069 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8074 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8075 (match_operator:SF 2 "unary_float_operator"
8076 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8077 (parallel [(match_operand 4
8078 "const_int_operand" "n")]))]))
8079 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8080 "TARGET_SHMEDIA_FPU"
8082 "TARGET_SHMEDIA_FPU && reload_completed"
8083 [(set (match_dup 5) (match_dup 6))]
8086 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8087 rtx op1 = gen_rtx_REG (SFmode,
8088 (true_regnum (operands[1])
8089 + (INTVAL (operands[4]) ^ endian)));
8091 operands[7] = gen_rtx_REG (SFmode,
8092 (true_regnum (operands[0])
8093 + (INTVAL (operands[3]) ^ endian)));
8094 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8096 [(set_attr "type" "fparith_media")])
8098 (define_insn_and_split "binary_sf_op"
8099 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8104 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8105 (match_operator:SF 3 "binary_float_operator"
8106 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8107 (parallel [(match_operand 5
8108 "const_int_operand" "n")]))
8109 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8110 (parallel [(match_operand 6
8111 "const_int_operand" "n")]))]))
8112 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8113 "TARGET_SHMEDIA_FPU"
8115 "TARGET_SHMEDIA_FPU && reload_completed"
8116 [(set (match_dup 7) (match_dup 8))]
8119 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8120 rtx op1 = gen_rtx_REG (SFmode,
8121 (true_regnum (operands[1])
8122 + (INTVAL (operands[5]) ^ endian)));
8123 rtx op2 = gen_rtx_REG (SFmode,
8124 (true_regnum (operands[2])
8125 + (INTVAL (operands[6]) ^ endian)));
8127 operands[7] = gen_rtx_REG (SFmode,
8128 (true_regnum (operands[0])
8129 + (INTVAL (operands[4]) ^ endian)));
8130 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8132 [(set_attr "type" "fparith_media")])
8134 (define_insn "addsf3_i"
8135 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8136 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8137 (match_operand:SF 2 "arith_reg_operand" "f")))
8138 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8141 [(set_attr "type" "fp")
8142 (set_attr "fp_mode" "single")])
8144 (define_expand "subsf3"
8145 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8146 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8147 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8148 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8153 expand_sf_binop (&gen_subsf3_i, operands);
8158 (define_insn "*subsf3_media"
8159 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8160 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8161 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8162 "TARGET_SHMEDIA_FPU"
8164 [(set_attr "type" "fparith_media")])
8166 (define_insn "subsf3_i"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8169 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8170 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8173 [(set_attr "type" "fp")
8174 (set_attr "fp_mode" "single")])
8176 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8177 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8178 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8179 ;; SH3E, we use a separate insn for SH3E mulsf3.
8181 (define_expand "mulsf3"
8182 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8183 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8184 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8185 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8189 expand_sf_binop (&gen_mulsf3_i4, operands);
8190 else if (TARGET_SH3E)
8191 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8192 if (! TARGET_SHMEDIA)
8196 (define_insn "*mulsf3_media"
8197 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8198 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8199 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8200 "TARGET_SHMEDIA_FPU"
8202 [(set_attr "type" "fparith_media")])
8204 (define_insn "mulsf3_i4"
8205 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8206 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8207 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8208 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8211 [(set_attr "type" "fp")
8212 (set_attr "fp_mode" "single")])
8214 (define_insn "mulsf3_ie"
8215 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8216 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8217 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8218 "TARGET_SH3E && ! TARGET_SH4"
8220 [(set_attr "type" "fp")])
8222 (define_insn "*mac_media"
8223 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8224 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8225 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8226 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8227 "TARGET_SHMEDIA_FPU"
8229 [(set_attr "type" "fparith_media")])
8231 (define_insn "*macsf3"
8232 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8233 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8234 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8235 (match_operand:SF 3 "arith_reg_operand" "0")))
8236 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8237 "TARGET_SH3E && ! TARGET_SH4"
8239 [(set_attr "type" "fp")
8240 (set_attr "fp_mode" "single")])
8242 (define_expand "divsf3"
8243 [(set (match_operand:SF 0 "arith_reg_operand" "")
8244 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8245 (match_operand:SF 2 "arith_reg_operand" "")))]
8246 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8251 expand_sf_binop (&gen_divsf3_i, operands);
8256 (define_insn "*divsf3_media"
8257 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8258 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8259 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8260 "TARGET_SHMEDIA_FPU"
8262 [(set_attr "type" "fdiv_media")])
8264 (define_insn "divsf3_i"
8265 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8266 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8267 (match_operand:SF 2 "arith_reg_operand" "f")))
8268 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8271 [(set_attr "type" "fdiv")
8272 (set_attr "fp_mode" "single")])
8274 (define_insn "floatdisf2"
8275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8276 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8277 "TARGET_SHMEDIA_FPU"
8279 [(set_attr "type" "fpconv_media")])
8281 (define_expand "floatsisf2"
8282 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8283 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8284 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8289 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8294 (define_insn "*floatsisf2_media"
8295 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8296 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8297 "TARGET_SHMEDIA_FPU"
8299 [(set_attr "type" "fpconv_media")])
8301 (define_insn "floatsisf2_i4"
8302 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8303 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8304 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8307 [(set_attr "type" "fp")
8308 (set_attr "fp_mode" "single")])
8310 (define_insn "*floatsisf2_ie"
8311 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8312 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8313 "TARGET_SH3E && ! TARGET_SH4"
8315 [(set_attr "type" "fp")])
8317 (define_insn "fix_truncsfdi2"
8318 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8319 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8320 "TARGET_SHMEDIA_FPU"
8322 [(set_attr "type" "fpconv_media")])
8324 (define_expand "fix_truncsfsi2"
8325 [(set (match_operand:SI 0 "fpul_operand" "=y")
8326 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8327 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8332 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8337 (define_insn "*fix_truncsfsi2_media"
8338 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8339 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8340 "TARGET_SHMEDIA_FPU"
8342 [(set_attr "type" "fpconv_media")])
8344 (define_insn "fix_truncsfsi2_i4"
8345 [(set (match_operand:SI 0 "fpul_operand" "=y")
8346 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8347 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8350 [(set_attr "type" "fp")
8351 (set_attr "fp_mode" "single")])
8353 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8354 ;; fix_truncsfsi2_i4.
8355 ;; (define_insn "fix_truncsfsi2_i4_2"
8356 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8357 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8358 ;; (use (reg:PSI FPSCR_REG))
8359 ;; (clobber (reg:SI FPUL_REG))]
8362 ;; [(set_attr "length" "4")
8363 ;; (set_attr "fp_mode" "single")])
8366 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8367 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8368 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8369 ;; (clobber (reg:SI FPUL_REG))]
8371 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8372 ;; (use (match_dup 2))])
8373 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8375 (define_insn "*fixsfsi"
8376 [(set (match_operand:SI 0 "fpul_operand" "=y")
8377 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8378 "TARGET_SH3E && ! TARGET_SH4"
8380 [(set_attr "type" "fp")])
8382 (define_insn "cmpgtsf_t"
8383 [(set (reg:SI T_REG)
8384 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8385 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8386 "TARGET_SH3E && ! TARGET_SH4"
8388 [(set_attr "type" "fp")
8389 (set_attr "fp_mode" "single")])
8391 (define_insn "cmpeqsf_t"
8392 [(set (reg:SI T_REG)
8393 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8394 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8395 "TARGET_SH3E && ! TARGET_SH4"
8397 [(set_attr "type" "fp")
8398 (set_attr "fp_mode" "single")])
8400 (define_insn "ieee_ccmpeqsf_t"
8401 [(set (reg:SI T_REG)
8402 (ior:SI (reg:SI T_REG)
8403 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8404 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8405 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8406 "* return output_ieee_ccmpeq (insn, operands);"
8407 [(set_attr "length" "4")])
8410 (define_insn "cmpgtsf_t_i4"
8411 [(set (reg:SI T_REG)
8412 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8413 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8414 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8417 [(set_attr "type" "fp")
8418 (set_attr "fp_mode" "single")])
8420 (define_insn "cmpeqsf_t_i4"
8421 [(set (reg:SI T_REG)
8422 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8423 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8424 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8427 [(set_attr "type" "fp")
8428 (set_attr "fp_mode" "single")])
8430 (define_insn "*ieee_ccmpeqsf_t_4"
8431 [(set (reg:SI T_REG)
8432 (ior:SI (reg:SI T_REG)
8433 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8434 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8435 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8436 "TARGET_IEEE && TARGET_SH4"
8437 "* return output_ieee_ccmpeq (insn, operands);"
8438 [(set_attr "length" "4")
8439 (set_attr "fp_mode" "single")])
8441 (define_insn "cmpeqsf_media"
8442 [(set (match_operand:DI 0 "register_operand" "=r")
8443 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8444 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8445 "TARGET_SHMEDIA_FPU"
8446 "fcmpeq.s %1, %2, %0"
8447 [(set_attr "type" "fcmp_media")])
8449 (define_insn "cmpgtsf_media"
8450 [(set (match_operand:DI 0 "register_operand" "=r")
8451 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8452 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8453 "TARGET_SHMEDIA_FPU"
8454 "fcmpgt.s %1, %2, %0"
8455 [(set_attr "type" "fcmp_media")])
8457 (define_insn "cmpgesf_media"
8458 [(set (match_operand:DI 0 "register_operand" "=r")
8459 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8460 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8461 "TARGET_SHMEDIA_FPU"
8462 "fcmpge.s %1, %2, %0"
8463 [(set_attr "type" "fcmp_media")])
8465 (define_insn "cmpunsf_media"
8466 [(set (match_operand:DI 0 "register_operand" "=r")
8467 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8468 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8469 "TARGET_SHMEDIA_FPU"
8470 "fcmpun.s %1, %2, %0"
8471 [(set_attr "type" "fcmp_media")])
8473 (define_expand "cmpsf"
8474 [(set (reg:SI T_REG)
8475 (compare (match_operand:SF 0 "arith_operand" "")
8476 (match_operand:SF 1 "arith_operand" "")))]
8477 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8480 sh_compare_op0 = operands[0];
8481 sh_compare_op1 = operands[1];
8485 (define_expand "negsf2"
8486 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8487 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8488 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8493 expand_sf_unop (&gen_negsf2_i, operands);
8498 (define_insn "*negsf2_media"
8499 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8500 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8501 "TARGET_SHMEDIA_FPU"
8503 [(set_attr "type" "fmove_media")])
8505 (define_insn "negsf2_i"
8506 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8507 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8508 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8511 [(set_attr "type" "fmove")
8512 (set_attr "fp_mode" "single")])
8514 (define_expand "sqrtsf2"
8515 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8516 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8517 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8522 expand_sf_unop (&gen_sqrtsf2_i, operands);
8527 (define_insn "*sqrtsf2_media"
8528 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8529 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8530 "TARGET_SHMEDIA_FPU"
8532 [(set_attr "type" "fdiv_media")])
8534 (define_insn "sqrtsf2_i"
8535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8536 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8537 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8540 [(set_attr "type" "fdiv")
8541 (set_attr "fp_mode" "single")])
8543 (define_expand "abssf2"
8544 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8545 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8546 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8551 expand_sf_unop (&gen_abssf2_i, operands);
8556 (define_insn "*abssf2_media"
8557 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8558 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8559 "TARGET_SHMEDIA_FPU"
8561 [(set_attr "type" "fmove_media")])
8563 (define_insn "abssf2_i"
8564 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8565 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8566 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8569 [(set_attr "type" "fmove")
8570 (set_attr "fp_mode" "single")])
8572 (define_expand "adddf3"
8573 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8574 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8575 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8576 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8581 expand_df_binop (&gen_adddf3_i, operands);
8586 (define_insn "*adddf3_media"
8587 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8588 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8589 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8590 "TARGET_SHMEDIA_FPU"
8592 [(set_attr "type" "dfparith_media")])
8594 (define_insn "adddf3_i"
8595 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8596 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8597 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8598 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8601 [(set_attr "type" "dfp_arith")
8602 (set_attr "fp_mode" "double")])
8604 (define_expand "subdf3"
8605 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8606 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8607 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8608 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8613 expand_df_binop (&gen_subdf3_i, operands);
8618 (define_insn "*subdf3_media"
8619 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8620 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8621 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8622 "TARGET_SHMEDIA_FPU"
8624 [(set_attr "type" "dfparith_media")])
8626 (define_insn "subdf3_i"
8627 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8628 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8629 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8630 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8633 [(set_attr "type" "dfp_arith")
8634 (set_attr "fp_mode" "double")])
8636 (define_expand "muldf3"
8637 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8638 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8639 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8640 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8645 expand_df_binop (&gen_muldf3_i, operands);
8650 (define_insn "*muldf3_media"
8651 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8652 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8653 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8654 "TARGET_SHMEDIA_FPU"
8656 [(set_attr "type" "dfmul_media")])
8658 (define_insn "muldf3_i"
8659 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8660 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8661 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8662 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8665 [(set_attr "type" "dfp_arith")
8666 (set_attr "fp_mode" "double")])
8668 (define_expand "divdf3"
8669 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8670 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8671 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8672 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8677 expand_df_binop (&gen_divdf3_i, operands);
8682 (define_insn "*divdf3_media"
8683 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8684 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8685 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8686 "TARGET_SHMEDIA_FPU"
8688 [(set_attr "type" "dfdiv_media")])
8690 (define_insn "divdf3_i"
8691 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8692 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8693 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8694 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8697 [(set_attr "type" "dfdiv")
8698 (set_attr "fp_mode" "double")])
8700 (define_insn "floatdidf2"
8701 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8702 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8703 "TARGET_SHMEDIA_FPU"
8705 [(set_attr "type" "dfpconv_media")])
8707 (define_expand "floatsidf2"
8708 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8709 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8710 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8715 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8721 (define_insn "*floatsidf2_media"
8722 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8723 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8724 "TARGET_SHMEDIA_FPU"
8726 [(set_attr "type" "dfpconv_media")])
8728 (define_insn "floatsidf2_i"
8729 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8730 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8731 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8734 [(set_attr "type" "dfp_conv")
8735 (set_attr "fp_mode" "double")])
8737 (define_insn "fix_truncdfdi2"
8738 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8739 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8740 "TARGET_SHMEDIA_FPU"
8742 [(set_attr "type" "dfpconv_media")])
8744 (define_expand "fix_truncdfsi2"
8745 [(set (match_operand:SI 0 "fpul_operand" "")
8746 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8747 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8752 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8758 (define_insn "*fix_truncdfsi2_media"
8759 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8760 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8761 "TARGET_SHMEDIA_FPU"
8763 [(set_attr "type" "dfpconv_media")])
8765 (define_insn "fix_truncdfsi2_i"
8766 [(set (match_operand:SI 0 "fpul_operand" "=y")
8767 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8768 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8771 [(set_attr "type" "dfp_conv")
8772 (set_attr "fp_mode" "double")])
8774 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8775 ;; fix_truncdfsi2_i.
8776 ;; (define_insn "fix_truncdfsi2_i4"
8777 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8778 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8779 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8780 ;; (clobber (reg:SI FPUL_REG))]
8783 ;; [(set_attr "length" "4")
8784 ;; (set_attr "fp_mode" "double")])
8787 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8788 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8789 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8790 ;; (clobber (reg:SI FPUL_REG))]
8792 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8793 ;; (use (match_dup 2))])
8794 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8796 (define_insn "cmpgtdf_t"
8797 [(set (reg:SI T_REG)
8798 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8799 (match_operand:DF 1 "arith_reg_operand" "f")))
8800 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8803 [(set_attr "type" "dfp_cmp")
8804 (set_attr "fp_mode" "double")])
8806 (define_insn "cmpeqdf_t"
8807 [(set (reg:SI T_REG)
8808 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8809 (match_operand:DF 1 "arith_reg_operand" "f")))
8810 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8813 [(set_attr "type" "dfp_cmp")
8814 (set_attr "fp_mode" "double")])
8816 (define_insn "*ieee_ccmpeqdf_t"
8817 [(set (reg:SI T_REG)
8818 (ior:SI (reg:SI T_REG)
8819 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8820 (match_operand:DF 1 "arith_reg_operand" "f"))))
8821 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8822 "TARGET_IEEE && TARGET_SH4"
8823 "* return output_ieee_ccmpeq (insn, operands);"
8824 [(set_attr "length" "4")
8825 (set_attr "fp_mode" "double")])
8827 (define_insn "cmpeqdf_media"
8828 [(set (match_operand:DI 0 "register_operand" "=r")
8829 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8830 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8831 "TARGET_SHMEDIA_FPU"
8833 [(set_attr "type" "fcmp_media")])
8835 (define_insn "cmpgtdf_media"
8836 [(set (match_operand:DI 0 "register_operand" "=r")
8837 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8838 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8839 "TARGET_SHMEDIA_FPU"
8841 [(set_attr "type" "fcmp_media")])
8843 (define_insn "cmpgedf_media"
8844 [(set (match_operand:DI 0 "register_operand" "=r")
8845 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8846 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8847 "TARGET_SHMEDIA_FPU"
8849 [(set_attr "type" "fcmp_media")])
8851 (define_insn "cmpundf_media"
8852 [(set (match_operand:DI 0 "register_operand" "=r")
8853 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8854 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8855 "TARGET_SHMEDIA_FPU"
8857 [(set_attr "type" "fcmp_media")])
8859 (define_expand "cmpdf"
8860 [(set (reg:SI T_REG)
8861 (compare (match_operand:DF 0 "arith_operand" "")
8862 (match_operand:DF 1 "arith_operand" "")))]
8863 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8866 sh_compare_op0 = operands[0];
8867 sh_compare_op1 = operands[1];
8871 (define_expand "negdf2"
8872 [(set (match_operand:DF 0 "arith_reg_operand" "")
8873 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8874 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8879 expand_df_unop (&gen_negdf2_i, operands);
8884 (define_insn "*negdf2_media"
8885 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8886 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8887 "TARGET_SHMEDIA_FPU"
8889 [(set_attr "type" "fmove_media")])
8891 (define_insn "negdf2_i"
8892 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8893 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8894 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8897 [(set_attr "type" "fmove")
8898 (set_attr "fp_mode" "double")])
8900 (define_expand "sqrtdf2"
8901 [(set (match_operand:DF 0 "arith_reg_operand" "")
8902 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8903 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8908 expand_df_unop (&gen_sqrtdf2_i, operands);
8913 (define_insn "*sqrtdf2_media"
8914 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8915 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8916 "TARGET_SHMEDIA_FPU"
8918 [(set_attr "type" "dfdiv_media")])
8920 (define_insn "sqrtdf2_i"
8921 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8922 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8923 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8926 [(set_attr "type" "dfdiv")
8927 (set_attr "fp_mode" "double")])
8929 (define_expand "absdf2"
8930 [(set (match_operand:DF 0 "arith_reg_operand" "")
8931 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8932 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8937 expand_df_unop (&gen_absdf2_i, operands);
8942 (define_insn "*absdf2_media"
8943 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8944 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8945 "TARGET_SHMEDIA_FPU"
8947 [(set_attr "type" "fmove_media")])
8949 (define_insn "absdf2_i"
8950 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8951 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8952 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8955 [(set_attr "type" "fmove")
8956 (set_attr "fp_mode" "double")])
8958 (define_expand "extendsfdf2"
8959 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8960 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8961 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8966 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8972 (define_insn "*extendsfdf2_media"
8973 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8974 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8975 "TARGET_SHMEDIA_FPU"
8977 [(set_attr "type" "dfpconv_media")])
8979 (define_insn "extendsfdf2_i4"
8980 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8981 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8982 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8985 [(set_attr "type" "fp")
8986 (set_attr "fp_mode" "double")])
8988 (define_expand "truncdfsf2"
8989 [(set (match_operand:SF 0 "fpul_operand" "")
8990 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8991 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8996 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9002 (define_insn "*truncdfsf2_media"
9003 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9004 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9005 "TARGET_SHMEDIA_FPU"
9007 [(set_attr "type" "dfpconv_media")])
9009 (define_insn "truncdfsf2_i4"
9010 [(set (match_operand:SF 0 "fpul_operand" "=y")
9011 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9012 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9015 [(set_attr "type" "fp")
9016 (set_attr "fp_mode" "double")])
9018 ;; Bit field extract patterns. These give better code for packed bitfields,
9019 ;; because they allow auto-increment addresses to be generated.
9021 (define_expand "insv"
9022 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9023 (match_operand:SI 1 "immediate_operand" "")
9024 (match_operand:SI 2 "immediate_operand" ""))
9025 (match_operand:SI 3 "general_operand" ""))]
9026 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9029 rtx addr_target, orig_address, shift_reg, qi_val;
9030 HOST_WIDE_INT bitsize, size, v;
9031 rtx x = operands[3];
9033 /* ??? expmed doesn't care for non-register predicates. */
9034 if (! memory_operand (operands[0], VOIDmode)
9035 || ! immediate_operand (operands[1], VOIDmode)
9036 || ! immediate_operand (operands[2], VOIDmode)
9037 || ! general_operand (x, VOIDmode))
9039 /* If this isn't a 16 / 24 / 32 bit field, or if
9040 it doesn't start on a byte boundary, then fail. */
9041 bitsize = INTVAL (operands[1]);
9042 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9043 || (INTVAL (operands[2]) % 8) != 0)
9047 orig_address = XEXP (operands[0], 0);
9048 shift_reg = gen_reg_rtx (SImode);
9049 if (GET_CODE (x) == CONST_INT)
9052 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9056 emit_insn (gen_movsi (shift_reg, operands[3]));
9057 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9059 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9061 operands[0] = replace_equiv_address (operands[0], addr_target);
9062 emit_insn (gen_movqi (operands[0], qi_val));
9066 if (GET_CODE (x) == CONST_INT)
9068 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9071 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9072 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9074 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9075 emit_insn (gen_movqi (operands[0], qi_val));
9081 ;; -------------------------------------------------------------------------
9083 ;; -------------------------------------------------------------------------
9085 ;; This matches cases where a stack pointer increment at the start of the
9086 ;; epilogue combines with a stack slot read loading the return value.
9089 [(set (match_operand:SI 0 "arith_reg_operand" "")
9090 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9091 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9092 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9095 ;; See the comment on the dt combiner pattern above.
9098 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9099 (plus:SI (match_dup 0)
9102 (eq:SI (match_dup 0)
9107 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9108 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9109 ;; reload when the constant is too large for a reg+offset address.
9111 ;; ??? We would get much better code if this was done in reload. This would
9112 ;; require modifying find_reloads_address to recognize that if the constant
9113 ;; is out-of-range for an immediate add, then we get better code by reloading
9114 ;; the constant into a register than by reloading the sum into a register,
9115 ;; since the former is one instruction shorter if the address does not need
9116 ;; to be offsettable. Unfortunately this does not work, because there is
9117 ;; only one register, r0, that can be used as an index register. This register
9118 ;; is also the function return value register. So, if we try to force reload
9119 ;; to use double-reg addresses, then we end up with some instructions that
9120 ;; need to use r0 twice. The only way to fix this is to change the calling
9121 ;; convention so that r0 is not used to return values.
9124 [(set (match_operand:SI 0 "register_operand" "=r")
9125 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9126 (set (mem:SI (match_dup 0))
9127 (match_operand:SI 2 "general_movsrc_operand" ""))]
9128 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9129 "mov.l %2,@(%0,%1)")
9132 [(set (match_operand:SI 0 "register_operand" "=r")
9133 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9134 (set (match_operand:SI 2 "general_movdst_operand" "")
9135 (mem:SI (match_dup 0)))]
9136 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9137 "mov.l @(%0,%1),%2")
9140 [(set (match_operand:SI 0 "register_operand" "=r")
9141 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9142 (set (mem:HI (match_dup 0))
9143 (match_operand:HI 2 "general_movsrc_operand" ""))]
9144 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9145 "mov.w %2,@(%0,%1)")
9148 [(set (match_operand:SI 0 "register_operand" "=r")
9149 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9150 (set (match_operand:HI 2 "general_movdst_operand" "")
9151 (mem:HI (match_dup 0)))]
9152 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9153 "mov.w @(%0,%1),%2")
9156 [(set (match_operand:SI 0 "register_operand" "=r")
9157 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9158 (set (mem:QI (match_dup 0))
9159 (match_operand:QI 2 "general_movsrc_operand" ""))]
9160 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9161 "mov.b %2,@(%0,%1)")
9164 [(set (match_operand:SI 0 "register_operand" "=r")
9165 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9166 (set (match_operand:QI 2 "general_movdst_operand" "")
9167 (mem:QI (match_dup 0)))]
9168 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9169 "mov.b @(%0,%1),%2")
9172 [(set (match_operand:SI 0 "register_operand" "=r")
9173 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9174 (set (mem:SF (match_dup 0))
9175 (match_operand:SF 2 "general_movsrc_operand" ""))]
9176 "TARGET_SH1 && REGNO (operands[0]) == 0
9177 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9178 || (GET_CODE (operands[2]) == SUBREG
9179 && REGNO (SUBREG_REG (operands[2])) < 16))
9180 && reg_unused_after (operands[0], insn)"
9181 "mov.l %2,@(%0,%1)")
9184 [(set (match_operand:SI 0 "register_operand" "=r")
9185 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9186 (set (match_operand:SF 2 "general_movdst_operand" "")
9188 (mem:SF (match_dup 0)))]
9189 "TARGET_SH1 && REGNO (operands[0]) == 0
9190 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9191 || (GET_CODE (operands[2]) == SUBREG
9192 && REGNO (SUBREG_REG (operands[2])) < 16))
9193 && reg_unused_after (operands[0], insn)"
9194 "mov.l @(%0,%1),%2")
9197 [(set (match_operand:SI 0 "register_operand" "=r")
9198 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9199 (set (mem:SF (match_dup 0))
9200 (match_operand:SF 2 "general_movsrc_operand" ""))]
9201 "TARGET_SH3E && REGNO (operands[0]) == 0
9202 && ((GET_CODE (operands[2]) == REG
9203 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9204 || (GET_CODE (operands[2]) == SUBREG
9205 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9206 && reg_unused_after (operands[0], insn)"
9207 "fmov{.s|} %2,@(%0,%1)")
9210 [(set (match_operand:SI 0 "register_operand" "=r")
9211 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9212 (set (match_operand:SF 2 "general_movdst_operand" "")
9214 (mem:SF (match_dup 0)))]
9215 "TARGET_SH3E && REGNO (operands[0]) == 0
9216 && ((GET_CODE (operands[2]) == REG
9217 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9218 || (GET_CODE (operands[2]) == SUBREG
9219 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9220 && reg_unused_after (operands[0], insn)"
9221 "fmov{.s|} @(%0,%1),%2")
9223 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9224 (define_insn "sp_switch_1"
9231 xoperands[0] = sp_switch;
9232 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9233 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9234 return \"mov r0,r15\";
9236 [(set_attr "length" "10")])
9238 ;; Switch back to the original stack for interrupt functions with the
9239 ;; sp_switch attribute. */
9240 (define_insn "sp_switch_2"
9243 "mov.l @r15+,r15\;mov.l @r15+,r0"
9244 [(set_attr "length" "4")])
9246 ;; Integer vector moves
9248 (define_expand "movv8qi"
9249 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9250 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9252 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9254 (define_insn "movv8qi_i"
9255 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9256 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9258 && (register_operand (operands[0], V8QImode)
9259 || register_operand (operands[1], V8QImode))"
9266 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9267 (set_attr "length" "4,4,16,4,4")])
9270 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9271 (subreg:V8QI (const_int 0) 0))]
9274 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9275 (const_int 0) (const_int 0) (const_int 0)
9276 (const_int 0) (const_int 0)]))])
9279 [(set (match_operand 0 "arith_reg_dest" "")
9280 (match_operand 1 "sh_rep_vec" ""))]
9281 "TARGET_SHMEDIA && reload_completed
9282 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9283 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9284 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9285 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9286 || XVECEXP (operands[1], 0, 1) != const0_rtx)"
9287 [(set (match_dup 0) (match_dup 1))
9291 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9292 rtx elt1 = XVECEXP (operands[1], 0, 1);
9295 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9297 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9298 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9299 operands[1] = XVECEXP (operands[1], 0, 0);
9302 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9303 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9304 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9305 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9308 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9310 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9316 [(set (match_operand 0 "arith_reg_dest" "")
9317 (match_operand 1 "sh_const_vec" ""))]
9318 "TARGET_SHMEDIA && reload_completed
9319 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9320 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9321 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9322 [(set (match_dup 0) (match_dup 1))]
9325 rtx v = operands[1];
9326 enum machine_mode new_mode
9327 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9329 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9331 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9334 (define_expand "movv2hi"
9335 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9336 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9338 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9340 (define_insn "movv2hi_i"
9341 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9342 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9344 && (register_operand (operands[0], V2HImode)
9345 || register_operand (operands[1], V2HImode))"
9352 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9353 (set_attr "length" "4,4,16,4,4")])
9355 (define_expand "movv4hi"
9356 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9357 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9359 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9361 (define_insn "movv4hi_i"
9362 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9363 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9365 && (register_operand (operands[0], V4HImode)
9366 || register_operand (operands[1], V4HImode))"
9373 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9374 (set_attr "length" "4,4,16,4,4")])
9376 (define_expand "movv2si"
9377 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9378 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9380 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9382 (define_insn "movv2si_i"
9383 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9384 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9386 && (register_operand (operands[0], V2SImode)
9387 || register_operand (operands[1], V2SImode))"
9394 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9395 (set_attr "length" "4,4,16,4,4")])
9397 ;; Multimedia Intrinsics
9399 (define_insn "absv2si2"
9400 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9401 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9404 [(set_attr "type" "mcmp_media")])
9406 (define_insn "absv4hi2"
9407 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9408 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9411 [(set_attr "type" "mcmp_media")])
9413 (define_insn "addv2si3"
9414 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9415 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9416 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9419 [(set_attr "type" "arith_media")])
9421 (define_insn "addv4hi3"
9422 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9423 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9424 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9427 [(set_attr "type" "arith_media")])
9429 (define_insn "ssaddv2si3"
9430 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9431 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9432 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9434 "madds.l %1, %2, %0"
9435 [(set_attr "type" "mcmp_media")])
9437 (define_insn "usaddv8qi3"
9438 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9439 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9440 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9442 "madds.ub %1, %2, %0"
9443 [(set_attr "type" "mcmp_media")])
9445 (define_insn "ssaddv4hi3"
9446 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9447 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9448 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9450 "madds.w %1, %2, %0"
9451 [(set_attr "type" "mcmp_media")])
9453 (define_insn "negcmpeqv8qi"
9454 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9455 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9456 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9458 "mcmpeq.b %N1, %N2, %0"
9459 [(set_attr "type" "mcmp_media")])
9461 (define_insn "negcmpeqv2si"
9462 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9463 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9464 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9466 "mcmpeq.l %N1, %N2, %0"
9467 [(set_attr "type" "mcmp_media")])
9469 (define_insn "negcmpeqv4hi"
9470 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9471 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9472 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9474 "mcmpeq.w %N1, %N2, %0"
9475 [(set_attr "type" "mcmp_media")])
9477 (define_insn "negcmpgtuv8qi"
9478 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9479 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9480 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9482 "mcmpgt.ub %N1, %N2, %0"
9483 [(set_attr "type" "mcmp_media")])
9485 (define_insn "negcmpgtv2si"
9486 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9487 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9488 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9490 "mcmpgt.l %N1, %N2, %0"
9491 [(set_attr "type" "mcmp_media")])
9493 (define_insn "negcmpgtv4hi"
9494 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9495 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9496 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9498 "mcmpgt.w %N1, %N2, %0"
9499 [(set_attr "type" "mcmp_media")])
9502 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9503 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9504 (match_operand:DI 2 "arith_reg_operand" "r"))
9505 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9506 (not:DI (match_dup 2)))))]
9509 [(set_attr "type" "arith_media")])
9511 (define_insn "mcnvs_lw"
9512 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9514 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9515 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9517 "mcnvs.lw %N1, %N2, %0"
9518 [(set_attr "type" "mcmp_media")])
9520 (define_insn "mcnvs_wb"
9521 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9523 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9524 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9526 "mcnvs.wb %N1, %N2, %0"
9527 [(set_attr "type" "mcmp_media")])
9529 (define_insn "mcnvs_wub"
9530 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9532 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9533 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9535 "mcnvs.wub %N1, %N2, %0"
9536 [(set_attr "type" "mcmp_media")])
9538 (define_insn "mextr_rl"
9539 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9540 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9541 (match_operand:HI 3 "mextr_bit_offset" "i"))
9542 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9543 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9544 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9547 static char templ[16];
9549 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9550 (int) INTVAL (operands[3]) >> 3);
9553 [(set_attr "type" "arith_media")])
9555 (define_insn "*mextr_lr"
9556 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9557 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9558 (match_operand:HI 3 "mextr_bit_offset" "i"))
9559 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9560 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9561 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9564 static char templ[16];
9566 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9567 (int) INTVAL (operands[4]) >> 3);
9570 [(set_attr "type" "arith_media")])
9572 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9573 ; vector then varies depending on endianness.
9574 (define_expand "mextr1"
9575 [(match_operand:DI 0 "arith_reg_dest" "")
9576 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9577 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9581 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9582 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9586 (define_expand "mextr2"
9587 [(match_operand:DI 0 "arith_reg_dest" "")
9588 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9589 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9593 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9594 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9598 (define_expand "mextr3"
9599 [(match_operand:DI 0 "arith_reg_dest" "")
9600 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9601 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9605 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9606 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9610 (define_expand "mextr4"
9611 [(match_operand:DI 0 "arith_reg_dest" "")
9612 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9613 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9617 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9618 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9622 (define_expand "mextr5"
9623 [(match_operand:DI 0 "arith_reg_dest" "")
9624 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9625 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9629 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9630 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9634 (define_expand "mextr6"
9635 [(match_operand:DI 0 "arith_reg_dest" "")
9636 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9637 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9641 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9642 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9646 (define_expand "mextr7"
9647 [(match_operand:DI 0 "arith_reg_dest" "")
9648 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9649 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9653 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9654 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9658 (define_expand "mmacfx_wl"
9659 [(match_operand:V2SI 0 "arith_reg_dest" "")
9660 (match_operand:V2HI 1 "extend_reg_operand" "")
9661 (match_operand:V2HI 2 "extend_reg_operand" "")
9662 (match_operand:V2SI 3 "arith_reg_operand" "")]
9666 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9667 operands[1], operands[2]));
9671 (define_insn "mmacfx_wl_i"
9672 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9674 (match_operand:V2SI 1 "arith_reg_operand" "0")
9679 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9680 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9683 "mmacfx.wl %2, %3, %0"
9684 [(set_attr "type" "mac_media")])
9686 (define_expand "mmacnfx_wl"
9687 [(match_operand:V2SI 0 "arith_reg_dest" "")
9688 (match_operand:V2HI 1 "extend_reg_operand" "")
9689 (match_operand:V2HI 2 "extend_reg_operand" "")
9690 (match_operand:V2SI 3 "arith_reg_operand" "")]
9694 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9695 operands[1], operands[2]));
9699 (define_insn "mmacnfx_wl_i"
9700 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9702 (match_operand:V2SI 1 "arith_reg_operand" "0")
9707 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9708 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9711 "mmacnfx.wl %2, %3, %0"
9712 [(set_attr "type" "mac_media")])
9714 (define_insn "mulv2si3"
9715 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9716 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9717 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9720 [(set_attr "type" "d2mpy_media")])
9722 (define_insn "mulv4hi3"
9723 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9724 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9725 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9728 [(set_attr "type" "dmpy_media")])
9730 (define_insn "mmulfx_l"
9731 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9735 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9736 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9739 "mmulfx.l %1, %2, %0"
9740 [(set_attr "type" "d2mpy_media")])
9742 (define_insn "mmulfx_w"
9743 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9747 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9748 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9751 "mmulfx.w %1, %2, %0"
9752 [(set_attr "type" "dmpy_media")])
9754 (define_insn "mmulfxrp_w"
9755 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9760 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9761 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9765 "mmulfxrp.w %1, %2, %0"
9766 [(set_attr "type" "dmpy_media")])
9768 (define_expand "mmulhi_wl"
9769 [(match_operand:V2SI 0 "arith_reg_dest" "")
9770 (match_operand:V4HI 1 "arith_reg_operand" "")
9771 (match_operand:V4HI 2 "arith_reg_operand" "")]
9775 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9776 (operands[0], operands[1], operands[2]));
9780 (define_expand "mmullo_wl"
9781 [(match_operand:V2SI 0 "arith_reg_dest" "")
9782 (match_operand:V4HI 1 "arith_reg_operand" "")
9783 (match_operand:V4HI 2 "arith_reg_operand" "")]
9787 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9788 (operands[0], operands[1], operands[2]));
9792 (define_insn "mmul23_wl"
9793 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9796 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9797 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9798 (parallel [(const_int 2) (const_int 3)])))]
9800 "* return (TARGET_LITTLE_ENDIAN
9801 ? \"mmulhi.wl %1, %2, %0\"
9802 : \"mmullo.wl %1, %2, %0\");"
9803 [(set_attr "type" "dmpy_media")])
9805 (define_insn "mmul01_wl"
9806 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9809 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9810 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9811 (parallel [(const_int 0) (const_int 1)])))]
9813 "* return (TARGET_LITTLE_ENDIAN
9814 ? \"mmullo.wl %1, %2, %0\"
9815 : \"mmulhi.wl %1, %2, %0\");"
9816 [(set_attr "type" "dmpy_media")])
9818 (define_expand "mmulsum_wq"
9819 [(match_operand:DI 0 "arith_reg_dest" "")
9820 (match_operand:V4HI 1 "arith_reg_operand" "")
9821 (match_operand:V4HI 2 "arith_reg_operand" "")
9822 (match_operand:DI 3 "arith_reg_operand" "")]
9826 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9827 operands[1], operands[2]));
9831 (define_insn "mmulsum_wq_i"
9832 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9833 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9838 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9839 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9840 (parallel [(const_int 0)]))
9841 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9842 (sign_extend:V4DI (match_dup 3)))
9843 (parallel [(const_int 1)])))
9845 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9846 (sign_extend:V4DI (match_dup 3)))
9847 (parallel [(const_int 2)]))
9848 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9849 (sign_extend:V4DI (match_dup 3)))
9850 (parallel [(const_int 3)]))))))]
9852 "mmulsum.wq %2, %3, %0"
9853 [(set_attr "type" "mac_media")])
9855 (define_expand "mperm_w"
9856 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9857 (match_operand:V4HI 1 "arith_reg_operand" "r")
9858 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9862 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9863 (operands[0], operands[1], operands[2]));
9866 ; This use of vec_select isn't exactly correct according to rtl.texi
9867 ; (because not constant), but it seems a straightforward extension.
9868 (define_insn "mperm_w_little"
9869 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9871 (match_operand:V4HI 1 "arith_reg_operand" "r")
9873 [(zero_extract (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9874 (const_int 2) (const_int 0))
9875 (zero_extract (match_dup 2) (const_int 2) (const_int 2))
9876 (zero_extract (match_dup 2) (const_int 2) (const_int 4))
9877 (zero_extract (match_dup 2) (const_int 2) (const_int 6))])))]
9878 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9879 "mperm.w %1, %N2, %0"
9880 [(set_attr "type" "arith_media")])
9882 (define_insn "mperm_w_big"
9883 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9885 (match_operand:V4HI 1 "arith_reg_operand" "r")
9887 [(zero_extract (not:QI (match_operand:QI 2
9888 "extend_reg_or_0_operand" "rU"))
9889 (const_int 2) (const_int 0))
9890 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9891 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9892 (zero_extract (not:QI (match_dup 2)) (const_int 2) (const_int 6))])))]
9893 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9894 "mperm.w %1, %N2, %0"
9895 [(set_attr "type" "arith_media")])
9897 (define_insn "mperm_w0"
9898 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9899 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9900 "trunc_hi_operand" "r"))))]
9902 "mperm.w %1, r63, %0"
9903 [(set_attr "type" "arith_media")])
9905 (define_expand "msad_ubq"
9906 [(match_operand:DI 0 "arith_reg_dest" "")
9907 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9908 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9909 (match_operand:DI 3 "arith_reg_operand" "")]
9913 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9914 operands[1], operands[2]));
9918 (define_insn "msad_ubq_i"
9919 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9924 (match_operand:DI 1 "arith_reg_operand" "0")
9925 (abs:DI (vec_select:DI
9928 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9930 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9931 (parallel [(const_int 0)]))))
9932 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9933 (zero_extend:V8DI (match_dup 3)))
9934 (parallel [(const_int 1)]))))
9936 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9937 (zero_extend:V8DI (match_dup 3)))
9938 (parallel [(const_int 2)])))
9939 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9940 (zero_extend:V8DI (match_dup 3)))
9941 (parallel [(const_int 3)])))))
9944 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9945 (zero_extend:V8DI (match_dup 3)))
9946 (parallel [(const_int 4)])))
9947 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9948 (zero_extend:V8DI (match_dup 3)))
9949 (parallel [(const_int 5)]))))
9951 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9952 (zero_extend:V8DI (match_dup 3)))
9953 (parallel [(const_int 6)])))
9954 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9955 (zero_extend:V8DI (match_dup 3)))
9956 (parallel [(const_int 7)])))))))]
9958 "msad.ubq %N2, %N3, %0"
9959 [(set_attr "type" "mac_media")])
9961 (define_insn "mshalds_l"
9962 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9965 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9966 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9969 "mshalds.l %1, %2, %0"
9970 [(set_attr "type" "mcmp_media")])
9972 (define_insn "mshalds_w"
9973 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9976 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9977 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9980 "mshalds.w %1, %2, %0"
9981 [(set_attr "type" "mcmp_media")])
9983 (define_insn "ashrv2si3"
9984 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9985 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9986 (match_operand:DI 2 "arith_reg_operand" "r")))]
9988 "mshard.l %1, %2, %0"
9989 [(set_attr "type" "arith_media")])
9991 (define_insn "ashrv4hi3"
9992 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9993 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9994 (match_operand:DI 2 "arith_reg_operand" "r")))]
9996 "mshard.w %1, %2, %0"
9997 [(set_attr "type" "arith_media")])
9999 (define_insn "mshards_q"
10000 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10002 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10003 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
10005 "mshards.q %1, %N2, %0"
10006 [(set_attr "type" "mcmp_media")])
10008 (define_expand "mshfhi_b"
10009 [(match_operand:V8QI 0 "arith_reg_dest" "")
10010 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10011 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
10015 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10016 (operands[0], operands[1], operands[2]));
10020 (define_expand "mshflo_b"
10021 [(match_operand:V8QI 0 "arith_reg_dest" "")
10022 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10023 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
10027 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10028 (operands[0], operands[1], operands[2]));
10032 (define_insn "mshf4_b"
10034 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10036 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10037 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10038 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10039 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10041 "* return (TARGET_LITTLE_ENDIAN
10042 ? \"mshfhi.b %N1, %N2, %0\"
10043 : \"mshflo.b %N1, %N2, %0\");"
10044 [(set_attr "type" "arith_media")])
10046 (define_insn "mshf0_b"
10048 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10050 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10051 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10052 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10053 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10055 "* return (TARGET_LITTLE_ENDIAN
10056 ? \"mshflo.b %N1, %N2, %0\"
10057 : \"mshfhi.b %N1, %N2, %0\");"
10058 [(set_attr "type" "arith_media")])
10060 (define_expand "mshfhi_l"
10061 [(match_operand:V2SI 0 "arith_reg_dest" "")
10062 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10063 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10067 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10068 (operands[0], operands[1], operands[2]));
10072 (define_expand "mshflo_l"
10073 [(match_operand:V2SI 0 "arith_reg_dest" "")
10074 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10075 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10079 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10080 (operands[0], operands[1], operands[2]));
10084 (define_insn "mshf4_l"
10085 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10087 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10088 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10089 (parallel [(const_int 1) (const_int 3)])))]
10091 "* return (TARGET_LITTLE_ENDIAN
10092 ? \"mshfhi.l %N1, %N2, %0\"
10093 : \"mshflo.l %N1, %N2, %0\");"
10094 [(set_attr "type" "arith_media")])
10096 (define_insn "mshf0_l"
10097 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10099 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10100 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10101 (parallel [(const_int 0) (const_int 2)])))]
10103 "* return (TARGET_LITTLE_ENDIAN
10104 ? \"mshflo.l %N1, %N2, %0\"
10105 : \"mshfhi.l %N1, %N2, %0\");"
10106 [(set_attr "type" "arith_media")])
10108 (define_expand "mshfhi_w"
10109 [(match_operand:V4HI 0 "arith_reg_dest" "")
10110 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10111 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10115 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10116 (operands[0], operands[1], operands[2]));
10120 (define_expand "mshflo_w"
10121 [(match_operand:V4HI 0 "arith_reg_dest" "")
10122 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10123 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10127 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10128 (operands[0], operands[1], operands[2]));
10132 (define_insn "mshf4_w"
10133 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10135 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10136 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10137 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10139 "* return (TARGET_LITTLE_ENDIAN
10140 ? \"mshfhi.w %N1, %N2, %0\"
10141 : \"mshflo.w %N1, %N2, %0\");"
10142 [(set_attr "type" "arith_media")])
10144 (define_insn "mshf0_w"
10145 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10147 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10148 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10149 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10151 "* return (TARGET_LITTLE_ENDIAN
10152 ? \"mshflo.w %N1, %N2, %0\"
10153 : \"mshfhi.w %N1, %N2, %0\");"
10154 [(set_attr "type" "arith_media")])
10156 (define_insn "mshflo_w_x"
10157 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10159 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10160 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10161 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10163 "mshflo.w %N1, %N2, %0"
10164 [(set_attr "type" "arith_media")])
10166 /* These are useful to expand ANDs and as combiner patterns. */
10167 (define_insn_and_split "mshfhi_l_di"
10168 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10169 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10171 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10172 (const_int -4294967296))))]
10175 mshfhi.l %N1, %N2, %0
10177 "TARGET_SHMEDIA && reload_completed
10178 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10179 [(set (match_dup 3) (match_dup 4))
10180 (set (match_dup 5) (match_dup 6))]
10183 operands[3] = gen_lowpart (SImode, operands[0]);
10184 operands[4] = gen_highpart (SImode, operands[1]);
10185 operands[5] = gen_highpart (SImode, operands[0]);
10186 operands[6] = gen_highpart (SImode, operands[2]);
10188 [(set_attr "type" "arith_media")])
10190 (define_insn "*mshfhi_l_di_rev"
10191 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10192 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10193 (const_int -4294967296))
10194 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10197 "mshfhi.l %N2, %N1, %0"
10198 [(set_attr "type" "arith_media")])
10201 [(set (match_operand:DI 0 "arith_reg_dest" "")
10202 (ior:DI (zero_extend:DI (match_operand:SI 1
10203 "extend_reg_or_0_operand" ""))
10204 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10205 (const_int -4294967296))))
10206 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10211 emit_insn (gen_ashldi3_media (operands[3],
10212 simplify_gen_subreg (DImode, operands[1],
10215 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10219 (define_insn "mshflo_l_di"
10220 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10221 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10222 (const_int 4294967295))
10223 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10227 "mshflo.l %N1, %N2, %0"
10228 [(set_attr "type" "arith_media")])
10230 (define_insn "*mshflo_l_di_rev"
10231 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10232 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10234 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10235 (const_int 4294967295))))]
10238 "mshflo.l %N2, %N1, %0"
10239 [(set_attr "type" "arith_media")])
10241 ;; Combiner pattern for trampoline initialization.
10242 (define_insn_and_split "*double_shori"
10243 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10244 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10246 (match_operand:DI 2 "const_int_operand" "n")))]
10248 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10250 "rtx_equal_p (operands[0], operands[1])"
10254 HOST_WIDE_INT v = INTVAL (operands[2]);
10256 emit_insn (gen_shori_media (operands[0], operands[0],
10257 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10258 emit_insn (gen_shori_media (operands[0], operands[0],
10259 gen_int_mode (v, HImode)));
10264 (define_insn "*mshflo_l_di_x"
10265 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10266 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10268 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10272 "mshflo.l %N1, %N2, %0"
10273 [(set_attr "type" "arith_media")])
10275 (define_insn_and_split "concat_v2sf"
10276 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10277 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10278 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10279 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10283 mshflo.l %N1, %N2, %0
10286 "TARGET_SHMEDIA && reload_completed
10287 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10288 [(set (match_dup 3) (match_dup 1))
10289 (set (match_dup 4) (match_dup 2))]
10292 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10293 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10295 [(set_attr "type" "arith_media")])
10297 (define_insn "*mshflo_l_di_x_rev"
10298 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10299 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10301 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10304 "mshflo.l %N2, %N1, %0"
10305 [(set_attr "type" "arith_media")])
10307 (define_insn "ashlv2si3"
10308 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10309 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10310 (match_operand:DI 2 "arith_reg_operand" "r")))]
10312 "mshlld.l %1, %2, %0"
10313 [(set_attr "type" "arith_media")])
10315 (define_insn "ashlv4hi3"
10316 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10317 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10318 (match_operand:DI 2 "arith_reg_operand" "r")))]
10320 "mshlld.w %1, %2, %0"
10321 [(set_attr "type" "arith_media")])
10323 (define_insn "lshrv2si3"
10324 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10325 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10326 (match_operand:DI 2 "arith_reg_operand" "r")))]
10328 "mshlrd.l %1, %2, %0"
10329 [(set_attr "type" "arith_media")])
10331 (define_insn "lshrv4hi3"
10332 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10333 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10334 (match_operand:DI 2 "arith_reg_operand" "r")))]
10336 "mshlrd.w %1, %2, %0"
10337 [(set_attr "type" "arith_media")])
10339 (define_insn "subv2si3"
10340 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10341 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10342 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10344 "msub.l %N1, %2, %0"
10345 [(set_attr "type" "arith_media")])
10347 (define_insn "subv4hi3"
10348 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10349 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10350 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10352 "msub.w %N1, %2, %0"
10353 [(set_attr "type" "arith_media")])
10355 (define_insn "sssubv2si3"
10356 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10357 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10358 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10360 "msubs.l %N1, %2, %0"
10361 [(set_attr "type" "mcmp_media")])
10363 (define_insn "ussubv8qi3"
10364 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10365 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10366 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10368 "msubs.ub %1, %2, %0"
10369 [(set_attr "type" "mcmp_media")])
10371 (define_insn "sssubv4hi3"
10372 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10373 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10374 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10376 "msubs.w %N1, %2, %0"
10377 [(set_attr "type" "mcmp_media")])
10379 ;; Floating Point Intrinsics
10381 (define_insn "fcosa_s"
10382 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10383 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10387 [(set_attr "type" "atrans_media")])
10389 (define_insn "fsina_s"
10390 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10391 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10395 [(set_attr "type" "atrans_media")])
10397 (define_insn "fipr"
10398 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10399 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10400 "fp_arith_reg_operand" "f")
10401 (match_operand:V4SF 2
10402 "fp_arith_reg_operand" "f"))
10403 (parallel [(const_int 0)]))
10404 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10405 (parallel [(const_int 1)])))
10406 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10407 (parallel [(const_int 2)]))
10408 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10409 (parallel [(const_int 3)])))))]
10412 [(set_attr "type" "fparith_media")])
10414 (define_insn "fsrra_s"
10415 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10416 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10420 [(set_attr "type" "atrans_media")])
10422 (define_insn "ftrv"
10423 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10427 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10428 (parallel [(const_int 0) (const_int 5)
10429 (const_int 10) (const_int 15)]))
10430 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10432 (vec_select:V4SF (match_dup 1)
10433 (parallel [(const_int 4) (const_int 9)
10434 (const_int 14) (const_int 3)]))
10435 (vec_select:V4SF (match_dup 2)
10436 (parallel [(const_int 1) (const_int 2)
10437 (const_int 3) (const_int 0)]))))
10440 (vec_select:V4SF (match_dup 1)
10441 (parallel [(const_int 8) (const_int 13)
10442 (const_int 2) (const_int 7)]))
10443 (vec_select:V4SF (match_dup 2)
10444 (parallel [(const_int 2) (const_int 3)
10445 (const_int 0) (const_int 1)])))
10447 (vec_select:V4SF (match_dup 1)
10448 (parallel [(const_int 12) (const_int 1)
10449 (const_int 6) (const_int 11)]))
10450 (vec_select:V4SF (match_dup 2)
10451 (parallel [(const_int 3) (const_int 0)
10452 (const_int 1) (const_int 2)]))))))]
10455 [(set_attr "type" "fparith_media")])
10458 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10459 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10463 [(set_attr "type" "arith_media")])
10465 (define_insn "nsbsi"
10466 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10468 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10472 [(set_attr "type" "arith_media")])
10474 (define_insn "nsbdi"
10475 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10477 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10481 [(set_attr "type" "arith_media")])
10483 (define_expand "ffsdi2"
10484 [(set (match_operand:DI 0 "arith_reg_dest" "")
10485 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10489 rtx scratch = gen_reg_rtx (DImode);
10492 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10493 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10494 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10495 emit_insn (gen_nsbdi (scratch, scratch));
10496 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10497 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10498 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10500 = gen_rtx_EXPR_LIST (REG_EQUAL,
10501 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10505 (define_expand "ffssi2"
10506 [(set (match_operand:SI 0 "arith_reg_dest" "")
10507 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10511 rtx scratch = gen_reg_rtx (SImode);
10512 rtx discratch = gen_reg_rtx (DImode);
10515 emit_insn (gen_adddi3z_media (discratch, operands[1],
10516 force_reg (SImode, GEN_INT (-1))));
10517 emit_insn (gen_andcdi3 (discratch, discratch,
10518 simplify_gen_subreg (DImode, operands[1],
10520 emit_insn (gen_nsbsi (scratch, discratch));
10521 last = emit_insn (gen_subsi3 (operands[0],
10522 force_reg (SImode, GEN_INT (-64)), scratch));
10524 = gen_rtx_EXPR_LIST (REG_EQUAL,
10525 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10529 (define_insn "byterev"
10530 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10531 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10532 (parallel [(const_int 7) (const_int 6) (const_int 5)
10533 (const_int 4) (const_int 3) (const_int 2)
10534 (const_int 1) (const_int 0)])))]
10537 [(set_attr "type" "arith_media")])
10539 ;; The following description models the
10540 ;; SH4 pipeline using the DFA based scheduler.
10541 ;; The DFA based description is better way to model
10542 ;; a superscalar pipeline as compared to function unit
10543 ;; reservation model.
10544 ;; 1. The function unit based model is oriented to describe at most one
10545 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10546 ;; pipeline units by same insn. This can be done using DFA based description.
10547 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10548 ;; 3. Writing all unit reservations for an instruction class is more natural description
10549 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10550 ;; old function unit based model.
10551 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10554 ;; Two automata are defined to reduce number of states
10555 ;; which a single large automaton will have.(Factoring)
10557 (define_automaton "inst_pipeline,fpu_pipe")
10559 ;; This unit is basically the decode unit of the processor.
10560 ;; Since SH4 is a dual issue machine,it is as if there are two
10561 ;; units so that any insn can be processed by either one
10562 ;; of the decoding unit.
10564 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10567 ;; The fixed point arithmetic calculator(?? EX Unit).
10569 (define_cpu_unit "int" "inst_pipeline")
10571 ;; f1_1 and f1_2 are floating point units.Actually there is
10572 ;; a f1 unit which can overlap with other f1 unit but
10573 ;; not another F1 unit.It is as though there were two
10576 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10578 ;; The floating point units.
10580 (define_cpu_unit "F1,F2,F3,FS" "fpu_pipe")
10582 ;; This is basically the MA unit of SH4
10583 ;; used in LOAD/STORE pipeline.
10585 (define_cpu_unit "memory" "inst_pipeline")
10587 ;; The address calculator used for branch instructions.
10588 ;; This will be reserved with "issue" of branch instructions
10589 ;; and this is to make sure that no two branch instructions
10590 ;; can be issued in parallel.
10592 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10594 ;; ----------------------------------------------------
10595 ;; This reservation is to simplify the dual issue description.
10597 (define_reservation "issue" "pipe_01|pipe_02")
10599 ;; This is to express the locking of D stage.
10601 (define_reservation "d_lock" "pipe_01+pipe_02")
10603 ;; This is to simplify description where F1,F2,FS
10604 ;; are used simultaneously.
10606 (define_reservation "fpu" "F1+F2+FS")
10608 ;; This is to highlight the fact that f1
10609 ;; cannot overlap with F1.
10611 (exclusion_set "f1_1,f1_2" "F1")
10613 ;; Although reg moves have a latency of zero
10614 ;; we need to highlight that they use D stage
10617 (define_insn_reservation "reg_mov" 0
10618 (eq_attr "type" "move,fmove")
10621 ;; Other MT group intructions(1 step operations)
10626 (define_insn_reservation "mt" 1
10627 (eq_attr "insn_class" "mt_group")
10630 ;; Fixed Point Arithmetic Instructions(1 step operations)
10635 (define_insn_reservation "simple_arith" 1
10636 (eq_attr "insn_class" "ex_group")
10639 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10644 (define_insn_reservation "load_store" 2
10645 (eq_attr "type" "load,load_si,pcload,pcload_si,store")
10648 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10650 ;; Latency: 2 (or 1) Actually Observed to be 5/7
10652 ;; The latency is 1 when displacement is 0.
10653 ;; This reservation can be further broken into 2
10654 ;; 1. branch_zero : One with latency 1 and in the TEST
10655 ;; part it also checks for 0 (ZERO) displacement
10656 ;; 2. branch: Latency 2.
10658 (define_insn_reservation "branch_zero" 5
10659 (and (eq_attr "type" "cbranch")
10660 (eq_attr "length" "2"))
10661 "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
10663 (define_insn_reservation "branch" 7
10664 (eq_attr "type" "cbranch")
10665 "(issue+pcr_addrcalc),pcr_addrcalc,nothing")
10667 ;; Branch Far (JMP,RTS,BRAF)
10671 ;; Since issue stage (D stage) is blocked for 2nd cycle,
10672 ;; cpu_unit int is reserved since it might be required for far
10673 ;; address calculation.
10675 (define_insn_reservation "branch_far" 12
10676 (and (eq_attr "type" "jump,return")
10677 (eq_attr "length" "6"))
10678 "d_lock*2,int+pcr_addrcalc,pcr_addrcalc")
10684 ;; this instruction can be executed in any of the pipelines
10685 ;; and blocks the pipeline for next 4 stages.
10687 (define_insn_reservation "return_from_exp" 5
10688 (eq_attr "type" "rte")
10689 "(issue+pcr_addrcalc),d_lock*4,int+pcr_addrcalc,nothing")
10696 (define_insn_reservation "ocbwb" 5
10697 (eq_attr "insn_class" "cwb")
10698 "issue,(int+memory),memory*5")
10704 ;; The SX stage is blocked for last 2 cycles.
10706 (define_insn_reservation "lds_to_pr" 3
10707 (eq_attr "type" "prset,call,sfunc")
10708 "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+pcr_addrcalc)*2")
10714 ;; The SX unit is blocked for last 2 cycles.
10716 (define_insn_reservation "ldsmem_to_pr" 3
10717 (eq_attr "type" "pload")
10718 "(issue+pcr_addrcalc),(issue+int+pcr_addrcalc),(int+memory+pcr_addrcalc),(int+pcr_addrcalc)")
10724 ;; The SX unit in second and third cycles.
10726 (define_insn_reservation "sts_from_pr" 2
10727 (eq_attr "type" "prget")
10728 "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+pcr_addrcalc),nothing")
10735 (define_insn_reservation "prload_mem" 2
10736 (eq_attr "type" "pstore")
10737 "(issue+pcr_addrcalc),(pipe_01+int+pcr_addrcalc),(int+memory+pcr_addrcalc),memory")
10743 ;; F1 is blocked for last three cycles.
10745 (define_insn_reservation "fpscr_store" 4
10746 (eq_attr "insn_class" "lds_to_fpscr")
10752 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10754 ;; F1 is blocked for last three cycles.
10756 (define_insn_reservation "fpscr_store_mem" 4
10757 (eq_attr "insn_class" "ldsmem_to_fpscr")
10758 "issue,(int+memory),(F1+memory),F1*2")
10761 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10766 (define_insn_reservation "multi" 4
10767 (eq_attr "type" "smpy,dmpy")
10768 "issue,(issue+int+f1_1),(int+f1_1),(f1_1|f1_2)*2,F2,FS")
10771 ;; Single precision floating point computation FCMP/EQ,
10772 ;; FCP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10777 (define_insn_reservation "fp_arith" 4
10778 (eq_attr "type" "fp")
10781 ;; Single Precision FDIV/SQRT
10786 (define_insn_reservation "fp_div" 13
10787 (eq_attr "type" "fdiv")
10788 "issue,F1+F3,F1+F2+F3,F3*7,F1+F3,F2,FS")
10790 ;; Double Precision floating point computation
10791 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10793 ;; Latency: (3,4)/5
10796 (define_insn_reservation "dp_float" 5
10797 (eq_attr "type" "dfp_conv")
10798 "issue,F1,F1+F2,F2+FS,FS")
10800 ;; Double-precision floating-point (FADD ,FMUL,FSUB)
10802 ;; Latency: (7,8)/9
10805 (define_insn_reservation "fp_double_arith" 9
10806 (eq_attr "type" "dfp_arith")
10807 "issue,F1,F1+F2,fpu*4,F2+FS,FS")
10809 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10814 (define_insn_reservation "fp_double_cmp" 5
10815 (eq_attr "type" "dfp_cmp")
10816 "issue,(issue+F1),F1+F2,F2+FS,FS")
10818 ;; Double precision FDIV/SQRT
10820 ;; Latency: (24,25)/26
10823 (define_insn_reservation "dp_div" 26
10824 (eq_attr "type" "dfdiv")
10825 "issue,F1+F3,F1+F2+F3,F2+F3+FS,F3*16,F1+F3,F1+F2+F3,fpu+F3,F2+FS,FS")