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 ;; -------------------------------------------------------------------------
113 ;; These are used with unspec.
114 (UNSPEC_COMPACT_ARGS 0)
128 ;; These are used with unspec_volatile.
134 (UNSPECV_WINDOW_END 10)
135 (UNSPECV_CONST_END 11)
138 ;; -------------------------------------------------------------------------
140 ;; -------------------------------------------------------------------------
145 "sh1,sh2,sh3,sh3e,sh4,sh5"
146 (const (symbol_ref "sh_cpu_attr")))
148 (define_attr "endian" "big,little"
149 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
150 (const_string "little") (const_string "big"))))
152 ;; Indicate if the default fpu mode is single precision.
153 (define_attr "fpu_single" "yes,no"
154 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
155 (const_string "yes") (const_string "no"))))
157 (define_attr "fmovd" "yes,no"
158 (const (if_then_else (symbol_ref "TARGET_FMOVD")
159 (const_string "yes") (const_string "no"))))
161 (define_attr "issues" "1,2"
162 (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
164 ;; cbranch conditional branch instructions
165 ;; jump unconditional jumps
166 ;; arith ordinary arithmetic
167 ;; arith3 a compound insn that behaves similarly to a sequence of
168 ;; three insns of type arith
169 ;; arith3b like above, but might end with a redirected branch
171 ;; load_si Likewise, SImode variant for general register.
173 ;; move register to register
174 ;; fmove register to register, floating point
175 ;; smpy word precision integer multiply
176 ;; dmpy longword or doublelongword precision integer multiply
178 ;; pload load of pr reg, which can't be put into delay slot of rts
179 ;; prset copy register to pr reg, ditto
180 ;; pstore store of pr reg, which can't be put into delay slot of jsr
181 ;; prget copy pr to register, ditto
182 ;; pcload pc relative load of constant value
183 ;; pcload_si Likewise, SImode variant for general register.
184 ;; rte return from exception
185 ;; sfunc special function call with known used registers
186 ;; call function call
188 ;; fdiv floating point divide (or square root)
189 ;; gp_fpul move between general purpose register and fpul
190 ;; dfp_arith, dfp_cmp,dfp_conv
191 ;; dfdiv double precision floating point divide (or square root)
192 ;; nil no-op move, will be deleted.
195 "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pt,ptabs,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,nil"
196 (const_string "other"))
198 ;; Indicate what precision must be selected in fpscr for this insn, if any.
200 (define_attr "fp_mode" "single,double,none" (const_string "none"))
202 ; If a conditional branch destination is within -252..258 bytes away
203 ; from the instruction it can be 2 bytes long. Something in the
204 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
205 ; branches are initially assumed to be 16 bytes long.
206 ; In machine_dependent_reorg, we split all branches that are longer than
209 ;; The maximum range used for SImode constant pool entries is 1018. A final
210 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
211 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
212 ;; instruction around the pool table, 2 bytes of alignment before the table,
213 ;; and 30 bytes of alignment after the table. That gives a maximum total
214 ;; pool size of 1058 bytes.
215 ;; Worst case code/pool content size ratio is 1:2 (using asms).
216 ;; Thus, in the worst case, there is one instruction in front of a maximum
217 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
218 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
219 ;; If we have a forward branch, the initial table will be put after the
220 ;; unconditional branch.
222 ;; ??? We could do much better by keeping track of the actual pcloads within
223 ;; the branch range and in the pcload range in front of the branch range.
225 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
227 (define_attr "short_cbranch_p" "no,yes"
228 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
230 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
232 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
234 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
236 ] (const_string "no")))
238 (define_attr "med_branch_p" "no,yes"
239 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
242 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
244 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
247 ] (const_string "no")))
249 (define_attr "med_cbranch_p" "no,yes"
250 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
253 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
255 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
258 ] (const_string "no")))
260 (define_attr "braf_branch_p" "no,yes"
261 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
263 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
266 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
268 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
271 ] (const_string "no")))
273 (define_attr "braf_cbranch_p" "no,yes"
274 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
276 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
279 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
281 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
284 ] (const_string "no")))
286 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
287 ; For wider ranges, we need a combination of a code and a data part.
288 ; If we can get a scratch register for a long range jump, the code
289 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
290 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
291 ; long; otherwise, it must be 6 bytes long.
293 ; All other instructions are two bytes long by default.
295 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
296 ;; but getattrtab doesn't understand this.
297 (define_attr "length" ""
298 (cond [(eq_attr "type" "cbranch")
299 (cond [(eq_attr "short_cbranch_p" "yes")
301 (eq_attr "med_cbranch_p" "yes")
303 (eq_attr "braf_cbranch_p" "yes")
305 ;; ??? using pc is not computed transitively.
306 (ne (match_dup 0) (match_dup 0))
308 (ne (symbol_ref ("flag_pic")) (const_int 0))
311 (eq_attr "type" "jump")
312 (cond [(eq_attr "med_branch_p" "yes")
314 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
316 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
317 (symbol_ref "code_for_indirect_jump_scratch")))
318 (if_then_else (eq_attr "braf_branch_p" "yes")
321 (eq_attr "braf_branch_p" "yes")
323 ;; ??? using pc is not computed transitively.
324 (ne (match_dup 0) (match_dup 0))
326 (ne (symbol_ref ("flag_pic")) (const_int 0))
329 (eq_attr "type" "pt")
330 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
331 (const_int 20) (const_int 12))
332 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
336 ;; (define_function_unit {name} {num-units} {n-users} {test}
337 ;; {ready-delay} {issue-delay} [{conflict-list}])
339 ;; Load and store instructions save a cycle if they are aligned on a
340 ;; four byte boundary. Using a function unit for stores encourages
341 ;; gcc to separate load and store instructions by one instruction,
342 ;; which makes it more likely that the linker will be able to word
343 ;; align them when relaxing.
345 ;; Loads have a latency of two.
346 ;; However, call insns can have a delay slot, so that we want one more
347 ;; insn to be scheduled between the load of the function address and the call.
348 ;; This is equivalent to a latency of three.
349 ;; We cannot use a conflict list for this, because we need to distinguish
350 ;; between the actual call address and the function arguments.
351 ;; ADJUST_COST can only properly handle reductions of the cost, so we
352 ;; use a latency of three here.
353 ;; We only do this for SImode loads of general registers, to make the work
354 ;; for ADJUST_COST easier.
355 (define_function_unit "memory" 1 0
356 (and (eq_attr "issues" "1")
357 (eq_attr "type" "load_si,pcload_si"))
359 (define_function_unit "memory" 1 0
360 (and (eq_attr "issues" "1")
361 (eq_attr "type" "load,pcload,pload,store,pstore"))
364 (define_function_unit "int" 1 0
365 (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
367 (define_function_unit "int" 1 0
368 (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
370 (define_function_unit "int" 1 0
371 (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
373 ;; ??? These are approximations.
374 (define_function_unit "mpy" 1 0
375 (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
376 (define_function_unit "mpy" 1 0
377 (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
379 (define_function_unit "fp" 1 0
380 (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
381 (define_function_unit "fp" 1 0
382 (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
386 ;; The SH4 is a dual-issue implementation, thus we have to multiply all
387 ;; costs by at least two.
388 ;; There will be single increments of the modeled that don't correspond
389 ;; to the actual target ;; whenever two insns to be issued depend one a
390 ;; single resource, and the scheduler picks to be the first one.
391 ;; If we multiplied the costs just by two, just two of these single
392 ;; increments would amount to an actual cycle. By picking a larger
393 ;; factor, we can ameliorate the effect; However, we then have to make sure
394 ;; that only two insns are modeled as issued per actual cycle.
395 ;; Moreover, we need a way to specify the latency of insns that don't
396 ;; use an actual function unit.
397 ;; We use an 'issue' function unit to do that, and a cost factor of 10.
399 (define_function_unit "issue" 2 0
400 (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
403 (define_function_unit "issue" 2 0
404 (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
407 ;; There is no point in providing exact scheduling information about branches,
408 ;; because they are at the starts / ends of basic blocks anyways.
410 ;; Some insns cannot be issued before/after another insn in the same cycle,
411 ;; irrespective of the type of the other insn.
413 ;; default is dual-issue, but can't be paired with an insn that
414 ;; uses multiple function units.
415 (define_function_unit "single_issue" 1 0
416 (and (eq_attr "issues" "2")
417 (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
419 [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
421 (define_function_unit "single_issue" 1 0
422 (and (eq_attr "issues" "2")
423 (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
427 ;; arith3 insns are always pairable at the start, but not inecessarily at
428 ;; the end; however, there doesn't seem to be a way to express that.
429 (define_function_unit "single_issue" 1 0
430 (and (eq_attr "issues" "2")
431 (eq_attr "type" "arith3"))
435 ;; arith3b insn are pairable at the end and have latency that prevents pairing
436 ;; with the following branch, but we don't want this latency be respected;
437 ;; When the following branch is immediately adjacent, we can redirect the
438 ;; internal branch, which is likly to be a larger win.
439 (define_function_unit "single_issue" 1 0
440 (and (eq_attr "issues" "2")
441 (eq_attr "type" "arith3b"))
445 ;; calls introduce a longisch delay that is likely to flush the pipelines.
446 (define_function_unit "single_issue" 1 0
447 (and (eq_attr "issues" "2")
448 (eq_attr "type" "call,sfunc"))
450 [(eq_attr "type" "!call") (eq_attr "type" "call")])
452 ;; Load and store instructions have no alignment peculiarities for the SH4,
453 ;; but they use the load-store unit, which they share with the fmove type
454 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
455 ;; Loads have a latency of two.
456 ;; However, call insns can only paired with a preceding insn, and have
457 ;; a delay slot, so that we want two more insns to be scheduled between the
458 ;; load of the function address and the call. This is equivalent to a
460 ;; We cannot use a conflict list for this, because we need to distinguish
461 ;; between the actual call address and the function arguments.
462 ;; ADJUST_COST can only properly handle reductions of the cost, so we
463 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
464 ;; We only do this for SImode loads of general registers, to make the work
465 ;; for ADJUST_COST easier.
467 ;; When specifying different latencies for different insns using the
468 ;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
469 ;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
470 ;; for an executing insn E and a candidate insn C.
471 ;; Therefore, we define three different function units for load_store:
472 ;; load_store, load and load_si.
474 (define_function_unit "load_si" 1 0
475 (and (eq_attr "issues" "2")
476 (eq_attr "type" "load_si,pcload_si")) 30 10)
477 (define_function_unit "load" 1 0
478 (and (eq_attr "issues" "2")
479 (eq_attr "type" "load,pcload,pload")) 20 10)
480 (define_function_unit "load_store" 1 0
481 (and (eq_attr "issues" "2")
482 (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
485 (define_function_unit "int" 1 0
486 (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
488 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
489 ;; spurious FIFO constraint; the multiply instructions use the "int"
490 ;; unit actually only for two cycles.
491 (define_function_unit "int" 1 0
492 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
494 ;; We use a fictous "mpy" unit to express the actual latency.
495 (define_function_unit "mpy" 1 0
496 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
498 ;; Again, we have to pretend a lower latency for the "int" unit to avoid a
499 ;; spurious FIFO constraint.
500 (define_function_unit "int" 1 0
501 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
503 ;; We use a fictous "gp_fpul" unit to express the actual latency.
504 (define_function_unit "gp_fpul" 1 0
505 (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
507 ;; ??? multiply uses the floating point unit, but with a two cycle delay.
508 ;; Thus, a simple single-precision fp operation could finish if issued in
509 ;; the very next cycle, but stalls when issued two or three cycles later.
510 ;; Similarily, a divide / sqrt can work without stalls if issued in
511 ;; the very next cycle, while it would have to block if issued two or
512 ;; three cycles later.
513 ;; There is no way to model this with gcc's function units. This problem is
514 ;; actually mentioned in md.texi. Tackling this problem requires first that
515 ;; it is possible to speak about the target in an open discussion.
517 ;; However, simple double-precision operations always conflict.
519 (define_function_unit "fp" 1 0
520 (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
521 [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
523 ;; The "fp" unit is for pipeline stages F1 and F2.
525 (define_function_unit "fp" 1 0
526 (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
528 ;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
529 ;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
531 (define_function_unit "fp" 1 0
532 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
534 ;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
535 ;; pipeline stages on the pipelining of fdiv/fsqrt insns.
536 ;; We also use it to give the actual latency here.
537 ;; fsqrt is actually one cycle faster than fdiv (and the value used here),
538 ;; but that will hardly matter in practice for scheduling.
539 (define_function_unit "fdiv" 1 0
540 (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
542 ;; There is again a late use of the "fp" unit by [d]fdiv type insns
543 ;; that we can't express.
545 (define_function_unit "fp" 1 0
546 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
548 (define_function_unit "fp" 1 0
549 (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
551 (define_function_unit "fp" 1 0
552 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
554 (define_function_unit "fdiv" 1 0
555 (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
557 ;; This should be enough for pt insns to be moved 5 insns ahead of
558 ;; corresponding branches.
559 (define_function_unit "pt" 1 0
560 (eq_attr "type" "pt,ptabs") 10 2)
562 ; Definitions for filling branch delay slots.
564 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
566 ;; ??? This should be (nil) instead of (const_int 0)
567 (define_attr "hit_stack" "yes,no"
568 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
571 (const_string "yes")))
573 (define_attr "interrupt_function" "no,yes"
574 (const (symbol_ref "current_function_interrupt")))
576 (define_attr "in_delay_slot" "yes,no"
577 (cond [(eq_attr "type" "cbranch") (const_string "no")
578 (eq_attr "type" "pcload,pcload_si") (const_string "no")
579 (eq_attr "needs_delay_slot" "yes") (const_string "no")
580 (eq_attr "length" "2") (const_string "yes")
581 ] (const_string "no")))
583 (define_attr "is_sfunc" ""
584 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
587 (eq_attr "needs_delay_slot" "yes")
588 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
590 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
591 ;; and thus we can't put a pop instruction in its delay slot.
592 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
593 ;; instruction can go in the delay slot.
595 ;; Since a normal return (rts) implicitly uses the PR register,
596 ;; we can't allow PR register loads in an rts delay slot.
599 (eq_attr "type" "return")
600 [(and (eq_attr "in_delay_slot" "yes")
601 (ior (and (eq_attr "interrupt_function" "no")
602 (eq_attr "type" "!pload,prset"))
603 (and (eq_attr "interrupt_function" "yes")
605 (ne (symbol_ref "TARGET_SH3") (const_int 0))
606 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
608 ;; Since a call implicitly uses the PR register, we can't allow
609 ;; a PR register store in a jsr delay slot.
612 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
613 [(and (eq_attr "in_delay_slot" "yes")
614 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
616 ;; Say that we have annulled true branches, since this gives smaller and
617 ;; faster code when branches are predicted as not taken.
620 (and (eq_attr "type" "cbranch")
621 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
622 [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
624 ;; -------------------------------------------------------------------------
625 ;; SImode signed integer comparisons
626 ;; -------------------------------------------------------------------------
630 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
631 (match_operand:SI 1 "arith_operand" "L,r"))
636 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
637 ;; That would still allow reload to create cmpi instructions, but would
638 ;; perhaps allow forcing the constant into a register when that is better.
639 ;; Probably should use r0 for mem/imm compares, but force constant into a
640 ;; register for pseudo/imm compares.
642 (define_insn "cmpeqsi_t"
644 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
645 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
652 (define_insn "cmpgtsi_t"
654 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
655 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
661 (define_insn "cmpgesi_t"
663 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
664 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
670 ;; -------------------------------------------------------------------------
671 ;; SImode unsigned integer comparisons
672 ;; -------------------------------------------------------------------------
674 (define_insn "cmpgeusi_t"
676 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
677 (match_operand:SI 1 "arith_reg_operand" "r")))]
681 (define_insn "cmpgtusi_t"
683 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
684 (match_operand:SI 1 "arith_reg_operand" "r")))]
688 ;; We save the compare operands in the cmpxx patterns and use them when
689 ;; we generate the branch.
691 (define_expand "cmpsi"
693 (compare (match_operand:SI 0 "arith_operand" "")
694 (match_operand:SI 1 "arith_operand" "")))]
698 sh_compare_op0 = operands[0];
699 sh_compare_op1 = operands[1];
703 ;; -------------------------------------------------------------------------
704 ;; DImode signed integer comparisons
705 ;; -------------------------------------------------------------------------
707 ;; ??? Could get better scheduling by splitting the initial test from the
708 ;; rest of the insn after reload. However, the gain would hardly justify
709 ;; the sh.md size increase necessary to do that.
713 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
714 (match_operand:DI 1 "arith_operand" "r"))
717 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
719 [(set_attr "length" "6")
720 (set_attr "type" "arith3b")])
722 (define_insn "cmpeqdi_t"
724 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
725 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
728 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
729 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
730 [(set_attr "length" "6")
731 (set_attr "type" "arith3b")])
735 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
736 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
737 ;; If we applied this split when not optimizing, it would only be
738 ;; applied during the machine-dependent reorg, when no new basic blocks
740 "TARGET_SH1 && reload_completed && optimize"
741 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
742 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
743 (label_ref (match_dup 6))
745 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
750 = gen_rtx_REG (SImode,
751 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
753 = (operands[1] == const0_rtx
755 : gen_rtx_REG (SImode,
756 true_regnum (operands[1])
757 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
758 operands[4] = gen_lowpart (SImode, operands[0]);
759 operands[5] = gen_lowpart (SImode, operands[1]);
760 operands[6] = gen_label_rtx ();
763 (define_insn "cmpgtdi_t"
765 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
766 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
769 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
770 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
771 [(set_attr "length" "8")
772 (set_attr "type" "arith3")])
774 (define_insn "cmpgedi_t"
776 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
777 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
780 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
782 [(set_attr "length" "8,2")
783 (set_attr "type" "arith3,arith")])
785 ;; -------------------------------------------------------------------------
786 ;; DImode unsigned integer comparisons
787 ;; -------------------------------------------------------------------------
789 (define_insn "cmpgeudi_t"
791 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
792 (match_operand:DI 1 "arith_reg_operand" "r")))]
794 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
795 [(set_attr "length" "8")
796 (set_attr "type" "arith3")])
798 (define_insn "cmpgtudi_t"
800 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
801 (match_operand:DI 1 "arith_reg_operand" "r")))]
803 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
804 [(set_attr "length" "8")
805 (set_attr "type" "arith3")])
807 (define_insn "cmpeqdi_media"
808 [(set (match_operand:DI 0 "register_operand" "=r,r")
809 (eq:DI (match_operand:DI 1 "register_operand" "%r,r")
810 (match_operand:DI 2 "arith_reg_or_0_operand" "N,r")))]
816 (define_insn "cmpgtdi_media"
817 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
818 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
819 (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
826 (define_insn "cmpgtudi_media"
827 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
828 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "N,r,r")
829 (match_operand:DI 2 "arith_reg_or_0_operand" "r,N,r")))]
836 ;; We save the compare operands in the cmpxx patterns and use them when
837 ;; we generate the branch.
839 (define_expand "cmpdi"
841 (compare (match_operand:DI 0 "arith_operand" "")
842 (match_operand:DI 1 "arith_operand" "")))]
843 "TARGET_SH2 || TARGET_SHMEDIA"
846 sh_compare_op0 = operands[0];
847 sh_compare_op1 = operands[1];
850 ;; -------------------------------------------------------------------------
851 ;; Conditional move instructions
852 ;; -------------------------------------------------------------------------
854 ;; The insn names may seem reversed, but note that cmveq performs the move
855 ;; if op1 == 0, and cmvne does it if op1 != 0.
857 (define_insn "movdicc_false"
858 [(set (match_operand:DI 0 "register_operand" "=r")
859 (if_then_else:DI (eq (match_operand:DI 1 "register_operand" "r")
861 (match_operand:DI 2 "register_operand" "r")
862 (match_operand:DI 3 "register_operand" "0")))]
866 (define_insn "movdicc_true"
867 [(set (match_operand:DI 0 "register_operand" "=r")
868 (if_then_else:DI (ne (match_operand:DI 1 "register_operand" "r")
870 (match_operand:DI 2 "register_operand" "r")
871 (match_operand:DI 3 "register_operand" "0")))]
875 (define_expand "movdicc"
876 [(set (match_operand:DI 0 "register_operand" "")
877 (if_then_else:DI (match_operand 1 "comparison_operator" "")
878 (match_operand:DI 2 "register_operand" "")
879 (match_operand:DI 3 "register_operand" "")))]
883 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
884 && GET_MODE (sh_compare_op0) == DImode
885 && sh_compare_op1 == const0_rtx)
886 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
887 sh_compare_op0, sh_compare_op1);
895 tmp = gen_reg_rtx (DImode);
897 switch (GET_CODE (operands[1]))
900 emit_insn (gen_seq (tmp));
901 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
905 emit_insn (gen_seq (tmp));
906 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
910 emit_insn (gen_sgt (tmp));
911 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
915 emit_insn (gen_slt (tmp));
916 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
920 emit_insn (gen_slt (tmp));
921 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
925 emit_insn (gen_sgt (tmp));
926 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
930 emit_insn (gen_sgtu (tmp));
931 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
935 emit_insn (gen_sltu (tmp));
936 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
940 emit_insn (gen_sltu (tmp));
941 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
945 emit_insn (gen_sgtu (tmp));
946 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
950 emit_insn (gen_sunordered (tmp));
951 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
955 emit_insn (gen_sunordered (tmp));
956 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
973 ;; -------------------------------------------------------------------------
974 ;; Addition instructions
975 ;; -------------------------------------------------------------------------
977 (define_expand "adddi3"
978 [(set (match_operand:DI 0 "arith_reg_operand" "")
979 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
980 (match_operand:DI 2 "arith_operand" "")))]
986 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
988 operands[2] = force_reg (DImode, operands[2]);
989 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
994 (define_insn "*adddi3_media"
995 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
996 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
997 (match_operand:DI 2 "arith_operand" "r,P")))]
1003 (define_insn "*adddi3z_media"
1004 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1006 (plus:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
1007 (match_operand:SI 2 "arith_reg_or_0_operand" "r,n"))))]
1011 addz.l %1, r63, %0")
1013 (define_insn "adddi3_compact"
1014 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1015 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1016 (match_operand:DI 2 "arith_reg_operand" "r")))
1017 (clobber (reg:SI T_REG))]
1020 [(set_attr "length" "6")])
1023 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1024 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1025 (match_operand:DI 2 "arith_reg_operand" "r")))
1026 (clobber (reg:SI T_REG))]
1027 "TARGET_SH1 && reload_completed"
1031 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1032 high0 = gen_rtx_REG (SImode,
1033 true_regnum (operands[0])
1034 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1035 high2 = gen_rtx_REG (SImode,
1036 true_regnum (operands[2])
1037 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1038 emit_insn (gen_clrt ());
1039 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1040 emit_insn (gen_addc1 (high0, high0, high2));
1045 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1046 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1047 (match_operand:SI 2 "arith_reg_operand" "r"))
1050 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1053 [(set_attr "type" "arith")])
1055 (define_insn "addc1"
1056 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1057 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1058 (match_operand:SI 2 "arith_reg_operand" "r"))
1060 (clobber (reg:SI T_REG))]
1063 [(set_attr "type" "arith")])
1065 (define_expand "addsi3"
1066 [(set (match_operand:SI 0 "arith_reg_operand" "")
1067 (plus:SI (match_operand:SI 1 "arith_operand" "")
1068 (match_operand:SI 2 "arith_operand" "")))]
1073 operands[1] = force_reg (SImode, operands[1]);
1076 (define_insn "addsi3_media"
1077 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1078 (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
1079 (match_operand:SI 2 "arith_operand" "r,P")))]
1085 (define_insn "*addsi3_compact"
1086 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1087 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1088 (match_operand:SI 2 "arith_operand" "rI")))]
1091 [(set_attr "type" "arith")])
1093 ;; -------------------------------------------------------------------------
1094 ;; Subtraction instructions
1095 ;; -------------------------------------------------------------------------
1097 (define_expand "subdi3"
1098 [(set (match_operand:DI 0 "arith_reg_operand" "")
1099 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1100 (match_operand:DI 2 "arith_reg_operand" "")))]
1106 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1111 (define_insn "*subdi3_media"
1112 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1113 (minus:DI (match_operand:DI 1 "arith_reg_operand" "r")
1114 (match_operand:DI 2 "arith_reg_operand" "r")))]
1118 (define_insn "subdi3_compact"
1119 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1120 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1121 (match_operand:DI 2 "arith_reg_operand" "r")))
1122 (clobber (reg:SI T_REG))]
1125 [(set_attr "length" "6")])
1128 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1129 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1130 (match_operand:DI 2 "arith_reg_operand" "r")))
1131 (clobber (reg:SI T_REG))]
1132 "TARGET_SH1 && reload_completed"
1136 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1137 high0 = gen_rtx_REG (SImode,
1138 true_regnum (operands[0])
1139 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1140 high2 = gen_rtx_REG (SImode,
1141 true_regnum (operands[2])
1142 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1143 emit_insn (gen_clrt ());
1144 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1145 emit_insn (gen_subc1 (high0, high0, high2));
1150 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1151 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1152 (match_operand:SI 2 "arith_reg_operand" "r"))
1155 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1158 [(set_attr "type" "arith")])
1160 (define_insn "subc1"
1161 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1162 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1163 (match_operand:SI 2 "arith_reg_operand" "r"))
1165 (clobber (reg:SI T_REG))]
1168 [(set_attr "type" "arith")])
1170 (define_insn "*subsi3_internal"
1171 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1172 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1173 (match_operand:SI 2 "arith_reg_operand" "r")))]
1176 [(set_attr "type" "arith")])
1178 (define_insn "*subsi3_media"
1179 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1180 (minus:SI (match_operand:SI 1 "arith_reg_operand" "r")
1181 (match_operand:SI 2 "arith_reg_operand" "r")))]
1185 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1186 ;; will sometimes save one instruction. Otherwise we might get
1187 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1190 (define_expand "subsi3"
1191 [(set (match_operand:SI 0 "arith_reg_operand" "")
1192 (minus:SI (match_operand:SI 1 "arith_operand" "")
1193 (match_operand:SI 2 "arith_reg_operand" "")))]
1197 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1199 emit_insn (gen_negsi2 (operands[0], operands[2]));
1200 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1205 if (no_new_pseudos && ! arith_reg_operand (operands[1], SImode))
1207 operands[1] = force_reg (SImode, operands[1]);
1211 ;; -------------------------------------------------------------------------
1212 ;; Division instructions
1213 ;; -------------------------------------------------------------------------
1215 ;; We take advantage of the library routines which don't clobber as many
1216 ;; registers as a normal function call would.
1218 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1219 ;; also has an effect on the register that holds the address of the sfunc.
1220 ;; To make this work, we have an extra dummy insns that shows the use
1221 ;; of this register for reorg.
1223 (define_insn "use_sfunc_addr"
1224 [(set (reg:SI PR_REG)
1225 (unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1228 [(set_attr "length" "0")])
1230 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1231 ;; hard register 0. If we used hard register 0, then the next instruction
1232 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1233 ;; gets allocated to a stack slot that needs its address reloaded, then
1234 ;; there is nothing to prevent reload from using r0 to reload the address.
1235 ;; This reload would clobber the value in r0 we are trying to store.
1236 ;; If we let reload allocate r0, then this problem can never happen.
1238 (define_insn "udivsi3_i1"
1239 [(set (match_operand:SI 0 "register_operand" "=z")
1240 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1241 (clobber (reg:SI T_REG))
1242 (clobber (reg:SI PR_REG))
1243 (clobber (reg:SI R4_REG))
1244 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1245 "TARGET_SH1 && ! TARGET_SH4"
1247 [(set_attr "type" "sfunc")
1248 (set_attr "needs_delay_slot" "yes")])
1250 (define_insn "udivsi3_i1_media"
1251 [(set (match_operand:SI 0 "register_operand" "=z")
1252 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1253 (clobber (reg:SI T_MEDIA_REG))
1254 (clobber (reg:SI PR_MEDIA_REG))
1255 (clobber (reg:SI R4_REG))
1256 (clobber (reg:DI TR0_REG))
1257 (clobber (reg:DI TR1_REG))
1258 (clobber (reg:DI TR2_REG))
1259 (use (match_operand:DI 1 "target_operand" "b"))]
1260 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1262 [(set_attr "type" "sfunc")
1263 (set_attr "needs_delay_slot" "yes")])
1265 (define_expand "udivsi3_i4_media"
1266 [(set (match_dup 2) (zero_extend:DI (reg:SI R4_REG)))
1267 (set (match_dup 3) (zero_extend:DI (reg:SI R5_REG)))
1268 (set (match_dup 4) (float:DF (match_dup 2)))
1269 (set (match_dup 5) (float:DF (match_dup 3)))
1270 (set (match_dup 6) (div:DF (match_dup 4) (match_dup 5)))
1271 (set (subreg:DI (match_operand:SI 0 "register_operand" "=r") 0)
1272 (fix:DI (match_dup 6)))]
1273 "TARGET_SHMEDIA_FPU"
1276 operands[2] = gen_reg_rtx (DImode);
1277 operands[3] = gen_reg_rtx (DImode);
1278 operands[4] = gen_reg_rtx (DFmode);
1279 operands[5] = gen_reg_rtx (DFmode);
1280 operands[6] = gen_reg_rtx (DFmode);
1283 (define_insn "udivsi3_i4"
1284 [(set (match_operand:SI 0 "register_operand" "=y")
1285 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1286 (clobber (reg:SI T_REG))
1287 (clobber (reg:SI PR_REG))
1288 (clobber (reg:DF DR0_REG))
1289 (clobber (reg:DF DR2_REG))
1290 (clobber (reg:DF DR4_REG))
1291 (clobber (reg:SI R0_REG))
1292 (clobber (reg:SI R1_REG))
1293 (clobber (reg:SI R4_REG))
1294 (clobber (reg:SI R5_REG))
1295 (use (reg:PSI FPSCR_REG))
1296 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1297 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1299 [(set_attr "type" "sfunc")
1300 (set_attr "fp_mode" "double")
1301 (set_attr "needs_delay_slot" "yes")])
1303 (define_insn "udivsi3_i4_single"
1304 [(set (match_operand:SI 0 "register_operand" "=y")
1305 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1306 (clobber (reg:SI T_REG))
1307 (clobber (reg:SI PR_REG))
1308 (clobber (reg:DF DR0_REG))
1309 (clobber (reg:DF DR2_REG))
1310 (clobber (reg:DF DR4_REG))
1311 (clobber (reg:SI R0_REG))
1312 (clobber (reg:SI R1_REG))
1313 (clobber (reg:SI R4_REG))
1314 (clobber (reg:SI R5_REG))
1315 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1316 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1318 [(set_attr "type" "sfunc")
1319 (set_attr "needs_delay_slot" "yes")])
1321 (define_expand "udivsi3"
1322 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1323 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1324 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1325 (parallel [(set (match_operand:SI 0 "register_operand" "")
1326 (udiv:SI (reg:SI R4_REG)
1328 (clobber (reg:SI T_REG))
1329 (clobber (reg:SI PR_REG))
1330 (clobber (reg:SI R4_REG))
1331 (use (match_dup 3))])]
1337 operands[3] = gen_reg_rtx (Pmode);
1338 /* Emit the move of the address to a pseudo outside of the libcall. */
1339 if (TARGET_HARD_SH4 && TARGET_SH3E)
1341 emit_move_insn (operands[3],
1342 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1343 if (TARGET_FPU_SINGLE)
1344 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1346 last = gen_udivsi3_i4 (operands[0], operands[3]);
1348 else if (TARGET_SHMEDIA_FPU)
1349 last = gen_udivsi3_i4_media (operands[0]);
1350 else if (TARGET_SH5)
1352 emit_move_insn (operands[3],
1353 gen_rtx_SYMBOL_REF (Pmode,
1359 last = gen_udivsi3_i1_media (operands[0],
1362 : gen_rtx_SUBREG (DImode, operands[3],
1364 else if (TARGET_FPU_ANY)
1365 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1367 last = gen_udivsi3_i1 (operands[0], operands[3]);
1371 emit_move_insn (operands[3],
1372 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1373 last = gen_udivsi3_i1 (operands[0], operands[3]);
1375 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1376 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1377 last = emit_insn (last);
1378 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1379 invariant code motion can move it. */
1380 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1381 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1385 (define_insn "divsi3_i1"
1386 [(set (match_operand:SI 0 "register_operand" "=z")
1387 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1388 (clobber (reg:SI T_REG))
1389 (clobber (reg:SI PR_REG))
1390 (clobber (reg:SI R1_REG))
1391 (clobber (reg:SI R2_REG))
1392 (clobber (reg:SI R3_REG))
1393 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1394 "TARGET_SH1 && ! TARGET_SH4"
1396 [(set_attr "type" "sfunc")
1397 (set_attr "needs_delay_slot" "yes")])
1399 (define_insn "divsi3_i1_media"
1400 [(set (match_operand:SI 0 "register_operand" "=z")
1401 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1402 (clobber (reg:SI T_MEDIA_REG))
1403 (clobber (reg:SI PR_MEDIA_REG))
1404 (clobber (reg:SI R1_REG))
1405 (clobber (reg:SI R2_REG))
1406 (clobber (reg:SI R3_REG))
1407 (clobber (reg:DI TR0_REG))
1408 (clobber (reg:DI TR1_REG))
1409 (clobber (reg:DI TR2_REG))
1410 (use (match_operand:DI 1 "target_operand" "b"))]
1411 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1414 (define_expand "divsi3_i4_media"
1415 [(set (match_dup 2) (reg:SI R4_REG))
1416 (set (match_dup 3) (reg:SI R5_REG))
1417 (set (match_dup 4) (float:DF (match_dup 2)))
1418 (set (match_dup 5) (float:DF (match_dup 3)))
1419 (set (match_dup 6) (div:DF (match_dup 4) (match_dup 5)))
1420 (set (match_operand:SI 0 "register_operand" "=r")
1421 (fix:SI (match_dup 6)))]
1422 "TARGET_SHMEDIA_FPU"
1425 operands[2] = gen_reg_rtx (SImode);
1426 operands[3] = gen_reg_rtx (SImode);
1427 operands[4] = gen_reg_rtx (DFmode);
1428 operands[5] = gen_reg_rtx (DFmode);
1429 operands[6] = gen_reg_rtx (DFmode);
1432 (define_insn "divsi3_i4"
1433 [(set (match_operand:SI 0 "register_operand" "=y")
1434 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1435 (clobber (reg:SI PR_REG))
1436 (clobber (reg:DF DR0_REG))
1437 (clobber (reg:DF DR2_REG))
1438 (use (reg:PSI FPSCR_REG))
1439 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1440 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1442 [(set_attr "type" "sfunc")
1443 (set_attr "fp_mode" "double")
1444 (set_attr "needs_delay_slot" "yes")])
1446 (define_insn "divsi3_i4_single"
1447 [(set (match_operand:SI 0 "register_operand" "=y")
1448 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1449 (clobber (reg:SI PR_REG))
1450 (clobber (reg:DF DR0_REG))
1451 (clobber (reg:DF DR2_REG))
1452 (clobber (reg:SI R2_REG))
1453 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1454 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1456 [(set_attr "type" "sfunc")
1457 (set_attr "needs_delay_slot" "yes")])
1459 (define_expand "divsi3"
1460 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1461 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1462 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1463 (parallel [(set (match_operand:SI 0 "register_operand" "")
1464 (div:SI (reg:SI R4_REG)
1466 (clobber (reg:SI T_REG))
1467 (clobber (reg:SI PR_REG))
1468 (clobber (reg:SI R1_REG))
1469 (clobber (reg:SI R2_REG))
1470 (clobber (reg:SI R3_REG))
1471 (use (match_dup 3))])]
1477 operands[3] = gen_reg_rtx (Pmode);
1478 /* Emit the move of the address to a pseudo outside of the libcall. */
1479 if (TARGET_HARD_SH4 && TARGET_SH3E)
1481 emit_move_insn (operands[3],
1482 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1483 if (TARGET_FPU_SINGLE)
1484 last = gen_divsi3_i4_single (operands[0], operands[3]);
1486 last = gen_divsi3_i4 (operands[0], operands[3]);
1488 else if (TARGET_SHMEDIA_FPU)
1489 last = gen_divsi3_i4_media (operands[0]);
1490 else if (TARGET_SH5)
1492 emit_move_insn (operands[3],
1493 gen_rtx_SYMBOL_REF (Pmode,
1499 last = gen_divsi3_i1_media (operands[0],
1502 : gen_rtx_SUBREG (DImode, operands[3],
1504 else if (TARGET_FPU_ANY)
1505 last = gen_divsi3_i4_single (operands[0], operands[3]);
1507 last = gen_divsi3_i1 (operands[0], operands[3]);
1511 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1512 last = gen_divsi3_i1 (operands[0], operands[3]);
1514 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1515 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1516 last = emit_insn (last);
1517 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1518 invariant code motion can move it. */
1519 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1520 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1524 ;; -------------------------------------------------------------------------
1525 ;; Multiplication instructions
1526 ;; -------------------------------------------------------------------------
1528 (define_insn "umulhisi3_i"
1529 [(set (reg:SI MACL_REG)
1530 (mult:SI (zero_extend:SI
1531 (match_operand:HI 0 "arith_reg_operand" "r"))
1533 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1536 [(set_attr "type" "smpy")])
1538 (define_insn "mulhisi3_i"
1539 [(set (reg:SI MACL_REG)
1540 (mult:SI (sign_extend:SI
1541 (match_operand:HI 0 "arith_reg_operand" "r"))
1543 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1546 [(set_attr "type" "smpy")])
1548 (define_expand "mulhisi3"
1549 [(set (reg:SI MACL_REG)
1550 (mult:SI (sign_extend:SI
1551 (match_operand:HI 1 "arith_reg_operand" ""))
1553 (match_operand:HI 2 "arith_reg_operand" ""))))
1554 (set (match_operand:SI 0 "arith_reg_operand" "")
1561 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1562 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1563 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1564 invariant code motion can move it. */
1565 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1566 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1570 (define_expand "umulhisi3"
1571 [(set (reg:SI MACL_REG)
1572 (mult:SI (zero_extend:SI
1573 (match_operand:HI 1 "arith_reg_operand" ""))
1575 (match_operand:HI 2 "arith_reg_operand" ""))))
1576 (set (match_operand:SI 0 "arith_reg_operand" "")
1583 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1584 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1585 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1586 invariant code motion can move it. */
1587 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1588 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1592 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1593 ;; a call to a routine which clobbers known registers.
1596 [(set (match_operand:SI 1 "register_operand" "=z")
1597 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1598 (clobber (reg:SI MACL_REG))
1599 (clobber (reg:SI T_REG))
1600 (clobber (reg:SI PR_REG))
1601 (clobber (reg:SI R3_REG))
1602 (clobber (reg:SI R2_REG))
1603 (clobber (reg:SI R1_REG))
1604 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1607 [(set_attr "type" "sfunc")
1608 (set_attr "needs_delay_slot" "yes")])
1610 (define_expand "mulsi3_call"
1611 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1612 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1613 (parallel[(set (match_operand:SI 0 "register_operand" "")
1614 (mult:SI (reg:SI R4_REG)
1616 (clobber (reg:SI MACL_REG))
1617 (clobber (reg:SI T_REG))
1618 (clobber (reg:SI PR_REG))
1619 (clobber (reg:SI R3_REG))
1620 (clobber (reg:SI R2_REG))
1621 (clobber (reg:SI R1_REG))
1622 (use (match_operand:SI 3 "register_operand" ""))])]
1626 (define_insn "mul_l"
1627 [(set (reg:SI MACL_REG)
1628 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1629 (match_operand:SI 1 "arith_reg_operand" "r")))]
1632 [(set_attr "type" "dmpy")])
1634 (define_expand "mulsi3"
1635 [(set (reg:SI MACL_REG)
1636 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1637 (match_operand:SI 2 "arith_reg_operand" "")))
1638 (set (match_operand:SI 0 "arith_reg_operand" "")
1647 /* The address must be set outside the libcall,
1648 since it goes into a pseudo. */
1649 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1650 rtx addr = force_reg (SImode, sym);
1651 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1653 first = XVECEXP (insns, 0, 0);
1654 last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
1659 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1661 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1662 /* consec_sets_giv can only recognize the first insn that sets a
1663 giv as the giv insn. So we must tag this also with a REG_EQUAL
1665 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1667 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1668 invariant code motion can move it. */
1669 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1670 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1674 (define_insn "mulsidi3_i"
1675 [(set (reg:SI MACH_REG)
1679 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1680 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1682 (set (reg:SI MACL_REG)
1683 (mult:SI (match_dup 0)
1687 [(set_attr "type" "dmpy")])
1689 (define_expand "mulsidi3"
1690 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1691 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1692 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1693 "TARGET_SH2 || TARGET_SHMEDIA"
1698 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1704 (define_insn "mulsidi3_media"
1705 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1706 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1707 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1709 "muls.l %1, %2, %0")
1711 (define_insn "mulsidi3_compact"
1712 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1714 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1715 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1716 (clobber (reg:SI MACH_REG))
1717 (clobber (reg:SI MACL_REG))]
1722 [(set (match_operand:DI 0 "arith_reg_operand" "")
1724 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1725 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1726 (clobber (reg:SI MACH_REG))
1727 (clobber (reg:SI MACL_REG))]
1732 rtx low_dst = gen_lowpart (SImode, operands[0]);
1733 rtx high_dst = gen_highpart (SImode, operands[0]);
1735 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1737 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1738 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1739 /* We need something to tag the possible REG_EQUAL notes on to. */
1740 emit_move_insn (operands[0], operands[0]);
1744 (define_insn "umulsidi3_i"
1745 [(set (reg:SI MACH_REG)
1749 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1750 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1752 (set (reg:SI MACL_REG)
1753 (mult:SI (match_dup 0)
1757 [(set_attr "type" "dmpy")])
1759 (define_expand "umulsidi3"
1760 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1761 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1762 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1763 "TARGET_SH2 || TARGET_SHMEDIA"
1768 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1774 (define_insn "umulsidi3_media"
1775 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1776 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "%r"))
1777 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1779 "mulu.l %1, %2, %0")
1781 (define_insn "umulsidi3_compact"
1782 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1784 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1785 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1786 (clobber (reg:SI MACH_REG))
1787 (clobber (reg:SI MACL_REG))]
1792 [(set (match_operand:DI 0 "arith_reg_operand" "")
1793 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1794 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1795 (clobber (reg:SI MACH_REG))
1796 (clobber (reg:SI MACL_REG))]
1801 rtx low_dst = gen_lowpart (SImode, operands[0]);
1802 rtx high_dst = gen_highpart (SImode, operands[0]);
1804 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1806 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1807 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1808 /* We need something to tag the possible REG_EQUAL notes on to. */
1809 emit_move_insn (operands[0], operands[0]);
1813 (define_insn "smulsi3_highpart_i"
1814 [(set (reg:SI MACH_REG)
1818 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1819 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1821 (clobber (reg:SI MACL_REG))]
1824 [(set_attr "type" "dmpy")])
1826 (define_expand "smulsi3_highpart"
1828 [(set (reg:SI MACH_REG)
1832 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1833 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1835 (clobber (reg:SI MACL_REG))])
1836 (set (match_operand:SI 0 "arith_reg_operand" "")
1843 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1844 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1845 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1846 invariant code motion can move it. */
1847 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1848 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1849 /* expand_binop can't find a suitable code in mul_highpart_optab to
1850 make a REG_EQUAL note from, so make one here.
1851 ??? Alternatively, we could put this at the calling site of expand_binop,
1852 i.e. expand_mult_highpart. */
1854 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1859 (define_insn "umulsi3_highpart_i"
1860 [(set (reg:SI MACH_REG)
1864 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1865 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1867 (clobber (reg:SI MACL_REG))]
1870 [(set_attr "type" "dmpy")])
1872 (define_expand "umulsi3_highpart"
1874 [(set (reg:SI MACH_REG)
1878 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1879 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1881 (clobber (reg:SI MACL_REG))])
1882 (set (match_operand:SI 0 "arith_reg_operand" "")
1889 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1890 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1891 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1892 invariant code motion can move it. */
1893 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1894 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1898 ;; -------------------------------------------------------------------------
1899 ;; Logical operations
1900 ;; -------------------------------------------------------------------------
1903 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1904 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1905 (match_operand:SI 2 "logical_operand" "r,L")))]
1908 [(set_attr "type" "arith")])
1910 ;; If the constant is 255, then emit a extu.b instruction instead of an
1911 ;; and, since that will give better code.
1913 (define_expand "andsi3"
1914 [(set (match_operand:SI 0 "arith_reg_operand" "")
1915 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1916 (match_operand:SI 2 "logical_operand" "")))]
1920 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1922 emit_insn (gen_zero_extendqisi2 (operands[0],
1923 gen_lowpart (QImode, operands[1])));
1928 (define_insn "anddi3"
1929 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1930 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1931 (match_operand:DI 2 "logical_operand" "r,P")))]
1937 (define_insn "*andcdi3"
1938 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1939 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1940 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1944 (define_insn "iorsi3"
1945 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1946 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1947 (match_operand:SI 2 "logical_operand" "r,L")))]
1950 [(set_attr "type" "arith")])
1952 (define_insn "iordi3"
1953 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1954 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1955 (match_operand:DI 2 "logical_operand" "r,P")))]
1961 (define_insn "xorsi3"
1962 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1963 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1964 (match_operand:SI 2 "logical_operand" "L,r")))]
1967 [(set_attr "type" "arith")])
1969 (define_insn "xordi3"
1970 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1971 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1972 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
1978 ;; -------------------------------------------------------------------------
1979 ;; Shifts and rotates
1980 ;; -------------------------------------------------------------------------
1982 (define_insn "rotlsi3_1"
1983 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1984 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1987 (lshiftrt:SI (match_dup 1) (const_int 31)))]
1990 [(set_attr "type" "arith")])
1992 (define_insn "rotlsi3_31"
1993 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1994 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1996 (clobber (reg:SI T_REG))]
1999 [(set_attr "type" "arith")])
2001 (define_insn "rotlsi3_16"
2002 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2003 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2007 [(set_attr "type" "arith")])
2009 (define_expand "rotlsi3"
2010 [(set (match_operand:SI 0 "arith_reg_operand" "")
2011 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2012 (match_operand:SI 2 "immediate_operand" "")))]
2016 static const char rot_tab[] = {
2017 000, 000, 000, 000, 000, 000, 010, 001,
2018 001, 001, 011, 013, 003, 003, 003, 003,
2019 003, 003, 003, 003, 003, 013, 012, 002,
2020 002, 002, 010, 000, 000, 000, 000, 000,
2025 if (GET_CODE (operands[2]) != CONST_INT)
2027 count = INTVAL (operands[2]);
2028 choice = rot_tab[count];
2029 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2035 emit_move_insn (operands[0], operands[1]);
2036 count -= (count & 16) * 2;
2039 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2046 parts[0] = gen_reg_rtx (SImode);
2047 parts[1] = gen_reg_rtx (SImode);
2048 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2049 parts[choice-1] = operands[1];
2050 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2051 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2052 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2053 count = (count & ~16) - 8;
2057 for (; count > 0; count--)
2058 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2059 for (; count < 0; count++)
2060 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2065 (define_insn "*rotlhi3_8"
2066 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2067 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2071 [(set_attr "type" "arith")])
2073 (define_expand "rotlhi3"
2074 [(set (match_operand:HI 0 "arith_reg_operand" "")
2075 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2076 (match_operand:HI 2 "immediate_operand" "")))]
2080 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2087 ;; This pattern is used by init_expmed for computing the costs of shift
2090 (define_insn_and_split "ashlsi3_std"
2091 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2092 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2093 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2094 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2096 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2097 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2105 && GET_CODE (operands[2]) == CONST_INT
2106 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2107 [(set (match_dup 3) (match_dup 2))
2109 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2110 (clobber (match_dup 4))])]
2111 "operands[4] = gen_rtx_SCRATCH (SImode);"
2112 [(set_attr "length" "*,*,*,4")
2113 (set_attr "type" "dyn_shift,arith,arith,arith")])
2115 (define_insn "ashlhi3_k"
2116 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2117 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2118 (match_operand:HI 2 "const_int_operand" "M,K")))]
2119 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2123 [(set_attr "type" "arith")])
2125 (define_insn "ashlsi3_n"
2126 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2127 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2128 (match_operand:SI 2 "const_int_operand" "n")))
2129 (clobber (reg:SI T_REG))]
2130 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2132 [(set (attr "length")
2133 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2135 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2137 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2139 (const_string "8")))
2140 (set_attr "type" "arith")])
2143 [(set (match_operand:SI 0 "arith_reg_operand" "")
2144 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2145 (match_operand:SI 2 "const_int_operand" "n")))
2146 (clobber (reg:SI T_REG))]
2147 "TARGET_SH1 && reload_completed"
2148 [(use (reg:SI R0_REG))]
2151 gen_shifty_op (ASHIFT, operands);
2155 (define_insn "ashlsi3_media"
2156 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2157 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2158 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2162 shlli.l %1, %2, %0")
2164 (define_expand "ashlsi3"
2165 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2166 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2167 (match_operand:SI 2 "nonmemory_operand" "")))
2168 (clobber (reg:SI T_REG))])]
2174 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2177 if (GET_CODE (operands[2]) == CONST_INT
2178 && sh_dynamicalize_shift_p (operands[2]))
2179 operands[2] = force_reg (SImode, operands[2]);
2182 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2185 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2189 (define_insn "ashlhi3"
2190 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2191 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2192 (match_operand:HI 2 "const_int_operand" "n")))
2193 (clobber (reg:SI T_REG))]
2196 [(set (attr "length")
2197 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2199 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2201 (const_string "6")))
2202 (set_attr "type" "arith")])
2205 [(set (match_operand:HI 0 "arith_reg_operand" "")
2206 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2207 (match_operand:HI 2 "const_int_operand" "n")))
2208 (clobber (reg:SI T_REG))]
2209 "TARGET_SH1 && reload_completed"
2210 [(use (reg:SI R0_REG))]
2213 gen_shifty_hi_op (ASHIFT, operands);
2218 ; arithmetic shift right
2221 (define_insn "ashrsi3_k"
2222 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2223 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2224 (match_operand:SI 2 "const_int_operand" "M")))
2225 (clobber (reg:SI T_REG))]
2226 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2228 [(set_attr "type" "arith")])
2230 ;; We can't do HImode right shifts correctly unless we start out with an
2231 ;; explicit zero / sign extension; doing that would result in worse overall
2232 ;; code, so just let the machine independent code widen the mode.
2233 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2236 ;; ??? This should be a define expand.
2238 (define_insn "ashrsi2_16"
2239 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2240 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2244 [(set_attr "length" "4")])
2247 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2248 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2251 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2252 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2253 "operands[2] = gen_lowpart (HImode, operands[0]);")
2255 ;; ??? This should be a define expand.
2257 (define_insn "ashrsi2_31"
2258 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2259 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2261 (clobber (reg:SI T_REG))]
2264 [(set_attr "length" "4")])
2267 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2268 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2270 (clobber (reg:SI T_REG))]
2275 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2276 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2280 (define_insn "ashlsi_c"
2281 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2282 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2284 (lt:SI (match_dup 1) (const_int 0)))]
2287 [(set_attr "type" "arith")])
2289 (define_insn "ashrsi3_d"
2290 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2291 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2292 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2295 [(set_attr "type" "dyn_shift")])
2297 (define_insn "ashrsi3_n"
2298 [(set (reg:SI R4_REG)
2299 (ashiftrt:SI (reg:SI R4_REG)
2300 (match_operand:SI 0 "const_int_operand" "i")))
2301 (clobber (reg:SI T_REG))
2302 (clobber (reg:SI PR_REG))
2303 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2306 [(set_attr "type" "sfunc")
2307 (set_attr "needs_delay_slot" "yes")])
2309 (define_insn "ashrsi3_media"
2310 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2311 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2312 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2316 shari.l %1, %2, %0")
2318 (define_expand "ashrsi3"
2319 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2320 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2321 (match_operand:SI 2 "nonmemory_operand" "")))
2322 (clobber (reg:SI T_REG))])]
2328 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2331 if (expand_ashiftrt (operands))
2337 ;; logical shift right
2339 (define_insn "lshrsi3_d"
2340 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2341 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2342 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2345 [(set_attr "type" "dyn_shift")])
2347 ;; Only the single bit shift clobbers the T bit.
2349 (define_insn "lshrsi3_m"
2350 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2351 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2352 (match_operand:SI 2 "const_int_operand" "M")))
2353 (clobber (reg:SI T_REG))]
2354 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2356 [(set_attr "type" "arith")])
2358 (define_insn "lshrsi3_k"
2359 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2360 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2361 (match_operand:SI 2 "const_int_operand" "K")))]
2362 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2363 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2365 [(set_attr "type" "arith")])
2367 (define_insn "lshrsi3_n"
2368 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2369 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2370 (match_operand:SI 2 "const_int_operand" "n")))
2371 (clobber (reg:SI T_REG))]
2372 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2374 [(set (attr "length")
2375 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2377 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2379 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2381 (const_string "8")))
2382 (set_attr "type" "arith")])
2385 [(set (match_operand:SI 0 "arith_reg_operand" "")
2386 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2387 (match_operand:SI 2 "const_int_operand" "n")))
2388 (clobber (reg:SI T_REG))]
2389 "TARGET_SH1 && reload_completed"
2390 [(use (reg:SI R0_REG))]
2393 gen_shifty_op (LSHIFTRT, operands);
2397 (define_insn "lshrsi3_media"
2398 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2399 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r,r")
2400 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2404 shlri.l %1, %2, %0")
2406 (define_expand "lshrsi3"
2407 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2408 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2409 (match_operand:SI 2 "nonmemory_operand" "")))
2410 (clobber (reg:SI T_REG))])]
2416 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2419 if (GET_CODE (operands[2]) == CONST_INT
2420 && sh_dynamicalize_shift_p (operands[2]))
2421 operands[2] = force_reg (SImode, operands[2]);
2422 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2424 rtx count = copy_to_mode_reg (SImode, operands[2]);
2425 emit_insn (gen_negsi2 (count, count));
2426 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2429 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2433 ;; ??? This should be a define expand.
2435 (define_insn "ashldi3_k"
2436 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2437 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2439 (clobber (reg:SI T_REG))]
2441 "shll %R0\;rotcl %S0"
2442 [(set_attr "length" "4")
2443 (set_attr "type" "arith")])
2445 (define_insn "ashldi3_media"
2446 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2447 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2448 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2454 (define_expand "ashldi3"
2455 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2456 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2457 (match_operand:DI 2 "immediate_operand" "")))
2458 (clobber (reg:SI T_REG))])]
2464 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2467 if (GET_CODE (operands[2]) != CONST_INT
2468 || INTVAL (operands[2]) != 1)
2472 ;; ??? This should be a define expand.
2474 (define_insn "lshrdi3_k"
2475 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2476 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2478 (clobber (reg:SI T_REG))]
2480 "shlr %S0\;rotcr %R0"
2481 [(set_attr "length" "4")
2482 (set_attr "type" "arith")])
2484 (define_insn "lshrdi3_media"
2485 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2486 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2487 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2493 (define_expand "lshrdi3"
2494 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2495 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2496 (match_operand:DI 2 "immediate_operand" "")))
2497 (clobber (reg:SI T_REG))])]
2503 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2506 if (GET_CODE (operands[2]) != CONST_INT
2507 || INTVAL (operands[2]) != 1)
2511 ;; ??? This should be a define expand.
2513 (define_insn "ashrdi3_k"
2514 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2515 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2517 (clobber (reg:SI T_REG))]
2519 "shar %S0\;rotcr %R0"
2520 [(set_attr "length" "4")
2521 (set_attr "type" "arith")])
2523 (define_insn "ashrdi3_media"
2524 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2525 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2526 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2532 (define_expand "ashrdi3"
2533 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2534 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2535 (match_operand:DI 2 "immediate_operand" "")))
2536 (clobber (reg:SI T_REG))])]
2542 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2545 if (GET_CODE (operands[2]) != CONST_INT
2546 || INTVAL (operands[2]) != 1)
2550 ;; combined left/right shift
2553 [(set (match_operand:SI 0 "register_operand" "")
2554 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2555 (match_operand:SI 2 "const_int_operand" "n"))
2556 (match_operand:SI 3 "const_int_operand" "n")))]
2557 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2558 [(use (reg:SI R0_REG))]
2559 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2563 [(set (match_operand:SI 0 "register_operand" "")
2564 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2565 (match_operand:SI 2 "const_int_operand" "n"))
2566 (match_operand:SI 3 "const_int_operand" "n")))
2567 (clobber (reg:SI T_REG))]
2568 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2569 [(use (reg:SI R0_REG))]
2570 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2574 [(set (match_operand:SI 0 "register_operand" "=r")
2575 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2576 (match_operand:SI 2 "const_int_operand" "n"))
2577 (match_operand:SI 3 "const_int_operand" "n")))
2578 (clobber (reg:SI T_REG))]
2579 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2581 [(set (attr "length")
2582 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2584 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2586 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2588 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2590 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2592 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2594 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2595 (const_string "16")]
2596 (const_string "18")))
2597 (set_attr "type" "arith")])
2600 [(set (match_operand:SI 0 "register_operand" "=z")
2601 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2602 (match_operand:SI 2 "const_int_operand" "n"))
2603 (match_operand:SI 3 "const_int_operand" "n")))
2604 (clobber (reg:SI T_REG))]
2605 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2607 [(set (attr "length")
2608 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2610 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2612 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2614 (const_string "10")))
2615 (set_attr "type" "arith")])
2617 ;; shift left / and combination with a scratch register: The combine pass
2618 ;; does not accept the individual instructions, even though they are
2619 ;; cheap. But it needs a precise description so that it is usable after
2621 (define_insn "and_shl_scratch"
2622 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2626 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2627 (match_operand:SI 2 "const_int_operand" "N,n"))
2628 (match_operand:SI 3 "" "0,r"))
2629 (match_operand:SI 4 "const_int_operand" "n,n"))
2630 (match_operand:SI 5 "const_int_operand" "n,n")))
2631 (clobber (reg:SI T_REG))]
2634 [(set (attr "length")
2635 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2637 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2639 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2641 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2642 (const_string "10")]
2643 (const_string "12")))
2644 (set_attr "type" "arith")])
2647 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2651 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2652 (match_operand:SI 2 "const_int_operand" "N,n"))
2653 (match_operand:SI 3 "register_operand" "0,r"))
2654 (match_operand:SI 4 "const_int_operand" "n,n"))
2655 (match_operand:SI 5 "const_int_operand" "n,n")))
2656 (clobber (reg:SI T_REG))]
2658 [(use (reg:SI R0_REG))]
2661 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2663 if (INTVAL (operands[2]))
2665 gen_shifty_op (LSHIFTRT, operands);
2667 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2668 operands[2] = operands[4];
2669 gen_shifty_op (ASHIFT, operands);
2670 if (INTVAL (operands[5]))
2672 operands[2] = operands[5];
2673 gen_shifty_op (LSHIFTRT, operands);
2678 ;; signed left/right shift combination.
2680 [(set (match_operand:SI 0 "register_operand" "=r")
2682 (ashift:SI (match_operand:SI 1 "register_operand" "r")
2683 (match_operand:SI 2 "const_int_operand" "n"))
2684 (match_operand:SI 3 "const_int_operand" "n")
2686 (clobber (reg:SI T_REG))]
2688 [(use (reg:SI R0_REG))]
2689 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2692 (define_insn "shl_sext_ext"
2693 [(set (match_operand:SI 0 "register_operand" "=r")
2695 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2696 (match_operand:SI 2 "const_int_operand" "n"))
2697 (match_operand:SI 3 "const_int_operand" "n")
2699 (clobber (reg:SI T_REG))]
2700 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2702 [(set (attr "length")
2703 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2705 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2707 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2709 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2711 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2713 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2715 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2717 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2718 (const_string "16")]
2719 (const_string "18")))
2720 (set_attr "type" "arith")])
2722 (define_insn "shl_sext_sub"
2723 [(set (match_operand:SI 0 "register_operand" "=z")
2725 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2726 (match_operand:SI 2 "const_int_operand" "n"))
2727 (match_operand:SI 3 "const_int_operand" "n")
2729 (clobber (reg:SI T_REG))]
2730 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2732 [(set (attr "length")
2733 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2735 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2737 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2739 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2740 (const_string "12")]
2741 (const_string "14")))
2742 (set_attr "type" "arith")])
2744 ;; These patterns are found in expansions of DImode shifts by 16, and
2745 ;; allow the xtrct instruction to be generated from C source.
2747 (define_insn "xtrct_left"
2748 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2749 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2751 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2755 [(set_attr "type" "arith")])
2757 (define_insn "xtrct_right"
2758 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2759 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2761 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2765 [(set_attr "type" "arith")])
2767 ;; -------------------------------------------------------------------------
2769 ;; -------------------------------------------------------------------------
2772 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2773 (neg:SI (plus:SI (reg:SI T_REG)
2774 (match_operand:SI 1 "arith_reg_operand" "r"))))
2776 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2780 [(set_attr "type" "arith")])
2782 (define_insn "*negdi_media"
2783 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2784 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2788 (define_expand "negdi2"
2789 [(set (match_operand:DI 0 "arith_reg_operand" "")
2790 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
2791 (clobber (reg:SI T_REG))]
2797 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2798 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2800 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2801 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2803 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2804 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2806 emit_insn (gen_clrt ());
2807 emit_insn (gen_negc (low_dst, low_src));
2808 emit_insn (gen_negc (high_dst, high_src));
2813 (define_insn "negsi2"
2814 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2815 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2818 [(set_attr "type" "arith")])
2820 (define_insn "one_cmplsi2"
2821 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2822 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2825 [(set_attr "type" "arith")])
2827 (define_expand "one_cmpldi2"
2828 [(set (match_operand:DI 0 "arith_reg_operand" "")
2829 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2831 "TARGET_SHMEDIA" "")
2833 ;; -------------------------------------------------------------------------
2834 ;; Zero extension instructions
2835 ;; -------------------------------------------------------------------------
2837 (define_insn "zero_extendsidi2"
2838 [(set (match_operand:DI 0 "register_operand" "=r")
2839 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2841 "addz.l %1, r63, %0")
2843 (define_insn "zero_extendhidi2"
2844 [(set (match_operand:DI 0 "register_operand" "=r,r")
2845 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
2852 [(set (match_operand:DI 0 "register_operand" "=r")
2853 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2854 "TARGET_SHMEDIA && reload_completed"
2855 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2856 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))])
2858 (define_insn "zero_extendqidi2"
2859 [(set (match_operand:DI 0 "register_operand" "=r,r")
2860 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2866 (define_insn "zero_extendhisi2"
2867 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2868 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2871 [(set_attr "type" "arith")])
2873 (define_insn "zero_extendqisi2"
2874 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2875 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2878 [(set_attr "type" "arith")])
2880 (define_insn "zero_extendqihi2"
2881 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2882 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
2885 [(set_attr "type" "arith")])
2887 ;; -------------------------------------------------------------------------
2888 ;; Sign extension instructions
2889 ;; -------------------------------------------------------------------------
2891 ;; ??? This should be a define expand.
2892 ;; ??? Or perhaps it should be dropped?
2894 ;; convert_move generates good code for SH[1-4].
2895 (define_insn "extendsidi2"
2896 [(set (match_operand:DI 0 "register_operand" "=r,r")
2897 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
2903 (define_insn "extendhidi2"
2904 [(set (match_operand:DI 0 "register_operand" "=r,r")
2905 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
2912 [(set (match_operand:DI 0 "register_operand" "=r")
2913 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2914 "TARGET_SHMEDIA && reload_completed"
2915 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2916 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))])
2918 (define_insn "extendqidi2"
2919 [(set (match_operand:DI 0 "register_operand" "=r,r")
2920 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
2927 [(set (match_operand:DI 0 "register_operand" "=r")
2928 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2929 "TARGET_SHMEDIA && reload_completed"
2930 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
2931 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))])
2933 (define_insn "extendhisi2"
2934 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2935 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
2940 [(set_attr "type" "arith,load")])
2942 (define_insn "extendqisi2"
2943 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2944 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2949 [(set_attr "type" "arith,load")])
2951 (define_insn "extendqihi2"
2952 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2953 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2958 [(set_attr "type" "arith,load")])
2960 ;; -------------------------------------------------------------------------
2961 ;; Move instructions
2962 ;; -------------------------------------------------------------------------
2964 ;; define push and pop so it is easy for sh.c
2965 ;; We can't use push and pop on SHcompact because the stack must always
2966 ;; be 8-byte aligned.
2968 (define_expand "push"
2969 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
2970 (match_operand:SI 0 "register_operand" "r,l,x"))]
2971 "TARGET_SH1 && ! TARGET_SH5"
2974 (define_expand "pop"
2975 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
2976 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
2977 "TARGET_SH1 && ! TARGET_SH5"
2980 (define_expand "push_e"
2981 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
2982 (match_operand:SF 0 "" ""))
2983 (use (reg:PSI FPSCR_REG))
2984 (clobber (scratch:SI))])]
2985 "TARGET_SH1 && ! TARGET_SH5"
2988 (define_insn "push_fpul"
2989 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
2990 "TARGET_SH3E && ! TARGET_SH5"
2992 [(set_attr "type" "store")
2993 (set_attr "hit_stack" "yes")])
2995 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
2997 (define_expand "push_4"
2998 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
2999 (match_operand:DF 0 "" ""))
3000 (use (reg:PSI FPSCR_REG))
3001 (clobber (scratch:SI))])]
3002 "TARGET_SH1 && ! TARGET_SH5"
3005 (define_expand "pop_e"
3006 [(parallel [(set (match_operand:SF 0 "" "")
3007 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3008 (use (reg:PSI FPSCR_REG))
3009 (clobber (scratch:SI))])]
3010 "TARGET_SH1 && ! TARGET_SH5"
3013 (define_insn "pop_fpul"
3014 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3015 "TARGET_SH3E && ! TARGET_SH5"
3017 [(set_attr "type" "load")
3018 (set_attr "hit_stack" "yes")])
3020 (define_expand "pop_4"
3021 [(parallel [(set (match_operand:DF 0 "" "")
3022 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3023 (use (reg:PSI FPSCR_REG))
3024 (clobber (scratch:SI))])]
3025 "TARGET_SH1 && ! TARGET_SH5"
3028 ;; These two patterns can happen as the result of optimization, when
3029 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3030 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3033 [(set (reg:SI T_REG) (const_int 0))]
3038 [(set (reg:SI T_REG) (const_int 1))]
3042 ;; t/r must come after r/r, lest reload will try to reload stuff like
3043 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3044 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3045 (define_insn "movsi_i"
3046 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3047 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3050 && (register_operand (operands[0], SImode)
3051 || register_operand (operands[1], SImode))"
3068 [(set_attr "type" "pcload_si,move,*,load_si,move,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3069 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3071 ;; t/r must come after r/r, lest reload will try to reload stuff like
3072 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3073 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3074 ;; will require a reload.
3075 (define_insn "movsi_ie"
3076 [(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")
3077 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3079 && (register_operand (operands[0], SImode)
3080 || register_operand (operands[1], SImode))"
3101 ! move optimized away"
3102 [(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")
3103 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3105 (define_insn "movsi_i_lowpart"
3106 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3107 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3109 && (register_operand (operands[0], SImode)
3110 || register_operand (operands[1], SImode))"
3120 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3122 (define_insn "*movsi_media"
3123 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b*k,r,b*k")
3124 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,r,f,f,r,*b*k,T"))]
3126 && (register_operand (operands[0], SImode)
3127 || register_operand (operands[1], SImode))"
3142 [(set_attr "type" "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3143 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3145 (define_insn "*movsi_media_nofpu"
3146 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b*k,r,b*k")
3147 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b*k,T"))]
3149 && (register_operand (operands[0], SImode)
3150 || register_operand (operands[1], SImode))"
3160 [(set_attr "type" "move,move,*,load,store,ptabs,move,pt")
3161 (set_attr "length" "4,4,8,4,4,4,4,12")])
3164 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3165 (match_operand:SI 1 "immediate_operand" "s"))]
3166 "TARGET_SHMEDIA && reload_completed
3167 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3168 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3171 operands[2] = shallow_copy_rtx (operands[1]);
3172 PUT_MODE (operands[2], DImode);
3176 [(set (match_operand:SI 0 "register_operand" "=r")
3177 (match_operand:SI 1 "immediate_operand" "n"))]
3179 && ((GET_CODE (operands[1]) == CONST_INT
3180 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3181 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3182 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3184 (define_expand "movsi"
3185 [(set (match_operand:SI 0 "general_movdst_operand" "")
3186 (match_operand:SI 1 "general_movsrc_operand" ""))]
3188 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3190 (define_expand "ic_invalidate_line"
3191 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3192 (match_dup 1)] UNSPEC_ICACHE)
3193 (clobber (scratch:SI))])]
3194 "TARGET_HARD_SH4 || TARGET_SH5"
3199 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3202 else if (TARGET_SHCOMPACT)
3204 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3205 operands[1] = force_reg (Pmode, operands[1]);
3206 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3209 operands[0] = force_reg (Pmode, operands[0]);
3210 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3214 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3215 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3216 ;; the requirement *1*00 for associative address writes. The alignment of
3217 ;; %0 implies that its least significant bit is cleared,
3218 ;; thus we clear the V bit of a matching entry if there is one.
3219 (define_insn "ic_invalidate_line_i"
3220 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3221 (match_operand:SI 1 "register_operand" "r")]
3223 (clobber (match_scratch:SI 2 "=&r"))]
3225 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3226 [(set_attr "length" "8")])
3228 (define_insn "ic_invalidate_line_media"
3229 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3233 [(set_attr "length" "8")])
3235 (define_insn "ic_invalidate_line_compact"
3236 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3237 (match_operand:SI 1 "register_operand" "r")]
3239 (clobber (reg:SI PR_REG))]
3242 [(set_attr "type" "sfunc")
3243 (set_attr "needs_delay_slot" "yes")])
3245 (define_insn "movqi_i"
3246 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3247 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3249 && (arith_reg_operand (operands[0], QImode)
3250 || arith_reg_operand (operands[1], QImode))"
3258 [(set_attr "type" "move,load,store,move,move,move")])
3260 (define_insn "*movqi_media"
3261 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3262 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3264 && (arith_reg_operand (operands[0], QImode)
3265 || arith_reg_operand (operands[1], QImode))"
3272 (define_expand "movqi"
3273 [(set (match_operand:QI 0 "general_operand" "")
3274 (match_operand:QI 1 "general_operand" ""))]
3276 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3278 (define_insn "movhi_i"
3279 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3280 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3282 && (arith_reg_operand (operands[0], HImode)
3283 || arith_reg_operand (operands[1], HImode))"
3293 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3295 (define_insn "*movhi_media"
3296 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3297 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3299 && (arith_reg_operand (operands[0], HImode)
3300 || arith_reg_operand (operands[1], HImode))"
3309 [(set (match_operand:HI 0 "register_operand" "=r")
3310 (match_operand:HI 1 "immediate_operand" "n"))]
3311 "TARGET_SHMEDIA && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3312 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3314 (define_expand "movhi"
3315 [(set (match_operand:HI 0 "general_movdst_operand" "")
3316 (match_operand:HI 1 "general_movsrc_operand" ""))]
3318 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3320 ;; ??? This should be a define expand.
3322 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3323 ;; compiled with -m2 -ml -O3 -funroll-loops
3325 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3326 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3328 && (arith_reg_operand (operands[0], DImode)
3329 || arith_reg_operand (operands[1], DImode))"
3330 "* return output_movedouble (insn, operands, DImode);"
3331 [(set_attr "length" "4")
3332 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3334 ;; If the output is a register and the input is memory or a register, we have
3335 ;; to be careful and see which word needs to be loaded first.
3338 [(set (match_operand:DI 0 "general_movdst_operand" "")
3339 (match_operand:DI 1 "general_movsrc_operand" ""))]
3340 "TARGET_SH1 && reload_completed"
3341 [(set (match_dup 2) (match_dup 3))
3342 (set (match_dup 4) (match_dup 5))]
3347 if ((GET_CODE (operands[0]) == MEM
3348 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3349 || (GET_CODE (operands[1]) == MEM
3350 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3353 if (GET_CODE (operands[0]) == REG)
3354 regno = REGNO (operands[0]);
3355 else if (GET_CODE (operands[0]) == SUBREG)
3356 regno = subreg_regno (operands[0]);
3357 else if (GET_CODE (operands[0]) == MEM)
3363 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3365 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3366 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3367 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3368 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3372 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3373 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3374 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3375 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3378 if (operands[2] == 0 || operands[3] == 0
3379 || operands[4] == 0 || operands[5] == 0)
3383 (define_insn "*movdi_media"
3384 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b*k,r,b*k")
3385 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,r,f,f,r,*b*k,T"))]
3387 && (register_operand (operands[0], DImode)
3388 || register_operand (operands[1], DImode))"
3403 [(set_attr "type" "move,move,*,load,store,load,store,move,move,move,ptabs,move,pt")
3404 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3406 (define_insn "*movdi_media_nofpu"
3407 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b*k,r,b*k")
3408 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b*k,T"))]
3410 && (register_operand (operands[0], DImode)
3411 || register_operand (operands[1], DImode))"
3421 [(set_attr "type" "move,move,*,load,store,ptabs,move,pt")
3422 (set_attr "length" "4,4,16,4,4,4,4,*")])
3425 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3426 (match_operand:DI 1 "immediate_operand" "s"))]
3427 "TARGET_SHMEDIA && reload_completed
3428 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3429 [(set (match_dup 0) (match_dup 1))]
3434 if (TARGET_SHMEDIA64)
3435 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3437 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3439 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3445 (define_expand "movdi_const"
3446 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3447 (const:DI (sign_extend:DI
3450 (match_operand:DI 1 "immediate_operand" "s")
3453 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3461 (const_int 32)))))))))
3463 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3471 (const_int 16)))))))))
3473 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3479 (match_dup 1))))))))]
3480 "TARGET_SHMEDIA64 && reload_completed
3481 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3484 if (GET_CODE (operands[1]) == LABEL_REF
3485 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3486 LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3487 else if (GOTOFF_P (operands[1])
3488 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3489 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3491 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3494 (define_expand "movdi_const_32bit"
3495 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3496 (const:DI (sign_extend:DI
3499 (match_operand:DI 1 "immediate_operand" "s")
3502 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3508 (match_dup 1))))))))]
3509 "TARGET_SHMEDIA32 && reload_completed
3510 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3513 if (GET_CODE (operands[1]) == LABEL_REF
3514 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3515 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3516 else if (GOTOFF_P (operands[1])
3517 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3518 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3520 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3523 (define_expand "movdi_const_16bit"
3524 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3525 (const:DI (sign_extend:DI
3527 (match_operand:DI 1 "immediate_operand" "s")))))]
3528 "TARGET_SHMEDIA && flag_pic && reload_completed
3529 && GET_CODE (operands[1]) == SYMBOL_REF"
3533 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3534 (match_operand:DI 1 "immediate_operand" "i"))]
3535 "TARGET_SHMEDIA && reload_completed
3536 && GET_CODE (operands[1]) == CONST_INT
3537 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3538 [(set (match_dup 0) (match_dup 2))
3540 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3541 (zero_extend:DI (truncate:HI (match_dup 1)))))]
3544 unsigned HOST_WIDE_INT low = INTVAL (operands[1]);
3545 unsigned HOST_WIDE_INT val = low;
3546 unsigned HOST_WIDE_INT sign;
3548 /* Sign-extend the 16 least-significant bits. */
3552 operands[1] = GEN_INT (val);
3554 /* Arithmetic shift right the word by 16 bits. */
3557 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3560 operands[2] = GEN_INT (low);
3564 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3565 (match_operand:DI 1 "immediate_operand" "F"))]
3566 "TARGET_SHMEDIA && reload_completed
3567 && GET_CODE (operands[1]) == CONST_DOUBLE"
3568 [(set (match_dup 0) (match_dup 2))
3570 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3571 (zero_extend:DI (truncate:HI (match_dup 1)))))]
3574 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
3575 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
3576 unsigned HOST_WIDE_INT val = low;
3577 unsigned HOST_WIDE_INT sign;
3579 /* Sign-extend the 16 least-significant bits. */
3583 operands[1] = GEN_INT (val);
3585 /* Arithmetic shift right the double-word by 16 bits. */
3587 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
3590 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3594 /* This will only be true if high is a sign-extension of low, i.e.,
3595 it must be either 0 or (unsigned)-1, and be zero iff the
3596 most-significant bit of low is set. */
3597 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
3598 operands[2] = GEN_INT (low);
3600 operands[2] = immed_double_const (low, high, DImode);
3603 (define_insn "*shori_media"
3604 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
3605 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
3609 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
3615 (define_expand "movdi"
3616 [(set (match_operand:DI 0 "general_movdst_operand" "")
3617 (match_operand:DI 1 "general_movsrc_operand" ""))]
3619 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
3621 (define_insn "movdf_media"
3622 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
3623 (match_operand:DF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
3625 && (register_operand (operands[0], DFmode)
3626 || register_operand (operands[1], DFmode))"
3637 [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
3639 (define_insn "movdf_media_nofpu"
3640 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3641 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
3643 && (register_operand (operands[0], DFmode)
3644 || register_operand (operands[1], DFmode))"
3650 [(set_attr "type" "move,*,load,store")])
3653 [(set (match_operand:DF 0 "arith_reg_operand" "")
3654 (match_operand:DF 1 "immediate_operand" ""))]
3655 "TARGET_SHMEDIA && reload_completed"
3656 [(set (match_dup 3) (match_dup 2))]
3659 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
3661 REAL_VALUE_TYPE value;
3663 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
3664 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
3666 if (HOST_BITS_PER_WIDE_INT >= 64)
3667 operands[2] = immed_double_const ((unsigned long) values[endian]
3668 | ((HOST_WIDE_INT) values[1 - endian]
3670 else if (HOST_BITS_PER_WIDE_INT == 32)
3671 operands[2] = immed_double_const (values[endian], values[1 - endian],
3676 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
3679 ;; ??? This should be a define expand.
3681 (define_insn "movdf_k"
3682 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
3683 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
3685 && (! TARGET_SH4 || reload_completed
3686 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
3687 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
3688 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
3689 && (arith_reg_operand (operands[0], DFmode)
3690 || arith_reg_operand (operands[1], DFmode))"
3691 "* return output_movedouble (insn, operands, DFmode);"
3692 [(set_attr "length" "4")
3693 (set_attr "type" "move,pcload,load,store")])
3695 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
3696 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
3697 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
3698 ;; the d/m/c/X alternative, which is split later into single-precision
3699 ;; instructions. And when not optimizing, no splits are done before fixing
3700 ;; up pcloads, so we need usable length information for that.
3701 (define_insn "movdf_i4"
3702 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
3703 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
3704 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
3705 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
3707 && (arith_reg_operand (operands[0], DFmode)
3708 || arith_reg_operand (operands[1], DFmode))"
3720 [(set_attr_alternative "length"
3721 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
3723 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
3724 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3725 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
3727 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
3728 ;; We can't use 4-byte push/pop on SHcompact, so we have to
3729 ;; increment or decrement r15 explicitly.
3731 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3732 (const_int 10) (const_int 8))
3734 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
3735 (const_int 10) (const_int 8))])
3736 (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")
3737 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
3738 (const_string "double")
3739 (const_string "none")))])
3741 ;; Moving DFmode between fp/general registers through memory
3742 ;; (the top of the stack) is faster than moving through fpul even for
3743 ;; little endian. Because the type of an instruction is important for its
3744 ;; scheduling, it is beneficial to split these operations, rather than
3745 ;; emitting them in one single chunk, even if this will expose a stack
3746 ;; use that will prevent scheduling of other stack accesses beyond this
3749 [(set (match_operand:DF 0 "register_operand" "")
3750 (match_operand:DF 1 "register_operand" ""))
3751 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3752 (clobber (match_scratch:SI 3 "=X"))]
3753 "TARGET_SH4 && reload_completed
3754 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
3760 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
3762 emit_move_insn (stack_pointer_rtx,
3763 plus_constant (stack_pointer_rtx, -8));
3764 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3767 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
3768 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
3769 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
3770 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3771 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3772 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
3774 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
3775 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
3776 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
3777 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
3779 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3783 ;; local-alloc sometimes allocates scratch registers even when not required,
3784 ;; so we must be prepared to handle these.
3786 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
3788 [(set (match_operand:DF 0 "general_movdst_operand" "")
3789 (match_operand:DF 1 "general_movsrc_operand" ""))
3790 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3791 (clobber (match_scratch:SI 3 "X"))]
3794 && true_regnum (operands[0]) < 16
3795 && true_regnum (operands[1]) < 16"
3796 [(set (match_dup 0) (match_dup 1))]
3799 /* If this was a reg <-> mem operation with base + index reg addressing,
3800 we have to handle this in a special way. */
3801 rtx mem = operands[0];
3803 if (! memory_operand (mem, DFmode))
3808 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
3809 mem = SUBREG_REG (mem);
3810 if (GET_CODE (mem) == MEM)
3812 rtx addr = XEXP (mem, 0);
3813 if (GET_CODE (addr) == PLUS
3814 && GET_CODE (XEXP (addr, 0)) == REG
3815 && GET_CODE (XEXP (addr, 1)) == REG)
3818 rtx reg0 = gen_rtx (REG, Pmode, 0);
3819 rtx regop = operands[store_p], word0 ,word1;
3821 if (GET_CODE (regop) == SUBREG)
3822 alter_subreg (®op);
3823 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
3827 mem = copy_rtx (mem);
3828 PUT_MODE (mem, SImode);
3829 word0 = gen_rtx (SUBREG, SImode, regop, 0);
3830 alter_subreg (&word0);
3831 word1 = gen_rtx (SUBREG, SImode, regop, 4);
3832 alter_subreg (&word1);
3833 if (store_p || ! refers_to_regno_p (REGNO (word0),
3834 REGNO (word0) + 1, addr, 0))
3837 ? gen_movsi_ie (mem, word0)
3838 : gen_movsi_ie (word0, mem));
3839 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
3840 mem = copy_rtx (mem);
3842 ? gen_movsi_ie (mem, word1)
3843 : gen_movsi_ie (word1, mem));
3844 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
3848 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
3849 emit_insn (gen_movsi_ie (word1, mem));
3850 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
3851 mem = copy_rtx (mem);
3852 emit_insn (gen_movsi_ie (word0, mem));
3859 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
3861 [(set (match_operand:DF 0 "register_operand" "")
3862 (match_operand:DF 1 "memory_operand" ""))
3863 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3864 (clobber (reg:SI R0_REG))]
3865 "TARGET_SH4 && reload_completed"
3866 [(parallel [(set (match_dup 0) (match_dup 1))
3868 (clobber (scratch:SI))])]
3871 (define_expand "reload_indf"
3872 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
3873 (match_operand:DF 1 "immediate_operand" "FQ"))
3874 (use (reg:PSI FPSCR_REG))
3875 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
3879 (define_expand "reload_outdf"
3880 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
3881 (match_operand:DF 1 "register_operand" "af,r"))
3882 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
3886 ;; Simplify no-op moves.
3888 [(set (match_operand:SF 0 "register_operand" "")
3889 (match_operand:SF 1 "register_operand" ""))
3890 (use (match_operand:PSI 2 "fpscr_operand" ""))
3891 (clobber (match_scratch:SI 3 "X"))]
3892 "TARGET_SH3E && reload_completed
3893 && true_regnum (operands[0]) == true_regnum (operands[1])"
3894 [(set (match_dup 0) (match_dup 0))]
3897 ;; fmovd substitute post-reload splits
3899 [(set (match_operand:DF 0 "register_operand" "")
3900 (match_operand:DF 1 "register_operand" ""))
3901 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3902 (clobber (match_scratch:SI 3 "X"))]
3903 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
3904 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
3905 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
3909 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
3910 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
3911 gen_rtx (REG, SFmode, src), operands[2]));
3912 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
3913 gen_rtx (REG, SFmode, src + 1), operands[2]));
3918 [(set (match_operand:DF 0 "register_operand" "")
3919 (mem:DF (match_operand:SI 1 "register_operand" "")))
3920 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3921 (clobber (match_scratch:SI 3 "X"))]
3922 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
3923 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
3924 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
3928 int regno = true_regnum (operands[0]);
3930 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
3932 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
3933 regno + !! TARGET_LITTLE_ENDIAN),
3934 mem2, operands[2]));
3935 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
3936 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
3937 regno + ! TARGET_LITTLE_ENDIAN),
3938 gen_rtx (MEM, SFmode, operands[1]),
3944 [(set (match_operand:DF 0 "register_operand" "")
3945 (match_operand:DF 1 "memory_operand" ""))
3946 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3947 (clobber (match_scratch:SI 3 "X"))]
3948 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
3949 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
3953 int regno = true_regnum (operands[0]);
3954 rtx addr, insn, adjust = NULL_RTX;
3955 rtx mem2 = copy_rtx (operands[1]);
3956 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
3957 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
3959 PUT_MODE (mem2, SFmode);
3960 operands[1] = copy_rtx (mem2);
3961 addr = XEXP (mem2, 0);
3962 if (GET_CODE (addr) != POST_INC)
3964 /* If we have to modify the stack pointer, the value that we have
3965 read with post-increment might be modified by an interrupt,
3966 so write it back. */
3967 if (REGNO (addr) == STACK_POINTER_REGNUM)
3968 adjust = gen_push_e (reg0);
3970 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
3971 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
3973 addr = XEXP (addr, 0);
3974 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
3975 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
3976 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
3980 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
3985 [(set (match_operand:DF 0 "memory_operand" "")
3986 (match_operand:DF 1 "register_operand" ""))
3987 (use (match_operand:PSI 2 "fpscr_operand" "c"))
3988 (clobber (match_scratch:SI 3 "X"))]
3989 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
3990 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
3994 int regno = true_regnum (operands[1]);
3995 rtx insn, addr, adjust = NULL_RTX;
3997 operands[0] = copy_rtx (operands[0]);
3998 PUT_MODE (operands[0], SFmode);
3999 insn = emit_insn (gen_movsf_ie (operands[0],
4000 gen_rtx (REG, SFmode,
4001 regno + ! TARGET_LITTLE_ENDIAN),
4003 operands[0] = copy_rtx (operands[0]);
4004 addr = XEXP (operands[0], 0);
4005 if (GET_CODE (addr) != PRE_DEC)
4007 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4008 emit_insn_before (adjust, insn);
4009 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4011 addr = XEXP (addr, 0);
4013 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4014 insn = emit_insn (gen_movsf_ie (operands[0],
4015 gen_rtx (REG, SFmode,
4016 regno + !! TARGET_LITTLE_ENDIAN),
4018 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4022 ;; If the output is a register and the input is memory or a register, we have
4023 ;; to be careful and see which word needs to be loaded first.
4026 [(set (match_operand:DF 0 "general_movdst_operand" "")
4027 (match_operand:DF 1 "general_movsrc_operand" ""))]
4028 "TARGET_SH1 && reload_completed"
4029 [(set (match_dup 2) (match_dup 3))
4030 (set (match_dup 4) (match_dup 5))]
4035 if ((GET_CODE (operands[0]) == MEM
4036 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4037 || (GET_CODE (operands[1]) == MEM
4038 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4041 if (GET_CODE (operands[0]) == REG)
4042 regno = REGNO (operands[0]);
4043 else if (GET_CODE (operands[0]) == SUBREG)
4044 regno = subreg_regno (operands[0]);
4045 else if (GET_CODE (operands[0]) == MEM)
4051 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4053 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4054 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4055 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4056 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4060 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4061 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4062 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4063 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4066 if (operands[2] == 0 || operands[3] == 0
4067 || operands[4] == 0 || operands[5] == 0)
4071 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4072 ;; used only once, let combine add in the index again.
4075 [(set (match_operand:SI 0 "register_operand" "")
4076 (match_operand:SI 1 "" ""))
4077 (clobber (match_operand 2 "register_operand" ""))]
4078 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4079 [(use (reg:SI R0_REG))]
4082 rtx addr, reg, const_int;
4084 if (GET_CODE (operands[1]) != MEM)
4086 addr = XEXP (operands[1], 0);
4087 if (GET_CODE (addr) != PLUS)
4089 reg = XEXP (addr, 0);
4090 const_int = XEXP (addr, 1);
4091 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4092 && GET_CODE (const_int) == CONST_INT))
4094 emit_move_insn (operands[2], const_int);
4095 emit_move_insn (operands[0],
4096 change_address (operands[1], VOIDmode,
4097 gen_rtx_PLUS (SImode, reg, operands[2])));
4102 [(set (match_operand:SI 1 "" "")
4103 (match_operand:SI 0 "register_operand" ""))
4104 (clobber (match_operand 2 "register_operand" ""))]
4105 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4106 [(use (reg:SI R0_REG))]
4109 rtx addr, reg, const_int;
4111 if (GET_CODE (operands[1]) != MEM)
4113 addr = XEXP (operands[1], 0);
4114 if (GET_CODE (addr) != PLUS)
4116 reg = XEXP (addr, 0);
4117 const_int = XEXP (addr, 1);
4118 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4119 && GET_CODE (const_int) == CONST_INT))
4121 emit_move_insn (operands[2], const_int);
4122 emit_move_insn (change_address (operands[1], VOIDmode,
4123 gen_rtx_PLUS (SImode, reg, operands[2])),
4128 (define_expand "movdf"
4129 [(set (match_operand:DF 0 "general_movdst_operand" "")
4130 (match_operand:DF 1 "general_movsrc_operand" ""))]
4134 if (prepare_move_operands (operands, DFmode)) DONE;
4137 if (TARGET_SHMEDIA_FPU)
4138 emit_insn (gen_movdf_media (operands[0], operands[1]));
4140 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4145 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4150 (define_insn "movv2sf_i"
4151 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4152 (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4154 && (fp_arith_reg_operand (operands[0], V2SFmode)
4155 || fp_arith_reg_operand (operands[1], V2SFmode))"
4162 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f")
4163 (match_operand:V2SF 1 "nonimmediate_operand" "f"))]
4164 "TARGET_SHMEDIA_FPU && reload_completed
4165 && fp_arith_reg_operand (operands[0], V2SFmode)
4166 && fp_arith_reg_operand (operands[1], V2SFmode)"
4167 [(set (subreg:DF (match_dup 0) 0) (subreg:DF (match_dup 1) 0))])
4169 (define_expand "movv2sf"
4170 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4171 (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4172 "TARGET_SHMEDIA_FPU"
4175 if (prepare_move_operands (operands, V2SFmode))
4179 (define_insn_and_split "*movv4sf_i"
4180 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4181 (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4182 "TARGET_SHMEDIA_FPU"
4184 "&& reload_completed"
4190 for (i = 0; i < 4/2; i++)
4194 if (GET_CODE (operands[0]) == MEM)
4195 x = gen_rtx_MEM (V2SFmode,
4196 plus_constant (XEXP (operands[0], 0),
4197 i * GET_MODE_SIZE (V2SFmode)));
4200 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4204 if (GET_CODE (operands[1]) == MEM)
4205 y = gen_rtx_MEM (V2SFmode,
4206 plus_constant (XEXP (operands[1], 0),
4207 i * GET_MODE_SIZE (V2SFmode)));
4210 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4214 emit_insn (gen_movv2sf_i (x, y));
4219 [(set_attr "length" "8")])
4221 (define_expand "movv4sf"
4222 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4223 (match_operand:V4SF 1 "nonimmediate_operand" "f,m,f"))]
4224 "TARGET_SHMEDIA_FPU"
4227 if (prepare_move_operands (operands, V4SFmode))
4231 (define_insn_and_split "*movv16sf_i"
4232 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4233 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4234 "TARGET_SHMEDIA_FPU"
4236 "&& reload_completed"
4242 for (i = 0; i < 16/2; i++)
4246 if (GET_CODE (operands[0]) == MEM)
4247 x = gen_rtx_MEM (V2SFmode,
4248 plus_constant (XEXP (operands[0], 0),
4249 i * GET_MODE_SIZE (V2SFmode)));
4252 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4256 if (GET_CODE (operands[1]) == MEM)
4257 y = gen_rtx_MEM (V2SFmode,
4258 plus_constant (XEXP (operands[1], 0),
4259 i * GET_MODE_SIZE (V2SFmode)));
4262 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4266 emit_insn (gen_movv2sf_i (x, y));
4271 [(set_attr "length" "32")])
4273 (define_expand "movv16sf"
4274 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4275 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4276 "TARGET_SHMEDIA_FPU"
4279 if (prepare_move_operands (operands, V16SFmode))
4283 (define_insn "movsf_media"
4284 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4285 (match_operand:SF 1 "general_movsrc_operand" "f,r,f,r,F,m,f,m,r"))]
4287 && (register_operand (operands[0], SFmode)
4288 || register_operand (operands[1], SFmode))"
4299 [(set_attr "type" "move,move,move,move,*,load,store,load,store")])
4301 (define_insn "movsf_media_nofpu"
4302 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4303 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4305 && (register_operand (operands[0], SFmode)
4306 || register_operand (operands[1], SFmode))"
4312 [(set_attr "type" "move,*,load,store")])
4315 [(set (match_operand:SF 0 "arith_reg_operand" "")
4316 (match_operand:SF 1 "immediate_operand" ""))]
4317 "TARGET_SHMEDIA && reload_completed"
4318 [(set (match_dup 3) (match_dup 2))]
4322 REAL_VALUE_TYPE value;
4324 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4325 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4326 operands[2] = GEN_INT (values);
4328 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4331 (define_insn "movsf_i"
4332 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4333 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4336 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4337 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4338 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4339 && (arith_reg_operand (operands[0], SFmode)
4340 || arith_reg_operand (operands[1], SFmode))"
4349 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4351 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4352 ;; update_flow_info would not know where to put REG_EQUAL notes
4353 ;; when the destination changes mode.
4354 (define_insn "movsf_ie"
4355 [(set (match_operand:SF 0 "general_movdst_operand"
4356 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4357 (match_operand:SF 1 "general_movsrc_operand"
4358 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4359 (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"))
4360 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4363 && (arith_reg_operand (operands[0], SFmode)
4364 || arith_reg_operand (operands[1], SFmode)
4365 || arith_reg_operand (operands[3], SImode)
4366 || (fpul_operand (operands[0], SFmode)
4367 && memory_operand (operands[1], SFmode)
4368 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4369 || (fpul_operand (operands[1], SFmode)
4370 && memory_operand (operands[0], SFmode)
4371 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4391 ! move optimized away"
4392 [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,store,load,nil")
4393 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4394 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4395 (const_string "single")
4396 (const_string "none")))])
4399 [(set (match_operand:SF 0 "register_operand" "")
4400 (match_operand:SF 1 "register_operand" ""))
4401 (use (match_operand:PSI 2 "fpscr_operand" "c"))
4402 (clobber (reg:SI FPUL_REG))]
4404 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4406 (clobber (scratch:SI))])
4407 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4409 (clobber (scratch:SI))])]
4412 (define_expand "movsf"
4413 [(set (match_operand:SF 0 "general_movdst_operand" "")
4414 (match_operand:SF 1 "general_movsrc_operand" ""))]
4418 if (prepare_move_operands (operands, SFmode))
4422 if (TARGET_SHMEDIA_FPU)
4423 emit_insn (gen_movsf_media (operands[0], operands[1]));
4425 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4430 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4435 (define_insn "mov_nop"
4436 [(set (match_operand 0 "register_operand" "") (match_dup 0))]
4439 [(set_attr "length" "0")
4440 (set_attr "type" "nil")])
4442 (define_expand "reload_insf"
4443 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4444 (match_operand:SF 1 "immediate_operand" "FQ"))
4445 (use (reg:PSI FPSCR_REG))
4446 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4450 (define_expand "reload_insi"
4451 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4452 (match_operand:SF 1 "immediate_operand" "FQ"))
4453 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4457 (define_insn "*movsi_y"
4458 [(set (match_operand:SI 0 "register_operand" "=y,y")
4459 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4460 (clobber (match_scratch:SI 2 "=&z,r"))]
4462 && (reload_in_progress || reload_completed)"
4464 [(set_attr "length" "4")
4465 (set_attr "type" "pcload,move")])
4468 [(set (match_operand:SI 0 "register_operand" "")
4469 (match_operand:SI 1 "immediate_operand" ""))
4470 (clobber (match_operand:SI 2 "register_operand" ""))]
4472 [(set (match_dup 2) (match_dup 1))
4473 (set (match_dup 0) (match_dup 2))]
4477 [(set (match_operand:SI 0 "register_operand" "")
4478 (match_operand:SI 1 "memory_operand" ""))
4479 (clobber (reg:SI R0_REG))]
4481 [(set (match_dup 0) (match_dup 1))]
4484 ;; ------------------------------------------------------------------------
4485 ;; Define the real conditional branch instructions.
4486 ;; ------------------------------------------------------------------------
4488 (define_insn "branch_true"
4489 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4490 (label_ref (match_operand 0 "" ""))
4493 "* return output_branch (1, insn, operands);"
4494 [(set_attr "type" "cbranch")])
4496 (define_insn "branch_false"
4497 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4498 (label_ref (match_operand 0 "" ""))
4501 "* return output_branch (0, insn, operands);"
4502 [(set_attr "type" "cbranch")])
4504 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4505 ;; which destination is too far away.
4506 ;; The const_int_operand is distinct for each branch target; it avoids
4507 ;; unwanted matches with redundant_insn.
4508 (define_insn "block_branch_redirect"
4509 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4512 [(set_attr "length" "0")])
4514 ;; This one has the additional purpose to record a possible scratch register
4515 ;; for the following branch.
4516 (define_insn "indirect_jump_scratch"
4517 [(set (match_operand 0 "register_operand" "=r")
4518 (unspec [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
4521 [(set_attr "length" "0")])
4523 ;; Conditional branch insns
4525 (define_expand "beq_media"
4527 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4528 (match_operand:DI 2 "arith_operand" "r,O"))
4529 (label_ref:DI (match_operand 0 "" ""))
4534 (define_insn "beq_media_i"
4536 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
4537 (match_operand:DI 2 "arith_operand" "r,O"))
4538 (match_operand:DI 0 "target_operand" "b,b")
4545 (define_expand "bne_media"
4547 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4548 (match_operand:DI 2 "arith_operand" "r,O"))
4549 (label_ref:DI (match_operand 0 "" ""))
4554 (define_insn "bne_media_i"
4556 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
4557 (match_operand:DI 2 "arith_operand" "r,O"))
4558 (match_operand:DI 0 "target_operand" "b,b")
4565 (define_expand "bgt_media"
4567 (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4568 (match_operand:DI 2 "arith_reg_operand" "r"))
4569 (label_ref:DI (match_operand 0 "" ""))
4574 (define_insn "bgt_media_i"
4576 (if_then_else (gt (match_operand:DI 1 "arith_reg_operand" "r")
4577 (match_operand:DI 2 "arith_reg_operand" "r"))
4578 (match_operand:DI 0 "target_operand" "b")
4583 (define_expand "bge_media"
4585 (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4586 (match_operand:DI 2 "arith_reg_operand" "r"))
4587 (label_ref:DI (match_operand 0 "" ""))
4592 (define_insn "bge_media_i"
4594 (if_then_else (ge (match_operand:DI 1 "arith_reg_operand" "r")
4595 (match_operand:DI 2 "arith_reg_operand" "r"))
4596 (match_operand:DI 0 "target_operand" "b")
4601 (define_expand "bgtu_media"
4603 (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4604 (match_operand:DI 2 "arith_reg_operand" "r"))
4605 (label_ref:DI (match_operand 0 "" ""))
4610 (define_insn "bgtu_media_i"
4612 (if_then_else (gtu (match_operand:DI 1 "arith_reg_operand" "r")
4613 (match_operand:DI 2 "arith_reg_operand" "r"))
4614 (match_operand:DI 0 "target_operand" "b")
4619 (define_expand "bgeu_media"
4621 (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4622 (match_operand:DI 2 "arith_reg_operand" "r"))
4623 (label_ref:DI (match_operand 0 "" ""))
4628 (define_insn "bgeu_media_i"
4630 (if_then_else (geu (match_operand:DI 1 "arith_reg_operand" "r")
4631 (match_operand:DI 2 "arith_reg_operand" "r"))
4632 (match_operand:DI 0 "target_operand" "b")
4637 ;; These are only needed to make invert_jump() happy.
4638 (define_insn "*ble_media_i"
4640 (if_then_else (le (match_operand:DI 1 "arith_reg_operand" "r")
4641 (match_operand:DI 2 "arith_reg_operand" "r"))
4642 (match_operand:DI 0 "target_operand" "b")
4647 (define_insn "*blt_media_i"
4649 (if_then_else (lt (match_operand:DI 1 "arith_reg_operand" "r")
4650 (match_operand:DI 2 "arith_reg_operand" "r"))
4651 (match_operand:DI 0 "target_operand" "b")
4656 (define_insn "*bleu_media_i"
4658 (if_then_else (leu (match_operand:DI 1 "arith_reg_operand" "r")
4659 (match_operand:DI 2 "arith_reg_operand" "r"))
4660 (match_operand:DI 0 "target_operand" "b")
4665 (define_insn "*bltu_media_i"
4667 (if_then_else (ltu (match_operand:DI 1 "arith_reg_operand" "r")
4668 (match_operand:DI 2 "arith_reg_operand" "r"))
4669 (match_operand:DI 0 "target_operand" "b")
4674 (define_expand "beq"
4676 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4677 (label_ref (match_operand 0 "" ""))
4684 if (GET_MODE (sh_compare_op0) != DImode)
4686 rtx tmp = gen_reg_rtx (DImode);
4688 emit_insn (gen_seq (tmp));
4689 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4693 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4694 emit_jump_insn (gen_beq_media (operands[0],
4695 sh_compare_op0, sh_compare_op1));
4699 from_compare (operands, EQ);
4702 (define_expand "bne"
4704 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4705 (label_ref (match_operand 0 "" ""))
4712 if (GET_MODE (sh_compare_op0) != DImode)
4714 rtx tmp = gen_reg_rtx (DImode);
4716 emit_insn (gen_seq (tmp));
4717 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
4721 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4722 emit_jump_insn (gen_bne_media (operands[0],
4723 sh_compare_op0, sh_compare_op1));
4727 from_compare (operands, EQ);
4730 (define_expand "bgt"
4732 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4733 (label_ref (match_operand 0 "" ""))
4740 if (GET_MODE (sh_compare_op0) != DImode)
4742 rtx tmp = gen_reg_rtx (DImode);
4744 emit_insn (gen_sgt (tmp));
4745 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4749 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4750 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4751 emit_jump_insn (gen_bgt_media (operands[0],
4752 sh_compare_op0, sh_compare_op1));
4756 from_compare (operands, GT);
4759 (define_expand "blt"
4761 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4762 (label_ref (match_operand 0 "" ""))
4769 if (GET_MODE (sh_compare_op0) != DImode)
4771 rtx tmp = gen_reg_rtx (DImode);
4773 emit_insn (gen_slt (tmp));
4774 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4778 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4779 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4780 emit_jump_insn (gen_bgt_media (operands[0],
4781 sh_compare_op1, sh_compare_op0));
4785 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4787 rtx tmp = sh_compare_op0;
4788 sh_compare_op0 = sh_compare_op1;
4789 sh_compare_op1 = tmp;
4790 emit_insn (gen_bgt (operands[0]));
4793 from_compare (operands, GE);
4796 (define_expand "ble"
4798 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4799 (label_ref (match_operand 0 "" ""))
4806 if (GET_MODE (sh_compare_op0) != DImode)
4808 rtx tmp = gen_reg_rtx (DImode);
4810 emit_insn (gen_sle (tmp));
4811 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4815 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4816 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4817 emit_jump_insn (gen_bge_media (operands[0],
4818 sh_compare_op1, sh_compare_op0));
4824 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4826 rtx tmp = sh_compare_op0;
4827 sh_compare_op0 = sh_compare_op1;
4828 sh_compare_op1 = tmp;
4829 emit_insn (gen_bge (operands[0]));
4832 from_compare (operands, GT);
4835 (define_expand "bge"
4837 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4838 (label_ref (match_operand 0 "" ""))
4845 if (GET_MODE (sh_compare_op0) != DImode)
4847 rtx tmp = gen_reg_rtx (DImode);
4849 emit_insn (gen_sge (tmp));
4850 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
4854 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4855 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4856 emit_jump_insn (gen_bge_media (operands[0],
4857 sh_compare_op0, sh_compare_op1));
4863 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
4865 rtx tmp = sh_compare_op0;
4866 sh_compare_op0 = sh_compare_op1;
4867 sh_compare_op1 = tmp;
4868 emit_insn (gen_ble (operands[0]));
4871 from_compare (operands, GE);
4874 (define_expand "bgtu"
4876 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4877 (label_ref (match_operand 0 "" ""))
4884 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4885 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4886 emit_jump_insn (gen_bgtu_media (operands[0],
4887 sh_compare_op0, sh_compare_op1));
4891 from_compare (operands, GTU);
4894 (define_expand "bltu"
4896 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4897 (label_ref (match_operand 0 "" ""))
4904 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4905 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4906 emit_jump_insn (gen_bgtu_media (operands[0],
4907 sh_compare_op1, sh_compare_op0));
4911 from_compare (operands, GEU);
4914 (define_expand "bgeu"
4916 (if_then_else (ne (reg:SI T_REG) (const_int 0))
4917 (label_ref (match_operand 0 "" ""))
4924 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4925 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4926 emit_jump_insn (gen_bgeu_media (operands[0],
4927 sh_compare_op0, sh_compare_op1));
4931 from_compare (operands, GEU);
4934 (define_expand "bleu"
4936 (if_then_else (eq (reg:SI T_REG) (const_int 0))
4937 (label_ref (match_operand 0 "" ""))
4944 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
4945 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
4946 emit_jump_insn (gen_bgeu_media (operands[0],
4947 sh_compare_op1, sh_compare_op0));
4951 from_compare (operands, GTU);
4954 (define_expand "bunordered"
4955 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
4957 (if_then_else (ne (match_dup 1) (const_int 0))
4958 (label_ref:DI (match_operand 0 "" ""))
4963 operands[1] = gen_reg_rtx (DImode);
4964 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
4965 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
4968 ;; ------------------------------------------------------------------------
4969 ;; Jump and linkage insns
4970 ;; ------------------------------------------------------------------------
4972 (define_insn "jump_compact"
4974 (label_ref (match_operand 0 "" "")))]
4978 /* The length is 16 if the delay slot is unfilled. */
4979 if (get_attr_length(insn) > 4)
4980 return output_far_jump(insn, operands[0]);
4982 return \"bra %l0%#\";
4984 [(set_attr "type" "jump")
4985 (set_attr "needs_delay_slot" "yes")])
4987 (define_insn "jump_media"
4989 (match_operand:DI 0 "target_operand" "b"))]
4993 (define_expand "jump"
4995 (label_ref (match_operand 0 "" "")))]
5000 emit_insn (gen_jump_compact (operands[0]));
5001 else if (TARGET_SHMEDIA)
5003 if (reload_in_progress || reload_completed)
5005 emit_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode, operands[0])));
5010 (define_insn "force_mode_for_call"
5011 [(use (reg:PSI FPSCR_REG))]
5014 [(set_attr "length" "0")
5015 (set (attr "fp_mode")
5016 (if_then_else (eq_attr "fpu_single" "yes")
5017 (const_string "single") (const_string "double")))])
5019 (define_insn "calli"
5020 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5021 (match_operand 1 "" ""))
5022 (use (reg:PSI FPSCR_REG))
5023 (clobber (reg:SI PR_REG))]
5026 [(set_attr "type" "call")
5027 (set (attr "fp_mode")
5028 (if_then_else (eq_attr "fpu_single" "yes")
5029 (const_string "single") (const_string "double")))
5030 (set_attr "needs_delay_slot" "yes")])
5032 ;; This is a pc-rel call, using bsrf, for use with PIC.
5034 (define_insn "calli_pcrel"
5035 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5036 (match_operand 1 "" ""))
5037 (use (reg:PSI FPSCR_REG))
5038 (use (reg:SI PIC_REG))
5039 (use (match_operand 2 "" ""))
5040 (clobber (reg:SI PR_REG))]
5043 [(set_attr "type" "call")
5044 (set (attr "fp_mode")
5045 (if_then_else (eq_attr "fpu_single" "yes")
5046 (const_string "single") (const_string "double")))
5047 (set_attr "needs_delay_slot" "yes")])
5049 (define_insn_and_split "call_pcrel"
5050 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5051 (match_operand 1 "" ""))
5052 (use (reg:PSI FPSCR_REG))
5053 (use (reg:SI PIC_REG))
5054 (clobber (reg:SI PR_REG))
5055 (clobber (match_scratch:SI 2 "=r"))]
5062 rtx lab = gen_call_site ();
5064 if (SYMBOL_REF_FLAG (operands[0]))
5065 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5067 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5068 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5071 [(set_attr "type" "call")
5072 (set (attr "fp_mode")
5073 (if_then_else (eq_attr "fpu_single" "yes")
5074 (const_string "single") (const_string "double")))
5075 (set_attr "needs_delay_slot" "yes")])
5077 (define_insn "call_compact"
5078 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5079 (match_operand 1 "" ""))
5080 (match_operand 2 "immediate_operand" "n")
5081 (use (reg:SI R0_REG))
5082 (use (reg:SI R1_REG))
5083 (use (reg:PSI FPSCR_REG))
5084 (clobber (reg:SI PR_REG))]
5085 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5087 [(set_attr "type" "call")
5088 (set (attr "fp_mode")
5089 (if_then_else (eq_attr "fpu_single" "yes")
5090 (const_string "single") (const_string "double")))
5091 (set_attr "needs_delay_slot" "yes")])
5093 (define_insn "call_compact_rettramp"
5094 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5095 (match_operand 1 "" ""))
5096 (match_operand 2 "immediate_operand" "n")
5097 (use (reg:SI R0_REG))
5098 (use (reg:SI R1_REG))
5099 (use (reg:PSI FPSCR_REG))
5100 (clobber (reg:SI R10_REG))
5101 (clobber (reg:SI PR_REG))]
5102 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5104 [(set_attr "type" "call")
5105 (set (attr "fp_mode")
5106 (if_then_else (eq_attr "fpu_single" "yes")
5107 (const_string "single") (const_string "double")))
5108 (set_attr "needs_delay_slot" "yes")])
5110 (define_insn "call_media"
5111 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5112 (match_operand 1 "" ""))
5113 (clobber (reg:DI PR_MEDIA_REG))]
5117 (define_insn "call_valuei"
5118 [(set (match_operand 0 "" "=rf")
5119 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5120 (match_operand 2 "" "")))
5121 (use (reg:PSI FPSCR_REG))
5122 (clobber (reg:SI PR_REG))]
5125 [(set_attr "type" "call")
5126 (set (attr "fp_mode")
5127 (if_then_else (eq_attr "fpu_single" "yes")
5128 (const_string "single") (const_string "double")))
5129 (set_attr "needs_delay_slot" "yes")])
5131 (define_insn "call_valuei_pcrel"
5132 [(set (match_operand 0 "" "=rf")
5133 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5134 (match_operand 2 "" "")))
5135 (use (reg:PSI FPSCR_REG))
5136 (use (reg:SI PIC_REG))
5137 (use (match_operand 3 "" ""))
5138 (clobber (reg:SI PR_REG))]
5141 [(set_attr "type" "call")
5142 (set (attr "fp_mode")
5143 (if_then_else (eq_attr "fpu_single" "yes")
5144 (const_string "single") (const_string "double")))
5145 (set_attr "needs_delay_slot" "yes")])
5147 (define_insn_and_split "call_value_pcrel"
5148 [(set (match_operand 0 "" "=rf")
5149 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5150 (match_operand 2 "" "")))
5151 (use (reg:PSI FPSCR_REG))
5152 (use (reg:SI PIC_REG))
5153 (clobber (reg:SI PR_REG))
5154 (clobber (match_scratch:SI 3 "=r"))]
5161 rtx lab = gen_call_site ();
5163 if (SYMBOL_REF_FLAG (operands[1]))
5164 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5166 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5167 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5171 [(set_attr "type" "call")
5172 (set (attr "fp_mode")
5173 (if_then_else (eq_attr "fpu_single" "yes")
5174 (const_string "single") (const_string "double")))
5175 (set_attr "needs_delay_slot" "yes")])
5177 (define_insn "call_value_compact"
5178 [(set (match_operand 0 "" "=rf")
5179 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5180 (match_operand 2 "" "")))
5181 (match_operand 3 "immediate_operand" "n")
5182 (use (reg:SI R0_REG))
5183 (use (reg:SI R1_REG))
5184 (use (reg:PSI FPSCR_REG))
5185 (clobber (reg:SI PR_REG))]
5186 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5188 [(set_attr "type" "call")
5189 (set (attr "fp_mode")
5190 (if_then_else (eq_attr "fpu_single" "yes")
5191 (const_string "single") (const_string "double")))
5192 (set_attr "needs_delay_slot" "yes")])
5194 (define_insn "call_value_compact_rettramp"
5195 [(set (match_operand 0 "" "=rf")
5196 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5197 (match_operand 2 "" "")))
5198 (match_operand 3 "immediate_operand" "n")
5199 (use (reg:SI R0_REG))
5200 (use (reg:SI R1_REG))
5201 (use (reg:PSI FPSCR_REG))
5202 (clobber (reg:SI R10_REG))
5203 (clobber (reg:SI PR_REG))]
5204 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5206 [(set_attr "type" "call")
5207 (set (attr "fp_mode")
5208 (if_then_else (eq_attr "fpu_single" "yes")
5209 (const_string "single") (const_string "double")))
5210 (set_attr "needs_delay_slot" "yes")])
5212 (define_insn "call_value_media"
5213 [(set (match_operand 0 "" "=rf")
5214 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5215 (match_operand 2 "" "")))
5216 (clobber (reg:DI PR_MEDIA_REG))]
5220 (define_expand "call"
5221 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5222 (match_operand 1 "" ""))
5223 (match_operand 2 "" "")
5224 (use (reg:PSI FPSCR_REG))
5225 (clobber (reg:SI PR_REG))])]
5231 operands[0] = XEXP (operands[0], 0);
5232 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5234 if (! SYMBOL_REF_FLAG (operands[0]))
5236 rtx reg = gen_reg_rtx (Pmode);
5238 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5243 operands[0] = gen_sym2PIC (operands[0]);
5244 PUT_MODE (operands[0], Pmode);
5247 if (GET_MODE (operands[0]) == SImode)
5249 if (GET_CODE (operands[0]) == REG)
5250 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5251 else if (GET_CODE (operands[0]) == SUBREG)
5253 operands[0] = SUBREG_REG (operands[0]);
5254 if (GET_MODE (operands[0]) != DImode)
5255 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5259 operands[0] = shallow_copy_rtx (operands[0]);
5260 PUT_MODE (operands[0], DImode);
5263 if (! target_reg_operand (operands[0], DImode))
5264 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5265 emit_call_insn (gen_call_media (operands[0], operands[1]));
5268 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5270 rtx cookie_rtx = operands[2];
5271 long cookie = INTVAL (cookie_rtx);
5272 rtx func = XEXP (operands[0], 0);
5277 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5279 rtx reg = gen_reg_rtx (Pmode);
5281 emit_insn (gen_symGOTPLT2reg (reg, func));
5285 func = legitimize_pic_address (func, Pmode, 0);
5288 r0 = gen_rtx_REG (SImode, R0_REG);
5289 r1 = gen_rtx_REG (SImode, R1_REG);
5291 /* Since such a call function may use all call-clobbered
5292 registers, we force a mode switch earlier, so that we don't
5293 run out of registers when adjusting fpscr for the call. */
5294 emit_insn (gen_force_mode_for_call ());
5296 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5297 \"__GCC_shcompact_call_trampoline\");
5300 rtx reg = gen_reg_rtx (Pmode);
5302 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5305 operands[0] = force_reg (SImode, operands[0]);
5307 emit_move_insn (r0, func);
5308 emit_move_insn (r1, cookie_rtx);
5310 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5311 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5314 emit_call_insn (gen_call_compact (operands[0], operands[1],
5319 else if (TARGET_SHCOMPACT && flag_pic
5320 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5321 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5323 rtx reg = gen_reg_rtx (Pmode);
5325 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5326 XEXP (operands[0], 0) = reg;
5328 if (flag_pic && TARGET_SH2
5329 && GET_CODE (operands[0]) == MEM
5330 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5332 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5336 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5338 emit_call_insn (gen_calli (operands[0], operands[1]));
5342 (define_insn "call_pop_compact"
5343 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5344 (match_operand 1 "" ""))
5345 (match_operand 2 "immediate_operand" "n")
5346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5347 (match_operand 3 "immediate_operand" "n")))
5348 (use (reg:SI R0_REG))
5349 (use (reg:SI R1_REG))
5350 (use (reg:PSI FPSCR_REG))
5351 (clobber (reg:SI PR_REG))]
5352 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5354 [(set_attr "type" "call")
5355 (set (attr "fp_mode")
5356 (if_then_else (eq_attr "fpu_single" "yes")
5357 (const_string "single") (const_string "double")))
5358 (set_attr "needs_delay_slot" "yes")])
5360 (define_insn "call_pop_compact_rettramp"
5361 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5362 (match_operand 1 "" ""))
5363 (match_operand 2 "immediate_operand" "n")
5364 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5365 (match_operand 3 "immediate_operand" "n")))
5366 (use (reg:SI R0_REG))
5367 (use (reg:SI R1_REG))
5368 (use (reg:PSI FPSCR_REG))
5369 (clobber (reg:SI R10_REG))
5370 (clobber (reg:SI PR_REG))]
5371 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5373 [(set_attr "type" "call")
5374 (set (attr "fp_mode")
5375 (if_then_else (eq_attr "fpu_single" "yes")
5376 (const_string "single") (const_string "double")))
5377 (set_attr "needs_delay_slot" "yes")])
5379 (define_expand "call_pop"
5380 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5381 (match_operand 1 "" ""))
5382 (match_operand 2 "" "")
5383 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5384 (match_operand 3 "" "")))])]
5388 if (operands[2] && INTVAL (operands[2]))
5390 rtx cookie_rtx = operands[2];
5391 long cookie = INTVAL (cookie_rtx);
5392 rtx func = XEXP (operands[0], 0);
5397 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5399 rtx reg = gen_reg_rtx (Pmode);
5401 emit_insn (gen_symGOTPLT2reg (reg, func));
5405 func = legitimize_pic_address (func, Pmode, 0);
5408 r0 = gen_rtx_REG (SImode, R0_REG);
5409 r1 = gen_rtx_REG (SImode, R1_REG);
5411 /* Since such a call function may use all call-clobbered
5412 registers, we force a mode switch earlier, so that we don't
5413 run out of registers when adjusting fpscr for the call. */
5414 emit_insn (gen_force_mode_for_call ());
5416 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5417 \"__GCC_shcompact_call_trampoline\");
5420 rtx reg = gen_reg_rtx (Pmode);
5422 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5425 operands[0] = force_reg (SImode, operands[0]);
5427 emit_move_insn (r0, func);
5428 emit_move_insn (r1, cookie_rtx);
5430 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5431 emit_call_insn (gen_call_pop_compact_rettramp
5432 (operands[0], operands[1], operands[2], operands[3]));
5434 emit_call_insn (gen_call_pop_compact
5435 (operands[0], operands[1], operands[2], operands[3]));
5443 (define_expand "call_value"
5444 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5445 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5446 (match_operand 2 "" "")))
5447 (match_operand 3 "" "")
5448 (use (reg:PSI FPSCR_REG))
5449 (clobber (reg:SI PR_REG))])]
5455 operands[1] = XEXP (operands[1], 0);
5456 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5458 if (! SYMBOL_REF_FLAG (operands[1]))
5460 rtx reg = gen_reg_rtx (Pmode);
5462 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5467 operands[1] = gen_sym2PIC (operands[1]);
5468 PUT_MODE (operands[1], Pmode);
5471 if (GET_MODE (operands[1]) == SImode)
5473 if (GET_CODE (operands[1]) == REG)
5474 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5475 else if (GET_CODE (operands[1]) == SUBREG)
5477 operands[1] = SUBREG_REG (operands[1]);
5478 if (GET_MODE (operands[1]) != DImode)
5479 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5483 operands[1] = shallow_copy_rtx (operands[1]);
5484 PUT_MODE (operands[1], DImode);
5487 if (! target_reg_operand (operands[1], DImode))
5488 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5489 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5493 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5495 rtx cookie_rtx = operands[3];
5496 long cookie = INTVAL (cookie_rtx);
5497 rtx func = XEXP (operands[1], 0);
5502 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5504 rtx reg = gen_reg_rtx (Pmode);
5506 emit_insn (gen_symGOTPLT2reg (reg, func));
5510 func = legitimize_pic_address (func, Pmode, 0);
5513 r0 = gen_rtx_REG (SImode, R0_REG);
5514 r1 = gen_rtx_REG (SImode, R1_REG);
5516 /* Since such a call function may use all call-clobbered
5517 registers, we force a mode switch earlier, so that we don't
5518 run out of registers when adjusting fpscr for the call. */
5519 emit_insn (gen_force_mode_for_call ());
5521 operands[1] = gen_rtx_SYMBOL_REF (SImode,
5522 \"__GCC_shcompact_call_trampoline\");
5525 rtx reg = gen_reg_rtx (Pmode);
5527 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5530 operands[1] = force_reg (SImode, operands[1]);
5532 emit_move_insn (r0, func);
5533 emit_move_insn (r1, cookie_rtx);
5535 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5536 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
5541 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
5542 operands[2], operands[3]));
5546 else if (TARGET_SHCOMPACT && flag_pic
5547 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
5548 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
5550 rtx reg = gen_reg_rtx (Pmode);
5552 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
5553 XEXP (operands[1], 0) = reg;
5555 if (flag_pic && TARGET_SH2
5556 && GET_CODE (operands[1]) == MEM
5557 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
5559 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
5564 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
5566 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
5570 (define_insn "sibcalli"
5571 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
5572 (match_operand 1 "" ""))
5573 (use (reg:PSI FPSCR_REG))
5577 [(set_attr "needs_delay_slot" "yes")
5578 (set (attr "fp_mode")
5579 (if_then_else (eq_attr "fpu_single" "yes")
5580 (const_string "single") (const_string "double")))
5581 (set_attr "type" "jump_ind")])
5583 (define_insn "sibcalli_pcrel"
5584 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
5585 (match_operand 1 "" ""))
5586 (use (match_operand 2 "" ""))
5587 (use (reg:PSI FPSCR_REG))
5591 [(set_attr "needs_delay_slot" "yes")
5592 (set (attr "fp_mode")
5593 (if_then_else (eq_attr "fpu_single" "yes")
5594 (const_string "single") (const_string "double")))
5595 (set_attr "type" "jump_ind")])
5597 (define_insn_and_split "sibcall_pcrel"
5598 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5599 (match_operand 1 "" ""))
5600 (use (reg:PSI FPSCR_REG))
5601 (clobber (match_scratch:SI 2 "=k"))
5609 rtx lab = gen_call_site ();
5612 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5613 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
5615 SIBLING_CALL_P (call_insn) = 1;
5618 [(set_attr "needs_delay_slot" "yes")
5619 (set (attr "fp_mode")
5620 (if_then_else (eq_attr "fpu_single" "yes")
5621 (const_string "single") (const_string "double")))
5622 (set_attr "type" "jump_ind")])
5624 (define_insn "sibcall_compact"
5625 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
5626 (match_operand 1 "" ""))
5628 (use (match_operand 2 "register_operand" "z,x"))
5629 (use (reg:SI R1_REG))
5630 (use (reg:PSI FPSCR_REG))
5631 ;; We want to make sure the `x' above will only match MACH_REG
5632 ;; because sibcall_epilogue may clobber MACL_REG.
5633 (clobber (reg:SI MACL_REG))]
5637 jmp @%0\\n sts %2, r0"
5638 [(set_attr "needs_delay_slot" "yes,no")
5639 (set_attr "length" "2,4")
5640 (set (attr "fp_mode") (const_string "single"))
5641 (set_attr "type" "jump_ind")])
5643 (define_insn "sibcall_media"
5644 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
5645 (match_operand 1 "" ""))
5650 (define_expand "sibcall"
5652 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5653 (match_operand 1 "" ""))
5654 (match_operand 2 "" "")
5655 (use (reg:PSI FPSCR_REG))
5662 operands[0] = XEXP (operands[0], 0);
5663 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5665 if (! SYMBOL_REF_FLAG (operands[0]))
5667 rtx reg = gen_reg_rtx (Pmode);
5669 /* We must not use GOTPLT for sibcalls, because PIC_REG
5670 must be restored before the PLT code gets to run. */
5671 emit_insn (gen_symGOT2reg (reg, operands[0]));
5676 operands[0] = gen_sym2PIC (operands[0]);
5677 PUT_MODE (operands[0], Pmode);
5680 if (GET_MODE (operands[0]) == SImode)
5682 if (GET_CODE (operands[0]) == REG)
5683 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5684 else if (GET_CODE (operands[0]) == SUBREG)
5686 operands[0] = SUBREG_REG (operands[0]);
5687 if (GET_MODE (operands[0]) != DImode)
5688 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5692 operands[0] = shallow_copy_rtx (operands[0]);
5693 PUT_MODE (operands[0], DImode);
5696 if (! target_reg_operand (operands[0], DImode))
5697 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5698 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
5701 else if (TARGET_SHCOMPACT && operands[2]
5702 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
5704 rtx cookie_rtx = operands[2];
5705 long cookie = INTVAL (cookie_rtx);
5706 rtx func = XEXP (operands[0], 0);
5711 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5713 rtx reg = gen_reg_rtx (Pmode);
5715 emit_insn (gen_symGOT2reg (reg, func));
5719 func = legitimize_pic_address (func, Pmode, 0);
5722 /* FIXME: if we could tell whether all argument registers are
5723 already taken, we could decide whether to force the use of
5724 MACH_REG or to stick to R0_REG. Unfortunately, there's no
5725 simple way to tell. We could use the CALL_COOKIE, but we
5726 can't currently tell a register used for regular argument
5727 passing from one that is unused. If we leave it up to reload
5728 to decide which register to use, it seems to always choose
5729 R0_REG, which leaves no available registers in SIBCALL_REGS
5730 to hold the address of the trampoline. */
5731 mach = gen_rtx_REG (SImode, MACH_REG);
5732 r1 = gen_rtx_REG (SImode, R1_REG);
5734 /* Since such a call function may use all call-clobbered
5735 registers, we force a mode switch earlier, so that we don't
5736 run out of registers when adjusting fpscr for the call. */
5737 emit_insn (gen_force_mode_for_call ());
5739 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5740 \"__GCC_shcompact_call_trampoline\");
5743 rtx reg = gen_reg_rtx (Pmode);
5745 emit_insn (gen_symGOT2reg (reg, operands[0]));
5748 operands[0] = force_reg (SImode, operands[0]);
5750 /* We don't need a return trampoline, since the callee will
5751 return directly to the upper caller. */
5752 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5754 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
5755 cookie_rtx = GEN_INT (cookie);
5758 emit_move_insn (mach, func);
5759 emit_move_insn (r1, cookie_rtx);
5761 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
5764 else if (TARGET_SHCOMPACT && flag_pic
5765 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5766 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5768 rtx reg = gen_reg_rtx (Pmode);
5770 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
5771 XEXP (operands[0], 0) = reg;
5773 if (flag_pic && TARGET_SH2
5774 && GET_CODE (operands[0]) == MEM
5775 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5776 /* The PLT needs the PIC register, but the epilogue would have
5777 to restore it, so we can only use PC-relative PIC calls for
5778 static functions. */
5779 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5781 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
5785 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5787 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
5791 (define_expand "sibcall_value"
5792 [(set (match_operand 0 "" "")
5793 (call (match_operand 1 "" "")
5794 (match_operand 2 "" "")))
5795 (match_operand 3 "" "")]
5799 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
5803 (define_insn "call_value_pop_compact"
5804 [(set (match_operand 0 "" "=rf")
5805 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5806 (match_operand 2 "" "")))
5807 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5808 (match_operand 4 "immediate_operand" "n")))
5809 (match_operand 3 "immediate_operand" "n")
5810 (use (reg:SI R0_REG))
5811 (use (reg:SI R1_REG))
5812 (use (reg:PSI FPSCR_REG))
5813 (clobber (reg:SI PR_REG))]
5814 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5816 [(set_attr "type" "call")
5817 (set (attr "fp_mode")
5818 (if_then_else (eq_attr "fpu_single" "yes")
5819 (const_string "single") (const_string "double")))
5820 (set_attr "needs_delay_slot" "yes")])
5822 (define_insn "call_value_pop_compact_rettramp"
5823 [(set (match_operand 0 "" "=rf")
5824 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5825 (match_operand 2 "" "")))
5826 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5827 (match_operand 4 "immediate_operand" "n")))
5828 (match_operand 3 "immediate_operand" "n")
5829 (use (reg:SI R0_REG))
5830 (use (reg:SI R1_REG))
5831 (use (reg:PSI FPSCR_REG))
5832 (clobber (reg:SI R10_REG))
5833 (clobber (reg:SI PR_REG))]
5834 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5836 [(set_attr "type" "call")
5837 (set (attr "fp_mode")
5838 (if_then_else (eq_attr "fpu_single" "yes")
5839 (const_string "single") (const_string "double")))
5840 (set_attr "needs_delay_slot" "yes")])
5842 (define_expand "call_value_pop"
5843 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5844 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5845 (match_operand 2 "" "")))
5846 (match_operand 3 "" "")
5847 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5848 (match_operand 4 "" "")))])]
5852 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5854 rtx cookie_rtx = operands[3];
5855 long cookie = INTVAL (cookie_rtx);
5856 rtx func = XEXP (operands[1], 0);
5861 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5863 rtx reg = gen_reg_rtx (Pmode);
5865 emit_insn (gen_symGOTPLT2reg (reg, func));
5869 func = legitimize_pic_address (func, Pmode, 0);
5872 r0 = gen_rtx_REG (SImode, R0_REG);
5873 r1 = gen_rtx_REG (SImode, R1_REG);
5875 /* Since such a call function may use all call-clobbered
5876 registers, we force a mode switch earlier, so that we don't
5877 run out of registers when adjusting fpscr for the call. */
5878 emit_insn (gen_force_mode_for_call ());
5880 operands[1] = gen_rtx_SYMBOL_REF (SImode,
5881 \"__GCC_shcompact_call_trampoline\");
5884 rtx reg = gen_reg_rtx (Pmode);
5886 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5889 operands[1] = force_reg (SImode, operands[1]);
5891 emit_move_insn (r0, func);
5892 emit_move_insn (r1, cookie_rtx);
5894 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5895 emit_call_insn (gen_call_value_pop_compact_rettramp
5896 (operands[0], operands[1], operands[2],
5897 operands[3], operands[4]));
5899 emit_call_insn (gen_call_value_pop_compact
5900 (operands[0], operands[1], operands[2],
5901 operands[3], operands[4]));
5909 (define_expand "sibcall_epilogue"
5914 sh_expand_epilogue ();
5915 if (TARGET_SHCOMPACT)
5919 /* If epilogue clobbers r0, preserve it in macl. */
5920 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5921 if ((set = single_set (insn))
5922 && GET_CODE (SET_DEST (set)) == REG
5923 && REGNO (SET_DEST (set)) == R0_REG)
5925 rtx r0 = gen_rtx_REG (SImode, R0_REG);
5926 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
5929 /* We can't tell at this point whether the sibcall is a
5930 sibcall_compact and, if it is, whether it uses r0 or
5931 mach as operand 2, so let the instructions that
5932 preserve r0 be optimized away if r0 turns out to be
5934 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
5935 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
5937 i = emit_move_insn (r0, tmp);
5938 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
5946 (define_insn "indirect_jump_compact"
5948 (match_operand:SI 0 "arith_reg_operand" "r"))]
5951 [(set_attr "needs_delay_slot" "yes")
5952 (set_attr "type" "jump_ind")])
5954 (define_expand "indirect_jump"
5956 (match_operand 0 "register_operand" ""))]
5960 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
5961 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5964 ;; The use of operand 1 / 2 helps us distinguish case table jumps
5965 ;; which can be present in structured code from indirect jumps which can not
5966 ;; be present in structured code. This allows -fprofile-arcs to work.
5968 ;; For SH1 processors.
5969 (define_insn "casesi_jump_1"
5971 (match_operand:SI 0 "register_operand" "r"))
5972 (use (label_ref (match_operand 1 "" "")))]
5975 [(set_attr "needs_delay_slot" "yes")
5976 (set_attr "type" "jump_ind")])
5978 ;; For all later processors.
5979 (define_insn "casesi_jump_2"
5980 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
5981 (label_ref (match_operand 1 "" ""))))
5982 (use (label_ref (match_operand 2 "" "")))]
5984 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
5986 [(set_attr "needs_delay_slot" "yes")
5987 (set_attr "type" "jump_ind")])
5989 (define_insn "casesi_jump_media"
5990 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
5991 (use (label_ref (match_operand 1 "" "")))]
5995 ;; Call subroutine returning any type.
5996 ;; ??? This probably doesn't work.
5998 (define_expand "untyped_call"
5999 [(parallel [(call (match_operand 0 "" "")
6001 (match_operand 1 "" "")
6002 (match_operand 2 "" "")])]
6003 "TARGET_SH3E || TARGET_SHMEDIA"
6008 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6010 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6012 rtx set = XVECEXP (operands[2], 0, i);
6013 emit_move_insn (SET_DEST (set), SET_SRC (set));
6016 /* The optimizer does not know that the call sets the function value
6017 registers we stored in the result block. We avoid problems by
6018 claiming that all hard registers are used and clobbered at this
6020 emit_insn (gen_blockage ());
6025 ;; ------------------------------------------------------------------------
6027 ;; ------------------------------------------------------------------------
6030 [(set (reg:SI T_REG)
6031 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6032 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6035 [(set_attr "type" "arith")])
6042 ;; Load address of a label. This is only generated by the casesi expand,
6043 ;; and by machine_dependent_reorg (fixing up fp moves).
6044 ;; This must use unspec, because this only works for labels that are
6048 [(set (reg:SI R0_REG)
6049 (unspec [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6052 [(set_attr "in_delay_slot" "no")
6053 (set_attr "type" "arith")])
6055 ;; machine_dependent_reorg() will make this a `mova'.
6056 (define_insn "mova_const"
6057 [(set (reg:SI R0_REG)
6058 (unspec [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6061 [(set_attr "in_delay_slot" "no")
6062 (set_attr "type" "arith")])
6064 (define_expand "GOTaddr2picreg"
6065 [(set (reg:SI R0_REG)
6066 (unspec [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6068 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6069 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6072 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6073 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6076 operands[1] = gen_datalabel_ref (operands[1]);
6080 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6081 rtx dipic = operands[0];
6082 rtx lab = gen_call_site ();
6085 equiv = operands[1];
6086 operands[1] = gen_rtx_MINUS (DImode,
6090 gen_rtx_MINUS (DImode,
6091 gen_rtx_CONST (DImode,
6094 operands[1] = gen_sym2PIC (operands[1]);
6095 PUT_MODE (operands[1], DImode);
6097 if (GET_MODE (dipic) != DImode)
6098 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6100 if (TARGET_SHMEDIA64)
6101 emit_insn (gen_movdi_const (dipic, operands[1]));
6103 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6105 emit_insn (gen_ptrel (tr, dipic, lab));
6107 if (GET_MODE (operands[0]) != GET_MODE (tr))
6108 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6110 insn = emit_move_insn (operands[0], tr);
6112 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6120 ;; When generating PIC, we must match label_refs especially, because
6121 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6122 ;; them to do, because they can't be loaded directly into
6123 ;; non-branch-target registers.
6125 [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6126 (match_operand:DI 1 "" "T"))]
6127 "TARGET_SHMEDIA && flag_pic
6128 && EXTRA_CONSTRAINT_T (operands[1])"
6130 [(set_attr "type" "pt")
6131 (set_attr "length" "*")])
6134 [(set (match_operand:DI 0 "target_reg_operand" "=b*k")
6135 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6136 UNSPEC_DATALABEL)))]
6137 "TARGET_SHMEDIA && flag_pic
6138 && EXTRA_CONSTRAINT_T (operands[1])"
6139 "ptb/u datalabel %1, %0"
6140 [(set_attr "type" "pt")
6141 (set_attr "length" "*")])
6143 (define_insn "ptrel"
6144 [(set (match_operand:DI 0 "target_reg_operand" "=bk")
6145 (plus (match_operand:DI 1 "register_operand" "r")
6147 (match_operand:DI 2 "" "")]
6149 "%O2: ptrel/u %1, %0"
6150 [(set_attr "type" "ptabs")])
6152 (define_expand "builtin_setjmp_receiver"
6153 [(match_operand 0 "" "")]
6157 emit_insn (gen_GOTaddr2picreg ());
6161 (define_expand "call_site"
6162 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6166 static HOST_WIDE_INT i = 0;
6167 operands[0] = GEN_INT (i);
6171 (define_expand "sym_label2reg"
6172 [(set (match_operand:SI 0 "" "")
6175 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6178 (match_operand:SI 2 "" "")
6182 (define_expand "symGOT_load"
6183 [(set (match_dup 2) (match_operand 1 "" ""))
6184 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6185 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6191 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6192 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6196 rtx reg = operands[2];
6198 if (GET_MODE (reg) != DImode)
6199 reg = gen_rtx_SUBREG (DImode, reg, 0);
6202 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6204 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6207 emit_move_insn (operands[2], operands[1]);
6209 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6211 gen_rtx_REG (Pmode, PIC_REG)));
6213 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6215 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6222 (define_expand "sym2GOT"
6223 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6227 (define_expand "symGOT2reg"
6228 [(match_operand 0 "" "") (match_operand 1 "" "")]
6234 gotsym = gen_sym2GOT (operands[1]);
6235 PUT_MODE (gotsym, Pmode);
6236 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6238 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6243 (define_expand "sym2GOTPLT"
6244 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6248 (define_expand "symGOTPLT2reg"
6249 [(match_operand 0 "" "") (match_operand 1 "" "")]
6253 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6257 (define_expand "sym2GOTOFF"
6258 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6262 (define_expand "symGOTOFF2reg"
6263 [(match_operand 0 "" "") (match_operand 1 "" "")]
6267 rtx gotoffsym, insn;
6268 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6270 gotoffsym = gen_sym2GOTOFF (operands[1]);
6271 PUT_MODE (gotoffsym, Pmode);
6272 emit_move_insn (t, gotoffsym);
6273 insn = emit_move_insn (operands[0],
6274 gen_rtx_PLUS (Pmode, t,
6275 gen_rtx_REG (Pmode, PIC_REG)));
6277 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6283 (define_expand "symPLT_label2reg"
6284 [(set (match_operand:SI 0 "" "")
6287 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6291 (match_operand:SI 2 "" "")
6293 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6294 ;; Even though the PIC register is not really used by the call
6295 ;; sequence in which this is expanded, the PLT code assumes the PIC
6296 ;; register is set, so we must not skip its initialization. Since
6297 ;; we only use this expand as part of calling sequences, and never
6298 ;; to take the address of a function, this is the best point to
6299 ;; insert the (use). Using the PLT to take the address of a
6300 ;; function would be wrong, not only because the PLT entry could
6301 ;; then be called from a function that doesn't initialize the PIC
6302 ;; register to the proper GOT, but also because pointers to the
6303 ;; same function might not compare equal, should they be set by
6304 ;; different shared libraries.
6305 (use (reg:SI PIC_REG))]
6309 (define_expand "sym2PIC"
6310 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6314 ;; case instruction for switch statements.
6316 ;; Operand 0 is index
6317 ;; operand 1 is the minimum bound
6318 ;; operand 2 is the maximum bound - minimum bound + 1
6319 ;; operand 3 is CODE_LABEL for the table;
6320 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6322 (define_expand "casesi"
6323 [(match_operand:SI 0 "arith_reg_operand" "")
6324 (match_operand:SI 1 "arith_reg_operand" "")
6325 (match_operand:SI 2 "arith_reg_operand" "")
6326 (match_operand 3 "" "") (match_operand 4 "" "")]
6330 rtx reg = gen_reg_rtx (SImode);
6331 rtx reg2 = gen_reg_rtx (SImode);
6334 rtx reg = gen_reg_rtx (DImode);
6335 rtx reg2 = gen_reg_rtx (DImode);
6336 rtx reg3 = gen_reg_rtx (DImode);
6337 rtx reg4 = gen_reg_rtx (DImode);
6338 rtx reg5 = gen_reg_rtx (DImode);
6340 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6341 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6342 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6344 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6345 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6346 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6347 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6348 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6349 (DImode, operands[3])));
6350 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6351 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6352 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6356 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6357 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6358 /* If optimizing, casesi_worker depends on the mode of the instruction
6359 before label it 'uses' - operands[3]. */
6360 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6362 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6364 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6366 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6367 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6368 operands[3], but to lab. We will fix this up in
6369 machine_dependent_reorg. */
6374 (define_expand "casesi_0"
6375 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6376 (set (match_dup 4) (minus:SI (match_dup 4)
6377 (match_operand:SI 1 "arith_operand" "")))
6379 (gtu:SI (match_dup 4)
6380 (match_operand:SI 2 "arith_reg_operand" "")))
6382 (if_then_else (ne (reg:SI T_REG)
6384 (label_ref (match_operand 3 "" ""))
6389 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6390 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6391 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6393 (define_insn "casesi_worker_0"
6394 [(set (match_operand:SI 0 "register_operand" "=r,r")
6395 (unspec:SI [(match_operand 1 "register_operand" "0,r")
6396 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6397 (clobber (match_scratch:SI 3 "=X,1"))
6398 (clobber (match_scratch:SI 4 "=&z,z"))]
6403 [(set (match_operand:SI 0 "register_operand" "")
6404 (unspec [(match_operand 1 "register_operand" "")
6405 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6406 (clobber (match_scratch:SI 3 ""))
6407 (clobber (match_scratch:SI 4 ""))]
6408 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6409 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6410 (parallel [(set (match_dup 0)
6411 (unspec [(reg:SI R0_REG) (match_dup 1)
6412 (label_ref (match_dup 2))] UNSPEC_CASESI))
6413 (clobber (match_dup 3))])
6414 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6415 "LABEL_NUSES (operands[2])++;")
6418 [(set (match_operand:SI 0 "register_operand" "")
6419 (unspec:SI [(match_operand 1 "register_operand" "")
6420 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6421 (clobber (match_scratch:SI 3 ""))
6422 (clobber (match_scratch:SI 4 ""))]
6423 "TARGET_SH2 && reload_completed"
6424 [(set (reg:SI R0_REG) (unspec [(label_ref (match_dup 2))] UNSPEC_MOVA))
6425 (parallel [(set (match_dup 0)
6426 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6427 (label_ref (match_dup 2))] UNSPEC_CASESI))
6428 (clobber (match_dup 3))])]
6429 "LABEL_NUSES (operands[2])++;")
6431 (define_insn "*casesi_worker"
6432 [(set (match_operand:SI 0 "register_operand" "=r,r")
6433 (unspec [(reg:SI R0_REG) (match_operand 1 "register_operand" "0,r")
6434 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6435 (clobber (match_scratch:SI 3 "=X,1"))]
6439 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6441 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6444 switch (GET_MODE (diff_vec))
6447 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6449 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6451 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6452 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6453 return \"mov.b @(r0,%1),%0\";
6458 [(set_attr "length" "4")])
6460 (define_insn "casesi_shift_media"
6461 [(set (match_operand 0 "arith_reg_operand" "=r")
6462 (ashift (match_operand 1 "arith_reg_operand" "r")
6463 (unspec [(label_ref:DI (match_operand 2 "" ""))] 2)))]
6467 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6469 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6472 switch (GET_MODE (diff_vec))
6475 return \"shlli %1, 2, %0\";
6477 return \"shlli %1, 1, %0\";
6479 if (rtx_equal_p (operands[0], operands[1]))
6481 return \"add %1, r63, %0\";
6487 (define_insn "casesi_load_media"
6488 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6489 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6490 (match_operand 2 "arith_reg_operand" "r")
6491 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6495 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6497 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6500 switch (GET_MODE (diff_vec))
6503 return \"ldx.l %1, %2, %0\";
6506 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6507 return \"ldx.uw %1, %2, %0\";
6509 return \"ldx.w %1, %2, %0\";
6511 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6512 return \"ldx.ub %1, %2, %0\";
6513 return \"ldx.b %1, %2, %0\";
6519 (define_expand "return"
6521 "reload_completed && ! sh_need_epilogue ()"
6526 emit_jump_insn (gen_return_media ());
6530 if (TARGET_SHCOMPACT
6531 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
6533 emit_jump_insn (gen_shcompact_return_tramp ());
6538 (define_insn "*return_i"
6540 "TARGET_SH1 && ! (TARGET_SHCOMPACT
6541 && (current_function_args_info.call_cookie
6542 & CALL_COOKIE_RET_TRAMP (1)))
6543 && reload_completed"
6545 [(set_attr "type" "return")
6546 (set_attr "needs_delay_slot" "yes")])
6548 (define_expand "shcompact_return_tramp"
6551 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6554 rtx reg = gen_rtx_REG (Pmode, R0_REG);
6555 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
6556 \"__GCC_shcompact_return_trampoline\");
6559 emit_insn (gen_symGOTPLT2reg (reg, sym));
6561 emit_move_insn (reg, sym);
6563 emit_jump_insn (gen_shcompact_return_tramp_i ());
6567 (define_insn "shcompact_return_tramp_i"
6568 [(parallel [(return) (use (reg:SI R0_REG))])]
6570 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
6572 [(set_attr "type" "jump_ind")
6573 (set_attr "needs_delay_slot" "yes")])
6575 (define_insn "return_media_i"
6576 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
6577 "TARGET_SHMEDIA && reload_completed"
6580 (define_expand "return_media"
6582 "TARGET_SHMEDIA && reload_completed"
6585 int tr_regno = sh_media_register_for_return ();
6590 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
6593 tr = gen_rtx_REG (DImode, tr_regno);
6594 emit_move_insn (tr, r18);
6597 tr = gen_rtx_REG (DImode, tr_regno);
6599 emit_jump_insn (gen_return_media_i (tr));
6603 (define_insn "shcompact_preserve_incoming_args"
6604 [(set (match_operand 0 "register_operand" "+r")
6605 (unspec [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
6608 [(set_attr "length" "0")])
6610 (define_insn "shcompact_incoming_args"
6611 [(set (reg:SI R2_REG) (unspec [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
6612 (set (reg:SI R3_REG) (unspec [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
6613 (set (reg:SI R4_REG) (unspec [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
6614 (set (reg:SI R5_REG) (unspec [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
6615 (set (reg:SI R6_REG) (unspec [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
6616 (set (reg:SI R7_REG) (unspec [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
6617 (set (reg:SI R8_REG) (unspec [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
6618 (set (reg:SI R9_REG) (unspec [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
6619 (set (mem:BLK (reg:SI MACL_REG))
6620 (unspec [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
6621 (use (reg:SI R0_REG))
6622 (clobber (reg:SI R0_REG))
6623 (clobber (reg:SI MACL_REG))
6624 (clobber (reg:SI MACH_REG))
6625 (clobber (reg:SI PR_REG))]
6628 [(set_attr "needs_delay_slot" "yes")])
6630 (define_insn "shmedia_save_restore_regs_compact"
6631 [(set (reg:SI SP_REG)
6632 (plus:SI (reg:SI SP_REG)
6633 (match_operand:SI 0 "immediate_operand" "i")))
6634 (use (reg:SI R0_REG))
6635 (clobber (reg:SI PR_REG))]
6637 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
6638 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
6640 [(set_attr "needs_delay_slot" "yes")])
6642 (define_expand "prologue"
6645 "sh_expand_prologue (); DONE;")
6647 (define_expand "epilogue"
6652 sh_expand_epilogue ();
6653 emit_jump_insn (gen_return ());
6657 (define_insn "blockage"
6658 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6661 [(set_attr "length" "0")])
6663 ;; ------------------------------------------------------------------------
6665 ;; ------------------------------------------------------------------------
6668 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
6669 (eq:SI (reg:SI T_REG) (const_int 1)))]
6672 [(set_attr "type" "arith")])
6674 (define_expand "seq"
6675 [(set (match_operand:SI 0 "arith_reg_operand" "")
6682 if (GET_MODE (operands[0]) != DImode)
6683 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6684 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6685 if (sh_compare_op1 != const0_rtx)
6686 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6687 ? GET_MODE (sh_compare_op0)
6688 : GET_MODE (sh_compare_op1),
6691 switch (GET_MODE (sh_compare_op0))
6694 emit_insn (gen_cmpeqdi_media (operands[0],
6695 sh_compare_op0, sh_compare_op1));
6699 if (! TARGET_SHMEDIA_FPU)
6701 emit_insn (gen_cmpeqsf_media (operands[0],
6702 sh_compare_op0, sh_compare_op1));
6706 if (! TARGET_SHMEDIA_FPU)
6708 emit_insn (gen_cmpeqdf_media (operands[0],
6709 sh_compare_op0, sh_compare_op1));
6717 operands[1] = prepare_scc_operands (EQ);
6720 (define_expand "slt"
6721 [(set (match_operand:SI 0 "arith_reg_operand" "")
6728 if (GET_MODE (operands[0]) != DImode)
6729 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6730 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6731 if (sh_compare_op1 != const0_rtx)
6732 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6733 ? GET_MODE (sh_compare_op0)
6734 : GET_MODE (sh_compare_op1),
6737 switch (GET_MODE (sh_compare_op0))
6740 emit_insn (gen_cmpgtdi_media (operands[0],
6741 sh_compare_op1, sh_compare_op0));
6745 if (! TARGET_SHMEDIA_FPU)
6747 emit_insn (gen_cmpgtsf_media (operands[0],
6748 sh_compare_op1, sh_compare_op0));
6752 if (! TARGET_SHMEDIA_FPU)
6754 emit_insn (gen_cmpgtdf_media (operands[0],
6755 sh_compare_op1, sh_compare_op0));
6763 operands[1] = prepare_scc_operands (LT);
6766 (define_expand "sle"
6767 [(match_operand:SI 0 "arith_reg_operand" "")]
6771 rtx tmp = sh_compare_op0;
6775 if (GET_MODE (operands[0]) != DImode)
6776 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6777 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6778 if (sh_compare_op1 != const0_rtx)
6779 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6780 ? GET_MODE (sh_compare_op0)
6781 : GET_MODE (sh_compare_op1),
6784 switch (GET_MODE (sh_compare_op0))
6788 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
6790 emit_insn (gen_cmpgtdi_media (tmp,
6791 sh_compare_op0, sh_compare_op1));
6792 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
6797 if (! TARGET_SHMEDIA_FPU)
6799 emit_insn (gen_cmpgesf_media (operands[0],
6800 sh_compare_op1, sh_compare_op0));
6804 if (! TARGET_SHMEDIA_FPU)
6806 emit_insn (gen_cmpgedf_media (operands[0],
6807 sh_compare_op1, sh_compare_op0));
6816 sh_compare_op0 = sh_compare_op1;
6817 sh_compare_op1 = tmp;
6818 emit_insn (gen_sge (operands[0]));
6822 (define_expand "sgt"
6823 [(set (match_operand:SI 0 "arith_reg_operand" "")
6830 if (GET_MODE (operands[0]) != DImode)
6831 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6832 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6833 if (sh_compare_op1 != const0_rtx)
6834 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6835 ? GET_MODE (sh_compare_op0)
6836 : GET_MODE (sh_compare_op1),
6839 switch (GET_MODE (sh_compare_op0))
6842 emit_insn (gen_cmpgtdi_media (operands[0],
6843 sh_compare_op0, sh_compare_op1));
6847 if (! TARGET_SHMEDIA_FPU)
6849 emit_insn (gen_cmpgtsf_media (operands[0],
6850 sh_compare_op0, sh_compare_op1));
6854 if (! TARGET_SHMEDIA_FPU)
6856 emit_insn (gen_cmpgtdf_media (operands[0],
6857 sh_compare_op0, sh_compare_op1));
6865 operands[1] = prepare_scc_operands (GT);
6868 (define_expand "sge"
6869 [(set (match_operand:SI 0 "arith_reg_operand" "")
6876 if (GET_MODE (operands[0]) != DImode)
6877 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6878 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6879 if (sh_compare_op1 != const0_rtx)
6880 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6881 ? GET_MODE (sh_compare_op0)
6882 : GET_MODE (sh_compare_op1),
6885 switch (GET_MODE (sh_compare_op0))
6889 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
6891 emit_insn (gen_cmpgtdi_media (tmp,
6892 sh_compare_op1, sh_compare_op0));
6893 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
6898 if (! TARGET_SHMEDIA_FPU)
6900 emit_insn (gen_cmpgesf_media (operands[0],
6901 sh_compare_op0, sh_compare_op1));
6905 if (! TARGET_SHMEDIA_FPU)
6907 emit_insn (gen_cmpgedf_media (operands[0],
6908 sh_compare_op0, sh_compare_op1));
6917 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6921 rtx lab = gen_label_rtx ();
6922 prepare_scc_operands (EQ);
6923 emit_jump_insn (gen_branch_true (lab));
6924 prepare_scc_operands (GT);
6926 emit_insn (gen_movt (operands[0]));
6929 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
6932 operands[1] = prepare_scc_operands (GE);
6935 (define_expand "sgtu"
6936 [(set (match_operand:SI 0 "arith_reg_operand" "")
6943 if (GET_MODE (operands[0]) != DImode)
6944 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6945 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6946 if (sh_compare_op1 != const0_rtx)
6947 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6948 ? GET_MODE (sh_compare_op0)
6949 : GET_MODE (sh_compare_op1),
6952 emit_insn (gen_cmpgtudi_media (operands[0],
6953 sh_compare_op0, sh_compare_op1));
6956 operands[1] = prepare_scc_operands (GTU);
6959 (define_expand "sltu"
6960 [(set (match_operand:SI 0 "arith_reg_operand" "")
6967 if (GET_MODE (operands[0]) != DImode)
6968 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6969 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6970 if (sh_compare_op1 != const0_rtx)
6971 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6972 ? GET_MODE (sh_compare_op0)
6973 : GET_MODE (sh_compare_op1),
6976 emit_insn (gen_cmpgtudi_media (operands[0],
6977 sh_compare_op1, sh_compare_op0));
6980 operands[1] = prepare_scc_operands (LTU);
6983 (define_expand "sleu"
6984 [(set (match_operand:SI 0 "arith_reg_operand" "")
6993 if (GET_MODE (operands[0]) != DImode)
6994 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6995 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
6996 if (sh_compare_op1 != const0_rtx)
6997 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
6998 ? GET_MODE (sh_compare_op0)
6999 : GET_MODE (sh_compare_op1),
7002 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7004 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7005 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7009 operands[1] = prepare_scc_operands (LEU);
7012 (define_expand "sgeu"
7013 [(set (match_operand:SI 0 "arith_reg_operand" "")
7022 if (GET_MODE (operands[0]) != DImode)
7023 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7024 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7025 if (sh_compare_op1 != const0_rtx)
7026 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7027 ? GET_MODE (sh_compare_op0)
7028 : GET_MODE (sh_compare_op1),
7031 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7033 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7034 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7039 operands[1] = prepare_scc_operands (GEU);
7042 ;; sne moves the complement of the T reg to DEST like this:
7046 ;; This is better than xoring compare result with 1 because it does
7047 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7050 (define_expand "sne"
7051 [(set (match_dup 2) (const_int -1))
7052 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7053 (neg:SI (plus:SI (match_dup 1)
7056 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7065 if (GET_MODE (operands[0]) != DImode)
7066 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7068 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7071 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7072 if (sh_compare_op1 != const0_rtx)
7073 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7074 ? GET_MODE (sh_compare_op0)
7075 : GET_MODE (sh_compare_op1),
7078 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7080 emit_insn (gen_seq (tmp));
7081 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7086 operands[1] = prepare_scc_operands (EQ);
7087 operands[2] = gen_reg_rtx (SImode);
7090 (define_expand "sunordered"
7091 [(set (match_operand:DI 0 "arith_reg_operand" "")
7092 (unordered:DI (match_dup 1) (match_dup 2)))]
7093 "TARGET_SHMEDIA_FPU"
7096 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7097 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7100 ;; Use the same trick for FP sle / sge
7101 (define_expand "movnegt"
7102 [(set (match_dup 2) (const_int -1))
7103 (parallel [(set (match_operand 0 "" "")
7104 (neg:SI (plus:SI (match_dup 1)
7107 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7110 "operands[2] = gen_reg_rtx (SImode);")
7112 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7113 ;; This prevents a regression that occurred when we switched from xor to
7117 [(set (match_operand:SI 0 "arith_reg_operand" "")
7118 (plus:SI (reg:SI T_REG)
7121 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7122 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7125 ;; -------------------------------------------------------------------------
7126 ;; Instructions to cope with inline literal tables
7127 ;; -------------------------------------------------------------------------
7129 ; 2 byte integer in line
7131 (define_insn "consttable_2"
7132 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7133 (match_operand 1 "" "")]
7138 if (operands[1] != const0_rtx)
7139 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7142 [(set_attr "length" "2")
7143 (set_attr "in_delay_slot" "no")])
7145 ; 4 byte integer in line
7147 (define_insn "consttable_4"
7148 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7149 (match_operand 1 "" "")]
7154 if (operands[1] != const0_rtx)
7155 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7158 [(set_attr "length" "4")
7159 (set_attr "in_delay_slot" "no")])
7161 ; 8 byte integer in line
7163 (define_insn "consttable_8"
7164 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7165 (match_operand 1 "" "")]
7170 if (operands[1] != const0_rtx)
7171 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7174 [(set_attr "length" "8")
7175 (set_attr "in_delay_slot" "no")])
7177 ; 4 byte floating point
7179 (define_insn "consttable_sf"
7180 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7181 (match_operand 1 "" "")]
7186 if (operands[1] != const0_rtx)
7188 union real_extract u;
7189 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
7190 assemble_real (u.d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7194 [(set_attr "length" "4")
7195 (set_attr "in_delay_slot" "no")])
7197 ; 8 byte floating point
7199 (define_insn "consttable_df"
7200 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7201 (match_operand 1 "" "")]
7206 if (operands[1] != const0_rtx)
7208 union real_extract u;
7209 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u);
7210 assemble_real (u.d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7214 [(set_attr "length" "8")
7215 (set_attr "in_delay_slot" "no")])
7217 ;; Alignment is needed for some constant tables; it may also be added for
7218 ;; Instructions at the start of loops, or after unconditional branches.
7219 ;; ??? We would get more accurate lengths if we did instruction
7220 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7221 ;; here is too conservative.
7223 ; align to a two byte boundary
7225 (define_expand "align_2"
7226 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7230 ; align to a four byte boundary
7231 ;; align_4 and align_log are instructions for the starts of loops, or
7232 ;; after unconditional branches, which may take up extra room.
7234 (define_expand "align_4"
7235 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7239 ; align to a cache line boundary
7241 (define_insn "align_log"
7242 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7245 [(set_attr "length" "0")
7246 (set_attr "in_delay_slot" "no")])
7248 ; emitted at the end of the literal table, used to emit the
7249 ; 32bit branch labels if needed.
7251 (define_insn "consttable_end"
7252 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7254 "* return output_jump_label_table ();"
7255 [(set_attr "in_delay_slot" "no")])
7257 ; emitted at the end of the window in the literal table.
7259 (define_insn "consttable_window_end"
7260 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7263 [(set_attr "length" "0")
7264 (set_attr "in_delay_slot" "no")])
7266 ;; -------------------------------------------------------------------------
7268 ;; -------------------------------------------------------------------------
7270 ;; String/block move insn.
7272 (define_expand "movstrsi"
7273 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7274 (mem:BLK (match_operand:BLK 1 "" "")))
7275 (use (match_operand:SI 2 "nonmemory_operand" ""))
7276 (use (match_operand:SI 3 "immediate_operand" ""))
7277 (clobber (reg:SI PR_REG))
7278 (clobber (reg:SI R4_REG))
7279 (clobber (reg:SI R5_REG))
7280 (clobber (reg:SI R0_REG))])]
7281 "TARGET_SH1 && ! TARGET_SH5"
7284 if(expand_block_move (operands))
7289 (define_insn "block_move_real"
7290 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7291 (mem:BLK (reg:SI R5_REG)))
7292 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7293 (clobber (reg:SI PR_REG))
7294 (clobber (reg:SI R0_REG))])]
7295 "TARGET_SH1 && ! TARGET_HARD_SH4"
7297 [(set_attr "type" "sfunc")
7298 (set_attr "needs_delay_slot" "yes")])
7300 (define_insn "block_lump_real"
7301 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7302 (mem:BLK (reg:SI R5_REG)))
7303 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7304 (use (reg:SI R6_REG))
7305 (clobber (reg:SI PR_REG))
7306 (clobber (reg:SI T_REG))
7307 (clobber (reg:SI R4_REG))
7308 (clobber (reg:SI R5_REG))
7309 (clobber (reg:SI R6_REG))
7310 (clobber (reg:SI R0_REG))])]
7311 "TARGET_SH1 && ! TARGET_HARD_SH4"
7313 [(set_attr "type" "sfunc")
7314 (set_attr "needs_delay_slot" "yes")])
7316 (define_insn "block_move_real_i4"
7317 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7318 (mem:BLK (reg:SI R5_REG)))
7319 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7320 (clobber (reg:SI PR_REG))
7321 (clobber (reg:SI R0_REG))
7322 (clobber (reg:SI R1_REG))
7323 (clobber (reg:SI R2_REG))])]
7326 [(set_attr "type" "sfunc")
7327 (set_attr "needs_delay_slot" "yes")])
7329 (define_insn "block_lump_real_i4"
7330 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7331 (mem:BLK (reg:SI R5_REG)))
7332 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7333 (use (reg:SI R6_REG))
7334 (clobber (reg:SI PR_REG))
7335 (clobber (reg:SI T_REG))
7336 (clobber (reg:SI R4_REG))
7337 (clobber (reg:SI R5_REG))
7338 (clobber (reg:SI R6_REG))
7339 (clobber (reg:SI R0_REG))
7340 (clobber (reg:SI R1_REG))
7341 (clobber (reg:SI R2_REG))
7342 (clobber (reg:SI R3_REG))])]
7345 [(set_attr "type" "sfunc")
7346 (set_attr "needs_delay_slot" "yes")])
7348 ;; -------------------------------------------------------------------------
7349 ;; Floating point instructions.
7350 ;; -------------------------------------------------------------------------
7352 ;; ??? All patterns should have a type attribute.
7354 (define_expand "fpu_switch0"
7355 [(set (match_operand:SI 0 "" "") (match_dup 2))
7356 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7360 operands[1] = get_fpscr_rtx ();
7361 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7363 operands[2] = legitimize_pic_address (operands[2], SImode,
7364 no_new_pseudos ? operands[0] : 0);
7367 (define_expand "fpu_switch1"
7368 [(set (match_operand:SI 0 "" "") (match_dup 2))
7369 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7370 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7374 operands[1] = get_fpscr_rtx ();
7375 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7377 operands[2] = legitimize_pic_address (operands[2], SImode,
7378 no_new_pseudos ? operands[0] : 0);
7379 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7382 (define_expand "movpsi"
7383 [(set (match_operand:PSI 0 "register_operand" "")
7384 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7388 ;; The c / m alternative is a fake to guide reload to load directly into
7389 ;; fpscr, since reload doesn't know how to use post-increment.
7390 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7391 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7392 ;; predicate after reload.
7393 ;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
7394 ;; like a gpr <-> fpul move.
7395 (define_insn "fpu_switch"
7396 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7397 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7399 && (! reload_completed
7400 || true_regnum (operands[0]) != FPSCR_REG
7401 || GET_CODE (operands[1]) != MEM
7402 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7404 ! precision stays the same
7412 [(set_attr "length" "0,2,2,4,2,2,2,2")
7413 (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")])
7416 [(set (reg:PSI FPSCR_REG)
7417 (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
7418 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7419 [(set (match_dup 0) (match_dup 0))]
7422 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7423 gen_rtx (MEM, PSImode,
7424 gen_rtx (POST_INC, Pmode,
7426 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7430 [(set (reg:PSI FPSCR_REG)
7431 (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
7433 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7436 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7437 gen_rtx (MEM, PSImode,
7438 gen_rtx (POST_INC, Pmode,
7440 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7443 ;; ??? This uses the fp unit, but has no type indicating that.
7444 ;; If we did that, this would either give a bogus latency or introduce
7445 ;; a bogus FIFO constraint.
7446 ;; Since this insn is currently only used for prologues/epilogues,
7447 ;; it is probably best to claim no function unit, which matches the
7449 (define_insn "toggle_sz"
7450 [(set (reg:PSI FPSCR_REG)
7451 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7455 (define_expand "addsf3"
7456 [(set (match_operand:SF 0 "arith_reg_operand" "")
7457 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7458 (match_operand:SF 2 "arith_reg_operand" "")))]
7459 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7464 expand_sf_binop (&gen_addsf3_i, operands);
7469 (define_insn "*addsf3_media"
7470 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7471 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7472 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7473 "TARGET_SHMEDIA_FPU"
7474 "fadd.s %1, %2, %0")
7476 (define_insn "addsf3_i"
7477 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7478 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
7479 (match_operand:SF 2 "arith_reg_operand" "f")))
7480 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7483 [(set_attr "type" "fp")
7484 (set_attr "fp_mode" "single")])
7486 (define_expand "subsf3"
7487 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7488 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7489 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7490 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7495 expand_sf_binop (&gen_subsf3_i, operands);
7500 (define_insn "*subsf3_media"
7501 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7502 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7503 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7504 "TARGET_SHMEDIA_FPU"
7505 "fsub.s %1, %2, %0")
7507 (define_insn "subsf3_i"
7508 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7509 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
7510 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7511 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7514 [(set_attr "type" "fp")
7515 (set_attr "fp_mode" "single")])
7517 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
7518 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
7519 ;; mixed-precision SH4 targets. To allow it to be still generated for the
7520 ;; SH3E, we use a separate insn for SH3E mulsf3.
7522 (define_expand "mulsf3"
7523 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7524 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
7525 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
7526 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7530 expand_sf_binop (&gen_mulsf3_i4, operands);
7531 else if (TARGET_SH3E)
7532 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
7533 if (! TARGET_SHMEDIA)
7537 (define_insn "*mulsf3_media"
7538 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7539 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7540 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7541 "TARGET_SHMEDIA_FPU"
7542 "fmul.s %1, %2, %0")
7544 (define_insn "mulsf3_i4"
7545 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7546 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7547 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
7548 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7551 [(set_attr "type" "fp")
7552 (set_attr "fp_mode" "single")])
7554 (define_insn "mulsf3_ie"
7555 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7556 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
7557 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7558 "TARGET_SH3E && ! TARGET_SH4"
7560 [(set_attr "type" "fp")])
7562 (define_insn "*mac_media"
7563 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7564 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7565 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7566 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
7567 "TARGET_SHMEDIA_FPU"
7568 "fmac.s %1, %2, %0")
7570 (define_insn "*macsf3"
7571 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7572 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
7573 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
7574 (match_operand:SF 3 "arith_reg_operand" "0")))
7575 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
7576 "TARGET_SH3E && ! TARGET_SH4"
7578 [(set_attr "type" "fp")
7579 (set_attr "fp_mode" "single")])
7581 (define_expand "divsf3"
7582 [(set (match_operand:SF 0 "arith_reg_operand" "")
7583 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
7584 (match_operand:SF 2 "arith_reg_operand" "")))]
7585 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7590 expand_sf_binop (&gen_divsf3_i, operands);
7595 (define_insn "*divsf3_media"
7596 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7597 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
7598 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7599 "TARGET_SHMEDIA_FPU"
7600 "fdiv.s %1, %2, %0")
7602 (define_insn "divsf3_i"
7603 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
7604 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
7605 (match_operand:SF 2 "arith_reg_operand" "f")))
7606 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7609 [(set_attr "type" "fdiv")
7610 (set_attr "fp_mode" "single")])
7612 (define_insn "floatdisf2"
7613 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7614 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
7615 "TARGET_SHMEDIA_FPU"
7618 (define_expand "floatsisf2"
7619 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7620 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
7621 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7626 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7631 (define_insn "*floatsisf2_media"
7632 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7633 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
7634 "TARGET_SHMEDIA_FPU"
7637 (define_insn "floatsisf2_i4"
7638 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7639 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
7640 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7643 [(set_attr "type" "fp")
7644 (set_attr "fp_mode" "single")])
7646 (define_insn "*floatsisf2_ie"
7647 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7648 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
7649 "TARGET_SH3E && ! TARGET_SH4"
7651 [(set_attr "type" "fp")])
7653 (define_insn "fix_truncsfdi2"
7654 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
7655 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7656 "TARGET_SHMEDIA_FPU"
7659 (define_expand "fix_truncsfsi2"
7660 [(set (match_operand:SI 0 "fpul_operand" "=y")
7661 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7662 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7667 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
7672 (define_insn "*fix_truncsfsi2_media"
7673 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
7674 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7675 "TARGET_SHMEDIA_FPU"
7678 (define_insn "fix_truncsfsi2_i4"
7679 [(set (match_operand:SI 0 "fpul_operand" "=y")
7680 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7681 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7684 [(set_attr "type" "fp")
7685 (set_attr "fp_mode" "single")])
7687 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
7688 ;; fix_truncsfsi2_i4.
7689 ;; (define_insn "fix_truncsfsi2_i4_2"
7690 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7691 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7692 ;; (use (reg:PSI FPSCR_REG))
7693 ;; (clobber (reg:SI FPUL_REG))]
7696 ;; [(set_attr "length" "4")
7697 ;; (set_attr "fp_mode" "single")])
7700 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7701 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
7702 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
7703 ;; (clobber (reg:SI FPUL_REG))]
7705 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
7706 ;; (use (match_dup 2))])
7707 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
7709 (define_insn "*fixsfsi"
7710 [(set (match_operand:SI 0 "fpul_operand" "=y")
7711 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7712 "TARGET_SH3E && ! TARGET_SH4"
7714 [(set_attr "type" "fp")])
7716 (define_insn "cmpgtsf_t"
7717 [(set (reg:SI T_REG)
7718 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7719 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7720 "TARGET_SH3E && ! TARGET_SH4"
7722 [(set_attr "type" "fp")
7723 (set_attr "fp_mode" "single")])
7725 (define_insn "cmpeqsf_t"
7726 [(set (reg:SI T_REG)
7727 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7728 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7729 "TARGET_SH3E && ! TARGET_SH4"
7731 [(set_attr "type" "fp")
7732 (set_attr "fp_mode" "single")])
7734 (define_insn "ieee_ccmpeqsf_t"
7735 [(set (reg:SI T_REG)
7736 (ior:SI (reg:SI T_REG)
7737 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7738 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
7739 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
7740 "* return output_ieee_ccmpeq (insn, operands);"
7741 [(set_attr "length" "4")])
7744 (define_insn "cmpgtsf_t_i4"
7745 [(set (reg:SI T_REG)
7746 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7747 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7748 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7751 [(set_attr "type" "fp")
7752 (set_attr "fp_mode" "single")])
7754 (define_insn "cmpeqsf_t_i4"
7755 [(set (reg:SI T_REG)
7756 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7757 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
7758 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7761 [(set_attr "type" "fp")
7762 (set_attr "fp_mode" "single")])
7764 (define_insn "*ieee_ccmpeqsf_t_4"
7765 [(set (reg:SI T_REG)
7766 (ior:SI (reg:SI T_REG)
7767 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
7768 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
7769 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7770 "TARGET_IEEE && TARGET_SH4"
7771 "* return output_ieee_ccmpeq (insn, operands);"
7772 [(set_attr "length" "4")
7773 (set_attr "fp_mode" "single")])
7775 (define_insn "cmpeqsf_media"
7776 [(set (match_operand:DI 0 "register_operand" "=r")
7777 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7778 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7779 "TARGET_SHMEDIA_FPU"
7780 "fcmpeq.s %1, %2, %0")
7782 (define_insn "cmpgtsf_media"
7783 [(set (match_operand:DI 0 "register_operand" "=r")
7784 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7785 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7786 "TARGET_SHMEDIA_FPU"
7787 "fcmpgt.s %1, %2, %0")
7789 (define_insn "cmpgesf_media"
7790 [(set (match_operand:DI 0 "register_operand" "=r")
7791 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7792 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7793 "TARGET_SHMEDIA_FPU"
7794 "fcmpge.s %1, %2, %0")
7796 (define_insn "cmpunsf_media"
7797 [(set (match_operand:DI 0 "register_operand" "=r")
7798 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
7799 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7800 "TARGET_SHMEDIA_FPU"
7801 "fcmpun.s %1, %2, %0")
7803 (define_expand "cmpsf"
7804 [(set (reg:SI T_REG)
7805 (compare (match_operand:SF 0 "arith_operand" "")
7806 (match_operand:SF 1 "arith_operand" "")))]
7807 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7810 sh_compare_op0 = operands[0];
7811 sh_compare_op1 = operands[1];
7815 (define_expand "negsf2"
7816 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7817 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
7818 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7823 expand_sf_unop (&gen_negsf2_i, operands);
7828 (define_insn "*negsf2_media"
7829 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7830 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7831 "TARGET_SHMEDIA_FPU"
7834 (define_insn "negsf2_i"
7835 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7836 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
7837 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7840 [(set_attr "type" "fmove")
7841 (set_attr "fp_mode" "single")])
7843 (define_expand "sqrtsf2"
7844 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7845 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
7846 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7851 expand_sf_unop (&gen_sqrtsf2_i, operands);
7856 (define_insn "*sqrtsf2_media"
7857 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7858 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7859 "TARGET_SHMEDIA_FPU"
7862 (define_insn "sqrtsf2_i"
7863 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7864 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
7865 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7868 [(set_attr "type" "fdiv")
7869 (set_attr "fp_mode" "single")])
7871 (define_expand "abssf2"
7872 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
7873 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
7874 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7879 expand_sf_unop (&gen_abssf2_i, operands);
7884 (define_insn "*abssf2_media"
7885 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7886 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
7887 "TARGET_SHMEDIA_FPU"
7890 (define_insn "abssf2_i"
7891 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7892 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
7893 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
7896 [(set_attr "type" "fmove")
7897 (set_attr "fp_mode" "single")])
7899 (define_expand "adddf3"
7900 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
7901 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
7902 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
7903 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
7908 expand_df_binop (&gen_adddf3_i, operands);
7913 (define_insn "*adddf3_media"
7914 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7915 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
7916 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
7917 "TARGET_SHMEDIA_FPU"
7918 "fadd.d %1, %2, %0")
7920 (define_insn "adddf3_i"
7921 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7922 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
7923 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
7924 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7927 [(set_attr "type" "dfp_arith")
7928 (set_attr "fp_mode" "double")])
7930 (define_expand "subdf3"
7931 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
7932 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
7933 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
7934 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
7939 expand_df_binop (&gen_subdf3_i, operands);
7944 (define_insn "*subdf3_media"
7945 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7946 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
7947 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
7948 "TARGET_SHMEDIA_FPU"
7949 "fsub.d %1, %2, %0")
7951 (define_insn "subdf3_i"
7952 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7953 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
7954 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
7955 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7958 [(set_attr "type" "dfp_arith")
7959 (set_attr "fp_mode" "double")])
7961 (define_expand "muldf3"
7962 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
7963 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
7964 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
7965 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
7970 expand_df_binop (&gen_muldf3_i, operands);
7975 (define_insn "*muldf3_media"
7976 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7977 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
7978 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
7979 "TARGET_SHMEDIA_FPU"
7980 "fmul.d %1, %2, %0")
7982 (define_insn "muldf3_i"
7983 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
7984 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
7985 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
7986 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
7989 [(set_attr "type" "dfp_arith")
7990 (set_attr "fp_mode" "double")])
7992 (define_expand "divdf3"
7993 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
7994 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
7995 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
7996 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8001 expand_df_binop (&gen_divdf3_i, operands);
8006 (define_insn "*divdf3_media"
8007 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8008 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8009 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8010 "TARGET_SHMEDIA_FPU"
8011 "fdiv.d %1, %2, %0")
8013 (define_insn "divdf3_i"
8014 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8015 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8016 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8017 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8020 [(set_attr "type" "dfdiv")
8021 (set_attr "fp_mode" "double")])
8023 (define_insn "floatdidf2"
8024 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8025 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8026 "TARGET_SHMEDIA_FPU"
8029 (define_expand "floatsidf2"
8030 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8031 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8032 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8037 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8043 (define_insn "*floatsidf2_media"
8044 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8045 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8046 "TARGET_SHMEDIA_FPU"
8049 (define_insn "floatsidf2_i"
8050 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8051 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8052 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8055 [(set_attr "type" "dfp_conv")
8056 (set_attr "fp_mode" "double")])
8058 (define_insn "fix_truncdfdi2"
8059 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8060 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8061 "TARGET_SHMEDIA_FPU"
8064 (define_expand "fix_truncdfsi2"
8065 [(set (match_operand:SI 0 "fpul_operand" "")
8066 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8067 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8072 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8078 (define_insn "*fix_truncdfsi2_media"
8079 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8080 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8081 "TARGET_SHMEDIA_FPU"
8084 (define_insn "fix_truncdfsi2_i"
8085 [(set (match_operand:SI 0 "fpul_operand" "=y")
8086 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8087 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8090 [(set_attr "type" "dfp_conv")
8091 (set_attr "fp_mode" "double")])
8093 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8094 ;; fix_truncdfsi2_i.
8095 ;; (define_insn "fix_truncdfsi2_i4"
8096 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8097 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8098 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8099 ;; (clobber (reg:SI FPUL_REG))]
8102 ;; [(set_attr "length" "4")
8103 ;; (set_attr "fp_mode" "double")])
8106 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8107 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8108 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8109 ;; (clobber (reg:SI FPUL_REG))]
8111 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8112 ;; (use (match_dup 2))])
8113 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8115 (define_insn "cmpgtdf_t"
8116 [(set (reg:SI T_REG)
8117 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8118 (match_operand:DF 1 "arith_reg_operand" "f")))
8119 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8122 [(set_attr "type" "dfp_cmp")
8123 (set_attr "fp_mode" "double")])
8125 (define_insn "cmpeqdf_t"
8126 [(set (reg:SI T_REG)
8127 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8128 (match_operand:DF 1 "arith_reg_operand" "f")))
8129 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8132 [(set_attr "type" "dfp_cmp")
8133 (set_attr "fp_mode" "double")])
8135 (define_insn "*ieee_ccmpeqdf_t"
8136 [(set (reg:SI T_REG)
8137 (ior:SI (reg:SI T_REG)
8138 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8139 (match_operand:DF 1 "arith_reg_operand" "f"))))
8140 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8141 "TARGET_IEEE && TARGET_SH4"
8142 "* return output_ieee_ccmpeq (insn, operands);"
8143 [(set_attr "length" "4")
8144 (set_attr "fp_mode" "double")])
8146 (define_insn "cmpeqdf_media"
8147 [(set (match_operand:DI 0 "register_operand" "=r")
8148 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8149 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8150 "TARGET_SHMEDIA_FPU"
8151 "fcmpeq.d %1,%2,%0")
8153 (define_insn "cmpgtdf_media"
8154 [(set (match_operand:DI 0 "register_operand" "=r")
8155 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8156 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8157 "TARGET_SHMEDIA_FPU"
8158 "fcmpgt.d %1,%2,%0")
8160 (define_insn "cmpgedf_media"
8161 [(set (match_operand:DI 0 "register_operand" "=r")
8162 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8163 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8164 "TARGET_SHMEDIA_FPU"
8165 "fcmpge.d %1,%2,%0")
8167 (define_insn "cmpundf_media"
8168 [(set (match_operand:DI 0 "register_operand" "=r")
8169 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8170 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8171 "TARGET_SHMEDIA_FPU"
8172 "fcmpun.d %1,%2,%0")
8174 (define_expand "cmpdf"
8175 [(set (reg:SI T_REG)
8176 (compare (match_operand:DF 0 "arith_operand" "")
8177 (match_operand:DF 1 "arith_operand" "")))]
8178 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8181 sh_compare_op0 = operands[0];
8182 sh_compare_op1 = operands[1];
8186 (define_expand "negdf2"
8187 [(set (match_operand:DF 0 "arith_reg_operand" "")
8188 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8189 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8194 expand_df_unop (&gen_negdf2_i, operands);
8199 (define_insn "*negdf2_media"
8200 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8201 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8202 "TARGET_SHMEDIA_FPU"
8205 (define_insn "negdf2_i"
8206 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8207 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8208 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8211 [(set_attr "type" "fmove")
8212 (set_attr "fp_mode" "double")])
8214 (define_expand "sqrtdf2"
8215 [(set (match_operand:DF 0 "arith_reg_operand" "")
8216 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8217 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8222 expand_df_unop (&gen_sqrtdf2_i, operands);
8227 (define_insn "*sqrtdf2_media"
8228 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8229 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8230 "TARGET_SHMEDIA_FPU"
8233 (define_insn "sqrtdf2_i"
8234 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8235 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8236 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8239 [(set_attr "type" "dfdiv")
8240 (set_attr "fp_mode" "double")])
8242 (define_expand "absdf2"
8243 [(set (match_operand:DF 0 "arith_reg_operand" "")
8244 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8245 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8250 expand_df_unop (&gen_absdf2_i, operands);
8255 (define_insn "*absdf2_media"
8256 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8257 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8258 "TARGET_SHMEDIA_FPU"
8261 (define_insn "absdf2_i"
8262 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8263 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8264 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8267 [(set_attr "type" "fmove")
8268 (set_attr "fp_mode" "double")])
8270 (define_expand "extendsfdf2"
8271 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8272 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8273 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8278 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8284 (define_insn "*extendsfdf2_media"
8285 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8286 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8287 "TARGET_SHMEDIA_FPU"
8290 (define_insn "extendsfdf2_i4"
8291 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8292 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8293 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8296 [(set_attr "type" "fp")
8297 (set_attr "fp_mode" "double")])
8299 (define_expand "truncdfsf2"
8300 [(set (match_operand:SF 0 "fpul_operand" "")
8301 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8302 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8307 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8313 (define_insn "*truncdfsf2_media"
8314 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8315 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8316 "TARGET_SHMEDIA_FPU"
8319 (define_insn "truncdfsf2_i4"
8320 [(set (match_operand:SF 0 "fpul_operand" "=y")
8321 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8322 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8325 [(set_attr "type" "fp")
8326 (set_attr "fp_mode" "double")])
8328 ;; Bit field extract patterns. These give better code for packed bitfields,
8329 ;; because they allow auto-increment addresses to be generated.
8331 (define_expand "insv"
8332 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8333 (match_operand:SI 1 "immediate_operand" "")
8334 (match_operand:SI 2 "immediate_operand" ""))
8335 (match_operand:SI 3 "general_operand" ""))]
8336 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8339 rtx addr_target, orig_address, shift_reg, qi_val;
8340 HOST_WIDE_INT bitsize, size, v;
8341 rtx x = operands[3];
8343 /* ??? expmed doesn't care for non-register predicates. */
8344 if (! memory_operand (operands[0], VOIDmode)
8345 || ! immediate_operand (operands[1], VOIDmode)
8346 || ! immediate_operand (operands[2], VOIDmode)
8347 || ! general_operand (x, VOIDmode))
8349 /* If this isn't a 16 / 24 / 32 bit field, or if
8350 it doesn't start on a byte boundary, then fail. */
8351 bitsize = INTVAL (operands[1]);
8352 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8353 || (INTVAL (operands[2]) % 8) != 0)
8357 orig_address = XEXP (operands[0], 0);
8358 shift_reg = gen_reg_rtx (SImode);
8359 if (GET_CODE (x) == CONST_INT)
8362 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8366 emit_insn (gen_movsi (shift_reg, operands[3]));
8367 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8369 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8371 operands[0] = replace_equiv_address (operands[0], addr_target);
8372 emit_insn (gen_movqi (operands[0], qi_val));
8376 if (GET_CODE (x) == CONST_INT)
8378 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8381 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8382 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8384 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8385 emit_insn (gen_movqi (operands[0], qi_val));
8391 ;; -------------------------------------------------------------------------
8393 ;; -------------------------------------------------------------------------
8395 ;; This matches cases where a stack pointer increment at the start of the
8396 ;; epilogue combines with a stack slot read loading the return value.
8399 [(set (match_operand:SI 0 "arith_reg_operand" "")
8400 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8401 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8402 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8405 ;; See the comment on the dt combiner pattern above.
8408 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8409 (plus:SI (match_dup 0)
8412 (eq:SI (match_dup 0)
8417 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
8418 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
8419 ;; reload when the constant is too large for a reg+offset address.
8421 ;; ??? We would get much better code if this was done in reload. This would
8422 ;; require modifying find_reloads_address to recognize that if the constant
8423 ;; is out-of-range for an immediate add, then we get better code by reloading
8424 ;; the constant into a register than by reloading the sum into a register,
8425 ;; since the former is one instruction shorter if the address does not need
8426 ;; to be offsettable. Unfortunately this does not work, because there is
8427 ;; only one register, r0, that can be used as an index register. This register
8428 ;; is also the function return value register. So, if we try to force reload
8429 ;; to use double-reg addresses, then we end up with some instructions that
8430 ;; need to use r0 twice. The only way to fix this is to change the calling
8431 ;; convention so that r0 is not used to return values.
8434 [(set (match_operand:SI 0 "register_operand" "=r")
8435 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8436 (set (mem:SI (match_dup 0))
8437 (match_operand:SI 2 "general_movsrc_operand" ""))]
8438 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8439 "mov.l %2,@(%0,%1)")
8442 [(set (match_operand:SI 0 "register_operand" "=r")
8443 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8444 (set (match_operand:SI 2 "general_movdst_operand" "")
8445 (mem:SI (match_dup 0)))]
8446 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8447 "mov.l @(%0,%1),%2")
8450 [(set (match_operand:SI 0 "register_operand" "=r")
8451 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8452 (set (mem:HI (match_dup 0))
8453 (match_operand:HI 2 "general_movsrc_operand" ""))]
8454 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8455 "mov.w %2,@(%0,%1)")
8458 [(set (match_operand:SI 0 "register_operand" "=r")
8459 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8460 (set (match_operand:HI 2 "general_movdst_operand" "")
8461 (mem:HI (match_dup 0)))]
8462 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8463 "mov.w @(%0,%1),%2")
8466 [(set (match_operand:SI 0 "register_operand" "=r")
8467 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8468 (set (mem:QI (match_dup 0))
8469 (match_operand:QI 2 "general_movsrc_operand" ""))]
8470 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8471 "mov.b %2,@(%0,%1)")
8474 [(set (match_operand:SI 0 "register_operand" "=r")
8475 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8476 (set (match_operand:QI 2 "general_movdst_operand" "")
8477 (mem:QI (match_dup 0)))]
8478 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8479 "mov.b @(%0,%1),%2")
8482 [(set (match_operand:SI 0 "register_operand" "=r")
8483 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8484 (set (mem:SF (match_dup 0))
8485 (match_operand:SF 2 "general_movsrc_operand" ""))]
8486 "TARGET_SH1 && REGNO (operands[0]) == 0
8487 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8488 || (GET_CODE (operands[2]) == SUBREG
8489 && REGNO (SUBREG_REG (operands[2])) < 16))
8490 && reg_unused_after (operands[0], insn)"
8491 "mov.l %2,@(%0,%1)")
8494 [(set (match_operand:SI 0 "register_operand" "=r")
8495 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8496 (set (match_operand:SF 2 "general_movdst_operand" "")
8498 (mem:SF (match_dup 0)))]
8499 "TARGET_SH1 && REGNO (operands[0]) == 0
8500 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
8501 || (GET_CODE (operands[2]) == SUBREG
8502 && REGNO (SUBREG_REG (operands[2])) < 16))
8503 && reg_unused_after (operands[0], insn)"
8504 "mov.l @(%0,%1),%2")
8507 [(set (match_operand:SI 0 "register_operand" "=r")
8508 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8509 (set (mem:SF (match_dup 0))
8510 (match_operand:SF 2 "general_movsrc_operand" ""))]
8511 "TARGET_SH3E && REGNO (operands[0]) == 0
8512 && ((GET_CODE (operands[2]) == REG
8513 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8514 || (GET_CODE (operands[2]) == SUBREG
8515 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8516 && reg_unused_after (operands[0], insn)"
8517 "fmov{.s|} %2,@(%0,%1)")
8520 [(set (match_operand:SI 0 "register_operand" "=r")
8521 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8522 (set (match_operand:SF 2 "general_movdst_operand" "")
8524 (mem:SF (match_dup 0)))]
8525 "TARGET_SH3E && REGNO (operands[0]) == 0
8526 && ((GET_CODE (operands[2]) == REG
8527 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
8528 || (GET_CODE (operands[2]) == SUBREG
8529 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
8530 && reg_unused_after (operands[0], insn)"
8531 "fmov{.s|} @(%0,%1),%2")
8533 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
8534 (define_insn "sp_switch_1"
8541 xoperands[0] = sp_switch;
8542 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
8543 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
8544 return \"mov r0,r15\";
8546 [(set_attr "length" "10")])
8548 ;; Switch back to the original stack for interrupt functions with the
8549 ;; sp_switch attribute. */
8550 (define_insn "sp_switch_2"
8553 "mov.l @r15+,r15\;mov.l @r15+,r0"
8554 [(set_attr "length" "4")])