1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
146 ;; These are used with unspec_volatile.
152 (UNSPECV_WINDOW_END 10)
153 (UNSPECV_CONST_END 11)
156 ;; -------------------------------------------------------------------------
158 ;; -------------------------------------------------------------------------
163 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
164 (const (symbol_ref "sh_cpu_attr")))
166 (define_attr "endian" "big,little"
167 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
168 (const_string "little") (const_string "big"))))
170 ;; Indicate if the default fpu mode is single precision.
171 (define_attr "fpu_single" "yes,no"
172 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
173 (const_string "yes") (const_string "no"))))
175 (define_attr "fmovd" "yes,no"
176 (const (if_then_else (symbol_ref "TARGET_FMOVD")
177 (const_string "yes") (const_string "no"))))
179 (define_attr "pipe_model" "sh1,sh4,sh5media"
181 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
182 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
183 (const_string "sh1"))))
185 ;; cbranch conditional branch instructions
186 ;; jump unconditional jumps
187 ;; arith ordinary arithmetic
188 ;; arith3 a compound insn that behaves similarly to a sequence of
189 ;; three insns of type arith
190 ;; arith3b like above, but might end with a redirected branch
192 ;; load_si Likewise, SImode variant for general register.
193 ;; fload Likewise, but load to fp register.
195 ;; move general purpose register to register
196 ;; mt_group other sh4 mt instructions
197 ;; fmove register to register, floating point
198 ;; smpy word precision integer multiply
199 ;; dmpy longword or doublelongword precision integer multiply
201 ;; pload load of pr reg, which can't be put into delay slot of rts
202 ;; prset copy register to pr reg, ditto
203 ;; pstore store of pr reg, which can't be put into delay slot of jsr
204 ;; prget copy pr to register, ditto
205 ;; pcload pc relative load of constant value
206 ;; pcfload Likewise, but load to fp register.
207 ;; pcload_si Likewise, SImode variant for general register.
208 ;; rte return from exception
209 ;; sfunc special function call with known used registers
210 ;; call function call
212 ;; fdiv floating point divide (or square root)
213 ;; gp_fpul move from general purpose register to fpul
214 ;; fpul_gp move from fpul to general purpose register
215 ;; mac_gp move from mac[lh] to general purpose register
216 ;; dfp_arith, dfp_cmp,dfp_conv
217 ;; ftrc_s fix_truncsfsi2_i4
218 ;; dfdiv double precision floating point divide (or square root)
219 ;; cwb ic_invalidate_line_i
220 ;; tls_load load TLS related address
221 ;; arith_media SHmedia arithmetic, logical, and shift instructions
222 ;; cbranch_media SHmedia conditional branch instructions
223 ;; cmp_media SHmedia compare instructions
224 ;; dfdiv_media SHmedia double precision divide and square root
225 ;; dfmul_media SHmedia double precision multiply instruction
226 ;; dfparith_media SHmedia double precision floating point arithmetic
227 ;; dfpconv_media SHmedia double precision floating point conversions
228 ;; dmpy_media SHmedia longword multiply
229 ;; fcmp_media SHmedia floating point compare instructions
230 ;; fdiv_media SHmedia single precision divide and square root
231 ;; fload_media SHmedia floating point register load instructions
232 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
233 ;; fparith_media SHmedia single precision floating point arithmetic
234 ;; fpconv_media SHmedia single precision floating point conversions
235 ;; fstore_media SHmedia floating point register store instructions
236 ;; gettr_media SHmedia gettr instruction
237 ;; invalidate_line_media SHmedia invalidate_line sequence
238 ;; jump_media SHmedia unconditional branch instructions
239 ;; load_media SHmedia general register load instructions
240 ;; pt_media SHmedia pt instruction (expanded by assembler)
241 ;; ptabs_media SHmedia ptabs instruction
242 ;; store_media SHmedia general register store instructions
243 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
244 ;; mac_media SHmedia mac-style fixed point operations
245 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
246 ;; atrans SHmedia approximate transcendental functions
247 ;; ustore_media SHmedia unaligned stores
248 ;; nil no-op move, will be deleted.
251 "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
252 (const_string "other"))
254 ;; We define a new attribute namely "insn_class".We use
255 ;; this for the DFA based pipeline description.
257 ;; mt_group SH4 "mt" group instructions.
259 ;; ex_group SH4 "ex" group instructions.
261 ;; ls_group SH4 "ls" group instructions.
264 (define_attr "insn_class"
265 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
266 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
267 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
268 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
269 (eq_attr "type" "cbranch,jump") (const_string "br_group")
270 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
271 (const_string "fe_group")
272 (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
273 (const_string "none")))
274 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
275 ;; so these do not belong in an insn group, although they are modeled
276 ;; with their own define_insn_reservations.
278 ;; Indicate what precision must be selected in fpscr for this insn, if any.
280 (define_attr "fp_mode" "single,double,none" (const_string "none"))
282 ; If a conditional branch destination is within -252..258 bytes away
283 ; from the instruction it can be 2 bytes long. Something in the
284 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
285 ; branches are initially assumed to be 16 bytes long.
286 ; In machine_dependent_reorg, we split all branches that are longer than
289 ;; The maximum range used for SImode constant pool entries is 1018. A final
290 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
291 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
292 ;; instruction around the pool table, 2 bytes of alignment before the table,
293 ;; and 30 bytes of alignment after the table. That gives a maximum total
294 ;; pool size of 1058 bytes.
295 ;; Worst case code/pool content size ratio is 1:2 (using asms).
296 ;; Thus, in the worst case, there is one instruction in front of a maximum
297 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
298 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
299 ;; If we have a forward branch, the initial table will be put after the
300 ;; unconditional branch.
302 ;; ??? We could do much better by keeping track of the actual pcloads within
303 ;; the branch range and in the pcload range in front of the branch range.
305 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
307 (define_attr "short_cbranch_p" "no,yes"
308 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
310 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
312 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
314 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
316 ] (const_string "no")))
318 (define_attr "med_branch_p" "no,yes"
319 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
322 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
324 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
327 ] (const_string "no")))
329 (define_attr "med_cbranch_p" "no,yes"
330 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
333 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
338 ] (const_string "no")))
340 (define_attr "braf_branch_p" "no,yes"
341 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
343 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
346 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
351 ] (const_string "no")))
353 (define_attr "braf_cbranch_p" "no,yes"
354 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
356 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
359 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
361 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
364 ] (const_string "no")))
366 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
367 ; For wider ranges, we need a combination of a code and a data part.
368 ; If we can get a scratch register for a long range jump, the code
369 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
370 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
371 ; long; otherwise, it must be 6 bytes long.
373 ; All other instructions are two bytes long by default.
375 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
376 ;; but getattrtab doesn't understand this.
377 (define_attr "length" ""
378 (cond [(eq_attr "type" "cbranch")
379 (cond [(eq_attr "short_cbranch_p" "yes")
381 (eq_attr "med_cbranch_p" "yes")
383 (eq_attr "braf_cbranch_p" "yes")
385 ;; ??? using pc is not computed transitively.
386 (ne (match_dup 0) (match_dup 0))
388 (ne (symbol_ref ("flag_pic")) (const_int 0))
391 (eq_attr "type" "jump")
392 (cond [(eq_attr "med_branch_p" "yes")
394 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
396 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
397 (symbol_ref "code_for_indirect_jump_scratch")))
398 (if_then_else (eq_attr "braf_branch_p" "yes")
401 (eq_attr "braf_branch_p" "yes")
403 ;; ??? using pc is not computed transitively.
404 (ne (match_dup 0) (match_dup 0))
406 (ne (symbol_ref ("flag_pic")) (const_int 0))
409 (eq_attr "type" "pt_media")
410 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
411 (const_int 20) (const_int 12))
412 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
416 ;; (define_function_unit {name} {num-units} {n-users} {test}
417 ;; {ready-delay} {issue-delay} [{conflict-list}])
419 ;; Load and store instructions save a cycle if they are aligned on a
420 ;; four byte boundary. Using a function unit for stores encourages
421 ;; gcc to separate load and store instructions by one instruction,
422 ;; which makes it more likely that the linker will be able to word
423 ;; align them when relaxing.
425 ;; Loads have a latency of two.
426 ;; However, call insns can have a delay slot, so that we want one more
427 ;; insn to be scheduled between the load of the function address and the call.
428 ;; This is equivalent to a latency of three.
429 ;; We cannot use a conflict list for this, because we need to distinguish
430 ;; between the actual call address and the function arguments.
431 ;; ADJUST_COST can only properly handle reductions of the cost, so we
432 ;; use a latency of three here.
433 ;; We only do this for SImode loads of general registers, to make the work
434 ;; for ADJUST_COST easier.
435 (define_function_unit "memory" 1 0
436 (and (eq_attr "pipe_model" "sh1")
437 (eq_attr "type" "load_si,pcload_si"))
439 (define_function_unit "memory" 1 0
440 (and (eq_attr "pipe_model" "sh1")
441 (eq_attr "type" "load,pcload,pload,store,pstore"))
444 (define_function_unit "int" 1 0
445 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
447 (define_function_unit "int" 1 0
448 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
450 (define_function_unit "int" 1 0
451 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
453 ;; ??? These are approximations.
454 (define_function_unit "mpy" 1 0
455 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
456 (define_function_unit "mpy" 1 0
457 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
459 (define_function_unit "fp" 1 0
460 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
461 (define_function_unit "fp" 1 0
462 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
465 ;; SH-5 SHmedia scheduling
466 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
467 ;; single-issue machine. It has four pipelines, the branch unit (br),
468 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
469 ;; the floating point unit (fpu).
470 ;; Here model the instructions with a latency greater than one cycle.
472 ;; Every instruction on SH-5 occupies the issue resource for at least one
474 (define_function_unit "sh5issue" 1 0
475 (and (eq_attr "pipe_model" "sh5media")
476 (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
478 ;; Specify the various types of instruction which have latency > 1
479 (define_function_unit "sh5issue" 1 0
480 (and (eq_attr "pipe_model" "sh5media")
481 (eq_attr "type" "mcmp_media")) 2 1)
483 (define_function_unit "sh5issue" 1 0
484 (and (eq_attr "pipe_model" "sh5media")
485 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
486 ;; but see sh_adjust_cost for mac_media exception.
488 (define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "fload_media,fmove_media")) 4 1)
492 (define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "d2mpy_media")) 4 2)
496 (define_function_unit "sh5issue" 1 0
497 (and (eq_attr "pipe_model" "sh5media")
498 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
500 (define_function_unit "sh5issue" 1 0
501 (and (eq_attr "pipe_model" "sh5media")
502 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
504 (define_function_unit "sh5issue" 1 0
505 (and (eq_attr "pipe_model" "sh5media")
506 (eq_attr "type" "invalidate_line_media")) 7 7)
508 (define_function_unit "sh5issue" 1 0
509 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
511 (define_function_unit "sh5issue" 1 0
512 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
514 ;; Floating-point divide and square-root occupy an additional resource,
515 ;; which is not internally pipelined. However, other instructions
516 ;; can continue to issue.
517 (define_function_unit "sh5fds" 1 0
518 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
520 (define_function_unit "sh5fds" 1 0
521 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
523 ; Definitions for filling branch delay slots.
525 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
527 ;; ??? This should be (nil) instead of (const_int 0)
528 (define_attr "hit_stack" "yes,no"
529 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
532 (const_string "yes")))
534 (define_attr "interrupt_function" "no,yes"
535 (const (symbol_ref "current_function_interrupt")))
537 (define_attr "in_delay_slot" "yes,no"
538 (cond [(eq_attr "type" "cbranch") (const_string "no")
539 (eq_attr "type" "pcload,pcload_si") (const_string "no")
540 (eq_attr "needs_delay_slot" "yes") (const_string "no")
541 (eq_attr "length" "2") (const_string "yes")
542 ] (const_string "no")))
544 (define_attr "cond_delay_slot" "yes,no"
545 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
546 ] (const_string "no")))
548 (define_attr "is_sfunc" ""
549 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
551 (define_attr "is_mac_media" ""
552 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
554 (define_attr "branch_zero" "yes,no"
555 (cond [(eq_attr "type" "!cbranch") (const_string "no")
556 (ne (symbol_ref "(next_active_insn (insn)\
557 == (prev_active_insn\
558 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
559 && get_attr_length (next_active_insn (insn)) == 2")
561 (const_string "yes")]
562 (const_string "no")))
564 ;; SH4 Double-precision computation with double-precision result -
565 ;; the two halves are ready at different times.
566 (define_attr "dfp_comp" "yes,no"
567 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
568 (const_string "no")))
570 ;; Insns for which the latency of a preceding fp insn is decreased by one.
571 (define_attr "late_fp_use" "yes,no" (const_string "no"))
572 ;; And feeding insns for which this relevant.
573 (define_attr "any_fp_comp" "yes,no"
574 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
575 (const_string "yes")]
576 (const_string "no")))
578 (define_attr "any_int_load" "yes,no"
579 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
580 (const_string "yes")]
581 (const_string "no")))
584 (eq_attr "needs_delay_slot" "yes")
585 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
587 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
588 ;; and thus we can't put a pop instruction in its delay slot.
589 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
590 ;; instruction can go in the delay slot.
592 ;; Since a normal return (rts) implicitly uses the PR register,
593 ;; we can't allow PR register loads in an rts delay slot.
596 (eq_attr "type" "return")
597 [(and (eq_attr "in_delay_slot" "yes")
598 (ior (and (eq_attr "interrupt_function" "no")
599 (eq_attr "type" "!pload,prset"))
600 (and (eq_attr "interrupt_function" "yes")
602 (ne (symbol_ref "TARGET_SH3") (const_int 0))
603 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
605 ;; Since a call implicitly uses the PR register, we can't allow
606 ;; a PR register store in a jsr delay slot.
609 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
610 [(and (eq_attr "in_delay_slot" "yes")
611 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
613 ;; Say that we have annulled true branches, since this gives smaller and
614 ;; faster code when branches are predicted as not taken.
617 (and (eq_attr "type" "cbranch")
618 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
619 ;; SH2e has a hardware bug that pretty much prohibits the use of
620 ;; annuled delay slots.
621 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
622 (not (eq_attr "cpu" "sh2e"))) (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" "K08,r"))
635 [(set_attr "type" "mt_group")])
637 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
638 ;; That would still allow reload to create cmpi instructions, but would
639 ;; perhaps allow forcing the constant into a register when that is better.
640 ;; Probably should use r0 for mem/imm compares, but force constant into a
641 ;; register for pseudo/imm compares.
643 (define_insn "cmpeqsi_t"
645 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
646 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
652 [(set_attr "type" "mt_group")])
654 (define_insn "cmpgtsi_t"
656 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
657 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
662 [(set_attr "type" "mt_group")])
664 (define_insn "cmpgesi_t"
666 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
667 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
672 [(set_attr "type" "mt_group")])
674 ;; -------------------------------------------------------------------------
675 ;; SImode unsigned integer comparisons
676 ;; -------------------------------------------------------------------------
678 (define_insn "cmpgeusi_t"
680 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681 (match_operand:SI 1 "arith_reg_operand" "r")))]
684 [(set_attr "type" "mt_group")])
686 (define_insn "cmpgtusi_t"
688 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
689 (match_operand:SI 1 "arith_reg_operand" "r")))]
692 [(set_attr "type" "mt_group")])
694 ;; We save the compare operands in the cmpxx patterns and use them when
695 ;; we generate the branch.
697 (define_expand "cmpsi"
699 (compare (match_operand:SI 0 "arith_operand" "")
700 (match_operand:SI 1 "arith_operand" "")))]
704 sh_compare_op0 = operands[0];
705 sh_compare_op1 = operands[1];
709 ;; -------------------------------------------------------------------------
710 ;; DImode signed integer comparisons
711 ;; -------------------------------------------------------------------------
713 ;; ??? Could get better scheduling by splitting the initial test from the
714 ;; rest of the insn after reload. However, the gain would hardly justify
715 ;; the sh.md size increase necessary to do that.
719 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
720 (match_operand:DI 1 "arith_operand" "r"))
723 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
725 [(set_attr "length" "6")
726 (set_attr "type" "arith3b")])
728 (define_insn "cmpeqdi_t"
730 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
731 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
734 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
735 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
736 [(set_attr "length" "6")
737 (set_attr "type" "arith3b")])
741 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
742 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
743 ;; If we applied this split when not optimizing, it would only be
744 ;; applied during the machine-dependent reorg, when no new basic blocks
746 "TARGET_SH1 && reload_completed && optimize"
747 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
748 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
749 (label_ref (match_dup 6))
751 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
756 = gen_rtx_REG (SImode,
757 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
759 = (operands[1] == const0_rtx
761 : gen_rtx_REG (SImode,
762 true_regnum (operands[1])
763 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
764 operands[4] = gen_lowpart (SImode, operands[0]);
765 operands[5] = gen_lowpart (SImode, operands[1]);
766 operands[6] = gen_label_rtx ();
769 (define_insn "cmpgtdi_t"
771 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
772 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
775 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
776 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
777 [(set_attr "length" "8")
778 (set_attr "type" "arith3")])
780 (define_insn "cmpgedi_t"
782 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
783 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
786 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
788 [(set_attr "length" "8,2")
789 (set_attr "type" "arith3,mt_group")])
791 ;; -------------------------------------------------------------------------
792 ;; DImode unsigned integer comparisons
793 ;; -------------------------------------------------------------------------
795 (define_insn "cmpgeudi_t"
797 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
798 (match_operand:DI 1 "arith_reg_operand" "r")))]
800 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
801 [(set_attr "length" "8")
802 (set_attr "type" "arith3")])
804 (define_insn "cmpgtudi_t"
806 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
807 (match_operand:DI 1 "arith_reg_operand" "r")))]
809 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
810 [(set_attr "length" "8")
811 (set_attr "type" "arith3")])
813 (define_insn "cmpeqdi_media"
814 [(set (match_operand:DI 0 "register_operand" "=r")
815 (eq:DI (match_operand:DI 1 "register_operand" "%r")
816 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
819 [(set_attr "type" "cmp_media")])
821 (define_insn "cmpgtdi_media"
822 [(set (match_operand:DI 0 "register_operand" "=r")
823 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
824 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827 [(set_attr "type" "cmp_media")])
829 (define_insn "cmpgtudi_media"
830 [(set (match_operand:DI 0 "register_operand" "=r")
831 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
832 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
834 "cmpgtu %N1, %N2, %0"
835 [(set_attr "type" "cmp_media")])
837 ;; We save the compare operands in the cmpxx patterns and use them when
838 ;; we generate the branch.
840 (define_expand "cmpdi"
842 (compare (match_operand:DI 0 "arith_operand" "")
843 (match_operand:DI 1 "arith_operand" "")))]
844 "TARGET_SH2 || TARGET_SHMEDIA"
847 sh_compare_op0 = operands[0];
848 sh_compare_op1 = operands[1];
851 ;; -------------------------------------------------------------------------
852 ;; Conditional move instructions
853 ;; -------------------------------------------------------------------------
855 ;; The insn names may seem reversed, but note that cmveq performs the move
856 ;; if op1 == 0, and cmvne does it if op1 != 0.
858 (define_insn "movdicc_false"
859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
860 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
862 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
863 (match_operand:DI 3 "arith_reg_operand" "0")))]
866 [(set_attr "type" "arith_media")])
868 (define_insn "movdicc_true"
869 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
870 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
872 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
873 (match_operand:DI 3 "arith_reg_operand" "0")))]
876 [(set_attr "type" "arith_media")])
878 (define_expand "movdicc"
879 [(set (match_operand:DI 0 "register_operand" "")
880 (if_then_else:DI (match_operand 1 "comparison_operator" "")
881 (match_operand:DI 2 "register_operand" "")
882 (match_operand:DI 3 "register_operand" "")))]
886 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
887 && GET_MODE (sh_compare_op0) == DImode
888 && sh_compare_op1 == const0_rtx)
889 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
890 sh_compare_op0, sh_compare_op1);
898 tmp = gen_reg_rtx (DImode);
900 switch (GET_CODE (operands[1]))
903 emit_insn (gen_seq (tmp));
904 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
908 emit_insn (gen_seq (tmp));
909 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
913 emit_insn (gen_sgt (tmp));
914 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
918 emit_insn (gen_slt (tmp));
919 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
923 emit_insn (gen_slt (tmp));
924 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
928 emit_insn (gen_sgt (tmp));
929 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
933 emit_insn (gen_sgtu (tmp));
934 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
938 emit_insn (gen_sltu (tmp));
939 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
943 emit_insn (gen_sltu (tmp));
944 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
948 emit_insn (gen_sgtu (tmp));
949 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
953 emit_insn (gen_sunordered (tmp));
954 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
958 emit_insn (gen_sunordered (tmp));
959 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
976 ;; -------------------------------------------------------------------------
977 ;; Addition instructions
978 ;; -------------------------------------------------------------------------
980 (define_expand "adddi3"
981 [(set (match_operand:DI 0 "arith_reg_operand" "")
982 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
983 (match_operand:DI 2 "arith_operand" "")))]
989 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
991 operands[2] = force_reg (DImode, operands[2]);
992 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
997 (define_insn "*adddi3_media"
998 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
999 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1000 (match_operand:DI 2 "arith_operand" "r,I10")))]
1005 [(set_attr "type" "arith_media")])
1007 (define_insn "adddi3z_media"
1008 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1010 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1011 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1013 "addz.l %1, %N2, %0"
1014 [(set_attr "type" "arith_media")])
1016 (define_insn "adddi3_compact"
1017 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1018 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1019 (match_operand:DI 2 "arith_reg_operand" "r")))
1020 (clobber (reg:SI T_REG))]
1023 [(set_attr "length" "6")])
1026 [(set (match_operand:DI 0 "arith_reg_operand" "")
1027 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1028 (match_operand:DI 2 "arith_reg_operand" "")))
1029 (clobber (reg:SI T_REG))]
1030 "TARGET_SH1 && reload_completed"
1034 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1035 high0 = gen_rtx_REG (SImode,
1036 true_regnum (operands[0])
1037 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1038 high2 = gen_rtx_REG (SImode,
1039 true_regnum (operands[2])
1040 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1041 emit_insn (gen_clrt ());
1042 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1043 emit_insn (gen_addc1 (high0, high0, high2));
1048 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1049 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1050 (match_operand:SI 2 "arith_reg_operand" "r"))
1053 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1056 [(set_attr "type" "arith")])
1058 (define_insn "addc1"
1059 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1060 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1061 (match_operand:SI 2 "arith_reg_operand" "r"))
1063 (clobber (reg:SI T_REG))]
1066 [(set_attr "type" "arith")])
1068 (define_expand "addsi3"
1069 [(set (match_operand:SI 0 "arith_reg_operand" "")
1070 (plus:SI (match_operand:SI 1 "arith_operand" "")
1071 (match_operand:SI 2 "arith_operand" "")))]
1076 operands[1] = force_reg (SImode, operands[1]);
1079 (define_insn "addsi3_media"
1080 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1081 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1082 (match_operand:SI 2 "arith_operand" "r,I10")))]
1087 [(set_attr "type" "arith_media")])
1089 (define_insn "*addsi3_compact"
1090 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1092 (match_operand:SI 2 "arith_operand" "rI08")))]
1095 [(set_attr "type" "arith")])
1097 ;; -------------------------------------------------------------------------
1098 ;; Subtraction instructions
1099 ;; -------------------------------------------------------------------------
1101 (define_expand "subdi3"
1102 [(set (match_operand:DI 0 "arith_reg_operand" "")
1103 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1104 (match_operand:DI 2 "arith_reg_operand" "")))]
1110 operands[1] = force_reg (DImode, operands[1]);
1111 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1116 (define_insn "*subdi3_media"
1117 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1118 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1119 (match_operand:DI 2 "arith_reg_operand" "r")))]
1122 [(set_attr "type" "arith_media")])
1124 (define_insn "subdi3_compact"
1125 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1126 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1127 (match_operand:DI 2 "arith_reg_operand" "r")))
1128 (clobber (reg:SI T_REG))]
1131 [(set_attr "length" "6")])
1134 [(set (match_operand:DI 0 "arith_reg_operand" "")
1135 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1136 (match_operand:DI 2 "arith_reg_operand" "")))
1137 (clobber (reg:SI T_REG))]
1138 "TARGET_SH1 && reload_completed"
1142 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1143 high0 = gen_rtx_REG (SImode,
1144 true_regnum (operands[0])
1145 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1146 high2 = gen_rtx_REG (SImode,
1147 true_regnum (operands[2])
1148 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1149 emit_insn (gen_clrt ());
1150 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1151 emit_insn (gen_subc1 (high0, high0, high2));
1156 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1157 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1158 (match_operand:SI 2 "arith_reg_operand" "r"))
1161 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1164 [(set_attr "type" "arith")])
1166 (define_insn "subc1"
1167 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169 (match_operand:SI 2 "arith_reg_operand" "r"))
1171 (clobber (reg:SI T_REG))]
1174 [(set_attr "type" "arith")])
1176 (define_insn "*subsi3_internal"
1177 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1178 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1179 (match_operand:SI 2 "arith_reg_operand" "r")))]
1182 [(set_attr "type" "arith")])
1184 (define_insn "*subsi3_media"
1185 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1186 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1187 (match_operand:SI 2 "extend_reg_operand" "r")))]
1190 [(set_attr "type" "arith_media")])
1192 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1193 ;; will sometimes save one instruction. Otherwise we might get
1194 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1197 (define_expand "subsi3"
1198 [(set (match_operand:SI 0 "arith_reg_operand" "")
1199 (minus:SI (match_operand:SI 1 "arith_operand" "")
1200 (match_operand:SI 2 "arith_reg_operand" "")))]
1204 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1206 emit_insn (gen_negsi2 (operands[0], operands[2]));
1207 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1212 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1214 if (operands[1] != const0_rtx)
1215 operands[1] = force_reg (SImode, operands[1]);
1219 ;; -------------------------------------------------------------------------
1220 ;; Division instructions
1221 ;; -------------------------------------------------------------------------
1223 ;; We take advantage of the library routines which don't clobber as many
1224 ;; registers as a normal function call would.
1226 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1227 ;; also has an effect on the register that holds the address of the sfunc.
1228 ;; To make this work, we have an extra dummy insn that shows the use
1229 ;; of this register for reorg.
1231 (define_insn "use_sfunc_addr"
1232 [(set (reg:SI PR_REG)
1233 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1236 [(set_attr "length" "0")])
1238 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1239 ;; hard register 0. If we used hard register 0, then the next instruction
1240 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1241 ;; gets allocated to a stack slot that needs its address reloaded, then
1242 ;; there is nothing to prevent reload from using r0 to reload the address.
1243 ;; This reload would clobber the value in r0 we are trying to store.
1244 ;; If we let reload allocate r0, then this problem can never happen.
1246 (define_insn "udivsi3_i1"
1247 [(set (match_operand:SI 0 "register_operand" "=z")
1248 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1249 (clobber (reg:SI T_REG))
1250 (clobber (reg:SI PR_REG))
1251 (clobber (reg:SI R4_REG))
1252 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1253 "TARGET_SH1 && ! TARGET_SH4"
1255 [(set_attr "type" "sfunc")
1256 (set_attr "needs_delay_slot" "yes")])
1258 ; Since shmedia-nofpu code could be linked against shcompact code, and
1259 ; the udivsi3 libcall has the same name, we must consider all registers
1260 ; clobbered that are in the union of the registers clobbered by the
1261 ; shmedia and the shcompact implementation. Note, if the shcompact
1262 ; implementation actually used shcompact code, we'd need to clobber
1263 ; also r23 and fr23.
1264 (define_insn "udivsi3_i1_media"
1265 [(set (match_operand:SI 0 "register_operand" "=z")
1266 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1267 (clobber (reg:SI T_MEDIA_REG))
1268 (clobber (reg:SI PR_MEDIA_REG))
1269 (clobber (reg:SI R20_REG))
1270 (clobber (reg:SI R21_REG))
1271 (clobber (reg:SI R22_REG))
1272 (clobber (reg:DI TR0_REG))
1273 (clobber (reg:DI TR1_REG))
1274 (clobber (reg:DI TR2_REG))
1275 (use (match_operand:DI 1 "target_operand" "b"))]
1276 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1278 [(set_attr "type" "sfunc")
1279 (set_attr "needs_delay_slot" "yes")])
1281 (define_expand "udivsi3_i4_media"
1283 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1285 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1286 (set (match_dup 5) (float:DF (match_dup 3)))
1287 (set (match_dup 6) (float:DF (match_dup 4)))
1288 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1289 (set (match_dup 8) (fix:DI (match_dup 7)))
1290 (set (match_operand:SI 0 "register_operand" "")
1291 (truncate:SI (match_dup 8)))]
1292 "TARGET_SHMEDIA_FPU"
1295 operands[3] = gen_reg_rtx (DImode);
1296 operands[4] = gen_reg_rtx (DImode);
1297 operands[5] = gen_reg_rtx (DFmode);
1298 operands[6] = gen_reg_rtx (DFmode);
1299 operands[7] = gen_reg_rtx (DFmode);
1300 operands[8] = gen_reg_rtx (DImode);
1303 (define_insn "udivsi3_i4"
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 (reg:PSI FPSCR_REG))
1316 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1317 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1319 [(set_attr "type" "sfunc")
1320 (set_attr "fp_mode" "double")
1321 (set_attr "needs_delay_slot" "yes")])
1323 (define_insn "udivsi3_i4_single"
1324 [(set (match_operand:SI 0 "register_operand" "=y")
1325 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1326 (clobber (reg:SI T_REG))
1327 (clobber (reg:SI PR_REG))
1328 (clobber (reg:DF DR0_REG))
1329 (clobber (reg:DF DR2_REG))
1330 (clobber (reg:DF DR4_REG))
1331 (clobber (reg:SI R0_REG))
1332 (clobber (reg:SI R1_REG))
1333 (clobber (reg:SI R4_REG))
1334 (clobber (reg:SI R5_REG))
1335 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1336 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1338 [(set_attr "type" "sfunc")
1339 (set_attr "needs_delay_slot" "yes")])
1341 (define_expand "udivsi3"
1342 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1343 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1344 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1345 (parallel [(set (match_operand:SI 0 "register_operand" "")
1346 (udiv:SI (reg:SI R4_REG)
1348 (clobber (reg:SI T_REG))
1349 (clobber (reg:SI PR_REG))
1350 (clobber (reg:SI R4_REG))
1351 (use (match_dup 3))])]
1357 operands[3] = gen_reg_rtx (Pmode);
1358 /* Emit the move of the address to a pseudo outside of the libcall. */
1359 if (TARGET_HARD_SH4 && TARGET_SH2E)
1361 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1362 if (TARGET_FPU_SINGLE)
1363 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1365 last = gen_udivsi3_i4 (operands[0], operands[3]);
1367 else if (TARGET_SHMEDIA_FPU)
1369 operands[1] = force_reg (SImode, operands[1]);
1370 operands[2] = force_reg (SImode, operands[2]);
1371 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1374 else if (TARGET_SH5)
1376 emit_move_insn (operands[3],
1377 function_symbol (TARGET_FPU_ANY
1382 last = gen_udivsi3_i1_media (operands[0],
1385 : gen_rtx_SUBREG (DImode, operands[3],
1387 else if (TARGET_FPU_ANY)
1388 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1390 last = gen_udivsi3_i1 (operands[0], operands[3]);
1394 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1395 last = gen_udivsi3_i1 (operands[0], operands[3]);
1397 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1398 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1399 last = emit_insn (last);
1400 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1401 invariant code motion can move it. */
1402 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1403 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1407 (define_insn "divsi3_i1"
1408 [(set (match_operand:SI 0 "register_operand" "=z")
1409 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1410 (clobber (reg:SI T_REG))
1411 (clobber (reg:SI PR_REG))
1412 (clobber (reg:SI R1_REG))
1413 (clobber (reg:SI R2_REG))
1414 (clobber (reg:SI R3_REG))
1415 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1416 "TARGET_SH1 && ! TARGET_SH4"
1418 [(set_attr "type" "sfunc")
1419 (set_attr "needs_delay_slot" "yes")])
1421 ; Since shmedia-nofpu code could be linked against shcompact code, and
1422 ; the sdivsi3 libcall has the same name, we must consider all registers
1423 ; clobbered that are in the union of the registers clobbered by the
1424 ; shmedia and the shcompact implementation. Note, if the shcompact
1425 ; implementation actually used shcompact code, we'd need to clobber
1426 ; also r22, r23 and fr23.
1427 (define_insn "divsi3_i1_media"
1428 [(set (match_operand:SI 0 "register_operand" "=z")
1429 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1430 (clobber (reg:SI T_MEDIA_REG))
1431 (clobber (reg:SI PR_MEDIA_REG))
1432 (clobber (reg:SI R1_REG))
1433 (clobber (reg:SI R2_REG))
1434 (clobber (reg:SI R3_REG))
1435 (clobber (reg:SI R20_REG))
1436 (clobber (reg:SI R21_REG))
1437 (clobber (reg:DI TR0_REG))
1438 (clobber (reg:DI TR1_REG))
1439 (clobber (reg:DI TR2_REG))
1440 (use (match_operand:DI 1 "target_operand" "b"))]
1441 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1443 [(set_attr "type" "sfunc")])
1445 (define_expand "divsi3_i4_media"
1446 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1447 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1448 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1449 (set (match_operand:SI 0 "register_operand" "=r")
1450 (fix:SI (match_dup 5)))]
1451 "TARGET_SHMEDIA_FPU"
1454 operands[3] = gen_reg_rtx (DFmode);
1455 operands[4] = gen_reg_rtx (DFmode);
1456 operands[5] = gen_reg_rtx (DFmode);
1459 (define_insn "divsi3_i4"
1460 [(set (match_operand:SI 0 "register_operand" "=y")
1461 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1462 (clobber (reg:SI PR_REG))
1463 (clobber (reg:DF DR0_REG))
1464 (clobber (reg:DF DR2_REG))
1465 (use (reg:PSI FPSCR_REG))
1466 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1467 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1469 [(set_attr "type" "sfunc")
1470 (set_attr "fp_mode" "double")
1471 (set_attr "needs_delay_slot" "yes")])
1473 (define_insn "divsi3_i4_single"
1474 [(set (match_operand:SI 0 "register_operand" "=y")
1475 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1476 (clobber (reg:SI PR_REG))
1477 (clobber (reg:DF DR0_REG))
1478 (clobber (reg:DF DR2_REG))
1479 (clobber (reg:SI R2_REG))
1480 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1483 [(set_attr "type" "sfunc")
1484 (set_attr "needs_delay_slot" "yes")])
1486 (define_expand "divsi3"
1487 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1488 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1489 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1490 (parallel [(set (match_operand:SI 0 "register_operand" "")
1491 (div:SI (reg:SI R4_REG)
1493 (clobber (reg:SI T_REG))
1494 (clobber (reg:SI PR_REG))
1495 (clobber (reg:SI R1_REG))
1496 (clobber (reg:SI R2_REG))
1497 (clobber (reg:SI R3_REG))
1498 (use (match_dup 3))])]
1504 operands[3] = gen_reg_rtx (Pmode);
1505 /* Emit the move of the address to a pseudo outside of the libcall. */
1506 if (TARGET_HARD_SH4 && TARGET_SH2E)
1508 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1509 if (TARGET_FPU_SINGLE)
1510 last = gen_divsi3_i4_single (operands[0], operands[3]);
1512 last = gen_divsi3_i4 (operands[0], operands[3]);
1514 else if (TARGET_SHMEDIA_FPU)
1516 operands[1] = force_reg (SImode, operands[1]);
1517 operands[2] = force_reg (SImode, operands[2]);
1518 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1521 else if (TARGET_SH5)
1523 emit_move_insn (operands[3],
1524 function_symbol (TARGET_FPU_ANY
1529 last = gen_divsi3_i1_media (operands[0],
1532 : gen_rtx_SUBREG (DImode, operands[3],
1534 else if (TARGET_FPU_ANY)
1535 last = gen_divsi3_i4_single (operands[0], operands[3]);
1537 last = gen_divsi3_i1 (operands[0], operands[3]);
1541 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1542 last = gen_divsi3_i1 (operands[0], operands[3]);
1544 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1545 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1546 last = emit_insn (last);
1547 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1548 invariant code motion can move it. */
1549 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1550 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1554 ;; -------------------------------------------------------------------------
1555 ;; Multiplication instructions
1556 ;; -------------------------------------------------------------------------
1558 (define_insn "umulhisi3_i"
1559 [(set (reg:SI MACL_REG)
1560 (mult:SI (zero_extend:SI
1561 (match_operand:HI 0 "arith_reg_operand" "r"))
1563 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1566 [(set_attr "type" "smpy")])
1568 (define_insn "mulhisi3_i"
1569 [(set (reg:SI MACL_REG)
1570 (mult:SI (sign_extend:SI
1571 (match_operand:HI 0 "arith_reg_operand" "r"))
1573 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1576 [(set_attr "type" "smpy")])
1578 (define_expand "mulhisi3"
1579 [(set (reg:SI MACL_REG)
1580 (mult:SI (sign_extend:SI
1581 (match_operand:HI 1 "arith_reg_operand" ""))
1583 (match_operand:HI 2 "arith_reg_operand" ""))))
1584 (set (match_operand:SI 0 "arith_reg_operand" "")
1591 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1592 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1593 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1594 invariant code motion can move it. */
1595 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1596 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1597 /* expand_binop can't find a suitable code in umul_widen_optab to
1598 make a REG_EQUAL note from, so make one here.
1599 See also smulsi3_highpart.
1600 ??? Alternatively, we could put this at the calling site of expand_binop,
1601 i.e. expand_expr. */
1603 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1608 (define_expand "umulhisi3"
1609 [(set (reg:SI MACL_REG)
1610 (mult:SI (zero_extend:SI
1611 (match_operand:HI 1 "arith_reg_operand" ""))
1613 (match_operand:HI 2 "arith_reg_operand" ""))))
1614 (set (match_operand:SI 0 "arith_reg_operand" "")
1621 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1622 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1623 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1624 invariant code motion can move it. */
1625 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1626 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1627 /* expand_binop can't find a suitable code in umul_widen_optab to
1628 make a REG_EQUAL note from, so make one here.
1629 See also smulsi3_highpart.
1630 ??? Alternatively, we could put this at the calling site of expand_binop,
1631 i.e. expand_expr. */
1633 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1638 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1639 ;; a call to a routine which clobbers known registers.
1642 [(set (match_operand:SI 1 "register_operand" "=z")
1643 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1644 (clobber (reg:SI MACL_REG))
1645 (clobber (reg:SI T_REG))
1646 (clobber (reg:SI PR_REG))
1647 (clobber (reg:SI R3_REG))
1648 (clobber (reg:SI R2_REG))
1649 (clobber (reg:SI R1_REG))
1650 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1653 [(set_attr "type" "sfunc")
1654 (set_attr "needs_delay_slot" "yes")])
1656 (define_expand "mulsi3_call"
1657 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1658 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1659 (parallel[(set (match_operand:SI 0 "register_operand" "")
1660 (mult:SI (reg:SI R4_REG)
1662 (clobber (reg:SI MACL_REG))
1663 (clobber (reg:SI T_REG))
1664 (clobber (reg:SI PR_REG))
1665 (clobber (reg:SI R3_REG))
1666 (clobber (reg:SI R2_REG))
1667 (clobber (reg:SI R1_REG))
1668 (use (match_operand:SI 3 "register_operand" ""))])]
1672 (define_insn "mul_l"
1673 [(set (reg:SI MACL_REG)
1674 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1675 (match_operand:SI 1 "arith_reg_operand" "r")))]
1678 [(set_attr "type" "dmpy")])
1680 (define_expand "mulsi3"
1681 [(set (reg:SI MACL_REG)
1682 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1683 (match_operand:SI 2 "arith_reg_operand" "")))
1684 (set (match_operand:SI 0 "arith_reg_operand" "")
1693 /* The address must be set outside the libcall,
1694 since it goes into a pseudo. */
1695 rtx sym = function_symbol (\"__mulsi3\");
1696 rtx addr = force_reg (SImode, sym);
1697 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1700 last = emit_insn (insns);
1704 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1706 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1707 /* consec_sets_giv can only recognize the first insn that sets a
1708 giv as the giv insn. So we must tag this also with a REG_EQUAL
1710 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1712 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1713 invariant code motion can move it. */
1714 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1715 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1719 (define_insn "mulsidi3_i"
1720 [(set (reg:SI MACH_REG)
1724 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1725 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1727 (set (reg:SI MACL_REG)
1728 (mult:SI (match_dup 0)
1732 [(set_attr "type" "dmpy")])
1734 (define_expand "mulsidi3"
1735 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1736 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1737 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1738 "TARGET_SH2 || TARGET_SHMEDIA"
1743 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1749 (define_insn "mulsidi3_media"
1750 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1751 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1752 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1755 [(set_attr "type" "dmpy_media")])
1757 (define_insn "mulsidi3_compact"
1758 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1761 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1762 (clobber (reg:SI MACH_REG))
1763 (clobber (reg:SI MACL_REG))]
1768 [(set (match_operand:DI 0 "arith_reg_operand" "")
1770 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1771 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1772 (clobber (reg:SI MACH_REG))
1773 (clobber (reg:SI MACL_REG))]
1778 rtx low_dst = gen_lowpart (SImode, operands[0]);
1779 rtx high_dst = gen_highpart (SImode, operands[0]);
1781 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1783 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1784 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1785 /* We need something to tag the possible REG_EQUAL notes on to. */
1786 emit_move_insn (operands[0], operands[0]);
1790 (define_insn "umulsidi3_i"
1791 [(set (reg:SI MACH_REG)
1795 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1796 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1798 (set (reg:SI MACL_REG)
1799 (mult:SI (match_dup 0)
1803 [(set_attr "type" "dmpy")])
1805 (define_expand "umulsidi3"
1806 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1807 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1808 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1809 "TARGET_SH2 || TARGET_SHMEDIA"
1814 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1820 (define_insn "umulsidi3_media"
1821 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1822 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1823 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1826 [(set_attr "type" "dmpy_media")])
1828 (define_insn "umulsidi3_compact"
1829 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1832 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1833 (clobber (reg:SI MACH_REG))
1834 (clobber (reg:SI MACL_REG))]
1839 [(set (match_operand:DI 0 "arith_reg_operand" "")
1840 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1842 (clobber (reg:SI MACH_REG))
1843 (clobber (reg:SI MACL_REG))]
1848 rtx low_dst = gen_lowpart (SImode, operands[0]);
1849 rtx high_dst = gen_highpart (SImode, operands[0]);
1851 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1853 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1854 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1855 /* We need something to tag the possible REG_EQUAL notes on to. */
1856 emit_move_insn (operands[0], operands[0]);
1860 (define_insn "smulsi3_highpart_i"
1861 [(set (reg:SI MACH_REG)
1865 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1866 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1868 (clobber (reg:SI MACL_REG))]
1871 [(set_attr "type" "dmpy")])
1873 (define_expand "smulsi3_highpart"
1875 [(set (reg:SI MACH_REG)
1879 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1880 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1882 (clobber (reg:SI MACL_REG))])
1883 (set (match_operand:SI 0 "arith_reg_operand" "")
1890 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1891 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1892 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1893 invariant code motion can move it. */
1894 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1895 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1896 /* expand_binop can't find a suitable code in mul_highpart_optab to
1897 make a REG_EQUAL note from, so make one here.
1898 See also {,u}mulhisi.
1899 ??? Alternatively, we could put this at the calling site of expand_binop,
1900 i.e. expand_mult_highpart. */
1902 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1907 (define_insn "umulsi3_highpart_i"
1908 [(set (reg:SI MACH_REG)
1912 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1913 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1915 (clobber (reg:SI MACL_REG))]
1918 [(set_attr "type" "dmpy")])
1920 (define_expand "umulsi3_highpart"
1922 [(set (reg:SI MACH_REG)
1926 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1927 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1929 (clobber (reg:SI MACL_REG))])
1930 (set (match_operand:SI 0 "arith_reg_operand" "")
1937 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1938 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1939 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1940 invariant code motion can move it. */
1941 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1942 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1946 ;; -------------------------------------------------------------------------
1947 ;; Logical operations
1948 ;; -------------------------------------------------------------------------
1950 (define_insn "*andsi3_compact"
1951 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1952 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1953 (match_operand:SI 2 "logical_operand" "r,K08")))]
1956 [(set_attr "type" "arith")])
1958 ;; If the constant is 255, then emit an extu.b instruction instead of an
1959 ;; and, since that will give better code.
1961 (define_expand "andsi3"
1962 [(set (match_operand:SI 0 "arith_reg_operand" "")
1963 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1964 (match_operand:SI 2 "logical_operand" "")))]
1968 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1970 emit_insn (gen_zero_extendqisi2 (operands[0],
1971 gen_lowpart (QImode, operands[1])));
1976 (define_insn_and_split "anddi3"
1977 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1978 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1979 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1986 && ! logical_operand (operands[2], DImode)"
1990 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1991 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1993 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1996 [(set_attr "type" "arith_media")])
1998 (define_insn "andcdi3"
1999 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2000 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2001 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2004 [(set_attr "type" "arith_media")])
2006 (define_insn "iorsi3"
2007 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2008 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2009 (match_operand:SI 2 "logical_operand" "r,K08")))]
2012 [(set_attr "type" "arith")])
2014 (define_insn "iordi3"
2015 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2016 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2017 (match_operand:DI 2 "logical_operand" "r,I10")))]
2022 [(set_attr "type" "arith_media")])
2024 (define_insn "xorsi3"
2025 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2026 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2027 (match_operand:SI 2 "logical_operand" "K08,r")))]
2030 [(set_attr "type" "arith")])
2032 (define_insn "xordi3"
2033 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2034 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2035 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2040 [(set_attr "type" "arith_media")])
2042 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2043 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2045 [(set (match_operand:DI 0 "arith_reg_operand" "")
2046 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2047 [(match_operand 1 "any_register_operand" "")
2048 (match_operand 2 "any_register_operand" "")])))]
2050 [(set (match_dup 5) (match_dup 4))
2051 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2054 enum machine_mode inmode = GET_MODE (operands[1]);
2055 int regno, offset = 0;
2057 if (GET_CODE (operands[0]) == SUBREG)
2059 offset = SUBREG_BYTE (operands[0]);
2060 operands[0] = SUBREG_REG (operands[0]);
2062 if (GET_CODE (operands[0]) != REG)
2064 if (! TARGET_LITTLE_ENDIAN)
2065 offset += 8 - GET_MODE_SIZE (inmode);
2066 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2069 ;; -------------------------------------------------------------------------
2070 ;; Shifts and rotates
2071 ;; -------------------------------------------------------------------------
2073 (define_expand "rotldi3"
2074 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2075 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2076 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2078 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2080 (define_insn "rotldi3_mextr"
2081 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2082 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2083 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2087 static char templ[16];
2089 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2090 8 - (int) (INTVAL (operands[2]) >> 3));
2093 [(set_attr "type" "arith_media")])
2095 (define_expand "rotrdi3"
2096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2097 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2098 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2100 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2102 (define_insn "rotrdi3_mextr"
2103 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2104 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2105 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2109 static char templ[16];
2111 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2114 [(set_attr "type" "arith_media")])
2116 (define_insn "rotlsi3_1"
2117 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2118 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2121 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2124 [(set_attr "type" "arith")])
2126 (define_insn "rotlsi3_31"
2127 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2128 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130 (clobber (reg:SI T_REG))]
2133 [(set_attr "type" "arith")])
2135 (define_insn "rotlsi3_16"
2136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2141 [(set_attr "type" "arith")])
2143 (define_expand "rotlsi3"
2144 [(set (match_operand:SI 0 "arith_reg_operand" "")
2145 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2146 (match_operand:SI 2 "immediate_operand" "")))]
2150 static const char rot_tab[] = {
2151 000, 000, 000, 000, 000, 000, 010, 001,
2152 001, 001, 011, 013, 003, 003, 003, 003,
2153 003, 003, 003, 003, 003, 013, 012, 002,
2154 002, 002, 010, 000, 000, 000, 000, 000,
2159 if (GET_CODE (operands[2]) != CONST_INT)
2161 count = INTVAL (operands[2]);
2162 choice = rot_tab[count];
2163 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2169 emit_move_insn (operands[0], operands[1]);
2170 count -= (count & 16) * 2;
2173 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2180 parts[0] = gen_reg_rtx (SImode);
2181 parts[1] = gen_reg_rtx (SImode);
2182 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2183 parts[choice-1] = operands[1];
2184 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2185 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2186 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2187 count = (count & ~16) - 8;
2191 for (; count > 0; count--)
2192 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2193 for (; count < 0; count++)
2194 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2199 (define_insn "*rotlhi3_8"
2200 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2201 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2205 [(set_attr "type" "arith")])
2207 (define_expand "rotlhi3"
2208 [(set (match_operand:HI 0 "arith_reg_operand" "")
2209 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2210 (match_operand:HI 2 "immediate_operand" "")))]
2214 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2221 ;; This pattern is used by init_expmed for computing the costs of shift
2224 (define_insn_and_split "ashlsi3_std"
2225 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2226 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2227 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2228 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2230 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2231 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2239 && GET_CODE (operands[2]) == CONST_INT
2240 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2241 [(set (match_dup 3) (match_dup 2))
2243 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2244 (clobber (match_dup 4))])]
2245 "operands[4] = gen_rtx_SCRATCH (SImode);"
2246 [(set_attr "length" "*,*,*,4")
2247 (set_attr "type" "dyn_shift,arith,arith,arith")])
2249 (define_insn "ashlhi3_k"
2250 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2251 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2252 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2253 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2257 [(set_attr "type" "arith")])
2259 (define_insn "ashlsi3_n"
2260 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2261 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2262 (match_operand:SI 2 "const_int_operand" "n")))
2263 (clobber (reg:SI T_REG))]
2264 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2266 [(set (attr "length")
2267 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2269 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2271 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2273 (const_string "8")))
2274 (set_attr "type" "arith")])
2277 [(set (match_operand:SI 0 "arith_reg_operand" "")
2278 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2279 (match_operand:SI 2 "const_int_operand" "")))
2280 (clobber (reg:SI T_REG))]
2281 "TARGET_SH1 && reload_completed"
2282 [(use (reg:SI R0_REG))]
2285 gen_shifty_op (ASHIFT, operands);
2289 (define_insn "ashlsi3_media"
2290 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2291 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2292 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2297 [(set_attr "type" "arith_media")])
2299 (define_expand "ashlsi3"
2300 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2301 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2302 (match_operand:SI 2 "nonmemory_operand" "")))
2303 (clobber (reg:SI T_REG))])]
2309 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2312 if (GET_CODE (operands[2]) == CONST_INT
2313 && sh_dynamicalize_shift_p (operands[2]))
2314 operands[2] = force_reg (SImode, operands[2]);
2317 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2320 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2324 (define_insn "ashlhi3"
2325 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2326 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2327 (match_operand:HI 2 "const_int_operand" "n")))
2328 (clobber (reg:SI T_REG))]
2331 [(set (attr "length")
2332 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2334 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2336 (const_string "6")))
2337 (set_attr "type" "arith")])
2340 [(set (match_operand:HI 0 "arith_reg_operand" "")
2341 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2342 (match_operand:HI 2 "const_int_operand" "")))
2343 (clobber (reg:SI T_REG))]
2344 "TARGET_SH1 && reload_completed"
2345 [(use (reg:SI R0_REG))]
2348 gen_shifty_hi_op (ASHIFT, operands);
2353 ; arithmetic shift right
2356 (define_insn "ashrsi3_k"
2357 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2358 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2359 (match_operand:SI 2 "const_int_operand" "M")))
2360 (clobber (reg:SI T_REG))]
2361 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2363 [(set_attr "type" "arith")])
2365 ;; We can't do HImode right shifts correctly unless we start out with an
2366 ;; explicit zero / sign extension; doing that would result in worse overall
2367 ;; code, so just let the machine independent code widen the mode.
2368 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2371 ;; ??? This should be a define expand.
2373 (define_insn "ashrsi2_16"
2374 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2379 [(set_attr "length" "4")])
2382 [(set (match_operand:SI 0 "arith_reg_operand" "")
2383 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2386 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2387 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2388 "operands[2] = gen_lowpart (HImode, operands[0]);")
2390 ;; ??? This should be a define expand.
2392 (define_insn "ashrsi2_31"
2393 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2394 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2396 (clobber (reg:SI T_REG))]
2399 [(set_attr "length" "4")])
2402 [(set (match_operand:SI 0 "arith_reg_operand" "")
2403 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2405 (clobber (reg:SI T_REG))]
2410 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2411 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2415 (define_insn "ashlsi_c"
2416 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2417 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2419 (lt:SI (match_dup 1) (const_int 0)))]
2422 [(set_attr "type" "arith")])
2424 (define_insn "ashrsi3_d"
2425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2427 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2430 [(set_attr "type" "dyn_shift")])
2432 (define_insn "ashrsi3_n"
2433 [(set (reg:SI R4_REG)
2434 (ashiftrt:SI (reg:SI R4_REG)
2435 (match_operand:SI 0 "const_int_operand" "i")))
2436 (clobber (reg:SI T_REG))
2437 (clobber (reg:SI PR_REG))
2438 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2441 [(set_attr "type" "sfunc")
2442 (set_attr "needs_delay_slot" "yes")])
2444 (define_insn "ashrsi3_media"
2445 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2446 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2447 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2452 [(set_attr "type" "arith_media")])
2454 (define_expand "ashrsi3"
2455 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2456 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2457 (match_operand:SI 2 "nonmemory_operand" "")))
2458 (clobber (reg:SI T_REG))])]
2464 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2467 if (expand_ashiftrt (operands))
2473 ;; logical shift right
2475 (define_insn "lshrsi3_d"
2476 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2481 [(set_attr "type" "dyn_shift")])
2483 ;; Only the single bit shift clobbers the T bit.
2485 (define_insn "lshrsi3_m"
2486 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2487 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2488 (match_operand:SI 2 "const_int_operand" "M")))
2489 (clobber (reg:SI T_REG))]
2490 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2492 [(set_attr "type" "arith")])
2494 (define_insn "lshrsi3_k"
2495 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497 (match_operand:SI 2 "const_int_operand" "P27")))]
2498 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2499 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2501 [(set_attr "type" "arith")])
2503 (define_insn "lshrsi3_n"
2504 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506 (match_operand:SI 2 "const_int_operand" "n")))
2507 (clobber (reg:SI T_REG))]
2508 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2510 [(set (attr "length")
2511 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2513 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2515 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2517 (const_string "8")))
2518 (set_attr "type" "arith")])
2521 [(set (match_operand:SI 0 "arith_reg_operand" "")
2522 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2523 (match_operand:SI 2 "const_int_operand" "")))
2524 (clobber (reg:SI T_REG))]
2525 "TARGET_SH1 && reload_completed"
2526 [(use (reg:SI R0_REG))]
2529 gen_shifty_op (LSHIFTRT, operands);
2533 (define_insn "lshrsi3_media"
2534 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2535 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2536 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2541 [(set_attr "type" "arith_media")])
2543 (define_expand "lshrsi3"
2544 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2545 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2546 (match_operand:SI 2 "nonmemory_operand" "")))
2547 (clobber (reg:SI T_REG))])]
2553 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2556 if (GET_CODE (operands[2]) == CONST_INT
2557 && sh_dynamicalize_shift_p (operands[2]))
2558 operands[2] = force_reg (SImode, operands[2]);
2559 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2561 rtx count = copy_to_mode_reg (SImode, operands[2]);
2562 emit_insn (gen_negsi2 (count, count));
2563 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2566 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2570 ;; ??? This should be a define expand.
2572 (define_insn "ashldi3_k"
2573 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2574 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2576 (clobber (reg:SI T_REG))]
2578 "shll %R0\;rotcl %S0"
2579 [(set_attr "length" "4")
2580 (set_attr "type" "arith")])
2582 (define_insn "ashldi3_media"
2583 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2584 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2585 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2590 [(set_attr "type" "arith_media")])
2592 (define_expand "ashldi3"
2593 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2594 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2595 (match_operand:DI 2 "immediate_operand" "")))
2596 (clobber (reg:SI T_REG))])]
2602 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2605 if (GET_CODE (operands[2]) != CONST_INT
2606 || INTVAL (operands[2]) != 1)
2610 ;; ??? This should be a define expand.
2612 (define_insn "lshrdi3_k"
2613 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2614 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2616 (clobber (reg:SI T_REG))]
2618 "shlr %S0\;rotcr %R0"
2619 [(set_attr "length" "4")
2620 (set_attr "type" "arith")])
2622 (define_insn "lshrdi3_media"
2623 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2624 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2625 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2630 [(set_attr "type" "arith_media")])
2632 (define_expand "lshrdi3"
2633 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2634 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2635 (match_operand:DI 2 "immediate_operand" "")))
2636 (clobber (reg:SI T_REG))])]
2642 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2645 if (GET_CODE (operands[2]) != CONST_INT
2646 || INTVAL (operands[2]) != 1)
2650 ;; ??? This should be a define expand.
2652 (define_insn "ashrdi3_k"
2653 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2654 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2656 (clobber (reg:SI T_REG))]
2658 "shar %S0\;rotcr %R0"
2659 [(set_attr "length" "4")
2660 (set_attr "type" "arith")])
2662 (define_insn "ashrdi3_media"
2663 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2664 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2665 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2670 [(set_attr "type" "arith_media")])
2672 (define_expand "ashrdi3"
2673 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2674 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2675 (match_operand:DI 2 "immediate_operand" "")))
2676 (clobber (reg:SI T_REG))])]
2682 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2685 if (GET_CODE (operands[2]) != CONST_INT
2686 || INTVAL (operands[2]) != 1)
2690 ;; combined left/right shift
2693 [(set (match_operand:SI 0 "register_operand" "")
2694 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695 (match_operand:SI 2 "const_int_operand" ""))
2696 (match_operand:SI 3 "const_int_operand" "")))]
2697 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2698 [(use (reg:SI R0_REG))]
2699 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2703 [(set (match_operand:SI 0 "register_operand" "")
2704 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2705 (match_operand:SI 2 "const_int_operand" ""))
2706 (match_operand:SI 3 "const_int_operand" "")))
2707 (clobber (reg:SI T_REG))]
2708 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2709 [(use (reg:SI R0_REG))]
2710 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2714 [(set (match_operand:SI 0 "register_operand" "=r")
2715 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2716 (match_operand:SI 2 "const_int_operand" "n"))
2717 (match_operand:SI 3 "const_int_operand" "n")))
2718 (clobber (reg:SI T_REG))]
2719 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2721 [(set (attr "length")
2722 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2724 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2726 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2728 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2730 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2732 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2734 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2735 (const_string "16")]
2736 (const_string "18")))
2737 (set_attr "type" "arith")])
2740 [(set (match_operand:SI 0 "register_operand" "=z")
2741 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2742 (match_operand:SI 2 "const_int_operand" "n"))
2743 (match_operand:SI 3 "const_int_operand" "n")))
2744 (clobber (reg:SI T_REG))]
2745 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2747 [(set (attr "length")
2748 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2750 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2752 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2754 (const_string "10")))
2755 (set_attr "type" "arith")])
2757 ;; shift left / and combination with a scratch register: The combine pass
2758 ;; does not accept the individual instructions, even though they are
2759 ;; cheap. But it needs a precise description so that it is usable after
2761 (define_insn "and_shl_scratch"
2762 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2766 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2767 (match_operand:SI 2 "const_int_operand" "N,n"))
2768 (match_operand:SI 3 "" "0,r"))
2769 (match_operand:SI 4 "const_int_operand" "n,n"))
2770 (match_operand:SI 5 "const_int_operand" "n,n")))
2771 (clobber (reg:SI T_REG))]
2774 [(set (attr "length")
2775 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2777 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2779 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2781 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2782 (const_string "10")]
2783 (const_string "12")))
2784 (set_attr "type" "arith")])
2787 [(set (match_operand:SI 0 "register_operand" "")
2791 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2792 (match_operand:SI 2 "const_int_operand" ""))
2793 (match_operand:SI 3 "register_operand" ""))
2794 (match_operand:SI 4 "const_int_operand" ""))
2795 (match_operand:SI 5 "const_int_operand" "")))
2796 (clobber (reg:SI T_REG))]
2798 [(use (reg:SI R0_REG))]
2801 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2803 if (INTVAL (operands[2]))
2805 gen_shifty_op (LSHIFTRT, operands);
2807 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2808 operands[2] = operands[4];
2809 gen_shifty_op (ASHIFT, operands);
2810 if (INTVAL (operands[5]))
2812 operands[2] = operands[5];
2813 gen_shifty_op (LSHIFTRT, operands);
2818 ;; signed left/right shift combination.
2820 [(set (match_operand:SI 0 "register_operand" "")
2822 (ashift:SI (match_operand:SI 1 "register_operand" "")
2823 (match_operand:SI 2 "const_int_operand" ""))
2824 (match_operand:SI 3 "const_int_operand" "")
2826 (clobber (reg:SI T_REG))]
2828 [(use (reg:SI R0_REG))]
2829 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2832 (define_insn "shl_sext_ext"
2833 [(set (match_operand:SI 0 "register_operand" "=r")
2835 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2836 (match_operand:SI 2 "const_int_operand" "n"))
2837 (match_operand:SI 3 "const_int_operand" "n")
2839 (clobber (reg:SI T_REG))]
2840 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2842 [(set (attr "length")
2843 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2845 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2847 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2849 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2851 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2853 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2855 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2857 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2858 (const_string "16")]
2859 (const_string "18")))
2860 (set_attr "type" "arith")])
2862 (define_insn "shl_sext_sub"
2863 [(set (match_operand:SI 0 "register_operand" "=z")
2865 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2866 (match_operand:SI 2 "const_int_operand" "n"))
2867 (match_operand:SI 3 "const_int_operand" "n")
2869 (clobber (reg:SI T_REG))]
2870 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2872 [(set (attr "length")
2873 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2875 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2877 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2879 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2880 (const_string "12")]
2881 (const_string "14")))
2882 (set_attr "type" "arith")])
2884 ;; These patterns are found in expansions of DImode shifts by 16, and
2885 ;; allow the xtrct instruction to be generated from C source.
2887 (define_insn "xtrct_left"
2888 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2891 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2895 [(set_attr "type" "arith")])
2897 (define_insn "xtrct_right"
2898 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2899 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2901 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2905 [(set_attr "type" "arith")])
2907 ;; -------------------------------------------------------------------------
2909 ;; -------------------------------------------------------------------------
2912 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913 (neg:SI (plus:SI (reg:SI T_REG)
2914 (match_operand:SI 1 "arith_reg_operand" "r"))))
2916 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2920 [(set_attr "type" "arith")])
2922 (define_insn "*negdi_media"
2923 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2924 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2927 [(set_attr "type" "arith_media")])
2929 (define_expand "negdi2"
2930 [(set (match_operand:DI 0 "arith_reg_operand" "")
2931 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2937 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2938 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2940 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2941 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2943 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2944 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2946 emit_insn (gen_clrt ());
2947 emit_insn (gen_negc (low_dst, low_src));
2948 emit_insn (gen_negc (high_dst, high_src));
2953 (define_insn "negsi2"
2954 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2955 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2958 [(set_attr "type" "arith")])
2960 (define_insn "one_cmplsi2"
2961 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2962 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2965 [(set_attr "type" "arith")])
2967 (define_expand "one_cmpldi2"
2968 [(set (match_operand:DI 0 "arith_reg_operand" "")
2969 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2971 "TARGET_SHMEDIA" "")
2973 ;; -------------------------------------------------------------------------
2974 ;; Zero extension instructions
2975 ;; -------------------------------------------------------------------------
2977 (define_insn "zero_extendsidi2"
2978 [(set (match_operand:DI 0 "register_operand" "=r")
2979 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2981 "addz.l %1, r63, %0"
2982 [(set_attr "type" "arith_media")])
2984 (define_insn "zero_extendhidi2"
2985 [(set (match_operand:DI 0 "register_operand" "=r,r")
2986 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2991 [(set_attr "type" "*,load_media")])
2994 [(set (match_operand:DI 0 "register_operand" "")
2995 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2996 "TARGET_SHMEDIA && reload_completed"
2997 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2998 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3001 if (GET_CODE (operands[1]) == TRUNCATE)
3002 operands[1] = XEXP (operands[1], 0);
3005 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3006 ;; reload the entrire truncate expression.
3007 (define_insn_and_split "*loaddi_trunc"
3008 [(set (match_operand 0 "int_gpr_dest" "=r")
3009 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3010 "TARGET_SHMEDIA && reload_completed"
3012 "TARGET_SHMEDIA && reload_completed"
3013 [(set (match_dup 0) (match_dup 1))]
3014 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3016 (define_insn "zero_extendqidi2"
3017 [(set (match_operand:DI 0 "register_operand" "=r,r")
3018 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3023 [(set_attr "type" "arith_media,load_media")])
3025 (define_expand "zero_extendhisi2"
3026 [(set (match_operand:SI 0 "arith_reg_operand" "")
3027 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3031 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3032 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3035 (define_insn "*zero_extendhisi2_compact"
3036 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3037 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3040 [(set_attr "type" "arith")])
3042 (define_insn "*zero_extendhisi2_media"
3043 [(set (match_operand:SI 0 "register_operand" "=r,r")
3044 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3049 [(set_attr "type" "arith_media,load_media")])
3052 [(set (match_operand:SI 0 "register_operand" "")
3053 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3054 "TARGET_SHMEDIA && reload_completed"
3055 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3056 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3059 if (GET_CODE (operands[1]) == TRUNCATE)
3060 operands[1] = XEXP (operands[1], 0);
3063 (define_expand "zero_extendqisi2"
3064 [(set (match_operand:SI 0 "arith_reg_operand" "")
3065 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3069 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3070 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3073 (define_insn "*zero_extendqisi2_compact"
3074 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3075 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3078 [(set_attr "type" "arith")])
3080 (define_insn "*zero_extendqisi2_media"
3081 [(set (match_operand:SI 0 "register_operand" "=r,r")
3082 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3087 [(set_attr "type" "arith_media,load_media")])
3089 (define_insn "zero_extendqihi2"
3090 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3091 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3094 [(set_attr "type" "arith")])
3096 ;; -------------------------------------------------------------------------
3097 ;; Sign extension instructions
3098 ;; -------------------------------------------------------------------------
3100 ;; ??? This should be a define expand.
3101 ;; ??? Or perhaps it should be dropped?
3103 ;; convert_move generates good code for SH[1-4].
3104 (define_insn "extendsidi2"
3105 [(set (match_operand:DI 0 "register_operand" "=r,r")
3106 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3111 [(set_attr "type" "arith_media,load_media")])
3113 (define_insn "extendhidi2"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r")
3115 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3120 [(set_attr "type" "*,load_media")])
3123 [(set (match_operand:DI 0 "register_operand" "")
3124 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3125 "TARGET_SHMEDIA && reload_completed"
3126 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3127 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3130 if (GET_CODE (operands[1]) == TRUNCATE)
3131 operands[1] = XEXP (operands[1], 0);
3134 (define_insn "extendqidi2"
3135 [(set (match_operand:DI 0 "register_operand" "=r,r")
3136 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3141 [(set_attr "type" "*,load_media")])
3144 [(set (match_operand:DI 0 "register_operand" "")
3145 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3146 "TARGET_SHMEDIA && reload_completed"
3147 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3148 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3151 if (GET_CODE (operands[1]) == TRUNCATE)
3152 operands[1] = XEXP (operands[1], 0);
3155 (define_expand "extendhisi2"
3156 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3157 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3161 (define_insn "*extendhisi2_compact"
3162 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3163 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3168 [(set_attr "type" "arith,load")])
3170 (define_insn "*extendhisi2_media"
3171 [(set (match_operand:SI 0 "register_operand" "=r,r")
3172 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3177 [(set_attr "type" "arith_media,load_media")])
3180 [(set (match_operand:SI 0 "register_operand" "")
3181 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3182 "TARGET_SHMEDIA && reload_completed"
3183 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3184 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3187 if (GET_CODE (operands[1]) == TRUNCATE)
3188 operands[1] = XEXP (operands[1], 0);
3191 (define_expand "extendqisi2"
3192 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3193 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3197 (define_insn "*extendqisi2_compact"
3198 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3199 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3204 [(set_attr "type" "arith,load")])
3206 (define_insn "*extendqisi2_media"
3207 [(set (match_operand:SI 0 "register_operand" "=r,r")
3208 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3213 [(set_attr "type" "arith_media,load_media")])
3216 [(set (match_operand:SI 0 "register_operand" "")
3217 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3218 "TARGET_SHMEDIA && reload_completed"
3219 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3220 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3223 if (GET_CODE (operands[1]) == TRUNCATE)
3224 operands[1] = XEXP (operands[1], 0);
3227 (define_insn "extendqihi2"
3228 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3229 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3234 [(set_attr "type" "arith,load")])
3236 /* It would seem useful to combine the truncXi patterns into the movXi
3237 patterns, but unary operators are ignored when matching constraints,
3238 so we need separate patterns. */
3239 (define_insn "truncdisi2"
3240 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3241 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3250 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3253 (define_insn "truncdihi2"
3254 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3255 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3258 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3260 [(set_attr "type" "arith_media,store_media")
3261 (set_attr "length" "8,4")])
3263 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3264 ; Because we use zero extension, we can't provide signed QImode compares
3265 ; using a simple compare or conditional banch insn.
3266 (define_insn "truncdiqi2"
3267 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3268 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3273 [(set_attr "type" "arith_media,store")])
3275 ;; -------------------------------------------------------------------------
3276 ;; Move instructions
3277 ;; -------------------------------------------------------------------------
3279 ;; define push and pop so it is easy for sh.c
3280 ;; We can't use push and pop on SHcompact because the stack must always
3281 ;; be 8-byte aligned.
3283 (define_expand "push"
3284 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3285 (match_operand:SI 0 "register_operand" "r,l,x"))]
3286 "TARGET_SH1 && ! TARGET_SH5"
3289 (define_expand "pop"
3290 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3291 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3292 "TARGET_SH1 && ! TARGET_SH5"
3295 (define_expand "push_e"
3296 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3297 (match_operand:SF 0 "" ""))
3298 (use (reg:PSI FPSCR_REG))
3299 (clobber (scratch:SI))])]
3300 "TARGET_SH1 && ! TARGET_SH5"
3303 (define_insn "push_fpul"
3304 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3305 "TARGET_SH2E && ! TARGET_SH5"
3307 [(set_attr "type" "store")
3308 (set_attr "late_fp_use" "yes")
3309 (set_attr "hit_stack" "yes")])
3311 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3313 (define_expand "push_4"
3314 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3315 (match_operand:DF 0 "" ""))
3316 (use (reg:PSI FPSCR_REG))
3317 (clobber (scratch:SI))])]
3318 "TARGET_SH1 && ! TARGET_SH5"
3321 (define_expand "pop_e"
3322 [(parallel [(set (match_operand:SF 0 "" "")
3323 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3324 (use (reg:PSI FPSCR_REG))
3325 (clobber (scratch:SI))])]
3326 "TARGET_SH1 && ! TARGET_SH5"
3329 (define_insn "pop_fpul"
3330 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3331 "TARGET_SH2E && ! TARGET_SH5"
3333 [(set_attr "type" "load")
3334 (set_attr "hit_stack" "yes")])
3336 (define_expand "pop_4"
3337 [(parallel [(set (match_operand:DF 0 "" "")
3338 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3339 (use (reg:PSI FPSCR_REG))
3340 (clobber (scratch:SI))])]
3341 "TARGET_SH1 && ! TARGET_SH5"
3344 (define_expand "push_fpscr"
3349 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3350 gen_rtx (PRE_DEC, Pmode,
3351 stack_pointer_rtx)),
3353 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3357 (define_expand "pop_fpscr"
3362 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3363 gen_rtx (MEM, PSImode,
3364 gen_rtx (POST_INC, Pmode,
3365 stack_pointer_rtx))));
3366 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3370 ;; These two patterns can happen as the result of optimization, when
3371 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3372 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3375 [(set (reg:SI T_REG) (const_int 0))]
3380 [(set (reg:SI T_REG) (const_int 1))]
3384 ;; t/r must come after r/r, lest reload will try to reload stuff like
3385 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3386 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3387 (define_insn "movsi_i"
3388 [(set (match_operand:SI 0 "general_movdst_operand"
3389 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3390 (match_operand:SI 1 "general_movsrc_operand"
3391 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3394 && (register_operand (operands[0], SImode)
3395 || register_operand (operands[1], SImode))"
3412 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3413 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3415 ;; t/r must come after r/r, lest reload will try to reload stuff like
3416 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3417 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3418 ;; will require a reload.
3419 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3420 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3421 (define_insn "movsi_ie"
3422 [(set (match_operand:SI 0 "general_movdst_operand"
3423 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3424 (match_operand:SI 1 "general_movsrc_operand"
3425 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3427 && (register_operand (operands[0], SImode)
3428 || register_operand (operands[1], SImode))"
3452 ! move optimized away"
3453 [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3454 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3455 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3457 (define_insn "movsi_i_lowpart"
3458 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3459 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3461 && (register_operand (operands[0], SImode)
3462 || register_operand (operands[1], SImode))"
3472 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3474 (define_insn "*movsi_media"
3475 [(set (match_operand:SI 0 "general_movdst_operand"
3476 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3477 (match_operand:SI 1 "general_movsrc_operand"
3478 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3480 && (register_operand (operands[0], SImode)
3481 || sh_register_operand (operands[1], SImode))"
3496 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3497 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3499 (define_insn "*movsi_media_nofpu"
3500 [(set (match_operand:SI 0 "general_movdst_operand"
3501 "=r,r,r,r,m,*b,r,b")
3502 (match_operand:SI 1 "general_movsrc_operand"
3503 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3505 && (register_operand (operands[0], SImode)
3506 || sh_register_operand (operands[1], SImode))"
3516 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3517 (set_attr "length" "4,4,8,4,4,4,4,12")])
3520 [(set (match_operand:SI 0 "arith_reg_operand" "")
3521 (match_operand:SI 1 "immediate_operand" ""))]
3522 "TARGET_SHMEDIA && reload_completed
3523 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3524 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3527 operands[2] = shallow_copy_rtx (operands[1]);
3528 PUT_MODE (operands[2], DImode);
3532 [(set (match_operand:SI 0 "register_operand" "")
3533 (match_operand:SI 1 "immediate_operand" ""))]
3534 "TARGET_SHMEDIA && reload_completed
3535 && ((GET_CODE (operands[1]) == CONST_INT
3536 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3537 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3538 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3540 (define_expand "movsi"
3541 [(set (match_operand:SI 0 "general_movdst_operand" "")
3542 (match_operand:SI 1 "general_movsrc_operand" ""))]
3544 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3546 (define_expand "ic_invalidate_line"
3547 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3548 (match_dup 1)] UNSPEC_ICACHE)
3549 (clobber (scratch:SI))])]
3550 "TARGET_HARD_SH4 || TARGET_SH5"
3555 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3558 else if (TARGET_SHCOMPACT)
3560 operands[1] = function_symbol (\"__ic_invalidate\");
3561 operands[1] = force_reg (Pmode, operands[1]);
3562 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3565 operands[0] = force_reg (Pmode, operands[0]);
3566 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3570 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3571 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3572 ;; the requirement *1*00 for associative address writes. The alignment of
3573 ;; %0 implies that its least significant bit is cleared,
3574 ;; thus we clear the V bit of a matching entry if there is one.
3575 (define_insn "ic_invalidate_line_i"
3576 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3577 (match_operand:SI 1 "register_operand" "r")]
3579 (clobber (match_scratch:SI 2 "=&r"))]
3581 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3582 [(set_attr "length" "8")
3583 (set_attr "type" "cwb")])
3585 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3586 ;; an add in the code that calculates the address.
3587 (define_insn "ic_invalidate_line_media"
3588 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3591 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3592 [(set_attr "length" "16")
3593 (set_attr "type" "invalidate_line_media")])
3595 (define_insn "ic_invalidate_line_compact"
3596 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3597 (match_operand:SI 1 "register_operand" "r")]
3599 (clobber (reg:SI PR_REG))]
3602 [(set_attr "type" "sfunc")
3603 (set_attr "needs_delay_slot" "yes")])
3605 (define_expand "initialize_trampoline"
3606 [(match_operand:SI 0 "" "")
3607 (match_operand:SI 1 "" "")
3608 (match_operand:SI 2 "" "")]
3614 tramp = force_reg (Pmode, operands[0]);
3615 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3616 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3617 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3619 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3623 (define_insn "initialize_trampoline_compact"
3624 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3625 (match_operand:SI 1 "register_operand" "r")
3626 (reg:SI R2_REG) (reg:SI R3_REG)]
3629 (clobber (reg:SI PR_REG))]
3632 [(set_attr "type" "sfunc")
3633 (set_attr "needs_delay_slot" "yes")])
3635 (define_insn "movqi_i"
3636 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3637 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3639 && (arith_reg_operand (operands[0], QImode)
3640 || arith_reg_operand (operands[1], QImode))"
3648 [(set_attr "type" "move,load,store,move,move,move")])
3650 (define_insn "*movqi_media"
3651 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3652 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3654 && (arith_reg_operand (operands[0], QImode)
3655 || arith_reg_or_0_operand (operands[1], QImode))"
3661 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3663 (define_expand "movqi"
3664 [(set (match_operand:QI 0 "general_operand" "")
3665 (match_operand:QI 1 "general_operand" ""))]
3667 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3669 (define_expand "reload_inqi"
3670 [(set (match_operand:SI 2 "" "=&r")
3671 (match_operand:QI 1 "inqhi_operand" ""))
3672 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3673 (truncate:QI (match_dup 3)))]
3677 rtx inner = XEXP (operands[1], 0);
3678 int regno = REGNO (inner);
3680 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3681 operands[1] = gen_rtx_REG (SImode, regno);
3682 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3685 /* When storing r0, we have to avoid reg+reg addressing. */
3686 (define_insn "movhi_i"
3687 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3688 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3690 && (arith_reg_operand (operands[0], HImode)
3691 || arith_reg_operand (operands[1], HImode))
3692 && (GET_CODE (operands[0]) != MEM
3693 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3694 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3695 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3705 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3707 (define_insn "*movhi_media"
3708 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3709 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3711 && (arith_reg_operand (operands[0], HImode)
3712 || arith_reg_or_0_operand (operands[1], HImode))"
3719 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3722 [(set (match_operand:HI 0 "register_operand" "")
3723 (match_operand:HI 1 "immediate_operand" ""))]
3724 "TARGET_SHMEDIA && reload_completed
3725 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3726 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3728 (define_expand "movhi"
3729 [(set (match_operand:HI 0 "general_movdst_operand" "")
3730 (match_operand:HI 1 "general_movsrc_operand" ""))]
3732 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3734 (define_expand "reload_inhi"
3735 [(set (match_operand:SI 2 "" "=&r")
3736 (match_operand:HI 1 "inqhi_operand" ""))
3737 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3738 (truncate:HI (match_dup 3)))]
3742 rtx inner = XEXP (operands[1], 0);
3743 int regno = REGNO (inner);
3745 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3746 operands[1] = gen_rtx_REG (SImode, regno);
3747 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3750 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3751 ;; compiled with -m2 -ml -O3 -funroll-loops
3752 (define_insn "*movdi_i"
3753 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3754 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3756 && (arith_reg_operand (operands[0], DImode)
3757 || arith_reg_operand (operands[1], DImode))"
3758 "* return output_movedouble (insn, operands, DImode);"
3759 [(set_attr "length" "4")
3760 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3762 ;; If the output is a register and the input is memory or a register, we have
3763 ;; to be careful and see which word needs to be loaded first.
3766 [(set (match_operand:DI 0 "general_movdst_operand" "")
3767 (match_operand:DI 1 "general_movsrc_operand" ""))]
3768 "TARGET_SH1 && reload_completed"
3769 [(set (match_dup 2) (match_dup 3))
3770 (set (match_dup 4) (match_dup 5))]
3775 if ((GET_CODE (operands[0]) == MEM
3776 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3777 || (GET_CODE (operands[1]) == MEM
3778 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3781 if (GET_CODE (operands[0]) == REG)
3782 regno = REGNO (operands[0]);
3783 else if (GET_CODE (operands[0]) == SUBREG)
3784 regno = subreg_regno (operands[0]);
3785 else if (GET_CODE (operands[0]) == MEM)
3791 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3793 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3794 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3795 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3796 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3800 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3801 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3802 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3803 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3806 if (operands[2] == 0 || operands[3] == 0
3807 || operands[4] == 0 || operands[5] == 0)
3811 (define_insn "*movdi_media"
3812 [(set (match_operand:DI 0 "general_movdst_operand"
3813 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3814 (match_operand:DI 1 "general_movsrc_operand"
3815 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3817 && (register_operand (operands[0], DImode)
3818 || sh_register_operand (operands[1], DImode))"
3833 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3834 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3836 (define_insn "*movdi_media_nofpu"
3837 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3838 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3840 && (register_operand (operands[0], DImode)
3841 || sh_register_operand (operands[1], DImode))"
3851 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3852 (set_attr "length" "4,4,16,4,4,4,4,*")])
3855 [(set (match_operand:DI 0 "arith_reg_operand" "")
3856 (match_operand:DI 1 "immediate_operand" ""))]
3857 "TARGET_SHMEDIA && reload_completed
3858 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3859 [(set (match_dup 0) (match_dup 1))]
3864 if (TARGET_SHMEDIA64)
3865 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3867 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3869 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3875 (define_expand "movdi_const"
3876 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3877 (const:DI (sign_extend:DI
3880 (match_operand:DI 1 "immediate_operand" "s")
3883 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3891 (const_int 32)))))))))
3893 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3901 (const_int 16)))))))))
3903 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3909 (match_dup 1))))))))]
3910 "TARGET_SHMEDIA64 && reload_completed
3911 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3914 sh_mark_label (operands[1], 4);
3917 (define_expand "movdi_const_32bit"
3918 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3919 (const:DI (sign_extend:DI
3922 (match_operand:DI 1 "immediate_operand" "s")
3925 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3931 (match_dup 1))))))))]
3932 "TARGET_SHMEDIA32 && reload_completed
3933 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3936 sh_mark_label (operands[1], 2);
3939 (define_expand "movdi_const_16bit"
3940 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3941 (const:DI (sign_extend:DI
3943 (match_operand:DI 1 "immediate_operand" "s")))))]
3944 "TARGET_SHMEDIA && flag_pic && reload_completed
3945 && GET_CODE (operands[1]) == SYMBOL_REF"
3949 [(set (match_operand:DI 0 "arith_reg_operand" "")
3950 (match_operand:DI 1 "immediate_operand" ""))]
3951 "TARGET_SHMEDIA && reload_completed
3952 && GET_CODE (operands[1]) == CONST_INT
3953 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3954 [(set (match_dup 0) (match_dup 2))
3958 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3959 unsigned HOST_WIDE_INT low = val;
3960 unsigned HOST_WIDE_INT high = val;
3961 unsigned HOST_WIDE_INT sign;
3962 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3964 /* Sign-extend the 16 least-significant bits. */
3969 /* Arithmetic shift right the word by 16 bits. */
3972 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3977 /* If we can't generate the constant with a two-insn movi / shori
3978 sequence, try some other strategies. */
3979 if (! CONST_OK_FOR_I16 (high))
3981 /* Try constant load / left shift. We know VAL != 0. */
3982 val2 = val ^ (val-1);
3985 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3987 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
3988 || (! CONST_OK_FOR_I16 (high >> 16)
3989 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
3991 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3992 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3993 GEN_INT (trailing_zeroes));
3997 /* Try constant load / right shift. */
3998 val2 = (val >> 15) + 1;
3999 if (val2 == (val2 & -val2))
4001 int shift = 49 - exact_log2 (val2);
4003 val2 = trunc_int_for_mode (val << shift, DImode);
4004 if (CONST_OK_FOR_I16 (val2))
4006 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4012 val2 = val & 0xffff;
4013 if ((val >> 16 & 0xffff) == val2
4014 && (val >> 32 & 0xffff) == val2
4015 && (val >> 48 & 0xffff) == val2)
4017 val2 = (HOST_WIDE_INT) val >> 48;
4018 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4019 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4022 /* Try movi / mshflo.l */
4023 val2 = (HOST_WIDE_INT) val >> 32;
4024 if (val2 == trunc_int_for_mode (val, SImode))
4026 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4030 /* Try movi / mshflo.l w/ r63. */
4031 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4032 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4034 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4040 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4043 operands[2] = GEN_INT (val2);
4047 [(set (match_operand:DI 0 "arith_reg_operand" "")
4048 (match_operand:DI 1 "immediate_operand" ""))]
4049 "TARGET_SHMEDIA && reload_completed
4050 && GET_CODE (operands[1]) == CONST_DOUBLE"
4051 [(set (match_dup 0) (match_dup 2))
4053 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4054 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4057 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4058 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4059 unsigned HOST_WIDE_INT val = low;
4060 unsigned HOST_WIDE_INT sign;
4062 /* Sign-extend the 16 least-significant bits. */
4066 operands[1] = GEN_INT (val);
4068 /* Arithmetic shift right the double-word by 16 bits. */
4070 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4073 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4077 /* This will only be true if high is a sign-extension of low, i.e.,
4078 it must be either 0 or (unsigned)-1, and be zero iff the
4079 most-significant bit of low is set. */
4080 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4081 operands[2] = GEN_INT (low);
4083 operands[2] = immed_double_const (low, high, DImode);
4086 (define_insn "shori_media"
4087 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4088 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4092 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4097 [(set_attr "type" "arith_media,*")])
4099 (define_expand "movdi"
4100 [(set (match_operand:DI 0 "general_movdst_operand" "")
4101 (match_operand:DI 1 "general_movsrc_operand" ""))]
4103 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4105 (define_insn "movdf_media"
4106 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4107 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4109 && (register_operand (operands[0], DFmode)
4110 || sh_register_operand (operands[1], DFmode))"
4121 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4123 (define_insn "movdf_media_nofpu"
4124 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4125 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4127 && (register_operand (operands[0], DFmode)
4128 || sh_register_operand (operands[1], DFmode))"
4134 [(set_attr "type" "arith_media,*,load_media,store_media")])
4137 [(set (match_operand:DF 0 "arith_reg_operand" "")
4138 (match_operand:DF 1 "immediate_operand" ""))]
4139 "TARGET_SHMEDIA && reload_completed"
4140 [(set (match_dup 3) (match_dup 2))]
4143 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4145 REAL_VALUE_TYPE value;
4147 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4148 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4150 if (HOST_BITS_PER_WIDE_INT >= 64)
4151 operands[2] = immed_double_const ((unsigned long) values[endian]
4152 | ((HOST_WIDE_INT) values[1 - endian]
4154 else if (HOST_BITS_PER_WIDE_INT == 32)
4155 operands[2] = immed_double_const (values[endian], values[1 - endian],
4160 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4163 ;; ??? This should be a define expand.
4165 (define_insn "movdf_k"
4166 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4167 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4169 && (! TARGET_SH4 || reload_completed
4170 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4171 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4172 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4173 && (arith_reg_operand (operands[0], DFmode)
4174 || arith_reg_operand (operands[1], DFmode))"
4175 "* return output_movedouble (insn, operands, DFmode);"
4176 [(set_attr "length" "4")
4177 (set_attr "type" "move,pcload,load,store")])
4179 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4180 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4181 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4182 ;; the d/m/c/X alternative, which is split later into single-precision
4183 ;; instructions. And when not optimizing, no splits are done before fixing
4184 ;; up pcloads, so we need usable length information for that.
4185 (define_insn "movdf_i4"
4186 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4187 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4188 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4189 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4191 && (arith_reg_operand (operands[0], DFmode)
4192 || arith_reg_operand (operands[1], DFmode))"
4204 [(set_attr_alternative "length"
4205 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4207 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4208 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4209 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4211 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4212 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4213 ;; increment or decrement r15 explicitly.
4215 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4216 (const_int 10) (const_int 8))
4218 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4219 (const_int 10) (const_int 8))])
4220 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4221 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4222 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4223 (const_string "double")
4224 (const_string "none")))])
4226 ;; Moving DFmode between fp/general registers through memory
4227 ;; (the top of the stack) is faster than moving through fpul even for
4228 ;; little endian. Because the type of an instruction is important for its
4229 ;; scheduling, it is beneficial to split these operations, rather than
4230 ;; emitting them in one single chunk, even if this will expose a stack
4231 ;; use that will prevent scheduling of other stack accesses beyond this
4234 [(set (match_operand:DF 0 "register_operand" "")
4235 (match_operand:DF 1 "register_operand" ""))
4236 (use (match_operand:PSI 2 "fpscr_operand" ""))
4237 (clobber (match_scratch:SI 3 "=X"))]
4238 "TARGET_SH4 && reload_completed
4239 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4245 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4247 emit_move_insn (stack_pointer_rtx,
4248 plus_constant (stack_pointer_rtx, -8));
4249 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4252 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4253 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4254 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4255 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4256 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4257 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4259 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4260 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4261 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4262 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4264 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4268 ;; local-alloc sometimes allocates scratch registers even when not required,
4269 ;; so we must be prepared to handle these.
4271 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4273 [(set (match_operand:DF 0 "general_movdst_operand" "")
4274 (match_operand:DF 1 "general_movsrc_operand" ""))
4275 (use (match_operand:PSI 2 "fpscr_operand" ""))
4276 (clobber (match_scratch:SI 3 ""))]
4279 && true_regnum (operands[0]) < 16
4280 && true_regnum (operands[1]) < 16"
4281 [(set (match_dup 0) (match_dup 1))]
4284 /* If this was a reg <-> mem operation with base + index reg addressing,
4285 we have to handle this in a special way. */
4286 rtx mem = operands[0];
4288 if (! memory_operand (mem, DFmode))
4293 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4294 mem = SUBREG_REG (mem);
4295 if (GET_CODE (mem) == MEM)
4297 rtx addr = XEXP (mem, 0);
4298 if (GET_CODE (addr) == PLUS
4299 && GET_CODE (XEXP (addr, 0)) == REG
4300 && GET_CODE (XEXP (addr, 1)) == REG)
4303 rtx reg0 = gen_rtx (REG, Pmode, 0);
4304 rtx regop = operands[store_p], word0 ,word1;
4306 if (GET_CODE (regop) == SUBREG)
4307 alter_subreg (®op);
4308 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4312 mem = copy_rtx (mem);
4313 PUT_MODE (mem, SImode);
4314 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4315 alter_subreg (&word0);
4316 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4317 alter_subreg (&word1);
4318 if (store_p || ! refers_to_regno_p (REGNO (word0),
4319 REGNO (word0) + 1, addr, 0))
4322 ? gen_movsi_ie (mem, word0)
4323 : gen_movsi_ie (word0, mem));
4324 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4325 mem = copy_rtx (mem);
4327 ? gen_movsi_ie (mem, word1)
4328 : gen_movsi_ie (word1, mem));
4329 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4333 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4334 emit_insn (gen_movsi_ie (word1, mem));
4335 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4336 mem = copy_rtx (mem);
4337 emit_insn (gen_movsi_ie (word0, mem));
4344 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4346 [(set (match_operand:DF 0 "register_operand" "")
4347 (match_operand:DF 1 "memory_operand" ""))
4348 (use (match_operand:PSI 2 "fpscr_operand" ""))
4349 (clobber (reg:SI R0_REG))]
4350 "TARGET_SH4 && reload_completed"
4351 [(parallel [(set (match_dup 0) (match_dup 1))
4353 (clobber (scratch:SI))])]
4356 (define_expand "reload_indf"
4357 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4358 (match_operand:DF 1 "immediate_operand" "FQ"))
4359 (use (reg:PSI FPSCR_REG))
4360 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4364 (define_expand "reload_outdf"
4365 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4366 (match_operand:DF 1 "register_operand" "af,r"))
4367 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4371 ;; Simplify no-op moves.
4373 [(set (match_operand:SF 0 "register_operand" "")
4374 (match_operand:SF 1 "register_operand" ""))
4375 (use (match_operand:PSI 2 "fpscr_operand" ""))
4376 (clobber (match_scratch:SI 3 "X"))]
4377 "TARGET_SH2E && reload_completed
4378 && true_regnum (operands[0]) == true_regnum (operands[1])"
4379 [(set (match_dup 0) (match_dup 0))]
4382 ;; fmovd substitute post-reload splits
4384 [(set (match_operand:DF 0 "register_operand" "")
4385 (match_operand:DF 1 "register_operand" ""))
4386 (use (match_operand:PSI 2 "fpscr_operand" ""))
4387 (clobber (match_scratch:SI 3 "X"))]
4388 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4389 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4390 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4394 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4395 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4396 gen_rtx (REG, SFmode, src), operands[2]));
4397 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4398 gen_rtx (REG, SFmode, src + 1), operands[2]));
4403 [(set (match_operand:DF 0 "register_operand" "")
4404 (mem:DF (match_operand:SI 1 "register_operand" "")))
4405 (use (match_operand:PSI 2 "fpscr_operand" ""))
4406 (clobber (match_scratch:SI 3 ""))]
4407 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4408 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4409 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4413 int regno = true_regnum (operands[0]);
4415 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4417 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4418 regno + !! TARGET_LITTLE_ENDIAN),
4419 mem2, operands[2]));
4420 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4421 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4422 regno + ! TARGET_LITTLE_ENDIAN),
4423 gen_rtx (MEM, SFmode, operands[1]),
4429 [(set (match_operand:DF 0 "register_operand" "")
4430 (match_operand:DF 1 "memory_operand" ""))
4431 (use (match_operand:PSI 2 "fpscr_operand" ""))
4432 (clobber (match_scratch:SI 3 ""))]
4433 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4434 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4438 int regno = true_regnum (operands[0]);
4439 rtx addr, insn, adjust = NULL_RTX;
4440 rtx mem2 = copy_rtx (operands[1]);
4441 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4442 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4444 PUT_MODE (mem2, SFmode);
4445 operands[1] = copy_rtx (mem2);
4446 addr = XEXP (mem2, 0);
4447 if (GET_CODE (addr) != POST_INC)
4449 /* If we have to modify the stack pointer, the value that we have
4450 read with post-increment might be modified by an interrupt,
4451 so write it back. */
4452 if (REGNO (addr) == STACK_POINTER_REGNUM)
4453 adjust = gen_push_e (reg0);
4455 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4456 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4458 addr = XEXP (addr, 0);
4459 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4460 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4461 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4465 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4470 [(set (match_operand:DF 0 "memory_operand" "")
4471 (match_operand:DF 1 "register_operand" ""))
4472 (use (match_operand:PSI 2 "fpscr_operand" ""))
4473 (clobber (match_scratch:SI 3 ""))]
4474 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4475 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4479 int regno = true_regnum (operands[1]);
4480 rtx insn, addr, adjust = NULL_RTX;
4482 operands[0] = copy_rtx (operands[0]);
4483 PUT_MODE (operands[0], SFmode);
4484 insn = emit_insn (gen_movsf_ie (operands[0],
4485 gen_rtx (REG, SFmode,
4486 regno + ! TARGET_LITTLE_ENDIAN),
4488 operands[0] = copy_rtx (operands[0]);
4489 addr = XEXP (operands[0], 0);
4490 if (GET_CODE (addr) != PRE_DEC)
4492 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4493 emit_insn_before (adjust, insn);
4494 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4496 addr = XEXP (addr, 0);
4498 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4499 insn = emit_insn (gen_movsf_ie (operands[0],
4500 gen_rtx (REG, SFmode,
4501 regno + !! TARGET_LITTLE_ENDIAN),
4503 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4507 ;; If the output is a register and the input is memory or a register, we have
4508 ;; to be careful and see which word needs to be loaded first.
4511 [(set (match_operand:DF 0 "general_movdst_operand" "")
4512 (match_operand:DF 1 "general_movsrc_operand" ""))]
4513 "TARGET_SH1 && reload_completed"
4514 [(set (match_dup 2) (match_dup 3))
4515 (set (match_dup 4) (match_dup 5))]
4520 if ((GET_CODE (operands[0]) == MEM
4521 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4522 || (GET_CODE (operands[1]) == MEM
4523 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4526 if (GET_CODE (operands[0]) == REG)
4527 regno = REGNO (operands[0]);
4528 else if (GET_CODE (operands[0]) == SUBREG)
4529 regno = subreg_regno (operands[0]);
4530 else if (GET_CODE (operands[0]) == MEM)
4536 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4538 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4539 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4540 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4541 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4545 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4546 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4547 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4548 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4551 if (operands[2] == 0 || operands[3] == 0
4552 || operands[4] == 0 || operands[5] == 0)
4556 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4557 ;; used only once, let combine add in the index again.
4560 [(set (match_operand:SI 0 "register_operand" "")
4561 (match_operand:SI 1 "" ""))
4562 (clobber (match_operand 2 "register_operand" ""))]
4563 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4564 [(use (reg:SI R0_REG))]
4567 rtx addr, reg, const_int;
4569 if (GET_CODE (operands[1]) != MEM)
4571 addr = XEXP (operands[1], 0);
4572 if (GET_CODE (addr) != PLUS)
4574 reg = XEXP (addr, 0);
4575 const_int = XEXP (addr, 1);
4576 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4577 && GET_CODE (const_int) == CONST_INT))
4579 emit_move_insn (operands[2], const_int);
4580 emit_move_insn (operands[0],
4581 change_address (operands[1], VOIDmode,
4582 gen_rtx_PLUS (SImode, reg, operands[2])));
4587 [(set (match_operand:SI 1 "" "")
4588 (match_operand:SI 0 "register_operand" ""))
4589 (clobber (match_operand 2 "register_operand" ""))]
4590 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4591 [(use (reg:SI R0_REG))]
4594 rtx addr, reg, const_int;
4596 if (GET_CODE (operands[1]) != MEM)
4598 addr = XEXP (operands[1], 0);
4599 if (GET_CODE (addr) != PLUS)
4601 reg = XEXP (addr, 0);
4602 const_int = XEXP (addr, 1);
4603 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4604 && GET_CODE (const_int) == CONST_INT))
4606 emit_move_insn (operands[2], const_int);
4607 emit_move_insn (change_address (operands[1], VOIDmode,
4608 gen_rtx_PLUS (SImode, reg, operands[2])),
4613 (define_expand "movdf"
4614 [(set (match_operand:DF 0 "general_movdst_operand" "")
4615 (match_operand:DF 1 "general_movsrc_operand" ""))]
4619 if (prepare_move_operands (operands, DFmode)) DONE;
4622 if (TARGET_SHMEDIA_FPU)
4623 emit_insn (gen_movdf_media (operands[0], operands[1]));
4625 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4630 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4635 ;;This is incompatible with the way gcc uses subregs.
4636 ;;(define_insn "movv2sf_i"
4637 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4638 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4639 ;; "TARGET_SHMEDIA_FPU
4640 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4641 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4645 ;; fst%M0.p %m0, %1"
4646 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4648 (define_insn_and_split "movv2sf_i"
4649 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4650 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4651 "TARGET_SHMEDIA_FPU"
4653 "TARGET_SHMEDIA_FPU && reload_completed"
4654 [(set (match_dup 0) (match_dup 1))]
4657 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4658 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4661 (define_expand "movv2sf"
4662 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4663 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4664 "TARGET_SHMEDIA_FPU"
4667 if (prepare_move_operands (operands, V2SFmode))
4671 (define_expand "addv2sf3"
4672 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4673 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4674 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4675 "TARGET_SHMEDIA_FPU"
4678 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4682 (define_expand "subv2sf3"
4683 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4684 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4685 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4686 "TARGET_SHMEDIA_FPU"
4689 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4693 (define_expand "mulv2sf3"
4694 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4695 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4696 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4697 "TARGET_SHMEDIA_FPU"
4700 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4704 (define_expand "divv2sf3"
4705 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4706 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4707 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4708 "TARGET_SHMEDIA_FPU"
4711 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4715 (define_insn_and_split "*movv4sf_i"
4716 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4717 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4718 "TARGET_SHMEDIA_FPU"
4720 "&& reload_completed"
4726 for (i = 0; i < 4/2; i++)
4730 if (GET_CODE (operands[0]) == MEM)
4731 x = gen_rtx_MEM (V2SFmode,
4732 plus_constant (XEXP (operands[0], 0),
4733 i * GET_MODE_SIZE (V2SFmode)));
4735 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4737 if (GET_CODE (operands[1]) == MEM)
4738 y = gen_rtx_MEM (V2SFmode,
4739 plus_constant (XEXP (operands[1], 0),
4740 i * GET_MODE_SIZE (V2SFmode)));
4742 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4744 emit_insn (gen_movv2sf_i (x, y));
4749 [(set_attr "length" "8")])
4751 (define_expand "movv4sf"
4752 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4753 (match_operand:V4SF 1 "general_operand" ""))]
4754 "TARGET_SHMEDIA_FPU"
4757 if (prepare_move_operands (operands, V4SFmode))
4761 (define_insn_and_split "*movv16sf_i"
4762 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4763 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4764 "TARGET_SHMEDIA_FPU"
4766 "&& reload_completed"
4772 for (i = 0; i < 16/2; i++)
4776 if (GET_CODE (operands[0]) == MEM)
4777 x = gen_rtx_MEM (V2SFmode,
4778 plus_constant (XEXP (operands[0], 0),
4779 i * GET_MODE_SIZE (V2SFmode)));
4782 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4786 if (GET_CODE (operands[1]) == MEM)
4787 y = gen_rtx_MEM (V2SFmode,
4788 plus_constant (XEXP (operands[1], 0),
4789 i * GET_MODE_SIZE (V2SFmode)));
4792 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4796 emit_insn (gen_movv2sf_i (x, y));
4801 [(set_attr "length" "32")])
4803 (define_expand "movv16sf"
4804 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4805 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4806 "TARGET_SHMEDIA_FPU"
4809 if (prepare_move_operands (operands, V16SFmode))
4813 (define_insn "movsf_media"
4814 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4815 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4817 && (register_operand (operands[0], SFmode)
4818 || sh_register_operand (operands[1], SFmode))"
4829 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4831 (define_insn "movsf_media_nofpu"
4832 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4833 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4835 && (register_operand (operands[0], SFmode)
4836 || sh_register_operand (operands[1], SFmode))"
4842 [(set_attr "type" "arith_media,*,load_media,store_media")])
4845 [(set (match_operand:SF 0 "arith_reg_operand" "")
4846 (match_operand:SF 1 "immediate_operand" ""))]
4847 "TARGET_SHMEDIA && reload_completed
4848 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4849 [(set (match_dup 3) (match_dup 2))]
4853 REAL_VALUE_TYPE value;
4855 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4856 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4857 operands[2] = GEN_INT (values);
4859 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4862 (define_insn "movsf_i"
4863 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4864 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4867 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4868 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4869 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4870 && (arith_reg_operand (operands[0], SFmode)
4871 || arith_reg_operand (operands[1], SFmode))"
4880 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4882 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4883 ;; update_flow_info would not know where to put REG_EQUAL notes
4884 ;; when the destination changes mode.
4885 (define_insn "movsf_ie"
4886 [(set (match_operand:SF 0 "general_movdst_operand"
4887 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4888 (match_operand:SF 1 "general_movsrc_operand"
4889 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4890 (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"))
4891 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4894 && (arith_reg_operand (operands[0], SFmode)
4895 || arith_reg_operand (operands[1], SFmode)
4896 || arith_reg_operand (operands[3], SImode)
4897 || (fpul_operand (operands[0], SFmode)
4898 && memory_operand (operands[1], SFmode)
4899 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4900 || (fpul_operand (operands[1], SFmode)
4901 && memory_operand (operands[0], SFmode)
4902 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4922 ! move optimized away"
4923 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4924 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4925 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4926 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4927 (const_string "single")
4928 (const_string "none")))])
4931 [(set (match_operand:SF 0 "register_operand" "")
4932 (match_operand:SF 1 "register_operand" ""))
4933 (use (match_operand:PSI 2 "fpscr_operand" ""))
4934 (clobber (reg:SI FPUL_REG))]
4936 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4938 (clobber (scratch:SI))])
4939 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4941 (clobber (scratch:SI))])]
4944 (define_expand "movsf"
4945 [(set (match_operand:SF 0 "general_movdst_operand" "")
4946 (match_operand:SF 1 "general_movsrc_operand" ""))]
4950 if (prepare_move_operands (operands, SFmode))
4954 if (TARGET_SHMEDIA_FPU)
4955 emit_insn (gen_movsf_media (operands[0], operands[1]));
4957 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4962 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4967 (define_insn "mov_nop"
4968 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4971 [(set_attr "length" "0")
4972 (set_attr "type" "nil")])
4974 (define_expand "reload_insf"
4975 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4976 (match_operand:SF 1 "immediate_operand" "FQ"))
4977 (use (reg:PSI FPSCR_REG))
4978 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4982 (define_expand "reload_insi"
4983 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4984 (match_operand:SF 1 "immediate_operand" "FQ"))
4985 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4989 (define_insn "*movsi_y"
4990 [(set (match_operand:SI 0 "register_operand" "=y,y")
4991 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
4992 (clobber (match_scratch:SI 2 "=&z,r"))]
4994 && (reload_in_progress || reload_completed)"
4996 [(set_attr "length" "4")
4997 (set_attr "type" "pcload,move")])
5000 [(set (match_operand:SI 0 "register_operand" "")
5001 (match_operand:SI 1 "immediate_operand" ""))
5002 (clobber (match_operand:SI 2 "register_operand" ""))]
5004 [(set (match_dup 2) (match_dup 1))
5005 (set (match_dup 0) (match_dup 2))]
5009 [(set (match_operand:SI 0 "register_operand" "")
5010 (match_operand:SI 1 "memory_operand" ""))
5011 (clobber (reg:SI R0_REG))]
5013 [(set (match_dup 0) (match_dup 1))]
5016 ;; ------------------------------------------------------------------------
5017 ;; Define the real conditional branch instructions.
5018 ;; ------------------------------------------------------------------------
5020 (define_insn "branch_true"
5021 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5022 (label_ref (match_operand 0 "" ""))
5025 "* return output_branch (1, insn, operands);"
5026 [(set_attr "type" "cbranch")])
5028 (define_insn "branch_false"
5029 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5030 (label_ref (match_operand 0 "" ""))
5033 "* return output_branch (0, insn, operands);"
5034 [(set_attr "type" "cbranch")])
5036 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5037 ;; which destination is too far away.
5038 ;; The const_int_operand is distinct for each branch target; it avoids
5039 ;; unwanted matches with redundant_insn.
5040 (define_insn "block_branch_redirect"
5041 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5044 [(set_attr "length" "0")])
5046 ;; This one has the additional purpose to record a possible scratch register
5047 ;; for the following branch.
5048 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5049 ;; because the insn then might be deemed dead and deleted. And we can't
5050 ;; make the use in the jump insn explicit because that would disable
5051 ;; delay slot scheduling from the target.
5052 (define_insn "indirect_jump_scratch"
5053 [(set (match_operand:SI 0 "register_operand" "=r")
5054 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5055 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5058 [(set_attr "length" "0")])
5060 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5061 ;; being pulled into the delay slot of a condbranch that has been made to
5062 ;; jump around the unconditional jump because it was out of range.
5063 (define_insn "stuff_delay_slot"
5065 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5066 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5069 [(set_attr "length" "0")
5070 (set_attr "cond_delay_slot" "yes")])
5072 ;; Conditional branch insns
5074 (define_expand "beq_media"
5076 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5077 (match_operand:DI 2 "arith_operand" "r,I06"))
5078 (label_ref:DI (match_operand 0 "" ""))
5083 (define_insn "*beq_media_i"
5085 (if_then_else (match_operator 3 "equality_comparison_operator"
5086 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5087 (match_operand:DI 2 "arith_operand" "r,I06")])
5088 (match_operand:DI 0 "target_operand" "b,b")
5094 [(set_attr "type" "cbranch_media")])
5096 (define_expand "bne_media"
5098 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5099 (match_operand:DI 2 "arith_operand" "r,I06"))
5100 (label_ref:DI (match_operand 0 "" ""))
5105 (define_expand "bgt_media"
5107 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5108 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5109 (label_ref:DI (match_operand 0 "" ""))
5114 (define_expand "bge_media"
5116 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5117 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5118 (label_ref:DI (match_operand 0 "" ""))
5123 (define_expand "bgtu_media"
5125 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5126 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5127 (label_ref:DI (match_operand 0 "" ""))
5132 (define_expand "bgeu_media"
5134 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5135 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5136 (label_ref:DI (match_operand 0 "" ""))
5141 (define_insn "*bgt_media_i"
5143 (if_then_else (match_operator 3 "greater_comparison_operator"
5144 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5145 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5146 (match_operand:DI 0 "target_operand" "b")
5149 "b%o3%' %N1, %N2, %0"
5150 [(set_attr "type" "cbranch_media")])
5152 ;; These are only needed to make invert_jump() happy.
5153 (define_insn "*blt_media_i"
5155 (if_then_else (match_operator 3 "less_comparison_operator"
5156 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5157 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5158 (match_operand:DI 0 "target_operand" "b")
5161 "b%o3%' %N2, %N1, %0"
5162 [(set_attr "type" "cbranch_media")])
5164 (define_expand "beq"
5166 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5167 (label_ref (match_operand 0 "" ""))
5174 if (GET_MODE (sh_compare_op0) != DImode)
5176 rtx tmp = gen_reg_rtx (DImode);
5178 emit_insn (gen_seq (tmp));
5179 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5183 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5184 emit_jump_insn (gen_beq_media (operands[0],
5185 sh_compare_op0, sh_compare_op1));
5189 from_compare (operands, EQ);
5192 (define_expand "bne"
5194 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5195 (label_ref (match_operand 0 "" ""))
5202 if (GET_MODE (sh_compare_op0) != DImode)
5204 rtx tmp = gen_reg_rtx (DImode);
5206 emit_insn (gen_seq (tmp));
5207 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5211 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5212 emit_jump_insn (gen_bne_media (operands[0],
5213 sh_compare_op0, sh_compare_op1));
5217 from_compare (operands, EQ);
5220 (define_expand "bgt"
5222 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5223 (label_ref (match_operand 0 "" ""))
5230 if (GET_MODE (sh_compare_op0) != DImode)
5232 rtx tmp = gen_reg_rtx (DImode);
5234 emit_insn (gen_sgt (tmp));
5235 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5239 if (sh_compare_op0 != const0_rtx)
5240 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5241 if (sh_compare_op1 != const0_rtx)
5242 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5243 emit_jump_insn (gen_bgt_media (operands[0],
5244 sh_compare_op0, sh_compare_op1));
5248 from_compare (operands, GT);
5251 (define_expand "blt"
5253 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5254 (label_ref (match_operand 0 "" ""))
5261 if (GET_MODE (sh_compare_op0) != DImode)
5263 rtx tmp = gen_reg_rtx (DImode);
5265 emit_insn (gen_slt (tmp));
5266 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5270 if (sh_compare_op0 != const0_rtx)
5271 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5272 if (sh_compare_op1 != const0_rtx)
5273 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5274 emit_jump_insn (gen_bgt_media (operands[0],
5275 sh_compare_op1, sh_compare_op0));
5279 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5281 rtx tmp = sh_compare_op0;
5282 sh_compare_op0 = sh_compare_op1;
5283 sh_compare_op1 = tmp;
5284 emit_insn (gen_bgt (operands[0]));
5287 from_compare (operands, GE);
5290 (define_expand "ble"
5292 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5293 (label_ref (match_operand 0 "" ""))
5300 if (GET_MODE (sh_compare_op0) != DImode)
5302 rtx tmp = gen_reg_rtx (DImode);
5304 emit_insn (gen_sle (tmp));
5305 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5309 if (sh_compare_op0 != const0_rtx)
5310 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5311 if (sh_compare_op1 != const0_rtx)
5312 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5313 emit_jump_insn (gen_bge_media (operands[0],
5314 sh_compare_op1, sh_compare_op0));
5320 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5322 rtx tmp = sh_compare_op0;
5323 sh_compare_op0 = sh_compare_op1;
5324 sh_compare_op1 = tmp;
5325 emit_insn (gen_bge (operands[0]));
5328 from_compare (operands, GT);
5331 (define_expand "bge"
5333 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5334 (label_ref (match_operand 0 "" ""))
5341 if (GET_MODE (sh_compare_op0) != DImode)
5343 rtx tmp = gen_reg_rtx (DImode);
5345 emit_insn (gen_sge (tmp));
5346 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5350 if (sh_compare_op0 != const0_rtx)
5351 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5352 if (sh_compare_op1 != const0_rtx)
5353 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5354 emit_jump_insn (gen_bge_media (operands[0],
5355 sh_compare_op0, sh_compare_op1));
5361 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5363 rtx tmp = sh_compare_op0;
5364 sh_compare_op0 = sh_compare_op1;
5365 sh_compare_op1 = tmp;
5366 emit_insn (gen_ble (operands[0]));
5369 from_compare (operands, GE);
5372 (define_expand "bgtu"
5374 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5375 (label_ref (match_operand 0 "" ""))
5382 if (sh_compare_op0 != const0_rtx)
5383 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5384 if (sh_compare_op1 != const0_rtx)
5385 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5386 emit_jump_insn (gen_bgtu_media (operands[0],
5387 sh_compare_op0, sh_compare_op1));
5391 from_compare (operands, GTU);
5394 (define_expand "bltu"
5396 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5397 (label_ref (match_operand 0 "" ""))
5404 if (sh_compare_op0 != const0_rtx)
5405 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5406 if (sh_compare_op1 != const0_rtx)
5407 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5408 emit_jump_insn (gen_bgtu_media (operands[0],
5409 sh_compare_op1, sh_compare_op0));
5413 from_compare (operands, GEU);
5416 (define_expand "bgeu"
5418 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5419 (label_ref (match_operand 0 "" ""))
5426 if (sh_compare_op0 != const0_rtx)
5427 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5428 if (sh_compare_op1 != const0_rtx)
5429 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5430 emit_jump_insn (gen_bgeu_media (operands[0],
5431 sh_compare_op0, sh_compare_op1));
5435 from_compare (operands, GEU);
5438 (define_expand "bleu"
5440 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5441 (label_ref (match_operand 0 "" ""))
5448 if (sh_compare_op0 != const0_rtx)
5449 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5450 if (sh_compare_op1 != const0_rtx)
5451 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5452 emit_jump_insn (gen_bgeu_media (operands[0],
5453 sh_compare_op1, sh_compare_op0));
5457 from_compare (operands, GTU);
5460 (define_expand "bunordered"
5461 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5463 (if_then_else (ne (match_dup 1) (const_int 0))
5464 (label_ref:DI (match_operand 0 "" ""))
5469 operands[1] = gen_reg_rtx (DImode);
5470 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5471 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5474 ;; ------------------------------------------------------------------------
5475 ;; Jump and linkage insns
5476 ;; ------------------------------------------------------------------------
5478 (define_insn "jump_compact"
5480 (label_ref (match_operand 0 "" "")))]
5484 /* The length is 16 if the delay slot is unfilled. */
5485 if (get_attr_length(insn) > 4)
5486 return output_far_jump(insn, operands[0]);
5488 return \"bra %l0%#\";
5490 [(set_attr "type" "jump")
5491 (set_attr "needs_delay_slot" "yes")])
5493 ;; ??? It would be much saner to explicitly use the scratch register
5494 ;; in the jump insn, and have indirect_jump_scratch only set it,
5495 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5496 ;; from the target then, as it uses simplejump_p.
5497 ;;(define_insn "jump_compact_far"
5499 ;; (label_ref (match_operand 0 "" "")))
5500 ;; (use (match_operand 1 "register_operand" "r")]
5502 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5503 ;; [(set_attr "type" "jump")
5504 ;; (set_attr "needs_delay_slot" "yes")])
5506 (define_insn "jump_media"
5508 (match_operand:DI 0 "target_operand" "b"))]
5511 [(set_attr "type" "jump_media")])
5513 (define_expand "jump"
5515 (label_ref (match_operand 0 "" "")))]
5520 emit_jump_insn (gen_jump_compact (operands[0]));
5521 else if (TARGET_SHMEDIA)
5523 if (reload_in_progress || reload_completed)
5525 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5531 (define_insn "force_mode_for_call"
5532 [(use (reg:PSI FPSCR_REG))]
5535 [(set_attr "length" "0")
5536 (set (attr "fp_mode")
5537 (if_then_else (eq_attr "fpu_single" "yes")
5538 (const_string "single") (const_string "double")))])
5540 (define_insn "calli"
5541 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5542 (match_operand 1 "" ""))
5543 (use (reg:PSI FPSCR_REG))
5544 (clobber (reg:SI PR_REG))]
5547 [(set_attr "type" "call")
5548 (set (attr "fp_mode")
5549 (if_then_else (eq_attr "fpu_single" "yes")
5550 (const_string "single") (const_string "double")))
5551 (set_attr "needs_delay_slot" "yes")])
5553 ;; This is a pc-rel call, using bsrf, for use with PIC.
5555 (define_insn "calli_pcrel"
5556 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5557 (match_operand 1 "" ""))
5558 (use (reg:PSI FPSCR_REG))
5559 (use (reg:SI PIC_REG))
5560 (use (match_operand 2 "" ""))
5561 (clobber (reg:SI PR_REG))]
5564 [(set_attr "type" "call")
5565 (set (attr "fp_mode")
5566 (if_then_else (eq_attr "fpu_single" "yes")
5567 (const_string "single") (const_string "double")))
5568 (set_attr "needs_delay_slot" "yes")])
5570 (define_insn_and_split "call_pcrel"
5571 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5572 (match_operand 1 "" ""))
5573 (use (reg:PSI FPSCR_REG))
5574 (use (reg:SI PIC_REG))
5575 (clobber (reg:SI PR_REG))
5576 (clobber (match_scratch:SI 2 "=r"))]
5583 rtx lab = PATTERN (gen_call_site ());
5585 if (SYMBOL_REF_LOCAL_P (operands[0]))
5586 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5588 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5589 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5592 [(set_attr "type" "call")
5593 (set (attr "fp_mode")
5594 (if_then_else (eq_attr "fpu_single" "yes")
5595 (const_string "single") (const_string "double")))
5596 (set_attr "needs_delay_slot" "yes")])
5598 (define_insn "call_compact"
5599 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5600 (match_operand 1 "" ""))
5601 (match_operand 2 "immediate_operand" "n")
5602 (use (reg:SI R0_REG))
5603 (use (reg:SI R1_REG))
5604 (use (reg:PSI FPSCR_REG))
5605 (clobber (reg:SI PR_REG))]
5606 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5608 [(set_attr "type" "call")
5609 (set (attr "fp_mode")
5610 (if_then_else (eq_attr "fpu_single" "yes")
5611 (const_string "single") (const_string "double")))
5612 (set_attr "needs_delay_slot" "yes")])
5614 (define_insn "call_compact_rettramp"
5615 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5616 (match_operand 1 "" ""))
5617 (match_operand 2 "immediate_operand" "n")
5618 (use (reg:SI R0_REG))
5619 (use (reg:SI R1_REG))
5620 (use (reg:PSI FPSCR_REG))
5621 (clobber (reg:SI R10_REG))
5622 (clobber (reg:SI PR_REG))]
5623 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5631 (define_insn "call_media"
5632 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5633 (match_operand 1 "" ""))
5634 (clobber (reg:DI PR_MEDIA_REG))]
5637 [(set_attr "type" "jump_media")])
5639 (define_insn "call_valuei"
5640 [(set (match_operand 0 "" "=rf")
5641 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5642 (match_operand 2 "" "")))
5643 (use (reg:PSI FPSCR_REG))
5644 (clobber (reg:SI PR_REG))]
5647 [(set_attr "type" "call")
5648 (set (attr "fp_mode")
5649 (if_then_else (eq_attr "fpu_single" "yes")
5650 (const_string "single") (const_string "double")))
5651 (set_attr "needs_delay_slot" "yes")])
5653 (define_insn "call_valuei_pcrel"
5654 [(set (match_operand 0 "" "=rf")
5655 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5656 (match_operand 2 "" "")))
5657 (use (reg:PSI FPSCR_REG))
5658 (use (reg:SI PIC_REG))
5659 (use (match_operand 3 "" ""))
5660 (clobber (reg:SI PR_REG))]
5663 [(set_attr "type" "call")
5664 (set (attr "fp_mode")
5665 (if_then_else (eq_attr "fpu_single" "yes")
5666 (const_string "single") (const_string "double")))
5667 (set_attr "needs_delay_slot" "yes")])
5669 (define_insn_and_split "call_value_pcrel"
5670 [(set (match_operand 0 "" "=rf")
5671 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5672 (match_operand 2 "" "")))
5673 (use (reg:PSI FPSCR_REG))
5674 (use (reg:SI PIC_REG))
5675 (clobber (reg:SI PR_REG))
5676 (clobber (match_scratch:SI 3 "=r"))]
5683 rtx lab = PATTERN (gen_call_site ());
5685 if (SYMBOL_REF_LOCAL_P (operands[1]))
5686 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5688 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5689 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5693 [(set_attr "type" "call")
5694 (set (attr "fp_mode")
5695 (if_then_else (eq_attr "fpu_single" "yes")
5696 (const_string "single") (const_string "double")))
5697 (set_attr "needs_delay_slot" "yes")])
5699 (define_insn "call_value_compact"
5700 [(set (match_operand 0 "" "=rf")
5701 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5702 (match_operand 2 "" "")))
5703 (match_operand 3 "immediate_operand" "n")
5704 (use (reg:SI R0_REG))
5705 (use (reg:SI R1_REG))
5706 (use (reg:PSI FPSCR_REG))
5707 (clobber (reg:SI PR_REG))]
5708 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5710 [(set_attr "type" "call")
5711 (set (attr "fp_mode")
5712 (if_then_else (eq_attr "fpu_single" "yes")
5713 (const_string "single") (const_string "double")))
5714 (set_attr "needs_delay_slot" "yes")])
5716 (define_insn "call_value_compact_rettramp"
5717 [(set (match_operand 0 "" "=rf")
5718 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5719 (match_operand 2 "" "")))
5720 (match_operand 3 "immediate_operand" "n")
5721 (use (reg:SI R0_REG))
5722 (use (reg:SI R1_REG))
5723 (use (reg:PSI FPSCR_REG))
5724 (clobber (reg:SI R10_REG))
5725 (clobber (reg:SI PR_REG))]
5726 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5728 [(set_attr "type" "call")
5729 (set (attr "fp_mode")
5730 (if_then_else (eq_attr "fpu_single" "yes")
5731 (const_string "single") (const_string "double")))
5732 (set_attr "needs_delay_slot" "yes")])
5734 (define_insn "call_value_media"
5735 [(set (match_operand 0 "" "=rf")
5736 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5737 (match_operand 2 "" "")))
5738 (clobber (reg:DI PR_MEDIA_REG))]
5741 [(set_attr "type" "jump_media")])
5743 (define_expand "call"
5744 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5745 (match_operand 1 "" ""))
5746 (match_operand 2 "" "")
5747 (use (reg:PSI FPSCR_REG))
5748 (clobber (reg:SI PR_REG))])]
5754 operands[0] = XEXP (operands[0], 0);
5755 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5757 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5759 rtx reg = gen_reg_rtx (Pmode);
5761 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5766 operands[0] = gen_sym2PIC (operands[0]);
5767 PUT_MODE (operands[0], Pmode);
5770 if (GET_MODE (operands[0]) == SImode)
5772 if (GET_CODE (operands[0]) == REG)
5773 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5774 else if (GET_CODE (operands[0]) == SUBREG)
5776 operands[0] = SUBREG_REG (operands[0]);
5777 if (GET_MODE (operands[0]) != DImode)
5778 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5782 operands[0] = shallow_copy_rtx (operands[0]);
5783 PUT_MODE (operands[0], DImode);
5786 if (! target_reg_operand (operands[0], DImode))
5787 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5788 emit_call_insn (gen_call_media (operands[0], operands[1]));
5791 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5793 rtx cookie_rtx = operands[2];
5794 long cookie = INTVAL (cookie_rtx);
5795 rtx func = XEXP (operands[0], 0);
5800 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5802 rtx reg = gen_reg_rtx (Pmode);
5804 emit_insn (gen_symGOTPLT2reg (reg, func));
5808 func = legitimize_pic_address (func, Pmode, 0);
5811 r0 = gen_rtx_REG (SImode, R0_REG);
5812 r1 = gen_rtx_REG (SImode, R1_REG);
5814 /* Since such a call function may use all call-clobbered
5815 registers, we force a mode switch earlier, so that we don't
5816 run out of registers when adjusting fpscr for the call. */
5817 emit_insn (gen_force_mode_for_call ());
5819 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5822 rtx reg = gen_reg_rtx (Pmode);
5824 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5827 operands[0] = force_reg (SImode, operands[0]);
5829 emit_move_insn (r0, func);
5830 emit_move_insn (r1, cookie_rtx);
5832 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5833 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5836 emit_call_insn (gen_call_compact (operands[0], operands[1],
5841 else if (TARGET_SHCOMPACT && flag_pic
5842 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5843 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5845 rtx reg = gen_reg_rtx (Pmode);
5847 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5848 XEXP (operands[0], 0) = reg;
5850 if (flag_pic && TARGET_SH2
5851 && GET_CODE (operands[0]) == MEM
5852 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5854 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5858 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5860 emit_call_insn (gen_calli (operands[0], operands[1]));
5864 (define_insn "call_pop_compact"
5865 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5866 (match_operand 1 "" ""))
5867 (match_operand 2 "immediate_operand" "n")
5868 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5869 (match_operand 3 "immediate_operand" "n")))
5870 (use (reg:SI R0_REG))
5871 (use (reg:SI R1_REG))
5872 (use (reg:PSI FPSCR_REG))
5873 (clobber (reg:SI PR_REG))]
5874 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5876 [(set_attr "type" "call")
5877 (set (attr "fp_mode")
5878 (if_then_else (eq_attr "fpu_single" "yes")
5879 (const_string "single") (const_string "double")))
5880 (set_attr "needs_delay_slot" "yes")])
5882 (define_insn "call_pop_compact_rettramp"
5883 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5884 (match_operand 1 "" ""))
5885 (match_operand 2 "immediate_operand" "n")
5886 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5887 (match_operand 3 "immediate_operand" "n")))
5888 (use (reg:SI R0_REG))
5889 (use (reg:SI R1_REG))
5890 (use (reg:PSI FPSCR_REG))
5891 (clobber (reg:SI R10_REG))
5892 (clobber (reg:SI PR_REG))]
5893 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5895 [(set_attr "type" "call")
5896 (set (attr "fp_mode")
5897 (if_then_else (eq_attr "fpu_single" "yes")
5898 (const_string "single") (const_string "double")))
5899 (set_attr "needs_delay_slot" "yes")])
5901 (define_expand "call_pop"
5902 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5903 (match_operand 1 "" ""))
5904 (match_operand 2 "" "")
5905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5906 (match_operand 3 "" "")))])]
5910 if (operands[2] && INTVAL (operands[2]))
5912 rtx cookie_rtx = operands[2];
5913 long cookie = INTVAL (cookie_rtx);
5914 rtx func = XEXP (operands[0], 0);
5919 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5921 rtx reg = gen_reg_rtx (Pmode);
5923 emit_insn (gen_symGOTPLT2reg (reg, func));
5927 func = legitimize_pic_address (func, Pmode, 0);
5930 r0 = gen_rtx_REG (SImode, R0_REG);
5931 r1 = gen_rtx_REG (SImode, R1_REG);
5933 /* Since such a call function may use all call-clobbered
5934 registers, we force a mode switch earlier, so that we don't
5935 run out of registers when adjusting fpscr for the call. */
5936 emit_insn (gen_force_mode_for_call ());
5938 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5941 rtx reg = gen_reg_rtx (Pmode);
5943 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5946 operands[0] = force_reg (SImode, operands[0]);
5948 emit_move_insn (r0, func);
5949 emit_move_insn (r1, cookie_rtx);
5951 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5952 emit_call_insn (gen_call_pop_compact_rettramp
5953 (operands[0], operands[1], operands[2], operands[3]));
5955 emit_call_insn (gen_call_pop_compact
5956 (operands[0], operands[1], operands[2], operands[3]));
5964 (define_expand "call_value"
5965 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5966 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5967 (match_operand 2 "" "")))
5968 (match_operand 3 "" "")
5969 (use (reg:PSI FPSCR_REG))
5970 (clobber (reg:SI PR_REG))])]
5976 operands[1] = XEXP (operands[1], 0);
5977 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5979 if (! SYMBOL_REF_LOCAL_P (operands[1]))
5981 rtx reg = gen_reg_rtx (Pmode);
5983 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5988 operands[1] = gen_sym2PIC (operands[1]);
5989 PUT_MODE (operands[1], Pmode);
5992 if (GET_MODE (operands[1]) == SImode)
5994 if (GET_CODE (operands[1]) == REG)
5995 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5996 else if (GET_CODE (operands[1]) == SUBREG)
5998 operands[1] = SUBREG_REG (operands[1]);
5999 if (GET_MODE (operands[1]) != DImode)
6000 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6004 operands[1] = shallow_copy_rtx (operands[1]);
6005 PUT_MODE (operands[1], DImode);
6008 if (! target_reg_operand (operands[1], DImode))
6009 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6010 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6014 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6016 rtx cookie_rtx = operands[3];
6017 long cookie = INTVAL (cookie_rtx);
6018 rtx func = XEXP (operands[1], 0);
6023 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6025 rtx reg = gen_reg_rtx (Pmode);
6027 emit_insn (gen_symGOTPLT2reg (reg, func));
6031 func = legitimize_pic_address (func, Pmode, 0);
6034 r0 = gen_rtx_REG (SImode, R0_REG);
6035 r1 = gen_rtx_REG (SImode, R1_REG);
6037 /* Since such a call function may use all call-clobbered
6038 registers, we force a mode switch earlier, so that we don't
6039 run out of registers when adjusting fpscr for the call. */
6040 emit_insn (gen_force_mode_for_call ());
6042 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6045 rtx reg = gen_reg_rtx (Pmode);
6047 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6050 operands[1] = force_reg (SImode, operands[1]);
6052 emit_move_insn (r0, func);
6053 emit_move_insn (r1, cookie_rtx);
6055 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6056 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6061 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6062 operands[2], operands[3]));
6066 else if (TARGET_SHCOMPACT && flag_pic
6067 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6068 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6070 rtx reg = gen_reg_rtx (Pmode);
6072 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6073 XEXP (operands[1], 0) = reg;
6075 if (flag_pic && TARGET_SH2
6076 && GET_CODE (operands[1]) == MEM
6077 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6079 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6084 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6086 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6090 (define_insn "sibcalli"
6091 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6092 (match_operand 1 "" ""))
6093 (use (reg:PSI FPSCR_REG))
6097 [(set_attr "needs_delay_slot" "yes")
6098 (set (attr "fp_mode")
6099 (if_then_else (eq_attr "fpu_single" "yes")
6100 (const_string "single") (const_string "double")))
6101 (set_attr "type" "jump_ind")])
6103 (define_insn "sibcalli_pcrel"
6104 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6105 (match_operand 1 "" ""))
6106 (use (match_operand 2 "" ""))
6107 (use (reg:PSI FPSCR_REG))
6111 [(set_attr "needs_delay_slot" "yes")
6112 (set (attr "fp_mode")
6113 (if_then_else (eq_attr "fpu_single" "yes")
6114 (const_string "single") (const_string "double")))
6115 (set_attr "type" "jump_ind")])
6117 (define_insn_and_split "sibcall_pcrel"
6118 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6119 (match_operand 1 "" ""))
6120 (use (reg:PSI FPSCR_REG))
6121 (clobber (match_scratch:SI 2 "=k"))
6129 rtx lab = PATTERN (gen_call_site ());
6132 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6133 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6135 SIBLING_CALL_P (call_insn) = 1;
6138 [(set_attr "needs_delay_slot" "yes")
6139 (set (attr "fp_mode")
6140 (if_then_else (eq_attr "fpu_single" "yes")
6141 (const_string "single") (const_string "double")))
6142 (set_attr "type" "jump_ind")])
6144 (define_insn "sibcall_compact"
6145 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6146 (match_operand 1 "" ""))
6148 (use (match_operand:SI 2 "register_operand" "z,x"))
6149 (use (reg:SI R1_REG))
6150 (use (reg:PSI FPSCR_REG))
6151 ;; We want to make sure the `x' above will only match MACH_REG
6152 ;; because sibcall_epilogue may clobber MACL_REG.
6153 (clobber (reg:SI MACL_REG))]
6157 jmp @%0\\n sts %2, r0"
6158 [(set_attr "needs_delay_slot" "yes,no")
6159 (set_attr "length" "2,4")
6160 (set (attr "fp_mode") (const_string "single"))
6161 (set_attr "type" "jump_ind")])
6163 (define_insn "sibcall_media"
6164 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6165 (match_operand 1 "" ""))
6169 [(set_attr "type" "jump_media")])
6171 (define_expand "sibcall"
6173 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6174 (match_operand 1 "" ""))
6175 (match_operand 2 "" "")
6176 (use (reg:PSI FPSCR_REG))
6183 operands[0] = XEXP (operands[0], 0);
6184 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6186 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6188 rtx reg = gen_reg_rtx (Pmode);
6190 /* We must not use GOTPLT for sibcalls, because PIC_REG
6191 must be restored before the PLT code gets to run. */
6192 emit_insn (gen_symGOT2reg (reg, operands[0]));
6197 operands[0] = gen_sym2PIC (operands[0]);
6198 PUT_MODE (operands[0], Pmode);
6201 if (GET_MODE (operands[0]) == SImode)
6203 if (GET_CODE (operands[0]) == REG)
6204 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6205 else if (GET_CODE (operands[0]) == SUBREG)
6207 operands[0] = SUBREG_REG (operands[0]);
6208 if (GET_MODE (operands[0]) != DImode)
6209 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6213 operands[0] = shallow_copy_rtx (operands[0]);
6214 PUT_MODE (operands[0], DImode);
6217 if (! target_reg_operand (operands[0], DImode))
6218 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6219 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6222 else if (TARGET_SHCOMPACT && operands[2]
6223 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6225 rtx cookie_rtx = operands[2];
6226 long cookie = INTVAL (cookie_rtx);
6227 rtx func = XEXP (operands[0], 0);
6232 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6234 rtx reg = gen_reg_rtx (Pmode);
6236 emit_insn (gen_symGOT2reg (reg, func));
6240 func = legitimize_pic_address (func, Pmode, 0);
6243 /* FIXME: if we could tell whether all argument registers are
6244 already taken, we could decide whether to force the use of
6245 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6246 simple way to tell. We could use the CALL_COOKIE, but we
6247 can't currently tell a register used for regular argument
6248 passing from one that is unused. If we leave it up to reload
6249 to decide which register to use, it seems to always choose
6250 R0_REG, which leaves no available registers in SIBCALL_REGS
6251 to hold the address of the trampoline. */
6252 mach = gen_rtx_REG (SImode, MACH_REG);
6253 r1 = gen_rtx_REG (SImode, R1_REG);
6255 /* Since such a call function may use all call-clobbered
6256 registers, we force a mode switch earlier, so that we don't
6257 run out of registers when adjusting fpscr for the call. */
6258 emit_insn (gen_force_mode_for_call ());
6260 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6263 rtx reg = gen_reg_rtx (Pmode);
6265 emit_insn (gen_symGOT2reg (reg, operands[0]));
6268 operands[0] = force_reg (SImode, operands[0]);
6270 /* We don't need a return trampoline, since the callee will
6271 return directly to the upper caller. */
6272 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6274 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6275 cookie_rtx = GEN_INT (cookie);
6278 emit_move_insn (mach, func);
6279 emit_move_insn (r1, cookie_rtx);
6281 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6284 else if (TARGET_SHCOMPACT && flag_pic
6285 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6286 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6288 rtx reg = gen_reg_rtx (Pmode);
6290 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6291 XEXP (operands[0], 0) = reg;
6293 if (flag_pic && TARGET_SH2
6294 && GET_CODE (operands[0]) == MEM
6295 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6296 /* The PLT needs the PIC register, but the epilogue would have
6297 to restore it, so we can only use PC-relative PIC calls for
6298 static functions. */
6299 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6301 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6305 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6307 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6311 (define_expand "sibcall_value"
6312 [(set (match_operand 0 "" "")
6313 (call (match_operand 1 "" "")
6314 (match_operand 2 "" "")))
6315 (match_operand 3 "" "")]
6319 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6323 (define_insn "call_value_pop_compact"
6324 [(set (match_operand 0 "" "=rf")
6325 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6326 (match_operand 2 "" "")))
6327 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6328 (match_operand 4 "immediate_operand" "n")))
6329 (match_operand 3 "immediate_operand" "n")
6330 (use (reg:SI R0_REG))
6331 (use (reg:SI R1_REG))
6332 (use (reg:PSI FPSCR_REG))
6333 (clobber (reg:SI PR_REG))]
6334 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6336 [(set_attr "type" "call")
6337 (set (attr "fp_mode")
6338 (if_then_else (eq_attr "fpu_single" "yes")
6339 (const_string "single") (const_string "double")))
6340 (set_attr "needs_delay_slot" "yes")])
6342 (define_insn "call_value_pop_compact_rettramp"
6343 [(set (match_operand 0 "" "=rf")
6344 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6345 (match_operand 2 "" "")))
6346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6347 (match_operand 4 "immediate_operand" "n")))
6348 (match_operand 3 "immediate_operand" "n")
6349 (use (reg:SI R0_REG))
6350 (use (reg:SI R1_REG))
6351 (use (reg:PSI FPSCR_REG))
6352 (clobber (reg:SI R10_REG))
6353 (clobber (reg:SI PR_REG))]
6354 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6356 [(set_attr "type" "call")
6357 (set (attr "fp_mode")
6358 (if_then_else (eq_attr "fpu_single" "yes")
6359 (const_string "single") (const_string "double")))
6360 (set_attr "needs_delay_slot" "yes")])
6362 (define_expand "call_value_pop"
6363 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6364 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6365 (match_operand 2 "" "")))
6366 (match_operand 3 "" "")
6367 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6368 (match_operand 4 "" "")))])]
6372 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6374 rtx cookie_rtx = operands[3];
6375 long cookie = INTVAL (cookie_rtx);
6376 rtx func = XEXP (operands[1], 0);
6381 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6383 rtx reg = gen_reg_rtx (Pmode);
6385 emit_insn (gen_symGOTPLT2reg (reg, func));
6389 func = legitimize_pic_address (func, Pmode, 0);
6392 r0 = gen_rtx_REG (SImode, R0_REG);
6393 r1 = gen_rtx_REG (SImode, R1_REG);
6395 /* Since such a call function may use all call-clobbered
6396 registers, we force a mode switch earlier, so that we don't
6397 run out of registers when adjusting fpscr for the call. */
6398 emit_insn (gen_force_mode_for_call ());
6400 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6403 rtx reg = gen_reg_rtx (Pmode);
6405 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6408 operands[1] = force_reg (SImode, operands[1]);
6410 emit_move_insn (r0, func);
6411 emit_move_insn (r1, cookie_rtx);
6413 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6414 emit_call_insn (gen_call_value_pop_compact_rettramp
6415 (operands[0], operands[1], operands[2],
6416 operands[3], operands[4]));
6418 emit_call_insn (gen_call_value_pop_compact
6419 (operands[0], operands[1], operands[2],
6420 operands[3], operands[4]));
6428 (define_expand "sibcall_epilogue"
6433 sh_expand_epilogue ();
6434 if (TARGET_SHCOMPACT)
6438 /* If epilogue clobbers r0, preserve it in macl. */
6439 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6440 if ((set = single_set (insn))
6441 && GET_CODE (SET_DEST (set)) == REG
6442 && REGNO (SET_DEST (set)) == R0_REG)
6444 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6445 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6448 /* We can't tell at this point whether the sibcall is a
6449 sibcall_compact and, if it is, whether it uses r0 or
6450 mach as operand 2, so let the instructions that
6451 preserve r0 be optimized away if r0 turns out to be
6453 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6454 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6456 i = emit_move_insn (r0, tmp);
6457 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6465 (define_insn "indirect_jump_compact"
6467 (match_operand:SI 0 "arith_reg_operand" "r"))]
6470 [(set_attr "needs_delay_slot" "yes")
6471 (set_attr "type" "jump_ind")])
6473 (define_expand "indirect_jump"
6475 (match_operand 0 "register_operand" ""))]
6479 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6480 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6483 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6484 ;; which can be present in structured code from indirect jumps which can not
6485 ;; be present in structured code. This allows -fprofile-arcs to work.
6487 ;; For SH1 processors.
6488 (define_insn "casesi_jump_1"
6490 (match_operand:SI 0 "register_operand" "r"))
6491 (use (label_ref (match_operand 1 "" "")))]
6494 [(set_attr "needs_delay_slot" "yes")
6495 (set_attr "type" "jump_ind")])
6497 ;; For all later processors.
6498 (define_insn "casesi_jump_2"
6499 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6500 (label_ref (match_operand 1 "" ""))))
6501 (use (label_ref (match_operand 2 "" "")))]
6503 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6505 [(set_attr "needs_delay_slot" "yes")
6506 (set_attr "type" "jump_ind")])
6508 (define_insn "casesi_jump_media"
6509 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6510 (use (label_ref (match_operand 1 "" "")))]
6513 [(set_attr "type" "jump_media")])
6515 ;; Call subroutine returning any type.
6516 ;; ??? This probably doesn't work.
6518 (define_expand "untyped_call"
6519 [(parallel [(call (match_operand 0 "" "")
6521 (match_operand 1 "" "")
6522 (match_operand 2 "" "")])]
6523 "TARGET_SH2E || TARGET_SHMEDIA"
6528 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6530 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6532 rtx set = XVECEXP (operands[2], 0, i);
6533 emit_move_insn (SET_DEST (set), SET_SRC (set));
6536 /* The optimizer does not know that the call sets the function value
6537 registers we stored in the result block. We avoid problems by
6538 claiming that all hard registers are used and clobbered at this
6540 emit_insn (gen_blockage ());
6545 ;; ------------------------------------------------------------------------
6547 ;; ------------------------------------------------------------------------
6550 [(set (reg:SI T_REG)
6551 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6552 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6555 [(set_attr "type" "arith")])
6562 ;; Load address of a label. This is only generated by the casesi expand,
6563 ;; and by machine_dependent_reorg (fixing up fp moves).
6564 ;; This must use unspec, because this only works for labels that are
6568 [(set (reg:SI R0_REG)
6569 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6572 [(set_attr "in_delay_slot" "no")
6573 (set_attr "type" "arith")])
6575 ;; machine_dependent_reorg will make this a `mova'.
6576 (define_insn "mova_const"
6577 [(set (reg:SI R0_REG)
6578 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6581 [(set_attr "in_delay_slot" "no")
6582 (set_attr "type" "arith")])
6584 (define_expand "GOTaddr2picreg"
6585 [(set (reg:SI R0_REG)
6586 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6588 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6589 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6592 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6593 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6596 operands[1] = gen_datalabel_ref (operands[1]);
6600 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6601 rtx dipic = operands[0];
6602 rtx lab = PATTERN (gen_call_site ());
6605 equiv = operands[1];
6606 operands[1] = gen_rtx_MINUS (DImode,
6610 gen_rtx_MINUS (DImode,
6611 gen_rtx_CONST (DImode,
6614 operands[1] = gen_sym2PIC (operands[1]);
6615 PUT_MODE (operands[1], DImode);
6617 if (GET_MODE (dipic) != DImode)
6618 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6620 if (TARGET_SHMEDIA64)
6621 emit_insn (gen_movdi_const (dipic, operands[1]));
6623 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6625 emit_insn (gen_ptrel (tr, dipic, lab));
6627 if (GET_MODE (operands[0]) != GET_MODE (tr))
6628 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6630 insn = emit_move_insn (operands[0], tr);
6632 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6641 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6642 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6643 UNSPEC_DATALABEL)))]
6644 "TARGET_SHMEDIA && flag_pic
6645 && EXTRA_CONSTRAINT_Csy (operands[1])"
6646 "ptb/u datalabel %1, %0"
6647 [(set_attr "type" "pt_media")
6648 (set_attr "length" "*")])
6650 (define_insn "ptrel"
6651 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6652 (plus:DI (match_operand:DI 1 "register_operand" "r")
6654 (match_operand:DI 2 "" "")]
6656 "%O2: ptrel/u %1, %0"
6657 [(set_attr "type" "ptabs_media")])
6659 (define_expand "builtin_setjmp_receiver"
6660 [(match_operand 0 "" "")]
6664 emit_insn (gen_GOTaddr2picreg ());
6668 (define_expand "call_site"
6669 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6673 static HOST_WIDE_INT i = 0;
6674 operands[0] = GEN_INT (i);
6678 (define_expand "sym_label2reg"
6679 [(set (match_operand:SI 0 "" "")
6682 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6685 (match_operand:SI 2 "" "")
6689 (define_expand "symGOT_load"
6690 [(set (match_dup 2) (match_operand 1 "" ""))
6691 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6692 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6698 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6699 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6703 rtx reg = operands[2];
6705 if (GET_MODE (reg) != DImode)
6706 reg = gen_rtx_SUBREG (DImode, reg, 0);
6709 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6711 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6714 emit_move_insn (operands[2], operands[1]);
6716 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6718 gen_rtx_REG (Pmode, PIC_REG)));
6720 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6722 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6729 (define_expand "sym2GOT"
6730 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6734 (define_expand "symGOT2reg"
6735 [(match_operand 0 "" "") (match_operand 1 "" "")]
6741 gotsym = gen_sym2GOT (operands[1]);
6742 PUT_MODE (gotsym, Pmode);
6743 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6745 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6750 (define_expand "sym2GOTPLT"
6751 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6755 (define_expand "symGOTPLT2reg"
6756 [(match_operand 0 "" "") (match_operand 1 "" "")]
6760 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6764 (define_expand "sym2GOTOFF"
6765 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6769 (define_expand "symGOTOFF2reg"
6770 [(match_operand 0 "" "") (match_operand 1 "" "")]
6774 rtx gotoffsym, insn;
6775 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6777 gotoffsym = gen_sym2GOTOFF (operands[1]);
6778 PUT_MODE (gotoffsym, Pmode);
6779 emit_move_insn (t, gotoffsym);
6780 insn = emit_move_insn (operands[0],
6781 gen_rtx_PLUS (Pmode, t,
6782 gen_rtx_REG (Pmode, PIC_REG)));
6784 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6790 (define_expand "symPLT_label2reg"
6791 [(set (match_operand:SI 0 "" "")
6794 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6798 (match_operand:SI 2 "" "")
6800 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6801 ;; Even though the PIC register is not really used by the call
6802 ;; sequence in which this is expanded, the PLT code assumes the PIC
6803 ;; register is set, so we must not skip its initialization. Since
6804 ;; we only use this expand as part of calling sequences, and never
6805 ;; to take the address of a function, this is the best point to
6806 ;; insert the (use). Using the PLT to take the address of a
6807 ;; function would be wrong, not only because the PLT entry could
6808 ;; then be called from a function that doesn't initialize the PIC
6809 ;; register to the proper GOT, but also because pointers to the
6810 ;; same function might not compare equal, should they be set by
6811 ;; different shared libraries.
6812 (use (reg:SI PIC_REG))]
6816 (define_expand "sym2PIC"
6817 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6821 ;; TLS code generation.
6822 ;; ??? this should be a define_insn_and_split
6823 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6824 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6827 (define_insn "tls_global_dynamic"
6828 [(set (match_operand:SI 0 "register_operand" "=&z")
6829 (unspec:SI [(match_operand:SI 1 "" "")]
6831 (use (reg:PSI FPSCR_REG))
6832 (use (reg:SI PIC_REG))
6833 (clobber (reg:SI PR_REG))
6834 (clobber (scratch:SI))]
6840 \\tmova\\t2f,r0\\n\\
6841 \\tmov.l\\t2f,r1\\n\\
6844 \\tadd\\tr12,r4\\n\\
6848 1:\\t.long\\t%a1@TLSGD\\n\\
6849 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6852 [(set_attr "type" "tls_load")
6853 (set_attr "length" "26")])
6855 (define_insn "tls_local_dynamic"
6856 [(set (match_operand:SI 0 "register_operand" "=&z")
6857 (unspec:SI [(match_operand:SI 1 "" "")]
6859 (use (reg:PSI FPSCR_REG))
6860 (use (reg:SI PIC_REG))
6861 (clobber (reg:SI PR_REG))
6862 (clobber (scratch:SI))]
6868 \\tmova\\t2f,r0\\n\\
6869 \\tmov.l\\t2f,r1\\n\\
6872 \\tadd\\tr12,r4\\n\\
6876 1:\\t.long\\t%a1@TLSLDM\\n\\
6877 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6880 [(set_attr "type" "tls_load")
6881 (set_attr "length" "26")])
6883 (define_expand "sym2DTPOFF"
6884 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6888 (define_expand "symDTPOFF2reg"
6889 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6893 rtx dtpoffsym, insn;
6894 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6896 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6897 PUT_MODE (dtpoffsym, Pmode);
6898 emit_move_insn (t, dtpoffsym);
6899 insn = emit_move_insn (operands[0],
6900 gen_rtx_PLUS (Pmode, t, operands[2]));
6904 (define_expand "sym2GOTTPOFF"
6905 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6909 (define_insn "tls_initial_exec"
6910 [(set (match_operand:SI 0 "register_operand" "=&r")
6911 (unspec:SI [(match_operand:SI 1 "" "")]
6913 (use (reg:SI GBR_REG))
6914 (use (reg:SI PIC_REG))
6915 (clobber (reg:SI R0_REG))]
6921 \\tstc\\tgbr,%0\\n\\
6922 \\tmov.l\\t@(r0,r12),r0\\n\\
6926 1:\\t.long\\t%a1\\n\\
6929 [(set_attr "type" "tls_load")
6930 (set_attr "length" "16")])
6932 (define_expand "sym2TPOFF"
6933 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6937 (define_expand "symTPOFF2reg"
6938 [(match_operand 0 "" "") (match_operand 1 "" "")]
6944 tpoffsym = gen_sym2TPOFF (operands[1]);
6945 PUT_MODE (tpoffsym, Pmode);
6946 insn = emit_move_insn (operands[0], tpoffsym);
6950 (define_insn "load_gbr"
6951 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6952 (use (reg:SI GBR_REG))]
6955 [(set_attr "type" "tls_load")])
6957 ;; case instruction for switch statements.
6959 ;; Operand 0 is index
6960 ;; operand 1 is the minimum bound
6961 ;; operand 2 is the maximum bound - minimum bound + 1
6962 ;; operand 3 is CODE_LABEL for the table;
6963 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6965 (define_expand "casesi"
6966 [(match_operand:SI 0 "arith_reg_operand" "")
6967 (match_operand:SI 1 "arith_reg_operand" "")
6968 (match_operand:SI 2 "arith_reg_operand" "")
6969 (match_operand 3 "" "") (match_operand 4 "" "")]
6973 rtx reg = gen_reg_rtx (SImode);
6974 rtx reg2 = gen_reg_rtx (SImode);
6977 rtx reg = gen_reg_rtx (DImode);
6978 rtx reg2 = gen_reg_rtx (DImode);
6979 rtx reg3 = gen_reg_rtx (DImode);
6980 rtx reg4 = gen_reg_rtx (DImode);
6981 rtx reg5 = gen_reg_rtx (DImode);
6983 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6984 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6985 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6987 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6988 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6989 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6990 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6991 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6992 (DImode, operands[3])));
6993 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6994 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6995 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6999 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7000 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7001 /* If optimizing, casesi_worker depends on the mode of the instruction
7002 before label it 'uses' - operands[3]. */
7003 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7005 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7007 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7009 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7010 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7011 operands[3], but to lab. We will fix this up in
7012 machine_dependent_reorg. */
7017 (define_expand "casesi_0"
7018 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7019 (set (match_dup 4) (minus:SI (match_dup 4)
7020 (match_operand:SI 1 "arith_operand" "")))
7022 (gtu:SI (match_dup 4)
7023 (match_operand:SI 2 "arith_reg_operand" "")))
7025 (if_then_else (ne (reg:SI T_REG)
7027 (label_ref (match_operand 3 "" ""))
7032 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7033 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7034 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7036 (define_insn "casesi_worker_0"
7037 [(set (match_operand:SI 0 "register_operand" "=r,r")
7038 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7039 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7040 (clobber (match_scratch:SI 3 "=X,1"))
7041 (clobber (match_scratch:SI 4 "=&z,z"))]
7046 [(set (match_operand:SI 0 "register_operand" "")
7047 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7048 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7049 (clobber (match_scratch:SI 3 ""))
7050 (clobber (match_scratch:SI 4 ""))]
7051 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7052 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7053 (parallel [(set (match_dup 0)
7054 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7055 (label_ref (match_dup 2))] UNSPEC_CASESI))
7056 (clobber (match_dup 3))])
7057 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7058 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7061 [(set (match_operand:SI 0 "register_operand" "")
7062 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7063 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7064 (clobber (match_scratch:SI 3 ""))
7065 (clobber (match_scratch:SI 4 ""))]
7066 "TARGET_SH2 && reload_completed"
7067 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7068 (parallel [(set (match_dup 0)
7069 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7070 (label_ref (match_dup 2))] UNSPEC_CASESI))
7071 (clobber (match_dup 3))])]
7072 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7074 (define_insn "*casesi_worker"
7075 [(set (match_operand:SI 0 "register_operand" "=r,r")
7076 (unspec:SI [(reg:SI R0_REG)
7077 (match_operand:SI 1 "register_operand" "0,r")
7078 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7079 (clobber (match_scratch:SI 3 "=X,1"))]
7083 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7085 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7088 switch (GET_MODE (diff_vec))
7091 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7093 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7095 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7096 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7097 return \"mov.b @(r0,%1),%0\";
7102 [(set_attr "length" "4")])
7104 (define_insn "casesi_shift_media"
7105 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7106 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7107 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7112 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7114 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7117 switch (GET_MODE (diff_vec))
7120 return \"shlli %1, 2, %0\";
7122 return \"shlli %1, 1, %0\";
7124 if (rtx_equal_p (operands[0], operands[1]))
7126 return \"add %1, r63, %0\";
7131 [(set_attr "type" "arith_media")])
7133 (define_insn "casesi_load_media"
7134 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7135 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7136 (match_operand 2 "arith_reg_operand" "r")
7137 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7141 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7143 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7146 switch (GET_MODE (diff_vec))
7149 return \"ldx.l %1, %2, %0\";
7152 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7153 return \"ldx.uw %1, %2, %0\";
7155 return \"ldx.w %1, %2, %0\";
7157 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7158 return \"ldx.ub %1, %2, %0\";
7159 return \"ldx.b %1, %2, %0\";
7164 [(set_attr "type" "load_media")])
7166 (define_expand "return"
7168 "reload_completed && ! sh_need_epilogue ()"
7173 emit_jump_insn (gen_return_media ());
7177 if (TARGET_SHCOMPACT
7178 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7180 emit_jump_insn (gen_shcompact_return_tramp ());
7185 (define_insn "*return_i"
7187 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7188 && (current_function_args_info.call_cookie
7189 & CALL_COOKIE_RET_TRAMP (1)))
7190 && reload_completed"
7192 [(set_attr "type" "return")
7193 (set_attr "needs_delay_slot" "yes")])
7195 (define_expand "shcompact_return_tramp"
7198 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7201 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7202 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7205 emit_insn (gen_symGOTPLT2reg (reg, sym));
7207 emit_move_insn (reg, sym);
7209 emit_jump_insn (gen_shcompact_return_tramp_i ());
7213 (define_insn "shcompact_return_tramp_i"
7214 [(parallel [(return) (use (reg:SI R0_REG))])]
7216 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7218 [(set_attr "type" "jump_ind")
7219 (set_attr "needs_delay_slot" "yes")])
7221 (define_insn "return_media_i"
7222 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7223 "TARGET_SHMEDIA && reload_completed"
7225 [(set_attr "type" "jump_media")])
7227 (define_insn "return_media_rte"
7229 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7231 [(set_attr "type" "jump_media")])
7233 (define_expand "return_media"
7235 "TARGET_SHMEDIA && reload_completed"
7238 int tr_regno = sh_media_register_for_return ();
7241 if (current_function_interrupt)
7243 emit_jump_insn (gen_return_media_rte ());
7248 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7251 tr = gen_rtx_REG (DImode, tr_regno);
7252 emit_move_insn (tr, r18);
7255 tr = gen_rtx_REG (DImode, tr_regno);
7257 emit_jump_insn (gen_return_media_i (tr));
7261 (define_insn "shcompact_preserve_incoming_args"
7262 [(set (match_operand:SI 0 "register_operand" "+r")
7263 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7266 [(set_attr "length" "0")])
7268 (define_insn "shcompact_incoming_args"
7269 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7270 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7271 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7272 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7273 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7274 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7275 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7276 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7277 (set (mem:BLK (reg:SI MACL_REG))
7278 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7279 (use (reg:SI R0_REG))
7280 (clobber (reg:SI R0_REG))
7281 (clobber (reg:SI MACL_REG))
7282 (clobber (reg:SI MACH_REG))
7283 (clobber (reg:SI PR_REG))]
7286 [(set_attr "needs_delay_slot" "yes")])
7288 (define_insn "shmedia_save_restore_regs_compact"
7289 [(set (reg:SI SP_REG)
7290 (plus:SI (reg:SI SP_REG)
7291 (match_operand:SI 0 "immediate_operand" "i")))
7292 (use (reg:SI R0_REG))
7293 (clobber (reg:SI PR_REG))]
7295 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7296 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7298 [(set_attr "needs_delay_slot" "yes")])
7300 (define_expand "prologue"
7303 "sh_expand_prologue (); DONE;")
7305 (define_expand "epilogue"
7310 sh_expand_epilogue ();
7311 emit_jump_insn (gen_return ());
7315 (define_expand "eh_return"
7316 [(use (match_operand 0 "register_operand" ""))]
7319 rtx tmp, ra = operands[0];
7321 if (TARGET_SHMEDIA64)
7322 emit_insn (gen_eh_set_ra_di (ra));
7324 emit_insn (gen_eh_set_ra_si (ra));
7329 ;; Clobber the return address on the stack. We can't expand this
7330 ;; until we know where it will be put in the stack frame.
7332 (define_insn "eh_set_ra_si"
7333 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7334 (clobber (match_scratch:SI 1 "=&r"))]
7335 "! TARGET_SHMEDIA64"
7338 (define_insn "eh_set_ra_di"
7339 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7340 (clobber (match_scratch:DI 1 "=&r"))]
7345 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7346 (clobber (match_scratch 1 ""))]
7351 sh_set_return_address (operands[0], operands[1]);
7355 (define_insn "blockage"
7356 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7359 [(set_attr "length" "0")])
7361 ;; ------------------------------------------------------------------------
7363 ;; ------------------------------------------------------------------------
7366 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7367 (eq:SI (reg:SI T_REG) (const_int 1)))]
7370 [(set_attr "type" "arith")])
7372 (define_expand "seq"
7373 [(set (match_operand:SI 0 "arith_reg_operand" "")
7380 if (GET_MODE (operands[0]) != DImode)
7381 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7382 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7383 if (sh_compare_op1 != const0_rtx)
7384 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7385 ? GET_MODE (sh_compare_op0)
7386 : GET_MODE (sh_compare_op1),
7389 switch (GET_MODE (sh_compare_op0))
7392 emit_insn (gen_cmpeqdi_media (operands[0],
7393 sh_compare_op0, sh_compare_op1));
7397 if (! TARGET_SHMEDIA_FPU)
7399 emit_insn (gen_cmpeqsf_media (operands[0],
7400 sh_compare_op0, sh_compare_op1));
7404 if (! TARGET_SHMEDIA_FPU)
7406 emit_insn (gen_cmpeqdf_media (operands[0],
7407 sh_compare_op0, sh_compare_op1));
7415 operands[1] = prepare_scc_operands (EQ);
7418 (define_expand "slt"
7419 [(set (match_operand:SI 0 "arith_reg_operand" "")
7426 if (GET_MODE (operands[0]) != DImode)
7427 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7428 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7429 if (sh_compare_op1 != const0_rtx)
7430 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7431 ? GET_MODE (sh_compare_op0)
7432 : GET_MODE (sh_compare_op1),
7435 switch (GET_MODE (sh_compare_op0))
7438 emit_insn (gen_cmpgtdi_media (operands[0],
7439 sh_compare_op1, sh_compare_op0));
7443 if (! TARGET_SHMEDIA_FPU)
7445 emit_insn (gen_cmpgtsf_media (operands[0],
7446 sh_compare_op1, sh_compare_op0));
7450 if (! TARGET_SHMEDIA_FPU)
7452 emit_insn (gen_cmpgtdf_media (operands[0],
7453 sh_compare_op1, sh_compare_op0));
7461 operands[1] = prepare_scc_operands (LT);
7464 (define_expand "sle"
7465 [(match_operand:SI 0 "arith_reg_operand" "")]
7469 rtx tmp = sh_compare_op0;
7473 if (GET_MODE (operands[0]) != DImode)
7474 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7475 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7476 if (sh_compare_op1 != const0_rtx)
7477 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7478 ? GET_MODE (sh_compare_op0)
7479 : GET_MODE (sh_compare_op1),
7482 switch (GET_MODE (sh_compare_op0))
7486 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7488 emit_insn (gen_cmpgtdi_media (tmp,
7489 sh_compare_op0, sh_compare_op1));
7490 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7495 if (! TARGET_SHMEDIA_FPU)
7497 emit_insn (gen_cmpgesf_media (operands[0],
7498 sh_compare_op1, sh_compare_op0));
7502 if (! TARGET_SHMEDIA_FPU)
7504 emit_insn (gen_cmpgedf_media (operands[0],
7505 sh_compare_op1, sh_compare_op0));
7514 sh_compare_op0 = sh_compare_op1;
7515 sh_compare_op1 = tmp;
7516 emit_insn (gen_sge (operands[0]));
7520 (define_expand "sgt"
7521 [(set (match_operand:SI 0 "arith_reg_operand" "")
7528 if (GET_MODE (operands[0]) != DImode)
7529 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7530 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7531 if (sh_compare_op1 != const0_rtx)
7532 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7533 ? GET_MODE (sh_compare_op0)
7534 : GET_MODE (sh_compare_op1),
7537 switch (GET_MODE (sh_compare_op0))
7540 emit_insn (gen_cmpgtdi_media (operands[0],
7541 sh_compare_op0, sh_compare_op1));
7545 if (! TARGET_SHMEDIA_FPU)
7547 emit_insn (gen_cmpgtsf_media (operands[0],
7548 sh_compare_op0, sh_compare_op1));
7552 if (! TARGET_SHMEDIA_FPU)
7554 emit_insn (gen_cmpgtdf_media (operands[0],
7555 sh_compare_op0, sh_compare_op1));
7563 operands[1] = prepare_scc_operands (GT);
7566 (define_expand "sge"
7567 [(set (match_operand:SI 0 "arith_reg_operand" "")
7574 if (GET_MODE (operands[0]) != DImode)
7575 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7576 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7577 if (sh_compare_op1 != const0_rtx)
7578 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7579 ? GET_MODE (sh_compare_op0)
7580 : GET_MODE (sh_compare_op1),
7583 switch (GET_MODE (sh_compare_op0))
7587 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7589 emit_insn (gen_cmpgtdi_media (tmp,
7590 sh_compare_op1, sh_compare_op0));
7591 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7596 if (! TARGET_SHMEDIA_FPU)
7598 emit_insn (gen_cmpgesf_media (operands[0],
7599 sh_compare_op0, sh_compare_op1));
7603 if (! TARGET_SHMEDIA_FPU)
7605 emit_insn (gen_cmpgedf_media (operands[0],
7606 sh_compare_op0, sh_compare_op1));
7615 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7619 rtx lab = gen_label_rtx ();
7620 prepare_scc_operands (EQ);
7621 emit_jump_insn (gen_branch_true (lab));
7622 prepare_scc_operands (GT);
7624 emit_insn (gen_movt (operands[0]));
7627 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7630 operands[1] = prepare_scc_operands (GE);
7633 (define_expand "sgtu"
7634 [(set (match_operand:SI 0 "arith_reg_operand" "")
7641 if (GET_MODE (operands[0]) != DImode)
7642 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7643 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7644 if (sh_compare_op1 != const0_rtx)
7645 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7646 ? GET_MODE (sh_compare_op0)
7647 : GET_MODE (sh_compare_op1),
7650 emit_insn (gen_cmpgtudi_media (operands[0],
7651 sh_compare_op0, sh_compare_op1));
7654 operands[1] = prepare_scc_operands (GTU);
7657 (define_expand "sltu"
7658 [(set (match_operand:SI 0 "arith_reg_operand" "")
7665 if (GET_MODE (operands[0]) != DImode)
7666 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7667 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7668 if (sh_compare_op1 != const0_rtx)
7669 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7670 ? GET_MODE (sh_compare_op0)
7671 : GET_MODE (sh_compare_op1),
7674 emit_insn (gen_cmpgtudi_media (operands[0],
7675 sh_compare_op1, sh_compare_op0));
7678 operands[1] = prepare_scc_operands (LTU);
7681 (define_expand "sleu"
7682 [(set (match_operand:SI 0 "arith_reg_operand" "")
7691 if (GET_MODE (operands[0]) != DImode)
7692 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7693 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7694 if (sh_compare_op1 != const0_rtx)
7695 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7696 ? GET_MODE (sh_compare_op0)
7697 : GET_MODE (sh_compare_op1),
7700 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7702 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7703 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7707 operands[1] = prepare_scc_operands (LEU);
7710 (define_expand "sgeu"
7711 [(set (match_operand:SI 0 "arith_reg_operand" "")
7720 if (GET_MODE (operands[0]) != DImode)
7721 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7722 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7723 if (sh_compare_op1 != const0_rtx)
7724 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7725 ? GET_MODE (sh_compare_op0)
7726 : GET_MODE (sh_compare_op1),
7729 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7731 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7732 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7737 operands[1] = prepare_scc_operands (GEU);
7740 ;; sne moves the complement of the T reg to DEST like this:
7744 ;; This is better than xoring compare result with 1 because it does
7745 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7748 (define_expand "sne"
7749 [(set (match_dup 2) (const_int -1))
7750 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7751 (neg:SI (plus:SI (match_dup 1)
7754 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7763 if (GET_MODE (operands[0]) != DImode)
7764 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7766 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7769 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7770 if (sh_compare_op1 != const0_rtx)
7771 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7772 ? GET_MODE (sh_compare_op0)
7773 : GET_MODE (sh_compare_op1),
7776 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7778 emit_insn (gen_seq (tmp));
7779 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7784 operands[1] = prepare_scc_operands (EQ);
7785 operands[2] = gen_reg_rtx (SImode);
7788 (define_expand "sunordered"
7789 [(set (match_operand:DI 0 "arith_reg_operand" "")
7790 (unordered:DI (match_dup 1) (match_dup 2)))]
7791 "TARGET_SHMEDIA_FPU"
7794 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7795 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7798 ;; Use the same trick for FP sle / sge
7799 (define_expand "movnegt"
7800 [(set (match_dup 2) (const_int -1))
7801 (parallel [(set (match_operand 0 "" "")
7802 (neg:SI (plus:SI (match_dup 1)
7805 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7808 "operands[2] = gen_reg_rtx (SImode);")
7810 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7811 ;; This prevents a regression that occurred when we switched from xor to
7815 [(set (match_operand:SI 0 "arith_reg_operand" "")
7816 (plus:SI (reg:SI T_REG)
7819 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7820 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7823 ;; -------------------------------------------------------------------------
7824 ;; Instructions to cope with inline literal tables
7825 ;; -------------------------------------------------------------------------
7827 ; 2 byte integer in line
7829 (define_insn "consttable_2"
7830 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7831 (match_operand 1 "" "")]
7836 if (operands[1] != const0_rtx)
7837 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7840 [(set_attr "length" "2")
7841 (set_attr "in_delay_slot" "no")])
7843 ; 4 byte integer in line
7845 (define_insn "consttable_4"
7846 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7847 (match_operand 1 "" "")]
7852 if (operands[1] != const0_rtx)
7853 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7856 [(set_attr "length" "4")
7857 (set_attr "in_delay_slot" "no")])
7859 ; 8 byte integer in line
7861 (define_insn "consttable_8"
7862 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7863 (match_operand 1 "" "")]
7868 if (operands[1] != const0_rtx)
7869 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7872 [(set_attr "length" "8")
7873 (set_attr "in_delay_slot" "no")])
7875 ; 4 byte floating point
7877 (define_insn "consttable_sf"
7878 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7879 (match_operand 1 "" "")]
7884 if (operands[1] != const0_rtx)
7887 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7888 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7892 [(set_attr "length" "4")
7893 (set_attr "in_delay_slot" "no")])
7895 ; 8 byte floating point
7897 (define_insn "consttable_df"
7898 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7899 (match_operand 1 "" "")]
7904 if (operands[1] != const0_rtx)
7907 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7908 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7912 [(set_attr "length" "8")
7913 (set_attr "in_delay_slot" "no")])
7915 ;; Alignment is needed for some constant tables; it may also be added for
7916 ;; Instructions at the start of loops, or after unconditional branches.
7917 ;; ??? We would get more accurate lengths if we did instruction
7918 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7919 ;; here is too conservative.
7921 ; align to a two byte boundary
7923 (define_expand "align_2"
7924 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7928 ; align to a four byte boundary
7929 ;; align_4 and align_log are instructions for the starts of loops, or
7930 ;; after unconditional branches, which may take up extra room.
7932 (define_expand "align_4"
7933 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7937 ; align to a cache line boundary
7939 (define_insn "align_log"
7940 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7943 [(set_attr "length" "0")
7944 (set_attr "in_delay_slot" "no")])
7946 ; emitted at the end of the literal table, used to emit the
7947 ; 32bit branch labels if needed.
7949 (define_insn "consttable_end"
7950 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7952 "* return output_jump_label_table ();"
7953 [(set_attr "in_delay_slot" "no")])
7955 ; emitted at the end of the window in the literal table.
7957 (define_insn "consttable_window_end"
7958 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7961 [(set_attr "length" "0")
7962 (set_attr "in_delay_slot" "no")])
7964 ;; -------------------------------------------------------------------------
7966 ;; -------------------------------------------------------------------------
7968 ;; String/block move insn.
7970 (define_expand "movstrsi"
7971 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7972 (mem:BLK (match_operand:BLK 1 "" "")))
7973 (use (match_operand:SI 2 "nonmemory_operand" ""))
7974 (use (match_operand:SI 3 "immediate_operand" ""))
7975 (clobber (reg:SI PR_REG))
7976 (clobber (reg:SI R4_REG))
7977 (clobber (reg:SI R5_REG))
7978 (clobber (reg:SI R0_REG))])]
7979 "TARGET_SH1 && ! TARGET_SH5"
7982 if(expand_block_move (operands))
7987 (define_insn "block_move_real"
7988 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7989 (mem:BLK (reg:SI R5_REG)))
7990 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7991 (clobber (reg:SI PR_REG))
7992 (clobber (reg:SI R0_REG))])]
7993 "TARGET_SH1 && ! TARGET_HARD_SH4"
7995 [(set_attr "type" "sfunc")
7996 (set_attr "needs_delay_slot" "yes")])
7998 (define_insn "block_lump_real"
7999 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8000 (mem:BLK (reg:SI R5_REG)))
8001 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8002 (use (reg:SI R6_REG))
8003 (clobber (reg:SI PR_REG))
8004 (clobber (reg:SI T_REG))
8005 (clobber (reg:SI R4_REG))
8006 (clobber (reg:SI R5_REG))
8007 (clobber (reg:SI R6_REG))
8008 (clobber (reg:SI R0_REG))])]
8009 "TARGET_SH1 && ! TARGET_HARD_SH4"
8011 [(set_attr "type" "sfunc")
8012 (set_attr "needs_delay_slot" "yes")])
8014 (define_insn "block_move_real_i4"
8015 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8016 (mem:BLK (reg:SI R5_REG)))
8017 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8018 (clobber (reg:SI PR_REG))
8019 (clobber (reg:SI R0_REG))
8020 (clobber (reg:SI R1_REG))
8021 (clobber (reg:SI R2_REG))])]
8024 [(set_attr "type" "sfunc")
8025 (set_attr "needs_delay_slot" "yes")])
8027 (define_insn "block_lump_real_i4"
8028 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8029 (mem:BLK (reg:SI R5_REG)))
8030 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8031 (use (reg:SI R6_REG))
8032 (clobber (reg:SI PR_REG))
8033 (clobber (reg:SI T_REG))
8034 (clobber (reg:SI R4_REG))
8035 (clobber (reg:SI R5_REG))
8036 (clobber (reg:SI R6_REG))
8037 (clobber (reg:SI R0_REG))
8038 (clobber (reg:SI R1_REG))
8039 (clobber (reg:SI R2_REG))
8040 (clobber (reg:SI R3_REG))])]
8043 [(set_attr "type" "sfunc")
8044 (set_attr "needs_delay_slot" "yes")])
8046 ;; -------------------------------------------------------------------------
8047 ;; Floating point instructions.
8048 ;; -------------------------------------------------------------------------
8050 ;; ??? All patterns should have a type attribute.
8052 (define_expand "fpu_switch0"
8053 [(set (match_operand:SI 0 "" "") (match_dup 2))
8054 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8058 operands[1] = get_fpscr_rtx ();
8059 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8061 operands[2] = legitimize_pic_address (operands[2], SImode,
8062 no_new_pseudos ? operands[0] : 0);
8065 (define_expand "fpu_switch1"
8066 [(set (match_operand:SI 0 "" "") (match_dup 2))
8067 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8068 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8072 operands[1] = get_fpscr_rtx ();
8073 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8075 operands[2] = legitimize_pic_address (operands[2], SImode,
8076 no_new_pseudos ? operands[0] : 0);
8077 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8080 (define_expand "movpsi"
8081 [(set (match_operand:PSI 0 "register_operand" "")
8082 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8086 ;; The c / m alternative is a fake to guide reload to load directly into
8087 ;; fpscr, since reload doesn't know how to use post-increment.
8088 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8089 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8090 ;; predicate after reload.
8091 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8092 ;; like a mac -> gpr move.
8093 (define_insn "fpu_switch"
8094 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8095 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8097 && (! reload_completed
8098 || true_regnum (operands[0]) != FPSCR_REG
8099 || GET_CODE (operands[1]) != MEM
8100 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8102 ! precision stays the same
8111 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8112 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8115 [(set (reg:PSI FPSCR_REG)
8116 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8117 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8118 [(set (match_dup 0) (match_dup 0))]
8121 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8122 gen_rtx (MEM, PSImode,
8123 gen_rtx (POST_INC, Pmode,
8125 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8129 [(set (reg:PSI FPSCR_REG)
8130 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8132 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8135 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8136 gen_rtx (MEM, PSImode,
8137 gen_rtx (POST_INC, Pmode,
8139 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8142 ;; ??? This uses the fp unit, but has no type indicating that.
8143 ;; If we did that, this would either give a bogus latency or introduce
8144 ;; a bogus FIFO constraint.
8145 ;; Since this insn is currently only used for prologues/epilogues,
8146 ;; it is probably best to claim no function unit, which matches the
8148 (define_insn "toggle_sz"
8149 [(set (reg:PSI FPSCR_REG)
8150 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8154 (define_expand "addsf3"
8155 [(set (match_operand:SF 0 "arith_reg_operand" "")
8156 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8157 (match_operand:SF 2 "arith_reg_operand" "")))]
8158 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8163 expand_sf_binop (&gen_addsf3_i, operands);
8168 (define_insn "*addsf3_media"
8169 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8170 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8171 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8172 "TARGET_SHMEDIA_FPU"
8174 [(set_attr "type" "fparith_media")])
8176 (define_insn_and_split "unary_sf_op"
8177 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8182 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8183 (match_operator:SF 2 "unary_float_operator"
8184 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8185 (parallel [(match_operand 4
8186 "const_int_operand" "n")]))]))
8187 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8188 "TARGET_SHMEDIA_FPU"
8190 "TARGET_SHMEDIA_FPU && reload_completed"
8191 [(set (match_dup 5) (match_dup 6))]
8194 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8195 rtx op1 = gen_rtx_REG (SFmode,
8196 (true_regnum (operands[1])
8197 + (INTVAL (operands[4]) ^ endian)));
8199 operands[7] = gen_rtx_REG (SFmode,
8200 (true_regnum (operands[0])
8201 + (INTVAL (operands[3]) ^ endian)));
8202 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8204 [(set_attr "type" "fparith_media")])
8206 (define_insn_and_split "binary_sf_op"
8207 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8212 (parallel [(match_operand 7 "const_int_operand" "n")]))
8213 (match_operator:SF 3 "binary_float_operator"
8214 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8215 (parallel [(match_operand 5
8216 "const_int_operand" "n")]))
8217 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8218 (parallel [(match_operand 6
8219 "const_int_operand" "n")]))]))
8220 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8221 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8223 "&& reload_completed"
8224 [(set (match_dup 8) (match_dup 9))]
8227 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8228 rtx op1 = gen_rtx_REG (SFmode,
8229 (true_regnum (operands[1])
8230 + (INTVAL (operands[5]) ^ endian)));
8231 rtx op2 = gen_rtx_REG (SFmode,
8232 (true_regnum (operands[2])
8233 + (INTVAL (operands[6]) ^ endian)));
8235 operands[8] = gen_rtx_REG (SFmode,
8236 (true_regnum (operands[0])
8237 + (INTVAL (operands[4]) ^ endian)));
8238 operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8240 [(set_attr "type" "fparith_media")])
8242 (define_insn "addsf3_i"
8243 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8244 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8245 (match_operand:SF 2 "arith_reg_operand" "f")))
8246 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8249 [(set_attr "type" "fp")
8250 (set_attr "fp_mode" "single")])
8252 (define_expand "subsf3"
8253 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8254 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8255 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8256 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8261 expand_sf_binop (&gen_subsf3_i, operands);
8266 (define_insn "*subsf3_media"
8267 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8268 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8269 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8270 "TARGET_SHMEDIA_FPU"
8272 [(set_attr "type" "fparith_media")])
8274 (define_insn "subsf3_i"
8275 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8276 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8277 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8278 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8281 [(set_attr "type" "fp")
8282 (set_attr "fp_mode" "single")])
8284 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8285 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8286 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8287 ;; SH3E, we use a separate insn for SH3E mulsf3.
8289 (define_expand "mulsf3"
8290 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8291 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8292 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8293 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8297 expand_sf_binop (&gen_mulsf3_i4, operands);
8298 else if (TARGET_SH2E)
8299 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8300 if (! TARGET_SHMEDIA)
8304 (define_insn "*mulsf3_media"
8305 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8306 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8307 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8308 "TARGET_SHMEDIA_FPU"
8310 [(set_attr "type" "fparith_media")])
8312 (define_insn "mulsf3_i4"
8313 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8314 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8315 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8316 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8319 [(set_attr "type" "fp")
8320 (set_attr "fp_mode" "single")])
8322 (define_insn "mulsf3_ie"
8323 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8324 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8325 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8326 "TARGET_SH2E && ! TARGET_SH4"
8328 [(set_attr "type" "fp")])
8330 (define_insn "*mac_media"
8331 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8332 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8333 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8334 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8335 "TARGET_SHMEDIA_FPU"
8337 [(set_attr "type" "fparith_media")])
8339 (define_insn "*macsf3"
8340 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8341 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8342 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8343 (match_operand:SF 3 "arith_reg_operand" "0")))
8344 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8345 "TARGET_SH2E && ! TARGET_SH4"
8347 [(set_attr "type" "fp")
8348 (set_attr "fp_mode" "single")])
8350 (define_expand "divsf3"
8351 [(set (match_operand:SF 0 "arith_reg_operand" "")
8352 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8353 (match_operand:SF 2 "arith_reg_operand" "")))]
8354 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8359 expand_sf_binop (&gen_divsf3_i, operands);
8364 (define_insn "*divsf3_media"
8365 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8366 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8367 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8368 "TARGET_SHMEDIA_FPU"
8370 [(set_attr "type" "fdiv_media")])
8372 (define_insn "divsf3_i"
8373 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8374 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8375 (match_operand:SF 2 "arith_reg_operand" "f")))
8376 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8379 [(set_attr "type" "fdiv")
8380 (set_attr "fp_mode" "single")])
8382 (define_insn "floatdisf2"
8383 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8384 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8385 "TARGET_SHMEDIA_FPU"
8387 [(set_attr "type" "fpconv_media")])
8389 (define_expand "floatsisf2"
8390 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8391 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8392 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8397 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8402 (define_insn "*floatsisf2_media"
8403 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8404 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
8407 [(set_attr "type" "fpconv_media")])
8409 (define_insn "floatsisf2_i4"
8410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8411 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8412 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8415 [(set_attr "type" "fp")
8416 (set_attr "fp_mode" "single")])
8418 (define_insn "*floatsisf2_ie"
8419 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8420 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8421 "TARGET_SH2E && ! TARGET_SH4"
8423 [(set_attr "type" "fp")])
8425 (define_insn "fix_truncsfdi2"
8426 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8427 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8428 "TARGET_SHMEDIA_FPU"
8430 [(set_attr "type" "fpconv_media")])
8432 (define_expand "fix_truncsfsi2"
8433 [(set (match_operand:SI 0 "fpul_operand" "=y")
8434 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8435 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8440 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8445 (define_insn "*fix_truncsfsi2_media"
8446 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8447 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8448 "TARGET_SHMEDIA_FPU"
8450 [(set_attr "type" "fpconv_media")])
8452 (define_insn "fix_truncsfsi2_i4"
8453 [(set (match_operand:SI 0 "fpul_operand" "=y")
8454 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8455 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8458 [(set_attr "type" "ftrc_s")
8459 (set_attr "fp_mode" "single")])
8461 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8462 ;; fix_truncsfsi2_i4.
8463 ;; (define_insn "fix_truncsfsi2_i4_2"
8464 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8465 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8466 ;; (use (reg:PSI FPSCR_REG))
8467 ;; (clobber (reg:SI FPUL_REG))]
8470 ;; [(set_attr "length" "4")
8471 ;; (set_attr "fp_mode" "single")])
8474 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8475 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8476 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8477 ;; (clobber (reg:SI FPUL_REG))]
8479 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8480 ;; (use (match_dup 2))])
8481 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8483 (define_insn "*fixsfsi"
8484 [(set (match_operand:SI 0 "fpul_operand" "=y")
8485 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8486 "TARGET_SH2E && ! TARGET_SH4"
8488 [(set_attr "type" "fp")])
8490 (define_insn "cmpgtsf_t"
8491 [(set (reg:SI T_REG)
8492 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8493 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8494 "TARGET_SH2E && ! TARGET_SH4"
8496 [(set_attr "type" "fp")
8497 (set_attr "fp_mode" "single")])
8499 (define_insn "cmpeqsf_t"
8500 [(set (reg:SI T_REG)
8501 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8502 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8503 "TARGET_SH2E && ! TARGET_SH4"
8505 [(set_attr "type" "fp")
8506 (set_attr "fp_mode" "single")])
8508 (define_insn "ieee_ccmpeqsf_t"
8509 [(set (reg:SI T_REG)
8510 (ior:SI (reg:SI T_REG)
8511 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8512 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8513 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8514 "* return output_ieee_ccmpeq (insn, operands);"
8515 [(set_attr "length" "4")])
8518 (define_insn "cmpgtsf_t_i4"
8519 [(set (reg:SI T_REG)
8520 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8521 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8522 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8525 [(set_attr "type" "fp")
8526 (set_attr "fp_mode" "single")])
8528 (define_insn "cmpeqsf_t_i4"
8529 [(set (reg:SI T_REG)
8530 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8531 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8532 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8535 [(set_attr "type" "fp")
8536 (set_attr "fp_mode" "single")])
8538 (define_insn "*ieee_ccmpeqsf_t_4"
8539 [(set (reg:SI T_REG)
8540 (ior:SI (reg:SI T_REG)
8541 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8542 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8543 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8544 "TARGET_IEEE && TARGET_SH4"
8545 "* return output_ieee_ccmpeq (insn, operands);"
8546 [(set_attr "length" "4")
8547 (set_attr "fp_mode" "single")])
8549 (define_insn "cmpeqsf_media"
8550 [(set (match_operand:DI 0 "register_operand" "=r")
8551 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8552 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8553 "TARGET_SHMEDIA_FPU"
8554 "fcmpeq.s %1, %2, %0"
8555 [(set_attr "type" "fcmp_media")])
8557 (define_insn "cmpgtsf_media"
8558 [(set (match_operand:DI 0 "register_operand" "=r")
8559 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8560 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8561 "TARGET_SHMEDIA_FPU"
8562 "fcmpgt.s %1, %2, %0"
8563 [(set_attr "type" "fcmp_media")])
8565 (define_insn "cmpgesf_media"
8566 [(set (match_operand:DI 0 "register_operand" "=r")
8567 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8568 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8569 "TARGET_SHMEDIA_FPU"
8570 "fcmpge.s %1, %2, %0"
8571 [(set_attr "type" "fcmp_media")])
8573 (define_insn "cmpunsf_media"
8574 [(set (match_operand:DI 0 "register_operand" "=r")
8575 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8576 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8577 "TARGET_SHMEDIA_FPU"
8578 "fcmpun.s %1, %2, %0"
8579 [(set_attr "type" "fcmp_media")])
8581 (define_expand "cmpsf"
8582 [(set (reg:SI T_REG)
8583 (compare (match_operand:SF 0 "arith_operand" "")
8584 (match_operand:SF 1 "arith_operand" "")))]
8585 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8588 sh_compare_op0 = operands[0];
8589 sh_compare_op1 = operands[1];
8593 (define_expand "negsf2"
8594 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8595 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8596 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8601 expand_sf_unop (&gen_negsf2_i, operands);
8606 (define_insn "*negsf2_media"
8607 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8608 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8609 "TARGET_SHMEDIA_FPU"
8611 [(set_attr "type" "fmove_media")])
8613 (define_insn "negsf2_i"
8614 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8615 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8616 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8619 [(set_attr "type" "fmove")
8620 (set_attr "fp_mode" "single")])
8622 (define_expand "sqrtsf2"
8623 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8624 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8625 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8630 expand_sf_unop (&gen_sqrtsf2_i, operands);
8635 (define_insn "*sqrtsf2_media"
8636 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8637 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8638 "TARGET_SHMEDIA_FPU"
8640 [(set_attr "type" "fdiv_media")])
8642 (define_insn "sqrtsf2_i"
8643 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8644 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8645 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8648 [(set_attr "type" "fdiv")
8649 (set_attr "fp_mode" "single")])
8651 (define_expand "abssf2"
8652 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8653 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8654 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8659 expand_sf_unop (&gen_abssf2_i, operands);
8664 (define_insn "*abssf2_media"
8665 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8666 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8667 "TARGET_SHMEDIA_FPU"
8669 [(set_attr "type" "fmove_media")])
8671 (define_insn "abssf2_i"
8672 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8673 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8674 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8677 [(set_attr "type" "fmove")
8678 (set_attr "fp_mode" "single")])
8680 (define_expand "adddf3"
8681 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8682 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8683 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8684 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8689 expand_df_binop (&gen_adddf3_i, operands);
8694 (define_insn "*adddf3_media"
8695 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8696 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8697 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8698 "TARGET_SHMEDIA_FPU"
8700 [(set_attr "type" "dfparith_media")])
8702 (define_insn "adddf3_i"
8703 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8704 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8705 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8706 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8709 [(set_attr "type" "dfp_arith")
8710 (set_attr "fp_mode" "double")])
8712 (define_expand "subdf3"
8713 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8714 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8715 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8716 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8721 expand_df_binop (&gen_subdf3_i, operands);
8726 (define_insn "*subdf3_media"
8727 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8728 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8729 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8730 "TARGET_SHMEDIA_FPU"
8732 [(set_attr "type" "dfparith_media")])
8734 (define_insn "subdf3_i"
8735 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8736 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8737 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8738 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8741 [(set_attr "type" "dfp_arith")
8742 (set_attr "fp_mode" "double")])
8744 (define_expand "muldf3"
8745 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8746 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8747 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8748 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8753 expand_df_binop (&gen_muldf3_i, operands);
8758 (define_insn "*muldf3_media"
8759 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8760 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8761 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8762 "TARGET_SHMEDIA_FPU"
8764 [(set_attr "type" "dfmul_media")])
8766 (define_insn "muldf3_i"
8767 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8768 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8769 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8770 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8773 [(set_attr "type" "dfp_arith")
8774 (set_attr "fp_mode" "double")])
8776 (define_expand "divdf3"
8777 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8778 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8779 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8780 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8785 expand_df_binop (&gen_divdf3_i, operands);
8790 (define_insn "*divdf3_media"
8791 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8792 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8793 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8794 "TARGET_SHMEDIA_FPU"
8796 [(set_attr "type" "dfdiv_media")])
8798 (define_insn "divdf3_i"
8799 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8800 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8801 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8802 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8805 [(set_attr "type" "dfdiv")
8806 (set_attr "fp_mode" "double")])
8808 (define_insn "floatdidf2"
8809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8810 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8811 "TARGET_SHMEDIA_FPU"
8813 [(set_attr "type" "dfpconv_media")])
8815 (define_expand "floatsidf2"
8816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8817 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8818 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8823 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8829 (define_insn "*floatsidf2_media"
8830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8832 "TARGET_SHMEDIA_FPU"
8834 [(set_attr "type" "dfpconv_media")])
8836 (define_insn "floatsidf2_i"
8837 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8838 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8839 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8842 [(set_attr "type" "dfp_conv")
8843 (set_attr "fp_mode" "double")])
8845 (define_insn "fix_truncdfdi2"
8846 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8847 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8848 "TARGET_SHMEDIA_FPU"
8850 [(set_attr "type" "dfpconv_media")])
8852 (define_expand "fix_truncdfsi2"
8853 [(set (match_operand:SI 0 "fpul_operand" "")
8854 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8855 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8860 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8866 (define_insn "*fix_truncdfsi2_media"
8867 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8868 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8869 "TARGET_SHMEDIA_FPU"
8871 [(set_attr "type" "dfpconv_media")])
8873 (define_insn "fix_truncdfsi2_i"
8874 [(set (match_operand:SI 0 "fpul_operand" "=y")
8875 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8876 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8879 [(set_attr "type" "dfp_conv")
8880 (set_attr "dfp_comp" "no")
8881 (set_attr "fp_mode" "double")])
8883 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8884 ;; fix_truncdfsi2_i.
8885 ;; (define_insn "fix_truncdfsi2_i4"
8886 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8887 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8888 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8889 ;; (clobber (reg:SI FPUL_REG))]
8892 ;; [(set_attr "length" "4")
8893 ;; (set_attr "fp_mode" "double")])
8896 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8897 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8898 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8899 ;; (clobber (reg:SI FPUL_REG))]
8901 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8902 ;; (use (match_dup 2))])
8903 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8905 (define_insn "cmpgtdf_t"
8906 [(set (reg:SI T_REG)
8907 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8908 (match_operand:DF 1 "arith_reg_operand" "f")))
8909 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8912 [(set_attr "type" "dfp_cmp")
8913 (set_attr "fp_mode" "double")])
8915 (define_insn "cmpeqdf_t"
8916 [(set (reg:SI T_REG)
8917 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8918 (match_operand:DF 1 "arith_reg_operand" "f")))
8919 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8922 [(set_attr "type" "dfp_cmp")
8923 (set_attr "fp_mode" "double")])
8925 (define_insn "*ieee_ccmpeqdf_t"
8926 [(set (reg:SI T_REG)
8927 (ior:SI (reg:SI T_REG)
8928 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8929 (match_operand:DF 1 "arith_reg_operand" "f"))))
8930 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8931 "TARGET_IEEE && TARGET_SH4"
8932 "* return output_ieee_ccmpeq (insn, operands);"
8933 [(set_attr "length" "4")
8934 (set_attr "fp_mode" "double")])
8936 (define_insn "cmpeqdf_media"
8937 [(set (match_operand:DI 0 "register_operand" "=r")
8938 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8939 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8940 "TARGET_SHMEDIA_FPU"
8942 [(set_attr "type" "fcmp_media")])
8944 (define_insn "cmpgtdf_media"
8945 [(set (match_operand:DI 0 "register_operand" "=r")
8946 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8947 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8948 "TARGET_SHMEDIA_FPU"
8950 [(set_attr "type" "fcmp_media")])
8952 (define_insn "cmpgedf_media"
8953 [(set (match_operand:DI 0 "register_operand" "=r")
8954 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8955 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8956 "TARGET_SHMEDIA_FPU"
8958 [(set_attr "type" "fcmp_media")])
8960 (define_insn "cmpundf_media"
8961 [(set (match_operand:DI 0 "register_operand" "=r")
8962 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8963 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8964 "TARGET_SHMEDIA_FPU"
8966 [(set_attr "type" "fcmp_media")])
8968 (define_expand "cmpdf"
8969 [(set (reg:SI T_REG)
8970 (compare (match_operand:DF 0 "arith_operand" "")
8971 (match_operand:DF 1 "arith_operand" "")))]
8972 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8975 sh_compare_op0 = operands[0];
8976 sh_compare_op1 = operands[1];
8980 (define_expand "negdf2"
8981 [(set (match_operand:DF 0 "arith_reg_operand" "")
8982 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8983 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8988 expand_df_unop (&gen_negdf2_i, operands);
8993 (define_insn "*negdf2_media"
8994 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8995 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8996 "TARGET_SHMEDIA_FPU"
8998 [(set_attr "type" "fmove_media")])
9000 (define_insn "negdf2_i"
9001 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9002 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9003 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9006 [(set_attr "type" "fmove")
9007 (set_attr "fp_mode" "double")])
9009 (define_expand "sqrtdf2"
9010 [(set (match_operand:DF 0 "arith_reg_operand" "")
9011 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9012 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9017 expand_df_unop (&gen_sqrtdf2_i, operands);
9022 (define_insn "*sqrtdf2_media"
9023 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9024 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9025 "TARGET_SHMEDIA_FPU"
9027 [(set_attr "type" "dfdiv_media")])
9029 (define_insn "sqrtdf2_i"
9030 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9031 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9032 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9035 [(set_attr "type" "dfdiv")
9036 (set_attr "fp_mode" "double")])
9038 (define_expand "absdf2"
9039 [(set (match_operand:DF 0 "arith_reg_operand" "")
9040 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9041 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9046 expand_df_unop (&gen_absdf2_i, operands);
9051 (define_insn "*absdf2_media"
9052 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9053 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9054 "TARGET_SHMEDIA_FPU"
9056 [(set_attr "type" "fmove_media")])
9058 (define_insn "absdf2_i"
9059 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9060 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9061 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9064 [(set_attr "type" "fmove")
9065 (set_attr "fp_mode" "double")])
9067 (define_expand "extendsfdf2"
9068 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9069 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9070 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9075 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9081 (define_insn "*extendsfdf2_media"
9082 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9083 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9084 "TARGET_SHMEDIA_FPU"
9086 [(set_attr "type" "dfpconv_media")])
9088 (define_insn "extendsfdf2_i4"
9089 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9090 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9091 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9094 [(set_attr "type" "fp")
9095 (set_attr "fp_mode" "double")])
9097 (define_expand "truncdfsf2"
9098 [(set (match_operand:SF 0 "fpul_operand" "")
9099 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9100 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9105 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9111 (define_insn "*truncdfsf2_media"
9112 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9113 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9114 "TARGET_SHMEDIA_FPU"
9116 [(set_attr "type" "dfpconv_media")])
9118 (define_insn "truncdfsf2_i4"
9119 [(set (match_operand:SF 0 "fpul_operand" "=y")
9120 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9121 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9124 [(set_attr "type" "fp")
9125 (set_attr "fp_mode" "double")])
9127 ;; Bit field extract patterns. These give better code for packed bitfields,
9128 ;; because they allow auto-increment addresses to be generated.
9130 (define_expand "insv"
9131 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9132 (match_operand:SI 1 "immediate_operand" "")
9133 (match_operand:SI 2 "immediate_operand" ""))
9134 (match_operand:SI 3 "general_operand" ""))]
9135 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9138 rtx addr_target, orig_address, shift_reg, qi_val;
9139 HOST_WIDE_INT bitsize, size, v;
9140 rtx x = operands[3];
9142 /* ??? expmed doesn't care for non-register predicates. */
9143 if (! memory_operand (operands[0], VOIDmode)
9144 || ! immediate_operand (operands[1], VOIDmode)
9145 || ! immediate_operand (operands[2], VOIDmode)
9146 || ! general_operand (x, VOIDmode))
9148 /* If this isn't a 16 / 24 / 32 bit field, or if
9149 it doesn't start on a byte boundary, then fail. */
9150 bitsize = INTVAL (operands[1]);
9151 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9152 || (INTVAL (operands[2]) % 8) != 0)
9156 orig_address = XEXP (operands[0], 0);
9157 shift_reg = gen_reg_rtx (SImode);
9158 if (GET_CODE (x) == CONST_INT)
9161 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9165 emit_insn (gen_movsi (shift_reg, operands[3]));
9166 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9168 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9170 operands[0] = replace_equiv_address (operands[0], addr_target);
9171 emit_insn (gen_movqi (operands[0], qi_val));
9175 if (GET_CODE (x) == CONST_INT)
9177 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9180 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9181 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9183 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9184 emit_insn (gen_movqi (operands[0], qi_val));
9190 ;; -------------------------------------------------------------------------
9192 ;; -------------------------------------------------------------------------
9194 ;; This matches cases where a stack pointer increment at the start of the
9195 ;; epilogue combines with a stack slot read loading the return value.
9198 [(set (match_operand:SI 0 "arith_reg_operand" "")
9199 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9200 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9201 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9204 ;; See the comment on the dt combiner pattern above.
9207 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9208 (plus:SI (match_dup 0)
9211 (eq:SI (match_dup 0)
9216 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9217 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9218 ;; reload when the constant is too large for a reg+offset address.
9220 ;; ??? We would get much better code if this was done in reload. This would
9221 ;; require modifying find_reloads_address to recognize that if the constant
9222 ;; is out-of-range for an immediate add, then we get better code by reloading
9223 ;; the constant into a register than by reloading the sum into a register,
9224 ;; since the former is one instruction shorter if the address does not need
9225 ;; to be offsettable. Unfortunately this does not work, because there is
9226 ;; only one register, r0, that can be used as an index register. This register
9227 ;; is also the function return value register. So, if we try to force reload
9228 ;; to use double-reg addresses, then we end up with some instructions that
9229 ;; need to use r0 twice. The only way to fix this is to change the calling
9230 ;; convention so that r0 is not used to return values.
9233 [(set (match_operand:SI 0 "register_operand" "=r")
9234 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9235 (set (mem:SI (match_dup 0))
9236 (match_operand:SI 2 "general_movsrc_operand" ""))]
9237 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9238 "mov.l %2,@(%0,%1)")
9241 [(set (match_operand:SI 0 "register_operand" "=r")
9242 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9243 (set (match_operand:SI 2 "general_movdst_operand" "")
9244 (mem:SI (match_dup 0)))]
9245 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9246 "mov.l @(%0,%1),%2")
9249 [(set (match_operand:SI 0 "register_operand" "=r")
9250 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9251 (set (mem:HI (match_dup 0))
9252 (match_operand:HI 2 "general_movsrc_operand" ""))]
9253 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9254 "mov.w %2,@(%0,%1)")
9257 [(set (match_operand:SI 0 "register_operand" "=r")
9258 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9259 (set (match_operand:HI 2 "general_movdst_operand" "")
9260 (mem:HI (match_dup 0)))]
9261 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9262 "mov.w @(%0,%1),%2")
9265 [(set (match_operand:SI 0 "register_operand" "=r")
9266 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9267 (set (mem:QI (match_dup 0))
9268 (match_operand:QI 2 "general_movsrc_operand" ""))]
9269 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9270 "mov.b %2,@(%0,%1)")
9273 [(set (match_operand:SI 0 "register_operand" "=r")
9274 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9275 (set (match_operand:QI 2 "general_movdst_operand" "")
9276 (mem:QI (match_dup 0)))]
9277 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9278 "mov.b @(%0,%1),%2")
9281 [(set (match_operand:SI 0 "register_operand" "=r")
9282 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9283 (set (mem:SF (match_dup 0))
9284 (match_operand:SF 2 "general_movsrc_operand" ""))]
9285 "TARGET_SH1 && REGNO (operands[0]) == 0
9286 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9287 || (GET_CODE (operands[2]) == SUBREG
9288 && REGNO (SUBREG_REG (operands[2])) < 16))
9289 && reg_unused_after (operands[0], insn)"
9290 "mov.l %2,@(%0,%1)")
9293 [(set (match_operand:SI 0 "register_operand" "=r")
9294 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9295 (set (match_operand:SF 2 "general_movdst_operand" "")
9297 (mem:SF (match_dup 0)))]
9298 "TARGET_SH1 && REGNO (operands[0]) == 0
9299 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9300 || (GET_CODE (operands[2]) == SUBREG
9301 && REGNO (SUBREG_REG (operands[2])) < 16))
9302 && reg_unused_after (operands[0], insn)"
9303 "mov.l @(%0,%1),%2")
9306 [(set (match_operand:SI 0 "register_operand" "=r")
9307 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9308 (set (mem:SF (match_dup 0))
9309 (match_operand:SF 2 "general_movsrc_operand" ""))]
9310 "TARGET_SH2E && REGNO (operands[0]) == 0
9311 && ((GET_CODE (operands[2]) == REG
9312 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9313 || (GET_CODE (operands[2]) == SUBREG
9314 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9315 && reg_unused_after (operands[0], insn)"
9316 "fmov{.s|} %2,@(%0,%1)")
9319 [(set (match_operand:SI 0 "register_operand" "=r")
9320 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9321 (set (match_operand:SF 2 "general_movdst_operand" "")
9323 (mem:SF (match_dup 0)))]
9324 "TARGET_SH2E && REGNO (operands[0]) == 0
9325 && ((GET_CODE (operands[2]) == REG
9326 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9327 || (GET_CODE (operands[2]) == SUBREG
9328 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9329 && reg_unused_after (operands[0], insn)"
9330 "fmov{.s|} @(%0,%1),%2")
9332 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9333 (define_insn "sp_switch_1"
9340 xoperands[0] = sp_switch;
9341 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9342 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9343 return \"mov r0,r15\";
9345 [(set_attr "length" "10")])
9347 ;; Switch back to the original stack for interrupt functions with the
9348 ;; sp_switch attribute. */
9349 (define_insn "sp_switch_2"
9352 "mov.l @r15+,r15\;mov.l @r15+,r0"
9353 [(set_attr "length" "4")])
9355 ;; Integer vector moves
9357 (define_expand "movv8qi"
9358 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9359 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9361 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9363 (define_insn "movv8qi_i"
9364 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9365 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9367 && (register_operand (operands[0], V8QImode)
9368 || sh_register_operand (operands[1], V8QImode))"
9375 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9376 (set_attr "length" "4,4,16,4,4")])
9379 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9380 (subreg:V8QI (const_int 0) 0))]
9383 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9384 (const_int 0) (const_int 0) (const_int 0)
9385 (const_int 0) (const_int 0)]))])
9388 [(set (match_operand 0 "arith_reg_dest" "")
9389 (match_operand 1 "sh_rep_vec" ""))]
9390 "TARGET_SHMEDIA && reload_completed
9391 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9392 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9393 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9394 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9395 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9396 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9397 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9398 [(set (match_dup 0) (match_dup 1))
9402 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9403 rtx elt1 = XVECEXP (operands[1], 0, 1);
9406 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9410 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9411 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9413 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9414 operands[1] = XVECEXP (operands[1], 0, 0);
9417 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9418 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9419 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9420 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9423 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9425 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9431 [(set (match_operand 0 "arith_reg_dest" "")
9432 (match_operand 1 "sh_const_vec" ""))]
9433 "TARGET_SHMEDIA && reload_completed
9434 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9435 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9436 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9437 [(set (match_dup 0) (match_dup 1))]
9440 rtx v = operands[1];
9441 enum machine_mode new_mode
9442 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9444 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9446 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9449 (define_expand "movv2hi"
9450 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9451 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9453 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9455 (define_insn "movv2hi_i"
9456 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9457 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9459 && (register_operand (operands[0], V2HImode)
9460 || sh_register_operand (operands[1], V2HImode))"
9467 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9468 (set_attr "length" "4,4,16,4,4")])
9470 (define_expand "movv4hi"
9471 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9472 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9474 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9476 (define_insn "movv4hi_i"
9477 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9478 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9480 && (register_operand (operands[0], V4HImode)
9481 || sh_register_operand (operands[1], V4HImode))"
9488 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9489 (set_attr "length" "4,4,16,4,4")])
9491 (define_expand "movv2si"
9492 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9493 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9495 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9497 (define_insn "movv2si_i"
9498 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9499 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9501 && (register_operand (operands[0], V2SImode)
9502 || sh_register_operand (operands[1], V2SImode))"
9509 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9510 (set_attr "length" "4,4,16,4,4")])
9512 ;; Multimedia Intrinsics
9514 (define_insn "absv2si2"
9515 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9516 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9519 [(set_attr "type" "mcmp_media")])
9521 (define_insn "absv4hi2"
9522 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9523 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9526 [(set_attr "type" "mcmp_media")])
9528 (define_insn "addv2si3"
9529 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9530 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9531 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9534 [(set_attr "type" "arith_media")])
9536 (define_insn "addv4hi3"
9537 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9538 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9539 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9542 [(set_attr "type" "arith_media")])
9544 (define_insn "ssaddv2si3"
9545 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9546 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9547 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9549 "madds.l %1, %2, %0"
9550 [(set_attr "type" "mcmp_media")])
9552 (define_insn "usaddv8qi3"
9553 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9554 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9555 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9557 "madds.ub %1, %2, %0"
9558 [(set_attr "type" "mcmp_media")])
9560 (define_insn "ssaddv4hi3"
9561 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9562 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9563 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9565 "madds.w %1, %2, %0"
9566 [(set_attr "type" "mcmp_media")])
9568 (define_insn "negcmpeqv8qi"
9569 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9570 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9571 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9573 "mcmpeq.b %N1, %N2, %0"
9574 [(set_attr "type" "mcmp_media")])
9576 (define_insn "negcmpeqv2si"
9577 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9578 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9579 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9581 "mcmpeq.l %N1, %N2, %0"
9582 [(set_attr "type" "mcmp_media")])
9584 (define_insn "negcmpeqv4hi"
9585 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9586 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9587 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9589 "mcmpeq.w %N1, %N2, %0"
9590 [(set_attr "type" "mcmp_media")])
9592 (define_insn "negcmpgtuv8qi"
9593 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9594 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9595 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9597 "mcmpgt.ub %N1, %N2, %0"
9598 [(set_attr "type" "mcmp_media")])
9600 (define_insn "negcmpgtv2si"
9601 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9602 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9603 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9605 "mcmpgt.l %N1, %N2, %0"
9606 [(set_attr "type" "mcmp_media")])
9608 (define_insn "negcmpgtv4hi"
9609 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9610 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9611 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9613 "mcmpgt.w %N1, %N2, %0"
9614 [(set_attr "type" "mcmp_media")])
9617 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9618 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9619 (match_operand:DI 2 "arith_reg_operand" "r"))
9620 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9621 (not:DI (match_dup 2)))))]
9624 [(set_attr "type" "arith_media")])
9626 (define_insn "mcnvs_lw"
9627 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9629 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9630 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9632 "mcnvs.lw %N1, %N2, %0"
9633 [(set_attr "type" "mcmp_media")])
9635 (define_insn "mcnvs_wb"
9636 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9638 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9639 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9641 "mcnvs.wb %N1, %N2, %0"
9642 [(set_attr "type" "mcmp_media")])
9644 (define_insn "mcnvs_wub"
9645 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9647 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9648 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9650 "mcnvs.wub %N1, %N2, %0"
9651 [(set_attr "type" "mcmp_media")])
9653 (define_insn "mextr_rl"
9654 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9655 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9656 (match_operand:HI 3 "mextr_bit_offset" "i"))
9657 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9658 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9659 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9662 static char templ[16];
9664 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9665 (int) INTVAL (operands[3]) >> 3);
9668 [(set_attr "type" "arith_media")])
9670 (define_insn "*mextr_lr"
9671 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9672 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9673 (match_operand:HI 3 "mextr_bit_offset" "i"))
9674 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9675 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9676 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9679 static char templ[16];
9681 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9682 (int) INTVAL (operands[4]) >> 3);
9685 [(set_attr "type" "arith_media")])
9687 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9688 ; vector then varies depending on endianness.
9689 (define_expand "mextr1"
9690 [(match_operand:DI 0 "arith_reg_dest" "")
9691 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9692 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9696 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9697 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9701 (define_expand "mextr2"
9702 [(match_operand:DI 0 "arith_reg_dest" "")
9703 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9704 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9708 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9709 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9713 (define_expand "mextr3"
9714 [(match_operand:DI 0 "arith_reg_dest" "")
9715 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9716 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9720 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9721 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9725 (define_expand "mextr4"
9726 [(match_operand:DI 0 "arith_reg_dest" "")
9727 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9728 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9732 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9733 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9737 (define_expand "mextr5"
9738 [(match_operand:DI 0 "arith_reg_dest" "")
9739 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9740 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9744 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9745 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9749 (define_expand "mextr6"
9750 [(match_operand:DI 0 "arith_reg_dest" "")
9751 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9752 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9756 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9757 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9761 (define_expand "mextr7"
9762 [(match_operand:DI 0 "arith_reg_dest" "")
9763 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9764 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9768 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9769 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9773 (define_expand "mmacfx_wl"
9774 [(match_operand:V2SI 0 "arith_reg_dest" "")
9775 (match_operand:V2HI 1 "extend_reg_operand" "")
9776 (match_operand:V2HI 2 "extend_reg_operand" "")
9777 (match_operand:V2SI 3 "arith_reg_operand" "")]
9781 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9782 operands[1], operands[2]));
9786 (define_insn "mmacfx_wl_i"
9787 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9789 (match_operand:V2SI 1 "arith_reg_operand" "0")
9794 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9795 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9798 "mmacfx.wl %2, %3, %0"
9799 [(set_attr "type" "mac_media")])
9801 (define_expand "mmacnfx_wl"
9802 [(match_operand:V2SI 0 "arith_reg_dest" "")
9803 (match_operand:V2HI 1 "extend_reg_operand" "")
9804 (match_operand:V2HI 2 "extend_reg_operand" "")
9805 (match_operand:V2SI 3 "arith_reg_operand" "")]
9809 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9810 operands[1], operands[2]));
9814 (define_insn "mmacnfx_wl_i"
9815 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9817 (match_operand:V2SI 1 "arith_reg_operand" "0")
9822 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9823 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9826 "mmacnfx.wl %2, %3, %0"
9827 [(set_attr "type" "mac_media")])
9829 (define_insn "mulv2si3"
9830 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9831 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9832 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9835 [(set_attr "type" "d2mpy_media")])
9837 (define_insn "mulv4hi3"
9838 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9839 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9840 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9843 [(set_attr "type" "dmpy_media")])
9845 (define_insn "mmulfx_l"
9846 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9850 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9851 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9854 "mmulfx.l %1, %2, %0"
9855 [(set_attr "type" "d2mpy_media")])
9857 (define_insn "mmulfx_w"
9858 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9862 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9863 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9866 "mmulfx.w %1, %2, %0"
9867 [(set_attr "type" "dmpy_media")])
9869 (define_insn "mmulfxrp_w"
9870 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9875 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9876 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9880 "mmulfxrp.w %1, %2, %0"
9881 [(set_attr "type" "dmpy_media")])
9883 (define_expand "mmulhi_wl"
9884 [(match_operand:V2SI 0 "arith_reg_dest" "")
9885 (match_operand:V4HI 1 "arith_reg_operand" "")
9886 (match_operand:V4HI 2 "arith_reg_operand" "")]
9890 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9891 (operands[0], operands[1], operands[2]));
9895 (define_expand "mmullo_wl"
9896 [(match_operand:V2SI 0 "arith_reg_dest" "")
9897 (match_operand:V4HI 1 "arith_reg_operand" "")
9898 (match_operand:V4HI 2 "arith_reg_operand" "")]
9902 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9903 (operands[0], operands[1], operands[2]));
9907 (define_insn "mmul23_wl"
9908 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9911 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9912 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9913 (parallel [(const_int 2) (const_int 3)])))]
9915 "* return (TARGET_LITTLE_ENDIAN
9916 ? \"mmulhi.wl %1, %2, %0\"
9917 : \"mmullo.wl %1, %2, %0\");"
9918 [(set_attr "type" "dmpy_media")])
9920 (define_insn "mmul01_wl"
9921 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9924 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9925 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9926 (parallel [(const_int 0) (const_int 1)])))]
9928 "* return (TARGET_LITTLE_ENDIAN
9929 ? \"mmullo.wl %1, %2, %0\"
9930 : \"mmulhi.wl %1, %2, %0\");"
9931 [(set_attr "type" "dmpy_media")])
9933 (define_expand "mmulsum_wq"
9934 [(match_operand:DI 0 "arith_reg_dest" "")
9935 (match_operand:V4HI 1 "arith_reg_operand" "")
9936 (match_operand:V4HI 2 "arith_reg_operand" "")
9937 (match_operand:DI 3 "arith_reg_operand" "")]
9941 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9942 operands[1], operands[2]));
9946 (define_insn "mmulsum_wq_i"
9947 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9948 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9953 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9954 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9955 (parallel [(const_int 0)]))
9956 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9957 (sign_extend:V4DI (match_dup 3)))
9958 (parallel [(const_int 1)])))
9960 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9961 (sign_extend:V4DI (match_dup 3)))
9962 (parallel [(const_int 2)]))
9963 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9964 (sign_extend:V4DI (match_dup 3)))
9965 (parallel [(const_int 3)]))))))]
9967 "mmulsum.wq %2, %3, %0"
9968 [(set_attr "type" "mac_media")])
9970 (define_expand "mperm_w"
9971 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9972 (match_operand:V4HI 1 "arith_reg_operand" "r")
9973 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
9977 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9978 (operands[0], operands[1], operands[2]));
9982 ; This use of vec_select isn't exactly correct according to rtl.texi
9983 ; (because not constant), but it seems a straightforward extension.
9984 (define_insn "mperm_w_little"
9985 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9987 (match_operand:V4HI 1 "arith_reg_operand" "r")
9989 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
9990 (const_int 2) (const_int 0))
9991 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9992 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9993 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9994 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9995 "mperm.w %1, %N2, %0"
9996 [(set_attr "type" "arith_media")])
9998 (define_insn "mperm_w_big"
9999 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10001 (match_operand:V4HI 1 "arith_reg_operand" "r")
10003 [(zero_extract:QI (not:QI (match_operand:QI 2
10004 "extend_reg_or_0_operand" "rZ"))
10005 (const_int 2) (const_int 0))
10006 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10007 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10008 (zero_extract:QI (not:QI (match_dup 2))
10009 (const_int 2) (const_int 6))])))]
10010 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10011 "mperm.w %1, %N2, %0"
10012 [(set_attr "type" "arith_media")])
10014 (define_insn "mperm_w0"
10015 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10016 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10017 "trunc_hi_operand" "r"))))]
10019 "mperm.w %1, r63, %0"
10020 [(set_attr "type" "arith_media")])
10022 (define_expand "msad_ubq"
10023 [(match_operand:DI 0 "arith_reg_dest" "")
10024 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10025 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10026 (match_operand:DI 3 "arith_reg_operand" "")]
10030 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10031 operands[1], operands[2]));
10035 (define_insn "msad_ubq_i"
10036 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10041 (match_operand:DI 1 "arith_reg_operand" "0")
10042 (abs:DI (vec_select:DI
10045 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10047 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10048 (parallel [(const_int 0)]))))
10049 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10050 (zero_extend:V8DI (match_dup 3)))
10051 (parallel [(const_int 1)]))))
10053 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10054 (zero_extend:V8DI (match_dup 3)))
10055 (parallel [(const_int 2)])))
10056 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10057 (zero_extend:V8DI (match_dup 3)))
10058 (parallel [(const_int 3)])))))
10061 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10062 (zero_extend:V8DI (match_dup 3)))
10063 (parallel [(const_int 4)])))
10064 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10065 (zero_extend:V8DI (match_dup 3)))
10066 (parallel [(const_int 5)]))))
10068 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10069 (zero_extend:V8DI (match_dup 3)))
10070 (parallel [(const_int 6)])))
10071 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10072 (zero_extend:V8DI (match_dup 3)))
10073 (parallel [(const_int 7)])))))))]
10075 "msad.ubq %N2, %N3, %0"
10076 [(set_attr "type" "mac_media")])
10078 (define_insn "mshalds_l"
10079 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10082 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10083 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10084 (const_int 31)))))]
10086 "mshalds.l %1, %2, %0"
10087 [(set_attr "type" "mcmp_media")])
10089 (define_insn "mshalds_w"
10090 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10093 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10094 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10095 (const_int 15)))))]
10097 "mshalds.w %1, %2, %0"
10098 [(set_attr "type" "mcmp_media")])
10100 (define_insn "ashrv2si3"
10101 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10102 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10103 (match_operand:DI 2 "arith_reg_operand" "r")))]
10105 "mshard.l %1, %2, %0"
10106 [(set_attr "type" "arith_media")])
10108 (define_insn "ashrv4hi3"
10109 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10110 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10111 (match_operand:DI 2 "arith_reg_operand" "r")))]
10113 "mshard.w %1, %2, %0"
10114 [(set_attr "type" "arith_media")])
10116 (define_insn "mshards_q"
10117 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10119 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10120 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10122 "mshards.q %1, %N2, %0"
10123 [(set_attr "type" "mcmp_media")])
10125 (define_expand "mshfhi_b"
10126 [(match_operand:V8QI 0 "arith_reg_dest" "")
10127 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10128 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10132 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10133 (operands[0], operands[1], operands[2]));
10137 (define_expand "mshflo_b"
10138 [(match_operand:V8QI 0 "arith_reg_dest" "")
10139 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10140 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10144 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10145 (operands[0], operands[1], operands[2]));
10149 (define_insn "mshf4_b"
10151 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10153 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10154 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10155 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10156 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10158 "* return (TARGET_LITTLE_ENDIAN
10159 ? \"mshfhi.b %N1, %N2, %0\"
10160 : \"mshflo.b %N1, %N2, %0\");"
10161 [(set_attr "type" "arith_media")])
10163 (define_insn "mshf0_b"
10165 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10167 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10168 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10169 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10170 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10172 "* return (TARGET_LITTLE_ENDIAN
10173 ? \"mshflo.b %N1, %N2, %0\"
10174 : \"mshfhi.b %N1, %N2, %0\");"
10175 [(set_attr "type" "arith_media")])
10177 (define_expand "mshfhi_l"
10178 [(match_operand:V2SI 0 "arith_reg_dest" "")
10179 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10180 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10184 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10185 (operands[0], operands[1], operands[2]));
10189 (define_expand "mshflo_l"
10190 [(match_operand:V2SI 0 "arith_reg_dest" "")
10191 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10192 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10196 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10197 (operands[0], operands[1], operands[2]));
10201 (define_insn "mshf4_l"
10202 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10204 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10205 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10206 (parallel [(const_int 1) (const_int 3)])))]
10208 "* return (TARGET_LITTLE_ENDIAN
10209 ? \"mshfhi.l %N1, %N2, %0\"
10210 : \"mshflo.l %N1, %N2, %0\");"
10211 [(set_attr "type" "arith_media")])
10213 (define_insn "mshf0_l"
10214 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10216 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10217 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10218 (parallel [(const_int 0) (const_int 2)])))]
10220 "* return (TARGET_LITTLE_ENDIAN
10221 ? \"mshflo.l %N1, %N2, %0\"
10222 : \"mshfhi.l %N1, %N2, %0\");"
10223 [(set_attr "type" "arith_media")])
10225 (define_expand "mshfhi_w"
10226 [(match_operand:V4HI 0 "arith_reg_dest" "")
10227 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10228 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10232 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10233 (operands[0], operands[1], operands[2]));
10237 (define_expand "mshflo_w"
10238 [(match_operand:V4HI 0 "arith_reg_dest" "")
10239 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10240 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10244 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10245 (operands[0], operands[1], operands[2]));
10249 (define_insn "mshf4_w"
10250 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10252 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10253 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10254 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10256 "* return (TARGET_LITTLE_ENDIAN
10257 ? \"mshfhi.w %N1, %N2, %0\"
10258 : \"mshflo.w %N1, %N2, %0\");"
10259 [(set_attr "type" "arith_media")])
10261 (define_insn "mshf0_w"
10262 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10264 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10265 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10266 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10268 "* return (TARGET_LITTLE_ENDIAN
10269 ? \"mshflo.w %N1, %N2, %0\"
10270 : \"mshfhi.w %N1, %N2, %0\");"
10271 [(set_attr "type" "arith_media")])
10273 (define_insn "mshflo_w_x"
10274 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10276 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10277 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10278 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10280 "mshflo.w %N1, %N2, %0"
10281 [(set_attr "type" "arith_media")])
10283 /* These are useful to expand ANDs and as combiner patterns. */
10284 (define_insn_and_split "mshfhi_l_di"
10285 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10286 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10288 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10289 (const_int -4294967296))))]
10292 mshfhi.l %N1, %N2, %0
10294 "TARGET_SHMEDIA && reload_completed
10295 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10296 [(set (match_dup 3) (match_dup 4))
10297 (set (match_dup 5) (match_dup 6))]
10300 operands[3] = gen_lowpart (SImode, operands[0]);
10301 operands[4] = gen_highpart (SImode, operands[1]);
10302 operands[5] = gen_highpart (SImode, operands[0]);
10303 operands[6] = gen_highpart (SImode, operands[2]);
10305 [(set_attr "type" "arith_media")])
10307 (define_insn "*mshfhi_l_di_rev"
10308 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10309 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10310 (const_int -4294967296))
10311 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10314 "mshfhi.l %N2, %N1, %0"
10315 [(set_attr "type" "arith_media")])
10318 [(set (match_operand:DI 0 "arith_reg_dest" "")
10319 (ior:DI (zero_extend:DI (match_operand:SI 1
10320 "extend_reg_or_0_operand" ""))
10321 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10322 (const_int -4294967296))))
10323 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10328 emit_insn (gen_ashldi3_media (operands[3],
10329 simplify_gen_subreg (DImode, operands[1],
10332 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10336 (define_insn "mshflo_l_di"
10337 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10338 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10339 (const_int 4294967295))
10340 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10344 "mshflo.l %N1, %N2, %0"
10345 [(set_attr "type" "arith_media")])
10347 (define_insn "*mshflo_l_di_rev"
10348 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10349 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10351 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10352 (const_int 4294967295))))]
10355 "mshflo.l %N2, %N1, %0"
10356 [(set_attr "type" "arith_media")])
10358 ;; Combiner pattern for trampoline initialization.
10359 (define_insn_and_split "*double_shori"
10360 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10361 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10363 (match_operand:DI 2 "const_int_operand" "n")))]
10365 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10367 "rtx_equal_p (operands[0], operands[1])"
10371 HOST_WIDE_INT v = INTVAL (operands[2]);
10373 emit_insn (gen_shori_media (operands[0], operands[0],
10374 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10375 emit_insn (gen_shori_media (operands[0], operands[0],
10376 gen_int_mode (v, HImode)));
10381 (define_insn "*mshflo_l_di_x"
10382 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10383 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10385 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10389 "mshflo.l %N1, %N2, %0"
10390 [(set_attr "type" "arith_media")])
10392 (define_insn_and_split "concat_v2sf"
10393 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10394 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10395 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10396 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10400 mshflo.l %N1, %N2, %0
10403 "TARGET_SHMEDIA && reload_completed
10404 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10405 [(set (match_dup 3) (match_dup 1))
10406 (set (match_dup 4) (match_dup 2))]
10409 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10410 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10412 [(set_attr "type" "arith_media")])
10414 (define_insn "*mshflo_l_di_x_rev"
10415 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10416 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10418 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10421 "mshflo.l %N2, %N1, %0"
10422 [(set_attr "type" "arith_media")])
10424 (define_insn "ashlv2si3"
10425 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10426 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10427 (match_operand:DI 2 "arith_reg_operand" "r")))]
10429 "mshlld.l %1, %2, %0"
10430 [(set_attr "type" "arith_media")])
10432 (define_insn "ashlv4hi3"
10433 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10434 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10435 (match_operand:DI 2 "arith_reg_operand" "r")))]
10437 "mshlld.w %1, %2, %0"
10438 [(set_attr "type" "arith_media")])
10440 (define_insn "lshrv2si3"
10441 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10442 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10443 (match_operand:DI 2 "arith_reg_operand" "r")))]
10445 "mshlrd.l %1, %2, %0"
10446 [(set_attr "type" "arith_media")])
10448 (define_insn "lshrv4hi3"
10449 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10450 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10451 (match_operand:DI 2 "arith_reg_operand" "r")))]
10453 "mshlrd.w %1, %2, %0"
10454 [(set_attr "type" "arith_media")])
10456 (define_insn "subv2si3"
10457 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10458 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10459 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10461 "msub.l %N1, %2, %0"
10462 [(set_attr "type" "arith_media")])
10464 (define_insn "subv4hi3"
10465 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10466 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10467 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10469 "msub.w %N1, %2, %0"
10470 [(set_attr "type" "arith_media")])
10472 (define_insn "sssubv2si3"
10473 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10474 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10475 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10477 "msubs.l %N1, %2, %0"
10478 [(set_attr "type" "mcmp_media")])
10480 (define_insn "ussubv8qi3"
10481 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10482 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10483 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10485 "msubs.ub %1, %2, %0"
10486 [(set_attr "type" "mcmp_media")])
10488 (define_insn "sssubv4hi3"
10489 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10490 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10491 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10493 "msubs.w %N1, %2, %0"
10494 [(set_attr "type" "mcmp_media")])
10496 ;; Floating Point Intrinsics
10498 (define_insn "fcosa_s"
10499 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10500 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10504 [(set_attr "type" "atrans_media")])
10506 (define_insn "fsina_s"
10507 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10508 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10512 [(set_attr "type" "atrans_media")])
10514 (define_insn "fipr"
10515 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10516 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10517 "fp_arith_reg_operand" "f")
10518 (match_operand:V4SF 2
10519 "fp_arith_reg_operand" "f"))
10520 (parallel [(const_int 0)]))
10521 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10522 (parallel [(const_int 1)])))
10523 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10524 (parallel [(const_int 2)]))
10525 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10526 (parallel [(const_int 3)])))))]
10529 [(set_attr "type" "fparith_media")])
10531 (define_insn "fsrra_s"
10532 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10533 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10537 [(set_attr "type" "atrans_media")])
10539 (define_insn "ftrv"
10540 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10544 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10545 (parallel [(const_int 0) (const_int 5)
10546 (const_int 10) (const_int 15)]))
10547 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10549 (vec_select:V4SF (match_dup 1)
10550 (parallel [(const_int 4) (const_int 9)
10551 (const_int 14) (const_int 3)]))
10552 (vec_select:V4SF (match_dup 2)
10553 (parallel [(const_int 1) (const_int 2)
10554 (const_int 3) (const_int 0)]))))
10557 (vec_select:V4SF (match_dup 1)
10558 (parallel [(const_int 8) (const_int 13)
10559 (const_int 2) (const_int 7)]))
10560 (vec_select:V4SF (match_dup 2)
10561 (parallel [(const_int 2) (const_int 3)
10562 (const_int 0) (const_int 1)])))
10564 (vec_select:V4SF (match_dup 1)
10565 (parallel [(const_int 12) (const_int 1)
10566 (const_int 6) (const_int 11)]))
10567 (vec_select:V4SF (match_dup 2)
10568 (parallel [(const_int 3) (const_int 0)
10569 (const_int 1) (const_int 2)]))))))]
10572 [(set_attr "type" "fparith_media")])
10575 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10576 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10580 [(set_attr "type" "arith_media")])
10582 (define_insn "nsbsi"
10583 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10585 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10589 [(set_attr "type" "arith_media")])
10591 (define_insn "nsbdi"
10592 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10594 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10598 [(set_attr "type" "arith_media")])
10600 (define_expand "ffsdi2"
10601 [(set (match_operand:DI 0 "arith_reg_dest" "")
10602 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10606 rtx scratch = gen_reg_rtx (DImode);
10609 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10610 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10611 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10612 emit_insn (gen_nsbdi (scratch, scratch));
10613 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10614 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10615 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10617 = gen_rtx_EXPR_LIST (REG_EQUAL,
10618 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10622 (define_expand "ffssi2"
10623 [(set (match_operand:SI 0 "arith_reg_dest" "")
10624 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10628 rtx scratch = gen_reg_rtx (SImode);
10629 rtx discratch = gen_reg_rtx (DImode);
10632 emit_insn (gen_adddi3 (discratch,
10633 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10635 emit_insn (gen_andcdi3 (discratch,
10636 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10638 emit_insn (gen_nsbsi (scratch, discratch));
10639 last = emit_insn (gen_subsi3 (operands[0],
10640 force_reg (SImode, GEN_INT (63)), scratch));
10642 = gen_rtx_EXPR_LIST (REG_EQUAL,
10643 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10647 (define_insn "byterev"
10648 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10649 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10650 (parallel [(const_int 7) (const_int 6) (const_int 5)
10651 (const_int 4) (const_int 3) (const_int 2)
10652 (const_int 1) (const_int 0)])))]
10655 [(set_attr "type" "arith_media")])
10657 ;; The following description models the
10658 ;; SH4 pipeline using the DFA based scheduler.
10659 ;; The DFA based description is better way to model
10660 ;; a superscalar pipeline as compared to function unit
10661 ;; reservation model.
10662 ;; 1. The function unit based model is oriented to describe at most one
10663 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10664 ;; pipeline units by same insn. This can be done using DFA based description.
10665 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10666 ;; 3. Writing all unit reservations for an instruction class is more natural description
10667 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10668 ;; old function unit based model.
10669 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10672 ;; Two automata are defined to reduce number of states
10673 ;; which a single large automaton will have.(Factoring)
10675 (define_automaton "inst_pipeline,fpu_pipe")
10677 ;; This unit is basically the decode unit of the processor.
10678 ;; Since SH4 is a dual issue machine,it is as if there are two
10679 ;; units so that any insn can be processed by either one
10680 ;; of the decoding unit.
10682 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10685 ;; The fixed point arithmetic calculator(?? EX Unit).
10687 (define_cpu_unit "int" "inst_pipeline")
10689 ;; f1_1 and f1_2 are floating point units.Actually there is
10690 ;; a f1 unit which can overlap with other f1 unit but
10691 ;; not another F1 unit.It is as though there were two
10694 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10696 ;; The floating point units (except FS - F2 always precedes it.)
10698 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10700 ;; This is basically the MA unit of SH4
10701 ;; used in LOAD/STORE pipeline.
10703 (define_cpu_unit "memory" "inst_pipeline")
10705 ;; However, there are LS group insns that don't use it, even ones that
10706 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10707 (define_cpu_unit "load_store" "inst_pipeline")
10709 ;; The address calculator used for branch instructions.
10710 ;; This will be reserved after "issue" of branch instructions
10711 ;; and this is to make sure that no two branch instructions
10712 ;; can be issued in parallel.
10714 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10716 ;; ----------------------------------------------------
10717 ;; This reservation is to simplify the dual issue description.
10719 (define_reservation "issue" "pipe_01|pipe_02")
10721 ;; This is to express the locking of D stage.
10722 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10724 (define_reservation "d_lock" "pipe_01+pipe_02")
10726 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10727 (define_reservation "F01" "F0+F1")
10729 ;; This is to simplify description where F1,F2,FS
10730 ;; are used simultaneously.
10732 (define_reservation "fpu" "F1+F2")
10734 ;; This is to highlight the fact that f1
10735 ;; cannot overlap with F1.
10737 (exclusion_set "f1_1,f1_2" "F1")
10739 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10741 ;; Although reg moves have a latency of zero
10742 ;; we need to highlight that they use D stage
10747 (define_insn_reservation "reg_mov" 0
10748 (and (eq_attr "pipe_model" "sh4")
10749 (eq_attr "type" "move"))
10754 (define_insn_reservation "freg_mov" 0
10755 (and (eq_attr "pipe_model" "sh4")
10756 (eq_attr "type" "fmove"))
10757 "issue+load_store")
10759 ;; We don't model all pipeline stages; we model the issue ('D') stage
10760 ;; inasmuch as we allow only two instructions to issue simultaneously,
10761 ;; and CO instructions prevent any simultaneous issue of another instruction.
10762 ;; (This uses pipe_01 and pipe_02).
10763 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10764 ;; Double issue of EX / BR insns is prevented by using the int unit /
10765 ;; pcr_addrcalc unit in the EX stage.
10766 ;; Double issue of BR / LS instructions is prevented by using the
10767 ;; pcr_addrcalc / load_store unit in the issue cycle.
10768 ;; Double issue of FE instructions is prevented by using F0 in the first
10769 ;; pipeline stage after the first D stage.
10770 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10771 ;; (except in the cases outlined above), nor to describe the FS stage after
10774 ;; Other MT group instructions(1 step operations)
10779 (define_insn_reservation "mt" 1
10780 (and (eq_attr "pipe_model" "sh4")
10781 (eq_attr "type" "mt_group"))
10784 ;; Fixed Point Arithmetic Instructions(1 step operations)
10789 (define_insn_reservation "sh4_simple_arith" 1
10790 (and (eq_attr "pipe_model" "sh4")
10791 (eq_attr "insn_class" "ex_group"))
10794 ;; Load and store instructions have no alignment peculiarities for the SH4,
10795 ;; but they use the load-store unit, which they share with the fmove type
10796 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10797 ;; Loads have a latency of two.
10798 ;; However, call insns can only paired with a preceding insn, and have
10799 ;; a delay slot, so that we want two more insns to be scheduled between the
10800 ;; load of the function address and the call. This is equivalent to a
10801 ;; latency of three.
10802 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10803 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10804 ;; We only do this for SImode loads of general registers, to make the work
10805 ;; for ADJUST_COST easier.
10807 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10812 (define_insn_reservation "sh4_load" 2
10813 (and (eq_attr "pipe_model" "sh4")
10814 (eq_attr "type" "load,pcload"))
10815 "issue+load_store,nothing,memory")
10817 ;; calls / sfuncs need an extra instruction for their delay slot.
10818 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10819 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10820 ;; count of a dynamic shift.
10821 (define_insn_reservation "sh4_load_si" 3
10822 (and (eq_attr "pipe_model" "sh4")
10823 (eq_attr "type" "load_si,pcload_si"))
10824 "issue+load_store,nothing,memory")
10826 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10828 ;; The load latency is upped to three higher if the dependent insn does
10829 ;; double precision computation. We want the 'default' latency to reflect
10830 ;; that increased latency because otherwise the insn priorities won't
10831 ;; allow proper scheduling.
10832 (define_insn_reservation "sh4_fload" 3
10833 (and (eq_attr "pipe_model" "sh4")
10834 (eq_attr "type" "fload,pcfload"))
10835 "issue+load_store,nothing,memory")
10837 ;; (define_bypass 2 "sh4_fload" "!")
10839 (define_insn_reservation "sh4_store" 1
10840 (and (eq_attr "pipe_model" "sh4")
10841 (eq_attr "type" "store"))
10842 "issue+load_store,nothing,memory")
10844 ;; Load Store instructions.
10849 (define_insn_reservation "sh4_gp_fpul" 1
10850 (and (eq_attr "pipe_model" "sh4")
10851 (eq_attr "type" "gp_fpul"))
10852 "issue+load_store")
10854 ;; Load Store instructions.
10859 (define_insn_reservation "sh4_fpul_gp" 3
10860 (and (eq_attr "pipe_model" "sh4")
10861 (eq_attr "type" "fpul_gp"))
10862 "issue+load_store")
10864 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10866 ;; Latency when taken: 2 (or 1)
10868 ;; The latency is 1 when displacement is 0.
10869 ;; We can't really do much with the latency, even if we could express it,
10870 ;; but the pairing restrictions are useful to take into account.
10871 ;; ??? If the branch is likely, we might want to fill the delay slot;
10872 ;; if the branch is likely, but not very likely, should we pretend to use
10873 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10875 (define_insn_reservation "sh4_branch" 1
10876 (and (eq_attr "pipe_model" "sh4")
10877 (eq_attr "type" "cbranch,jump"))
10878 "issue+pcr_addrcalc")
10880 ;; Branch Far (JMP,RTS,BRAF)
10884 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10885 ;; can't be distinguished from bra for the "jump" pattern.
10887 (define_insn_reservation "sh4_return" 3
10888 (and (eq_attr "pipe_model" "sh4")
10889 (eq_attr "type" "return,jump_ind"))
10896 ;; this instruction can be executed in any of the pipelines
10897 ;; and blocks the pipeline for next 4 stages.
10899 (define_insn_reservation "sh4_return_from_exp" 5
10900 (and (eq_attr "pipe_model" "sh4")
10901 (eq_attr "type" "rte"))
10909 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10910 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10911 (define_insn_reservation "ocbwb" 6
10912 (and (eq_attr "pipe_model" "sh4")
10913 (eq_attr "type" "cwb"))
10914 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10920 ;; The SX stage is blocked for last 2 cycles.
10921 ;; OTOH, the only time that has an effect for insns generated by the compiler
10922 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10923 ;; or when we are doing a function call - and we don't do inter-function
10924 ;; scheduling. For the function call case, it's really best that we end with
10925 ;; something that models an rts.
10927 (define_insn_reservation "sh4_lds_to_pr" 3
10928 (and (eq_attr "pipe_model" "sh4")
10929 (eq_attr "type" "prset") )
10932 ;; calls introduce a longisch delay that is likely to flush the pipelines
10933 ;; of the caller's instructions. Ordinary functions tend to end with a
10934 ;; load to restore a register (in the delay slot of rts), while sfuncs
10935 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10936 ;; since there are no instructions that contend for memory access early.
10937 ;; We could, of course, provide exact scheduling information for specific
10938 ;; sfuncs, if that should prove useful.
10940 (define_insn_reservation "sh4_call" 16
10941 (and (eq_attr "pipe_model" "sh4")
10942 (eq_attr "type" "call,sfunc"))
10949 ;; The SX unit is blocked for last 2 cycles.
10951 (define_insn_reservation "ldsmem_to_pr" 3
10952 (and (eq_attr "pipe_model" "sh4")
10953 (eq_attr "type" "pload"))
10960 ;; The SX unit in second and third cycles.
10962 (define_insn_reservation "sts_from_pr" 2
10963 (and (eq_attr "pipe_model" "sh4")
10964 (eq_attr "type" "prget"))
10972 (define_insn_reservation "sh4_prstore_mem" 2
10973 (and (eq_attr "pipe_model" "sh4")
10974 (eq_attr "type" "pstore"))
10975 "d_lock*2,nothing,memory")
10981 ;; F1 is blocked for last three cycles.
10983 (define_insn_reservation "fpscr_load" 4
10984 (and (eq_attr "pipe_model" "sh4")
10985 (eq_attr "type" "gp_fpscr"))
10986 "d_lock,nothing,F1*3")
10991 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10993 ;; F1 is blocked for last three cycles.
10995 (define_insn_reservation "fpscr_load_mem" 4
10996 (and (eq_attr "pipe_model" "sh4")
10997 (eq_attr "type" "mem_fpscr"))
10998 "d_lock,nothing,(F1+memory),F1*2")
11001 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11006 (define_insn_reservation "multi" 4
11007 (and (eq_attr "pipe_model" "sh4")
11008 (eq_attr "type" "smpy,dmpy"))
11009 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11011 ;; Fixed STS from MACL / MACH
11016 (define_insn_reservation "sh4_mac_gp" 3
11017 (and (eq_attr "pipe_model" "sh4")
11018 (eq_attr "type" "mac_gp"))
11022 ;; Single precision floating point computation FCMP/EQ,
11023 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11028 (define_insn_reservation "fp_arith" 3
11029 (and (eq_attr "pipe_model" "sh4")
11030 (eq_attr "type" "fp"))
11033 (define_insn_reservation "fp_arith_ftrc" 3
11034 (and (eq_attr "pipe_model" "sh4")
11035 (eq_attr "type" "ftrc_s"))
11038 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11040 ;; Single Precision FDIV/SQRT
11042 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
11044 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11046 (define_insn_reservation "fp_div" 12
11047 (and (eq_attr "pipe_model" "sh4")
11048 (eq_attr "type" "fdiv"))
11049 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11051 ;; Double Precision floating point computation
11052 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11054 ;; Latency: (3,4)/5
11057 (define_insn_reservation "dp_float" 4
11058 (and (eq_attr "pipe_model" "sh4")
11059 (eq_attr "type" "dfp_conv"))
11060 "issue,F01,F1+F2,F2")
11062 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11064 ;; Latency: (7,8)/9
11067 (define_insn_reservation "fp_double_arith" 8
11068 (and (eq_attr "pipe_model" "sh4")
11069 (eq_attr "type" "dfp_arith"))
11070 "issue,F01,F1+F2,fpu*4,F2")
11072 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11077 (define_insn_reservation "fp_double_cmp" 3
11078 (and (eq_attr "pipe_model" "sh4")
11079 (eq_attr "type" "dfp_cmp"))
11080 "d_lock,(d_lock+F01),F1+F2,F2")
11082 ;; Double precision FDIV/SQRT
11084 ;; Latency: (24,25)/26
11087 (define_insn_reservation "dp_div" 25
11088 (and (eq_attr "pipe_model" "sh4")
11089 (eq_attr "type" "dfdiv"))
11090 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11093 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11094 ;; case, we'd get a d_lock instead of issue at the end.
11095 (define_insn_reservation "arith3" 3
11096 (and (eq_attr "pipe_model" "sh4")
11097 (eq_attr "type" "arith3"))
11098 "issue,d_lock+pcr_addrcalc,issue")
11100 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11101 (define_insn_reservation "arith3b" 2
11102 (and (eq_attr "pipe_model" "sh4")
11103 (eq_attr "type" "arith3"))
11104 "issue,d_lock+pcr_addrcalc")