1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004 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 GCC.
9 ;; GCC 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 ;; GCC 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 GCC; 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)
147 ;; These are used with unspec_volatile.
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
157 ;; -------------------------------------------------------------------------
159 ;; -------------------------------------------------------------------------
164 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; tls_load load TLS related address
222 ;; arith_media SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media SHmedia compare instructions
225 ;; dfdiv_media SHmedia double precision divide and square root
226 ;; dfmul_media SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media SHmedia longword multiply
230 ;; fcmp_media SHmedia floating point compare instructions
231 ;; fdiv_media SHmedia single precision divide and square root
232 ;; fload_media SHmedia floating point register load instructions
233 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media SHmedia unconditional branch instructions
240 ;; load_media SHmedia general register load instructions
241 ;; pt_media SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media SHmedia ptabs instruction
243 ;; store_media SHmedia general register store instructions
244 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media SHmedia mac-style fixed point operations
246 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
247 ;; atrans SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil no-op move, will be deleted.
252 "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"
253 (const_string "other"))
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
258 ;; mt_group SH4 "mt" group instructions.
260 ;; ex_group SH4 "ex" group instructions.
262 ;; ls_group SH4 "ls" group instructions.
265 (define_attr "insn_class"
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (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")]
274 (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
283 ;; Indicate if the fpu mode is set by this instruction
284 ;; "unknown" must have the value as "none" in fp_mode, and means
285 ;; that the instruction/abi has left the processor in an unknown
287 ;; "none" means that nothing has changed and no mode is set.
288 ;; This attribute is only used for the Renesas ABI.
289 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
291 ; If a conditional branch destination is within -252..258 bytes away
292 ; from the instruction it can be 2 bytes long. Something in the
293 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
294 ; branches are initially assumed to be 16 bytes long.
295 ; In machine_dependent_reorg, we split all branches that are longer than
298 ;; The maximum range used for SImode constant pool entries is 1018. A final
299 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
301 ;; instruction around the pool table, 2 bytes of alignment before the table,
302 ;; and 30 bytes of alignment after the table. That gives a maximum total
303 ;; pool size of 1058 bytes.
304 ;; Worst case code/pool content size ratio is 1:2 (using asms).
305 ;; Thus, in the worst case, there is one instruction in front of a maximum
306 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
308 ;; If we have a forward branch, the initial table will be put after the
309 ;; unconditional branch.
311 ;; ??? We could do much better by keeping track of the actual pcloads within
312 ;; the branch range and in the pcload range in front of the branch range.
314 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
316 (define_attr "short_cbranch_p" "no,yes"
317 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
319 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
321 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
323 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
325 ] (const_string "no")))
327 (define_attr "med_branch_p" "no,yes"
328 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
331 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
336 ] (const_string "no")))
338 (define_attr "med_cbranch_p" "no,yes"
339 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
347 ] (const_string "no")))
349 (define_attr "braf_branch_p" "no,yes"
350 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
360 ] (const_string "no")))
362 (define_attr "braf_cbranch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
373 ] (const_string "no")))
375 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
376 ; For wider ranges, we need a combination of a code and a data part.
377 ; If we can get a scratch register for a long range jump, the code
378 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
380 ; long; otherwise, it must be 6 bytes long.
382 ; All other instructions are two bytes long by default.
384 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385 ;; but getattrtab doesn't understand this.
386 (define_attr "length" ""
387 (cond [(eq_attr "type" "cbranch")
388 (cond [(eq_attr "short_cbranch_p" "yes")
390 (eq_attr "med_cbranch_p" "yes")
392 (eq_attr "braf_cbranch_p" "yes")
394 ;; ??? using pc is not computed transitively.
395 (ne (match_dup 0) (match_dup 0))
397 (ne (symbol_ref ("flag_pic")) (const_int 0))
400 (eq_attr "type" "jump")
401 (cond [(eq_attr "med_branch_p" "yes")
403 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
405 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
406 (symbol_ref "code_for_indirect_jump_scratch")))
407 (if_then_else (eq_attr "braf_branch_p" "yes")
410 (eq_attr "braf_branch_p" "yes")
412 ;; ??? using pc is not computed transitively.
413 (ne (match_dup 0) (match_dup 0))
415 (ne (symbol_ref ("flag_pic")) (const_int 0))
418 (eq_attr "type" "pt_media")
419 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420 (const_int 20) (const_int 12))
421 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425 ;; (define_function_unit {name} {num-units} {n-users} {test}
426 ;; {ready-delay} {issue-delay} [{conflict-list}])
428 ;; Load and store instructions save a cycle if they are aligned on a
429 ;; four byte boundary. Using a function unit for stores encourages
430 ;; gcc to separate load and store instructions by one instruction,
431 ;; which makes it more likely that the linker will be able to word
432 ;; align them when relaxing.
434 ;; Loads have a latency of two.
435 ;; However, call insns can have a delay slot, so that we want one more
436 ;; insn to be scheduled between the load of the function address and the call.
437 ;; This is equivalent to a latency of three.
438 ;; We cannot use a conflict list for this, because we need to distinguish
439 ;; between the actual call address and the function arguments.
440 ;; ADJUST_COST can only properly handle reductions of the cost, so we
441 ;; use a latency of three here.
442 ;; We only do this for SImode loads of general registers, to make the work
443 ;; for ADJUST_COST easier.
444 (define_function_unit "memory" 1 0
445 (and (eq_attr "pipe_model" "sh1")
446 (eq_attr "type" "load_si,pcload_si"))
448 (define_function_unit "memory" 1 0
449 (and (eq_attr "pipe_model" "sh1")
450 (eq_attr "type" "load,pcload,pload,store,pstore"))
453 (define_function_unit "int" 1 0
454 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
456 (define_function_unit "int" 1 0
457 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
459 (define_function_unit "int" 1 0
460 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
462 ;; ??? These are approximations.
463 (define_function_unit "mpy" 1 0
464 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
465 (define_function_unit "mpy" 1 0
466 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
468 (define_function_unit "fp" 1 0
469 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
470 (define_function_unit "fp" 1 0
471 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
474 ;; SH-5 SHmedia scheduling
475 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
476 ;; single-issue machine. It has four pipelines, the branch unit (br),
477 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478 ;; the floating point unit (fpu).
479 ;; Here model the instructions with a latency greater than one cycle.
481 ;; Every instruction on SH-5 occupies the issue resource for at least one
483 (define_function_unit "sh5issue" 1 0
484 (and (eq_attr "pipe_model" "sh5media")
485 (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)
487 ;; Specify the various types of instruction which have latency > 1
488 (define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "mcmp_media")) 2 1)
492 (define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495 ;; but see sh_adjust_cost for mac_media exception.
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "fload_media,fmove_media")) 4 1)
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "d2mpy_media")) 4 2)
505 (define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
509 (define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media")
511 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
513 (define_function_unit "sh5issue" 1 0
514 (and (eq_attr "pipe_model" "sh5media")
515 (eq_attr "type" "invalidate_line_media")) 7 7)
517 (define_function_unit "sh5issue" 1 0
518 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
520 (define_function_unit "sh5issue" 1 0
521 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
523 ;; Floating-point divide and square-root occupy an additional resource,
524 ;; which is not internally pipelined. However, other instructions
525 ;; can continue to issue.
526 (define_function_unit "sh5fds" 1 0
527 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
529 (define_function_unit "sh5fds" 1 0
530 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
532 ; Definitions for filling branch delay slots.
534 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
536 ;; ??? This should be (nil) instead of (const_int 0)
537 (define_attr "hit_stack" "yes,no"
538 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
541 (const_string "yes")))
543 (define_attr "interrupt_function" "no,yes"
544 (const (symbol_ref "current_function_interrupt")))
546 (define_attr "in_delay_slot" "yes,no"
547 (cond [(eq_attr "type" "cbranch") (const_string "no")
548 (eq_attr "type" "pcload,pcload_si") (const_string "no")
549 (eq_attr "needs_delay_slot" "yes") (const_string "no")
550 (eq_attr "length" "2") (const_string "yes")
551 ] (const_string "no")))
553 (define_attr "cond_delay_slot" "yes,no"
554 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555 ] (const_string "no")))
557 (define_attr "is_sfunc" ""
558 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
560 (define_attr "is_mac_media" ""
561 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
563 (define_attr "branch_zero" "yes,no"
564 (cond [(eq_attr "type" "!cbranch") (const_string "no")
565 (ne (symbol_ref "(next_active_insn (insn)\
566 == (prev_active_insn\
567 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568 && get_attr_length (next_active_insn (insn)) == 2")
570 (const_string "yes")]
571 (const_string "no")))
573 ;; SH4 Double-precision computation with double-precision result -
574 ;; the two halves are ready at different times.
575 (define_attr "dfp_comp" "yes,no"
576 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577 (const_string "no")))
579 ;; Insns for which the latency of a preceding fp insn is decreased by one.
580 (define_attr "late_fp_use" "yes,no" (const_string "no"))
581 ;; And feeding insns for which this relevant.
582 (define_attr "any_fp_comp" "yes,no"
583 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584 (const_string "yes")]
585 (const_string "no")))
587 (define_attr "any_int_load" "yes,no"
588 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589 (const_string "yes")]
590 (const_string "no")))
593 (eq_attr "needs_delay_slot" "yes")
594 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
596 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597 ;; and thus we can't put a pop instruction in its delay slot.
598 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599 ;; instruction can go in the delay slot.
601 ;; Since a normal return (rts) implicitly uses the PR register,
602 ;; we can't allow PR register loads in an rts delay slot.
605 (eq_attr "type" "return")
606 [(and (eq_attr "in_delay_slot" "yes")
607 (ior (and (eq_attr "interrupt_function" "no")
608 (eq_attr "type" "!pload,prset"))
609 (and (eq_attr "interrupt_function" "yes")
611 (ne (symbol_ref "TARGET_SH3") (const_int 0))
612 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
614 ;; Since a call implicitly uses the PR register, we can't allow
615 ;; a PR register store in a jsr delay slot.
618 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619 [(and (eq_attr "in_delay_slot" "yes")
620 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
622 ;; Say that we have annulled true branches, since this gives smaller and
623 ;; faster code when branches are predicted as not taken.
626 (and (eq_attr "type" "cbranch")
627 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
628 ;; SH2e has a hardware bug that pretty much prohibits the use of
629 ;; annuled delay slots.
630 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631 (not (eq_attr "cpu" "sh2e"))) (nil)])
633 ;; -------------------------------------------------------------------------
634 ;; SImode signed integer comparisons
635 ;; -------------------------------------------------------------------------
639 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
640 (match_operand:SI 1 "arith_operand" "K08,r"))
644 [(set_attr "type" "mt_group")])
646 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647 ;; That would still allow reload to create cmpi instructions, but would
648 ;; perhaps allow forcing the constant into a register when that is better.
649 ;; Probably should use r0 for mem/imm compares, but force constant into a
650 ;; register for pseudo/imm compares.
652 (define_insn "cmpeqsi_t"
654 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
655 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
661 [(set_attr "type" "mt_group")])
663 (define_insn "cmpgtsi_t"
665 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
671 [(set_attr "type" "mt_group")])
673 (define_insn "cmpgesi_t"
675 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
681 [(set_attr "type" "mt_group")])
683 ;; -------------------------------------------------------------------------
684 ;; SImode unsigned integer comparisons
685 ;; -------------------------------------------------------------------------
687 (define_insn "cmpgeusi_t"
689 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690 (match_operand:SI 1 "arith_reg_operand" "r")))]
693 [(set_attr "type" "mt_group")])
695 (define_insn "cmpgtusi_t"
697 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698 (match_operand:SI 1 "arith_reg_operand" "r")))]
701 [(set_attr "type" "mt_group")])
703 ;; We save the compare operands in the cmpxx patterns and use them when
704 ;; we generate the branch.
706 (define_expand "cmpsi"
708 (compare (match_operand:SI 0 "cmpsi_operand" "")
709 (match_operand:SI 1 "arith_operand" "")))]
713 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
714 && GET_CODE (operands[1]) != CONST_INT)
715 operands[0] = copy_to_mode_reg (SImode, operands[0]);
716 sh_compare_op0 = operands[0];
717 sh_compare_op1 = operands[1];
721 ;; -------------------------------------------------------------------------
722 ;; DImode signed integer comparisons
723 ;; -------------------------------------------------------------------------
725 ;; ??? Could get better scheduling by splitting the initial test from the
726 ;; rest of the insn after reload. However, the gain would hardly justify
727 ;; the sh.md size increase necessary to do that.
731 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
732 (match_operand:DI 1 "arith_operand" "r"))
735 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
737 [(set_attr "length" "6")
738 (set_attr "type" "arith3b")])
740 (define_insn "cmpeqdi_t"
742 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
743 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
746 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
747 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
748 [(set_attr "length" "6")
749 (set_attr "type" "arith3b")])
753 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
754 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
755 ;; If we applied this split when not optimizing, it would only be
756 ;; applied during the machine-dependent reorg, when no new basic blocks
758 "TARGET_SH1 && reload_completed && optimize"
759 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
760 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
761 (label_ref (match_dup 6))
763 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
768 = gen_rtx_REG (SImode,
769 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
771 = (operands[1] == const0_rtx
773 : gen_rtx_REG (SImode,
774 true_regnum (operands[1])
775 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
776 operands[4] = gen_lowpart (SImode, operands[0]);
777 operands[5] = gen_lowpart (SImode, operands[1]);
778 operands[6] = gen_label_rtx ();
781 (define_insn "cmpgtdi_t"
783 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
787 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
788 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
789 [(set_attr "length" "8")
790 (set_attr "type" "arith3")])
792 (define_insn "cmpgedi_t"
794 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
795 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
798 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
800 [(set_attr "length" "8,2")
801 (set_attr "type" "arith3,mt_group")])
803 ;; -------------------------------------------------------------------------
804 ;; DImode unsigned integer comparisons
805 ;; -------------------------------------------------------------------------
807 (define_insn "cmpgeudi_t"
809 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
810 (match_operand:DI 1 "arith_reg_operand" "r")))]
812 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
813 [(set_attr "length" "8")
814 (set_attr "type" "arith3")])
816 (define_insn "cmpgtudi_t"
818 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
819 (match_operand:DI 1 "arith_reg_operand" "r")))]
821 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
822 [(set_attr "length" "8")
823 (set_attr "type" "arith3")])
825 (define_insn "cmpeqdi_media"
826 [(set (match_operand:DI 0 "register_operand" "=r")
827 (eq:DI (match_operand:DI 1 "register_operand" "%r")
828 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
831 [(set_attr "type" "cmp_media")])
833 (define_insn "cmpgtdi_media"
834 [(set (match_operand:DI 0 "register_operand" "=r")
835 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
836 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
839 [(set_attr "type" "cmp_media")])
841 (define_insn "cmpgtudi_media"
842 [(set (match_operand:DI 0 "register_operand" "=r")
843 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
846 "cmpgtu %N1, %N2, %0"
847 [(set_attr "type" "cmp_media")])
849 ;; We save the compare operands in the cmpxx patterns and use them when
850 ;; we generate the branch.
852 (define_expand "cmpdi"
854 (compare (match_operand:DI 0 "arith_operand" "")
855 (match_operand:DI 1 "arith_operand" "")))]
856 "TARGET_SH2 || TARGET_SHMEDIA"
859 sh_compare_op0 = operands[0];
860 sh_compare_op1 = operands[1];
863 ;; -------------------------------------------------------------------------
864 ;; Conditional move instructions
865 ;; -------------------------------------------------------------------------
867 ;; The insn names may seem reversed, but note that cmveq performs the move
868 ;; if op1 == 0, and cmvne does it if op1 != 0.
870 (define_insn "movdicc_false"
871 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
872 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
874 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
875 (match_operand:DI 3 "arith_reg_operand" "0")))]
878 [(set_attr "type" "arith_media")])
880 (define_insn "movdicc_true"
881 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
882 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
884 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
885 (match_operand:DI 3 "arith_reg_operand" "0")))]
888 [(set_attr "type" "arith_media")])
890 (define_expand "movdicc"
891 [(set (match_operand:DI 0 "register_operand" "")
892 (if_then_else:DI (match_operand 1 "comparison_operator" "")
893 (match_operand:DI 2 "register_operand" "")
894 (match_operand:DI 3 "register_operand" "")))]
898 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
899 && GET_MODE (sh_compare_op0) == DImode
900 && sh_compare_op1 == const0_rtx)
901 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
902 sh_compare_op0, sh_compare_op1);
910 tmp = gen_reg_rtx (DImode);
912 switch (GET_CODE (operands[1]))
915 emit_insn (gen_seq (tmp));
916 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
920 emit_insn (gen_seq (tmp));
921 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
925 emit_insn (gen_sgt (tmp));
926 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
930 emit_insn (gen_slt (tmp));
931 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
935 emit_insn (gen_slt (tmp));
936 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
940 emit_insn (gen_sgt (tmp));
941 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
945 emit_insn (gen_sgtu (tmp));
946 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
950 emit_insn (gen_sltu (tmp));
951 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
955 emit_insn (gen_sltu (tmp));
956 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
960 emit_insn (gen_sgtu (tmp));
961 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
965 emit_insn (gen_sunordered (tmp));
966 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
970 emit_insn (gen_sunordered (tmp));
971 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
988 ;; -------------------------------------------------------------------------
989 ;; Addition instructions
990 ;; -------------------------------------------------------------------------
992 (define_expand "adddi3"
993 [(set (match_operand:DI 0 "arith_reg_operand" "")
994 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
995 (match_operand:DI 2 "arith_operand" "")))]
1001 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1003 operands[2] = force_reg (DImode, operands[2]);
1004 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1009 (define_insn "*adddi3_media"
1010 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1011 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1012 (match_operand:DI 2 "arith_operand" "r,I10")))]
1017 [(set_attr "type" "arith_media")])
1019 (define_insn "adddi3z_media"
1020 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1022 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1023 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1025 "addz.l %1, %N2, %0"
1026 [(set_attr "type" "arith_media")])
1028 (define_insn "adddi3_compact"
1029 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1030 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1031 (match_operand:DI 2 "arith_reg_operand" "r")))
1032 (clobber (reg:SI T_REG))]
1035 [(set_attr "length" "6")])
1038 [(set (match_operand:DI 0 "arith_reg_operand" "")
1039 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1040 (match_operand:DI 2 "arith_reg_operand" "")))
1041 (clobber (reg:SI T_REG))]
1042 "TARGET_SH1 && reload_completed"
1046 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1047 high0 = gen_rtx_REG (SImode,
1048 true_regnum (operands[0])
1049 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050 high2 = gen_rtx_REG (SImode,
1051 true_regnum (operands[2])
1052 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1053 emit_insn (gen_clrt ());
1054 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1055 emit_insn (gen_addc1 (high0, high0, high2));
1060 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062 (match_operand:SI 2 "arith_reg_operand" "r"))
1065 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1068 [(set_attr "type" "arith")])
1070 (define_insn "addc1"
1071 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1072 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1073 (match_operand:SI 2 "arith_reg_operand" "r"))
1075 (clobber (reg:SI T_REG))]
1078 [(set_attr "type" "arith")])
1080 (define_expand "addsi3"
1081 [(set (match_operand:SI 0 "arith_reg_operand" "")
1082 (plus:SI (match_operand:SI 1 "arith_operand" "")
1083 (match_operand:SI 2 "arith_operand" "")))]
1088 operands[1] = force_reg (SImode, operands[1]);
1091 (define_insn "addsi3_media"
1092 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1093 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1094 (match_operand:SI 2 "arith_operand" "r,I10")))]
1099 [(set_attr "type" "arith_media")])
1101 (define_insn "*addsi3_compact"
1102 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1103 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1104 (match_operand:SI 2 "arith_operand" "rI08")))]
1107 [(set_attr "type" "arith")])
1109 ;; -------------------------------------------------------------------------
1110 ;; Subtraction instructions
1111 ;; -------------------------------------------------------------------------
1113 (define_expand "subdi3"
1114 [(set (match_operand:DI 0 "arith_reg_operand" "")
1115 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1116 (match_operand:DI 2 "arith_reg_operand" "")))]
1122 operands[1] = force_reg (DImode, operands[1]);
1123 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1128 (define_insn "*subdi3_media"
1129 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1130 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1131 (match_operand:DI 2 "arith_reg_operand" "r")))]
1134 [(set_attr "type" "arith_media")])
1136 (define_insn "subdi3_compact"
1137 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1138 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1139 (match_operand:DI 2 "arith_reg_operand" "r")))
1140 (clobber (reg:SI T_REG))]
1143 [(set_attr "length" "6")])
1146 [(set (match_operand:DI 0 "arith_reg_operand" "")
1147 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1148 (match_operand:DI 2 "arith_reg_operand" "")))
1149 (clobber (reg:SI T_REG))]
1150 "TARGET_SH1 && reload_completed"
1154 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1155 high0 = gen_rtx_REG (SImode,
1156 true_regnum (operands[0])
1157 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158 high2 = gen_rtx_REG (SImode,
1159 true_regnum (operands[2])
1160 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1161 emit_insn (gen_clrt ());
1162 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1163 emit_insn (gen_subc1 (high0, high0, high2));
1168 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170 (match_operand:SI 2 "arith_reg_operand" "r"))
1173 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1178 [(set_attr "type" "arith")])
1180 (define_insn "subc1"
1181 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1182 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1183 (match_operand:SI 2 "arith_reg_operand" "r"))
1185 (clobber (reg:SI T_REG))]
1188 [(set_attr "type" "arith")])
1190 (define_insn "*subsi3_internal"
1191 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1192 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1193 (match_operand:SI 2 "arith_reg_operand" "r")))]
1196 [(set_attr "type" "arith")])
1198 (define_insn "*subsi3_media"
1199 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1200 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1201 (match_operand:SI 2 "extend_reg_operand" "r")))]
1204 [(set_attr "type" "arith_media")])
1206 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1207 ;; will sometimes save one instruction. Otherwise we might get
1208 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1211 (define_expand "subsi3"
1212 [(set (match_operand:SI 0 "arith_reg_operand" "")
1213 (minus:SI (match_operand:SI 1 "arith_operand" "")
1214 (match_operand:SI 2 "arith_reg_operand" "")))]
1218 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1220 emit_insn (gen_negsi2 (operands[0], operands[2]));
1221 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1226 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1228 if (operands[1] != const0_rtx)
1229 operands[1] = force_reg (SImode, operands[1]);
1233 ;; -------------------------------------------------------------------------
1234 ;; Division instructions
1235 ;; -------------------------------------------------------------------------
1237 ;; We take advantage of the library routines which don't clobber as many
1238 ;; registers as a normal function call would.
1240 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1241 ;; also has an effect on the register that holds the address of the sfunc.
1242 ;; To make this work, we have an extra dummy insn that shows the use
1243 ;; of this register for reorg.
1245 (define_insn "use_sfunc_addr"
1246 [(set (reg:SI PR_REG)
1247 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1248 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1250 [(set_attr "length" "0")])
1252 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1253 ;; hard register 0. If we used hard register 0, then the next instruction
1254 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1255 ;; gets allocated to a stack slot that needs its address reloaded, then
1256 ;; there is nothing to prevent reload from using r0 to reload the address.
1257 ;; This reload would clobber the value in r0 we are trying to store.
1258 ;; If we let reload allocate r0, then this problem can never happen.
1260 (define_insn "udivsi3_i1"
1261 [(set (match_operand:SI 0 "register_operand" "=z")
1262 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1263 (clobber (reg:SI T_REG))
1264 (clobber (reg:SI PR_REG))
1265 (clobber (reg:SI R4_REG))
1266 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267 "TARGET_SH1 && ! TARGET_SH4"
1269 [(set_attr "type" "sfunc")
1270 (set_attr "needs_delay_slot" "yes")])
1272 ; Since shmedia-nofpu code could be linked against shcompact code, and
1273 ; the udivsi3 libcall has the same name, we must consider all registers
1274 ; clobbered that are in the union of the registers clobbered by the
1275 ; shmedia and the shcompact implementation. Note, if the shcompact
1276 ; implementation actually used shcompact code, we'd need to clobber
1277 ; also r23 and fr23.
1278 (define_insn "udivsi3_i1_media"
1279 [(set (match_operand:SI 0 "register_operand" "=z")
1280 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1281 (clobber (reg:SI T_MEDIA_REG))
1282 (clobber (reg:SI PR_MEDIA_REG))
1283 (clobber (reg:SI R20_REG))
1284 (clobber (reg:SI R21_REG))
1285 (clobber (reg:SI R22_REG))
1286 (clobber (reg:DI TR0_REG))
1287 (clobber (reg:DI TR1_REG))
1288 (clobber (reg:DI TR2_REG))
1289 (use (match_operand:DI 1 "target_operand" "b"))]
1290 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1292 [(set_attr "type" "sfunc")
1293 (set_attr "needs_delay_slot" "yes")])
1295 (define_expand "udivsi3_i4_media"
1297 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1299 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1300 (set (match_dup 5) (float:DF (match_dup 3)))
1301 (set (match_dup 6) (float:DF (match_dup 4)))
1302 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1303 (set (match_dup 8) (fix:DI (match_dup 7)))
1304 (set (match_operand:SI 0 "register_operand" "")
1305 (truncate:SI (match_dup 8)))]
1306 "TARGET_SHMEDIA_FPU"
1309 operands[3] = gen_reg_rtx (DImode);
1310 operands[4] = gen_reg_rtx (DImode);
1311 operands[5] = gen_reg_rtx (DFmode);
1312 operands[6] = gen_reg_rtx (DFmode);
1313 operands[7] = gen_reg_rtx (DFmode);
1314 operands[8] = gen_reg_rtx (DImode);
1317 (define_insn "udivsi3_i4"
1318 [(set (match_operand:SI 0 "register_operand" "=y")
1319 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1320 (clobber (reg:SI T_REG))
1321 (clobber (reg:SI PR_REG))
1322 (clobber (reg:DF DR0_REG))
1323 (clobber (reg:DF DR2_REG))
1324 (clobber (reg:DF DR4_REG))
1325 (clobber (reg:SI R0_REG))
1326 (clobber (reg:SI R1_REG))
1327 (clobber (reg:SI R4_REG))
1328 (clobber (reg:SI R5_REG))
1329 (use (reg:PSI FPSCR_REG))
1330 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1331 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1333 [(set_attr "type" "sfunc")
1334 (set_attr "fp_mode" "double")
1335 (set_attr "needs_delay_slot" "yes")])
1337 (define_insn "udivsi3_i4_single"
1338 [(set (match_operand:SI 0 "register_operand" "=y")
1339 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1340 (clobber (reg:SI T_REG))
1341 (clobber (reg:SI PR_REG))
1342 (clobber (reg:DF DR0_REG))
1343 (clobber (reg:DF DR2_REG))
1344 (clobber (reg:DF DR4_REG))
1345 (clobber (reg:SI R0_REG))
1346 (clobber (reg:SI R1_REG))
1347 (clobber (reg:SI R4_REG))
1348 (clobber (reg:SI R5_REG))
1349 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1352 [(set_attr "type" "sfunc")
1353 (set_attr "needs_delay_slot" "yes")])
1355 (define_expand "udivsi3"
1356 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1357 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1358 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1359 (parallel [(set (match_operand:SI 0 "register_operand" "")
1360 (udiv:SI (reg:SI R4_REG)
1362 (clobber (reg:SI T_REG))
1363 (clobber (reg:SI PR_REG))
1364 (clobber (reg:SI R4_REG))
1365 (use (match_dup 3))])]
1371 operands[3] = gen_reg_rtx (Pmode);
1372 /* Emit the move of the address to a pseudo outside of the libcall. */
1373 if (TARGET_HARD_SH4 && TARGET_SH2E)
1375 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1376 if (TARGET_FPU_SINGLE)
1377 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1379 last = gen_udivsi3_i4 (operands[0], operands[3]);
1381 else if (TARGET_SHMEDIA_FPU)
1383 operands[1] = force_reg (SImode, operands[1]);
1384 operands[2] = force_reg (SImode, operands[2]);
1385 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1388 else if (TARGET_SH5)
1390 emit_move_insn (operands[3],
1391 function_symbol (TARGET_FPU_ANY
1396 last = gen_udivsi3_i1_media (operands[0],
1399 : gen_rtx_SUBREG (DImode, operands[3],
1401 else if (TARGET_FPU_ANY)
1402 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1404 last = gen_udivsi3_i1 (operands[0], operands[3]);
1408 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1409 last = gen_udivsi3_i1 (operands[0], operands[3]);
1411 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1412 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1413 last = emit_insn (last);
1414 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1415 invariant code motion can move it. */
1416 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1417 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1421 (define_insn "divsi3_i1"
1422 [(set (match_operand:SI 0 "register_operand" "=z")
1423 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424 (clobber (reg:SI T_REG))
1425 (clobber (reg:SI PR_REG))
1426 (clobber (reg:SI R1_REG))
1427 (clobber (reg:SI R2_REG))
1428 (clobber (reg:SI R3_REG))
1429 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1430 "TARGET_SH1 && ! TARGET_SH4"
1432 [(set_attr "type" "sfunc")
1433 (set_attr "needs_delay_slot" "yes")])
1435 ; Since shmedia-nofpu code could be linked against shcompact code, and
1436 ; the sdivsi3 libcall has the same name, we must consider all registers
1437 ; clobbered that are in the union of the registers clobbered by the
1438 ; shmedia and the shcompact implementation. Note, if the shcompact
1439 ; implementation actually used shcompact code, we'd need to clobber
1440 ; also r22, r23 and fr23.
1441 (define_insn "divsi3_i1_media"
1442 [(set (match_operand:SI 0 "register_operand" "=z")
1443 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1444 (clobber (reg:SI T_MEDIA_REG))
1445 (clobber (reg:SI PR_MEDIA_REG))
1446 (clobber (reg:SI R1_REG))
1447 (clobber (reg:SI R2_REG))
1448 (clobber (reg:SI R3_REG))
1449 (clobber (reg:SI R20_REG))
1450 (clobber (reg:SI R21_REG))
1451 (clobber (reg:DI TR0_REG))
1452 (clobber (reg:DI TR1_REG))
1453 (clobber (reg:DI TR2_REG))
1454 (use (match_operand:DI 1 "target_operand" "b"))]
1455 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1457 [(set_attr "type" "sfunc")])
1459 (define_expand "divsi3_i4_media"
1460 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1461 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1462 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1463 (set (match_operand:SI 0 "register_operand" "=r")
1464 (fix:SI (match_dup 5)))]
1465 "TARGET_SHMEDIA_FPU"
1468 operands[3] = gen_reg_rtx (DFmode);
1469 operands[4] = gen_reg_rtx (DFmode);
1470 operands[5] = gen_reg_rtx (DFmode);
1473 (define_insn "divsi3_i4"
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 (use (reg:PSI FPSCR_REG))
1480 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1483 [(set_attr "type" "sfunc")
1484 (set_attr "fp_mode" "double")
1485 (set_attr "needs_delay_slot" "yes")])
1487 (define_insn "divsi3_i4_single"
1488 [(set (match_operand:SI 0 "register_operand" "=y")
1489 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1490 (clobber (reg:SI PR_REG))
1491 (clobber (reg:DF DR0_REG))
1492 (clobber (reg:DF DR2_REG))
1493 (clobber (reg:SI R2_REG))
1494 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1495 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1497 [(set_attr "type" "sfunc")
1498 (set_attr "needs_delay_slot" "yes")])
1500 (define_expand "divsi3"
1501 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1502 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1503 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1504 (parallel [(set (match_operand:SI 0 "register_operand" "")
1505 (div:SI (reg:SI R4_REG)
1507 (clobber (reg:SI T_REG))
1508 (clobber (reg:SI PR_REG))
1509 (clobber (reg:SI R1_REG))
1510 (clobber (reg:SI R2_REG))
1511 (clobber (reg:SI R3_REG))
1512 (use (match_dup 3))])]
1518 operands[3] = gen_reg_rtx (Pmode);
1519 /* Emit the move of the address to a pseudo outside of the libcall. */
1520 if (TARGET_HARD_SH4 && TARGET_SH2E)
1522 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1523 if (TARGET_FPU_SINGLE)
1524 last = gen_divsi3_i4_single (operands[0], operands[3]);
1526 last = gen_divsi3_i4 (operands[0], operands[3]);
1528 else if (TARGET_SHMEDIA_FPU)
1530 operands[1] = force_reg (SImode, operands[1]);
1531 operands[2] = force_reg (SImode, operands[2]);
1532 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1535 else if (TARGET_SH5)
1537 emit_move_insn (operands[3],
1538 function_symbol (TARGET_FPU_ANY
1543 last = gen_divsi3_i1_media (operands[0],
1546 : gen_rtx_SUBREG (DImode, operands[3],
1548 else if (TARGET_FPU_ANY)
1549 last = gen_divsi3_i4_single (operands[0], operands[3]);
1551 last = gen_divsi3_i1 (operands[0], operands[3]);
1555 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1556 last = gen_divsi3_i1 (operands[0], operands[3]);
1558 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1559 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1560 last = emit_insn (last);
1561 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1562 invariant code motion can move it. */
1563 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1564 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1568 ;; -------------------------------------------------------------------------
1569 ;; Multiplication instructions
1570 ;; -------------------------------------------------------------------------
1572 (define_insn "umulhisi3_i"
1573 [(set (reg:SI MACL_REG)
1574 (mult:SI (zero_extend:SI
1575 (match_operand:HI 0 "arith_reg_operand" "r"))
1577 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1580 [(set_attr "type" "smpy")])
1582 (define_insn "mulhisi3_i"
1583 [(set (reg:SI MACL_REG)
1584 (mult:SI (sign_extend:SI
1585 (match_operand:HI 0 "arith_reg_operand" "r"))
1587 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1590 [(set_attr "type" "smpy")])
1592 (define_expand "mulhisi3"
1593 [(set (reg:SI MACL_REG)
1594 (mult:SI (sign_extend:SI
1595 (match_operand:HI 1 "arith_reg_operand" ""))
1597 (match_operand:HI 2 "arith_reg_operand" ""))))
1598 (set (match_operand:SI 0 "arith_reg_operand" "")
1605 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1606 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1607 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1608 invariant code motion can move it. */
1609 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1610 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1611 /* expand_binop can't find a suitable code in umul_widen_optab to
1612 make a REG_EQUAL note from, so make one here.
1613 See also smulsi3_highpart.
1614 ??? Alternatively, we could put this at the calling site of expand_binop,
1615 i.e. expand_expr. */
1617 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1622 (define_expand "umulhisi3"
1623 [(set (reg:SI MACL_REG)
1624 (mult:SI (zero_extend:SI
1625 (match_operand:HI 1 "arith_reg_operand" ""))
1627 (match_operand:HI 2 "arith_reg_operand" ""))))
1628 (set (match_operand:SI 0 "arith_reg_operand" "")
1635 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1636 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1637 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1638 invariant code motion can move it. */
1639 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1640 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1641 /* expand_binop can't find a suitable code in umul_widen_optab to
1642 make a REG_EQUAL note from, so make one here.
1643 See also smulsi3_highpart.
1644 ??? Alternatively, we could put this at the calling site of expand_binop,
1645 i.e. expand_expr. */
1647 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1652 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1653 ;; a call to a routine which clobbers known registers.
1656 [(set (match_operand:SI 1 "register_operand" "=z")
1657 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1658 (clobber (reg:SI MACL_REG))
1659 (clobber (reg:SI T_REG))
1660 (clobber (reg:SI PR_REG))
1661 (clobber (reg:SI R3_REG))
1662 (clobber (reg:SI R2_REG))
1663 (clobber (reg:SI R1_REG))
1664 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1667 [(set_attr "type" "sfunc")
1668 (set_attr "needs_delay_slot" "yes")])
1670 (define_expand "mulsi3_call"
1671 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1672 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1673 (parallel[(set (match_operand:SI 0 "register_operand" "")
1674 (mult:SI (reg:SI R4_REG)
1676 (clobber (reg:SI MACL_REG))
1677 (clobber (reg:SI T_REG))
1678 (clobber (reg:SI PR_REG))
1679 (clobber (reg:SI R3_REG))
1680 (clobber (reg:SI R2_REG))
1681 (clobber (reg:SI R1_REG))
1682 (use (match_operand:SI 3 "register_operand" ""))])]
1686 (define_insn "mul_l"
1687 [(set (reg:SI MACL_REG)
1688 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1689 (match_operand:SI 1 "arith_reg_operand" "r")))]
1692 [(set_attr "type" "dmpy")])
1694 (define_expand "mulsi3"
1695 [(set (reg:SI MACL_REG)
1696 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1697 (match_operand:SI 2 "arith_reg_operand" "")))
1698 (set (match_operand:SI 0 "arith_reg_operand" "")
1707 /* The address must be set outside the libcall,
1708 since it goes into a pseudo. */
1709 rtx sym = function_symbol (\"__mulsi3\");
1710 rtx addr = force_reg (SImode, sym);
1711 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1714 last = emit_insn (insns);
1718 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1720 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1721 /* consec_sets_giv can only recognize the first insn that sets a
1722 giv as the giv insn. So we must tag this also with a REG_EQUAL
1724 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1726 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1727 invariant code motion can move it. */
1728 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1729 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1733 (define_insn "mulsidi3_i"
1734 [(set (reg:SI MACH_REG)
1738 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1739 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1741 (set (reg:SI MACL_REG)
1742 (mult:SI (match_dup 0)
1746 [(set_attr "type" "dmpy")])
1748 (define_expand "mulsidi3"
1749 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1750 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1751 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1752 "TARGET_SH2 || TARGET_SHMEDIA"
1757 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1763 (define_insn "mulsidi3_media"
1764 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1766 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1769 [(set_attr "type" "dmpy_media")])
1771 (define_insn "mulsidi3_compact"
1772 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1774 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1775 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1776 (clobber (reg:SI MACH_REG))
1777 (clobber (reg:SI MACL_REG))]
1782 [(set (match_operand:DI 0 "arith_reg_operand" "")
1784 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1785 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1786 (clobber (reg:SI MACH_REG))
1787 (clobber (reg:SI MACL_REG))]
1792 rtx low_dst = gen_lowpart (SImode, operands[0]);
1793 rtx high_dst = gen_highpart (SImode, operands[0]);
1795 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1797 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1798 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1799 /* We need something to tag the possible REG_EQUAL notes on to. */
1800 emit_move_insn (operands[0], operands[0]);
1804 (define_insn "umulsidi3_i"
1805 [(set (reg:SI MACH_REG)
1809 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1810 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1812 (set (reg:SI MACL_REG)
1813 (mult:SI (match_dup 0)
1817 [(set_attr "type" "dmpy")])
1819 (define_expand "umulsidi3"
1820 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1821 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1822 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1823 "TARGET_SH2 || TARGET_SHMEDIA"
1828 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1834 (define_insn "umulsidi3_media"
1835 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1836 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1837 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1840 [(set_attr "type" "dmpy_media")])
1842 (define_insn "umulsidi3_compact"
1843 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1845 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1846 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1847 (clobber (reg:SI MACH_REG))
1848 (clobber (reg:SI MACL_REG))]
1853 [(set (match_operand:DI 0 "arith_reg_operand" "")
1854 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1855 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1856 (clobber (reg:SI MACH_REG))
1857 (clobber (reg:SI MACL_REG))]
1862 rtx low_dst = gen_lowpart (SImode, operands[0]);
1863 rtx high_dst = gen_highpart (SImode, operands[0]);
1865 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1867 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1868 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1869 /* We need something to tag the possible REG_EQUAL notes on to. */
1870 emit_move_insn (operands[0], operands[0]);
1874 (define_insn "smulsi3_highpart_i"
1875 [(set (reg:SI MACH_REG)
1879 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1880 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1882 (clobber (reg:SI MACL_REG))]
1885 [(set_attr "type" "dmpy")])
1887 (define_expand "smulsi3_highpart"
1889 [(set (reg:SI MACH_REG)
1893 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1894 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1896 (clobber (reg:SI MACL_REG))])
1897 (set (match_operand:SI 0 "arith_reg_operand" "")
1904 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1905 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1906 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1907 invariant code motion can move it. */
1908 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1909 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1910 /* expand_binop can't find a suitable code in mul_highpart_optab to
1911 make a REG_EQUAL note from, so make one here.
1912 See also {,u}mulhisi.
1913 ??? Alternatively, we could put this at the calling site of expand_binop,
1914 i.e. expand_mult_highpart. */
1916 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1921 (define_insn "umulsi3_highpart_i"
1922 [(set (reg:SI MACH_REG)
1926 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1927 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1929 (clobber (reg:SI MACL_REG))]
1932 [(set_attr "type" "dmpy")])
1934 (define_expand "umulsi3_highpart"
1936 [(set (reg:SI MACH_REG)
1940 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1941 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1943 (clobber (reg:SI MACL_REG))])
1944 (set (match_operand:SI 0 "arith_reg_operand" "")
1951 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1952 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1953 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1954 invariant code motion can move it. */
1955 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1956 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1960 ;; -------------------------------------------------------------------------
1961 ;; Logical operations
1962 ;; -------------------------------------------------------------------------
1964 (define_insn "*andsi3_compact"
1965 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967 (match_operand:SI 2 "logical_operand" "r,K08")))]
1970 [(set_attr "type" "arith")])
1972 ;; If the constant is 255, then emit an extu.b instruction instead of an
1973 ;; and, since that will give better code.
1975 (define_expand "andsi3"
1976 [(set (match_operand:SI 0 "arith_reg_operand" "")
1977 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1978 (match_operand:SI 2 "logical_operand" "")))]
1982 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1984 emit_insn (gen_zero_extendqisi2 (operands[0],
1985 gen_lowpart (QImode, operands[1])));
1990 (define_insn_and_split "anddi3"
1991 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1992 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1993 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
2000 && ! logical_operand (operands[2], DImode)"
2004 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2005 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2007 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2010 [(set_attr "type" "arith_media")])
2012 (define_insn "andcdi3"
2013 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2014 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2015 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2018 [(set_attr "type" "arith_media")])
2020 (define_insn "iorsi3"
2021 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2022 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2023 (match_operand:SI 2 "logical_operand" "r,K08")))]
2026 [(set_attr "type" "arith")])
2028 (define_insn "iordi3"
2029 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2030 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2031 (match_operand:DI 2 "logical_operand" "r,I10")))]
2036 [(set_attr "type" "arith_media")])
2038 (define_insn "xorsi3"
2039 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2040 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2041 (match_operand:SI 2 "logical_operand" "K08,r")))]
2044 [(set_attr "type" "arith")])
2046 (define_insn "xordi3"
2047 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2048 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2049 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2054 [(set_attr "type" "arith_media")])
2056 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2057 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2059 [(set (match_operand:DI 0 "arith_reg_operand" "")
2060 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2061 [(match_operand 1 "any_register_operand" "")
2062 (match_operand 2 "any_register_operand" "")])))]
2064 [(set (match_dup 5) (match_dup 4))
2065 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2068 enum machine_mode inmode = GET_MODE (operands[1]);
2071 if (GET_CODE (operands[0]) == SUBREG)
2073 offset = SUBREG_BYTE (operands[0]);
2074 operands[0] = SUBREG_REG (operands[0]);
2076 if (GET_CODE (operands[0]) != REG)
2078 if (! TARGET_LITTLE_ENDIAN)
2079 offset += 8 - GET_MODE_SIZE (inmode);
2080 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2083 ;; -------------------------------------------------------------------------
2084 ;; Shifts and rotates
2085 ;; -------------------------------------------------------------------------
2087 (define_expand "rotldi3"
2088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2089 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2090 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2092 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2094 (define_insn "rotldi3_mextr"
2095 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2096 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2097 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2101 static char templ[16];
2103 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2104 8 - (int) (INTVAL (operands[2]) >> 3));
2107 [(set_attr "type" "arith_media")])
2109 (define_expand "rotrdi3"
2110 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2111 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2112 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2114 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2116 (define_insn "rotrdi3_mextr"
2117 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2118 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2119 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2123 static char templ[16];
2125 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2128 [(set_attr "type" "arith_media")])
2130 (define_insn "rotlsi3_1"
2131 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2135 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2138 [(set_attr "type" "arith")])
2140 (define_insn "rotlsi3_31"
2141 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2142 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2144 (clobber (reg:SI T_REG))]
2147 [(set_attr "type" "arith")])
2149 (define_insn "rotlsi3_16"
2150 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2151 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2155 [(set_attr "type" "arith")])
2157 (define_expand "rotlsi3"
2158 [(set (match_operand:SI 0 "arith_reg_operand" "")
2159 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2160 (match_operand:SI 2 "immediate_operand" "")))]
2164 static const char rot_tab[] = {
2165 000, 000, 000, 000, 000, 000, 010, 001,
2166 001, 001, 011, 013, 003, 003, 003, 003,
2167 003, 003, 003, 003, 003, 013, 012, 002,
2168 002, 002, 010, 000, 000, 000, 000, 000,
2173 if (GET_CODE (operands[2]) != CONST_INT)
2175 count = INTVAL (operands[2]);
2176 choice = rot_tab[count];
2177 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2183 emit_move_insn (operands[0], operands[1]);
2184 count -= (count & 16) * 2;
2187 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2194 parts[0] = gen_reg_rtx (SImode);
2195 parts[1] = gen_reg_rtx (SImode);
2196 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2197 emit_move_insn (parts[choice-1], operands[1]);
2198 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2199 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2200 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2201 count = (count & ~16) - 8;
2205 for (; count > 0; count--)
2206 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2207 for (; count < 0; count++)
2208 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2213 (define_insn "*rotlhi3_8"
2214 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2215 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2219 [(set_attr "type" "arith")])
2221 (define_expand "rotlhi3"
2222 [(set (match_operand:HI 0 "arith_reg_operand" "")
2223 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2224 (match_operand:HI 2 "immediate_operand" "")))]
2228 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2235 ;; This pattern is used by init_expmed for computing the costs of shift
2238 (define_insn_and_split "ashlsi3_std"
2239 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2240 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2241 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2242 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2244 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2245 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2253 && GET_CODE (operands[2]) == CONST_INT
2254 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2255 [(set (match_dup 3) (match_dup 2))
2257 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2258 (clobber (match_dup 4))])]
2259 "operands[4] = gen_rtx_SCRATCH (SImode);"
2260 [(set_attr "length" "*,*,*,4")
2261 (set_attr "type" "dyn_shift,arith,arith,arith")])
2263 (define_insn "ashlhi3_k"
2264 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2265 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2266 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2267 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2271 [(set_attr "type" "arith")])
2273 (define_insn "ashlsi3_n"
2274 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2275 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2276 (match_operand:SI 2 "const_int_operand" "n")))
2277 (clobber (reg:SI T_REG))]
2278 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2280 [(set (attr "length")
2281 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2283 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2285 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2287 (const_string "8")))
2288 (set_attr "type" "arith")])
2291 [(set (match_operand:SI 0 "arith_reg_operand" "")
2292 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2293 (match_operand:SI 2 "const_int_operand" "")))
2294 (clobber (reg:SI T_REG))]
2295 "TARGET_SH1 && reload_completed"
2296 [(use (reg:SI R0_REG))]
2299 gen_shifty_op (ASHIFT, operands);
2303 (define_insn "ashlsi3_media"
2304 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2305 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2306 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2311 [(set_attr "type" "arith_media")])
2313 (define_expand "ashlsi3"
2314 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2315 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2316 (match_operand:SI 2 "nonmemory_operand" "")))
2317 (clobber (reg:SI T_REG))])]
2323 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2326 if (GET_CODE (operands[2]) == CONST_INT
2327 && sh_dynamicalize_shift_p (operands[2]))
2328 operands[2] = force_reg (SImode, operands[2]);
2331 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2334 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2338 (define_insn "ashlhi3"
2339 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2340 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2341 (match_operand:HI 2 "const_int_operand" "n")))
2342 (clobber (reg:SI T_REG))]
2345 [(set (attr "length")
2346 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2348 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2350 (const_string "6")))
2351 (set_attr "type" "arith")])
2354 [(set (match_operand:HI 0 "arith_reg_operand" "")
2355 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2356 (match_operand:HI 2 "const_int_operand" "")))
2357 (clobber (reg:SI T_REG))]
2358 "TARGET_SH1 && reload_completed"
2359 [(use (reg:SI R0_REG))]
2362 gen_shifty_hi_op (ASHIFT, operands);
2367 ; arithmetic shift right
2370 (define_insn "ashrsi3_k"
2371 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2372 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2373 (match_operand:SI 2 "const_int_operand" "M")))
2374 (clobber (reg:SI T_REG))]
2375 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2377 [(set_attr "type" "arith")])
2379 ;; We can't do HImode right shifts correctly unless we start out with an
2380 ;; explicit zero / sign extension; doing that would result in worse overall
2381 ;; code, so just let the machine independent code widen the mode.
2382 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2385 ;; ??? This should be a define expand.
2387 (define_insn "ashrsi2_16"
2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2393 [(set_attr "length" "4")])
2396 [(set (match_operand:SI 0 "arith_reg_operand" "")
2397 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2400 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2401 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2402 "operands[2] = gen_lowpart (HImode, operands[0]);")
2404 ;; ??? This should be a define expand.
2406 (define_insn "ashrsi2_31"
2407 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2408 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2410 (clobber (reg:SI T_REG))]
2413 [(set_attr "length" "4")])
2416 [(set (match_operand:SI 0 "arith_reg_operand" "")
2417 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2419 (clobber (reg:SI T_REG))]
2424 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2425 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2429 (define_insn "ashlsi_c"
2430 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2431 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2433 (lt:SI (match_dup 1) (const_int 0)))]
2436 [(set_attr "type" "arith")])
2438 (define_insn "ashrsi3_d"
2439 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2440 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2441 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2444 [(set_attr "type" "dyn_shift")])
2446 (define_insn "ashrsi3_n"
2447 [(set (reg:SI R4_REG)
2448 (ashiftrt:SI (reg:SI R4_REG)
2449 (match_operand:SI 0 "const_int_operand" "i")))
2450 (clobber (reg:SI T_REG))
2451 (clobber (reg:SI PR_REG))
2452 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2455 [(set_attr "type" "sfunc")
2456 (set_attr "needs_delay_slot" "yes")])
2458 (define_insn "ashrsi3_media"
2459 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2460 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2461 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2466 [(set_attr "type" "arith_media")])
2468 (define_expand "ashrsi3"
2469 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2470 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2471 (match_operand:SI 2 "nonmemory_operand" "")))
2472 (clobber (reg:SI T_REG))])]
2478 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2481 if (expand_ashiftrt (operands))
2487 ;; logical shift right
2489 (define_insn "lshrsi3_d"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2495 [(set_attr "type" "dyn_shift")])
2497 ;; Only the single bit shift clobbers the T bit.
2499 (define_insn "lshrsi3_m"
2500 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2501 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2502 (match_operand:SI 2 "const_int_operand" "M")))
2503 (clobber (reg:SI T_REG))]
2504 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2506 [(set_attr "type" "arith")])
2508 (define_insn "lshrsi3_k"
2509 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2510 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2511 (match_operand:SI 2 "const_int_operand" "P27")))]
2512 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2513 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2515 [(set_attr "type" "arith")])
2517 (define_insn "lshrsi3_n"
2518 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2519 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2520 (match_operand:SI 2 "const_int_operand" "n")))
2521 (clobber (reg:SI T_REG))]
2522 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2524 [(set (attr "length")
2525 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2527 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2529 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2531 (const_string "8")))
2532 (set_attr "type" "arith")])
2535 [(set (match_operand:SI 0 "arith_reg_operand" "")
2536 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2537 (match_operand:SI 2 "const_int_operand" "")))
2538 (clobber (reg:SI T_REG))]
2539 "TARGET_SH1 && reload_completed"
2540 [(use (reg:SI R0_REG))]
2543 gen_shifty_op (LSHIFTRT, operands);
2547 (define_insn "lshrsi3_media"
2548 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2549 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2550 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2555 [(set_attr "type" "arith_media")])
2557 (define_expand "lshrsi3"
2558 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2559 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2560 (match_operand:SI 2 "nonmemory_operand" "")))
2561 (clobber (reg:SI T_REG))])]
2567 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2570 if (GET_CODE (operands[2]) == CONST_INT
2571 && sh_dynamicalize_shift_p (operands[2]))
2572 operands[2] = force_reg (SImode, operands[2]);
2573 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2575 rtx count = copy_to_mode_reg (SImode, operands[2]);
2576 emit_insn (gen_negsi2 (count, count));
2577 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2580 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2584 ;; ??? This should be a define expand.
2586 (define_insn "ashldi3_k"
2587 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2588 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2590 (clobber (reg:SI T_REG))]
2592 "shll %R0\;rotcl %S0"
2593 [(set_attr "length" "4")
2594 (set_attr "type" "arith")])
2596 (define_insn "ashldi3_media"
2597 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2598 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2599 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2604 [(set_attr "type" "arith_media")])
2606 (define_expand "ashldi3"
2607 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2608 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2609 (match_operand:DI 2 "immediate_operand" "")))
2610 (clobber (reg:SI T_REG))])]
2616 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2619 if (GET_CODE (operands[2]) != CONST_INT
2620 || INTVAL (operands[2]) != 1)
2624 ;; ??? This should be a define expand.
2626 (define_insn "lshrdi3_k"
2627 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2628 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2630 (clobber (reg:SI T_REG))]
2632 "shlr %S0\;rotcr %R0"
2633 [(set_attr "length" "4")
2634 (set_attr "type" "arith")])
2636 (define_insn "lshrdi3_media"
2637 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2638 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2639 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2644 [(set_attr "type" "arith_media")])
2646 (define_expand "lshrdi3"
2647 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2648 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2649 (match_operand:DI 2 "immediate_operand" "")))
2650 (clobber (reg:SI T_REG))])]
2656 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2659 if (GET_CODE (operands[2]) != CONST_INT
2660 || INTVAL (operands[2]) != 1)
2664 ;; ??? This should be a define expand.
2666 (define_insn "ashrdi3_k"
2667 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2668 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2670 (clobber (reg:SI T_REG))]
2672 "shar %S0\;rotcr %R0"
2673 [(set_attr "length" "4")
2674 (set_attr "type" "arith")])
2676 (define_insn "ashrdi3_media"
2677 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2678 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2679 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2684 [(set_attr "type" "arith_media")])
2686 (define_expand "ashrdi3"
2687 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2688 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2689 (match_operand:DI 2 "immediate_operand" "")))
2690 (clobber (reg:SI T_REG))])]
2696 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2699 if (GET_CODE (operands[2]) != CONST_INT
2700 || INTVAL (operands[2]) != 1)
2704 ;; combined left/right shift
2707 [(set (match_operand:SI 0 "register_operand" "")
2708 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2709 (match_operand:SI 2 "const_int_operand" ""))
2710 (match_operand:SI 3 "const_int_operand" "")))]
2711 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2712 [(use (reg:SI R0_REG))]
2713 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2717 [(set (match_operand:SI 0 "register_operand" "")
2718 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2719 (match_operand:SI 2 "const_int_operand" ""))
2720 (match_operand:SI 3 "const_int_operand" "")))
2721 (clobber (reg:SI T_REG))]
2722 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2723 [(use (reg:SI R0_REG))]
2724 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2728 [(set (match_operand:SI 0 "register_operand" "=r")
2729 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730 (match_operand:SI 2 "const_int_operand" "n"))
2731 (match_operand:SI 3 "const_int_operand" "n")))
2732 (clobber (reg:SI T_REG))]
2733 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2735 [(set (attr "length")
2736 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2738 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2740 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2742 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2744 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2746 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2748 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2749 (const_string "16")]
2750 (const_string "18")))
2751 (set_attr "type" "arith")])
2754 [(set (match_operand:SI 0 "register_operand" "=z")
2755 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2756 (match_operand:SI 2 "const_int_operand" "n"))
2757 (match_operand:SI 3 "const_int_operand" "n")))
2758 (clobber (reg:SI T_REG))]
2759 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2761 [(set (attr "length")
2762 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2764 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2766 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2768 (const_string "10")))
2769 (set_attr "type" "arith")])
2771 ;; shift left / and combination with a scratch register: The combine pass
2772 ;; does not accept the individual instructions, even though they are
2773 ;; cheap. But it needs a precise description so that it is usable after
2775 (define_insn "and_shl_scratch"
2776 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2780 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2781 (match_operand:SI 2 "const_int_operand" "N,n"))
2782 (match_operand:SI 3 "" "0,r"))
2783 (match_operand:SI 4 "const_int_operand" "n,n"))
2784 (match_operand:SI 5 "const_int_operand" "n,n")))
2785 (clobber (reg:SI T_REG))]
2788 [(set (attr "length")
2789 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2791 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2793 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2795 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2796 (const_string "10")]
2797 (const_string "12")))
2798 (set_attr "type" "arith")])
2801 [(set (match_operand:SI 0 "register_operand" "")
2805 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2806 (match_operand:SI 2 "const_int_operand" ""))
2807 (match_operand:SI 3 "register_operand" ""))
2808 (match_operand:SI 4 "const_int_operand" ""))
2809 (match_operand:SI 5 "const_int_operand" "")))
2810 (clobber (reg:SI T_REG))]
2812 [(use (reg:SI R0_REG))]
2815 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2817 if (INTVAL (operands[2]))
2819 gen_shifty_op (LSHIFTRT, operands);
2821 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2822 operands[2] = operands[4];
2823 gen_shifty_op (ASHIFT, operands);
2824 if (INTVAL (operands[5]))
2826 operands[2] = operands[5];
2827 gen_shifty_op (LSHIFTRT, operands);
2832 ;; signed left/right shift combination.
2834 [(set (match_operand:SI 0 "register_operand" "")
2836 (ashift:SI (match_operand:SI 1 "register_operand" "")
2837 (match_operand:SI 2 "const_int_operand" ""))
2838 (match_operand:SI 3 "const_int_operand" "")
2840 (clobber (reg:SI T_REG))]
2842 [(use (reg:SI R0_REG))]
2843 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2846 (define_insn "shl_sext_ext"
2847 [(set (match_operand:SI 0 "register_operand" "=r")
2849 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2850 (match_operand:SI 2 "const_int_operand" "n"))
2851 (match_operand:SI 3 "const_int_operand" "n")
2853 (clobber (reg:SI T_REG))]
2854 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2856 [(set (attr "length")
2857 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2859 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2861 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2863 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2865 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2867 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2869 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2871 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2872 (const_string "16")]
2873 (const_string "18")))
2874 (set_attr "type" "arith")])
2876 (define_insn "shl_sext_sub"
2877 [(set (match_operand:SI 0 "register_operand" "=z")
2879 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2880 (match_operand:SI 2 "const_int_operand" "n"))
2881 (match_operand:SI 3 "const_int_operand" "n")
2883 (clobber (reg:SI T_REG))]
2884 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2886 [(set (attr "length")
2887 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2889 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2891 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2893 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2894 (const_string "12")]
2895 (const_string "14")))
2896 (set_attr "type" "arith")])
2898 ;; These patterns are found in expansions of DImode shifts by 16, and
2899 ;; allow the xtrct instruction to be generated from C source.
2901 (define_insn "xtrct_left"
2902 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2905 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2909 [(set_attr "type" "arith")])
2911 (define_insn "xtrct_right"
2912 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2915 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2919 [(set_attr "type" "arith")])
2921 ;; -------------------------------------------------------------------------
2923 ;; -------------------------------------------------------------------------
2926 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2927 (neg:SI (plus:SI (reg:SI T_REG)
2928 (match_operand:SI 1 "arith_reg_operand" "r"))))
2930 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2934 [(set_attr "type" "arith")])
2936 (define_insn "*negdi_media"
2937 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2938 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2941 [(set_attr "type" "arith_media")])
2943 (define_expand "negdi2"
2944 [(set (match_operand:DI 0 "arith_reg_operand" "")
2945 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2951 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2952 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2954 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2955 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2957 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2958 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2960 emit_insn (gen_clrt ());
2961 emit_insn (gen_negc (low_dst, low_src));
2962 emit_insn (gen_negc (high_dst, high_src));
2967 (define_insn "negsi2"
2968 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2969 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2972 [(set_attr "type" "arith")])
2974 (define_insn "one_cmplsi2"
2975 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2979 [(set_attr "type" "arith")])
2981 (define_expand "one_cmpldi2"
2982 [(set (match_operand:DI 0 "arith_reg_operand" "")
2983 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2985 "TARGET_SHMEDIA" "")
2987 ;; -------------------------------------------------------------------------
2988 ;; Zero extension instructions
2989 ;; -------------------------------------------------------------------------
2991 (define_insn "zero_extendsidi2"
2992 [(set (match_operand:DI 0 "register_operand" "=r")
2993 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2995 "addz.l %1, r63, %0"
2996 [(set_attr "type" "arith_media")])
2998 (define_insn "zero_extendhidi2"
2999 [(set (match_operand:DI 0 "register_operand" "=r,r")
3000 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3005 [(set_attr "type" "*,load_media")])
3008 [(set (match_operand:DI 0 "register_operand" "")
3009 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3010 "TARGET_SHMEDIA && reload_completed"
3011 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3012 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3015 if (GET_CODE (operands[1]) == TRUNCATE)
3016 operands[1] = XEXP (operands[1], 0);
3019 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3020 ;; reload the entire truncate expression.
3021 (define_insn_and_split "*loaddi_trunc"
3022 [(set (match_operand 0 "int_gpr_dest" "=r")
3023 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3024 "TARGET_SHMEDIA && reload_completed"
3026 "TARGET_SHMEDIA && reload_completed"
3027 [(set (match_dup 0) (match_dup 1))]
3028 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3030 (define_insn "zero_extendqidi2"
3031 [(set (match_operand:DI 0 "register_operand" "=r,r")
3032 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3037 [(set_attr "type" "arith_media,load_media")])
3039 (define_expand "zero_extendhisi2"
3040 [(set (match_operand:SI 0 "arith_reg_operand" "")
3041 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3045 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3046 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3049 (define_insn "*zero_extendhisi2_compact"
3050 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3051 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3054 [(set_attr "type" "arith")])
3056 (define_insn "*zero_extendhisi2_media"
3057 [(set (match_operand:SI 0 "register_operand" "=r,r")
3058 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3063 [(set_attr "type" "arith_media,load_media")])
3066 [(set (match_operand:SI 0 "register_operand" "")
3067 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3068 "TARGET_SHMEDIA && reload_completed"
3069 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3070 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3073 if (GET_CODE (operands[1]) == TRUNCATE)
3074 operands[1] = XEXP (operands[1], 0);
3077 (define_expand "zero_extendqisi2"
3078 [(set (match_operand:SI 0 "arith_reg_operand" "")
3079 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3083 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3084 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3087 (define_insn "*zero_extendqisi2_compact"
3088 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3089 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3092 [(set_attr "type" "arith")])
3094 (define_insn "*zero_extendqisi2_media"
3095 [(set (match_operand:SI 0 "register_operand" "=r,r")
3096 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3101 [(set_attr "type" "arith_media,load_media")])
3103 (define_insn "zero_extendqihi2"
3104 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3105 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3108 [(set_attr "type" "arith")])
3110 ;; -------------------------------------------------------------------------
3111 ;; Sign extension instructions
3112 ;; -------------------------------------------------------------------------
3114 ;; ??? This should be a define expand.
3115 ;; ??? Or perhaps it should be dropped?
3117 ;; convert_move generates good code for SH[1-4].
3118 (define_insn "extendsidi2"
3119 [(set (match_operand:DI 0 "register_operand" "=r,r")
3120 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3125 [(set_attr "type" "arith_media,load_media")])
3127 (define_insn "extendhidi2"
3128 [(set (match_operand:DI 0 "register_operand" "=r,r")
3129 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3134 [(set_attr "type" "*,load_media")])
3137 [(set (match_operand:DI 0 "register_operand" "")
3138 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3139 "TARGET_SHMEDIA && reload_completed"
3140 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3141 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3144 if (GET_CODE (operands[1]) == TRUNCATE)
3145 operands[1] = XEXP (operands[1], 0);
3148 (define_insn "extendqidi2"
3149 [(set (match_operand:DI 0 "register_operand" "=r,r")
3150 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3155 [(set_attr "type" "*,load_media")])
3158 [(set (match_operand:DI 0 "register_operand" "")
3159 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3160 "TARGET_SHMEDIA && reload_completed"
3161 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3162 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3165 if (GET_CODE (operands[1]) == TRUNCATE)
3166 operands[1] = XEXP (operands[1], 0);
3169 (define_expand "extendhisi2"
3170 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3171 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3175 (define_insn "*extendhisi2_compact"
3176 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3177 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3182 [(set_attr "type" "arith,load")])
3184 (define_insn "*extendhisi2_media"
3185 [(set (match_operand:SI 0 "register_operand" "=r,r")
3186 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3191 [(set_attr "type" "arith_media,load_media")])
3194 [(set (match_operand:SI 0 "register_operand" "")
3195 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3196 "TARGET_SHMEDIA && reload_completed"
3197 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3198 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3201 if (GET_CODE (operands[1]) == TRUNCATE)
3202 operands[1] = XEXP (operands[1], 0);
3205 (define_expand "extendqisi2"
3206 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3207 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3211 (define_insn "*extendqisi2_compact"
3212 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3213 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3218 [(set_attr "type" "arith,load")])
3220 (define_insn "*extendqisi2_media"
3221 [(set (match_operand:SI 0 "register_operand" "=r,r")
3222 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3227 [(set_attr "type" "arith_media,load_media")])
3230 [(set (match_operand:SI 0 "register_operand" "")
3231 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3232 "TARGET_SHMEDIA && reload_completed"
3233 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3234 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3237 if (GET_CODE (operands[1]) == TRUNCATE)
3238 operands[1] = XEXP (operands[1], 0);
3241 (define_insn "extendqihi2"
3242 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3243 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3248 [(set_attr "type" "arith,load")])
3250 /* It would seem useful to combine the truncXi patterns into the movXi
3251 patterns, but unary operators are ignored when matching constraints,
3252 so we need separate patterns. */
3253 (define_insn "truncdisi2"
3254 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3255 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3264 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3267 (define_insn "truncdihi2"
3268 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3269 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3272 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3274 [(set_attr "type" "arith_media,store_media")
3275 (set_attr "length" "8,4")])
3277 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3278 ; Because we use zero extension, we can't provide signed QImode compares
3279 ; using a simple compare or conditional banch insn.
3280 (define_insn "truncdiqi2"
3281 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3282 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3287 [(set_attr "type" "arith_media,store")])
3289 ;; -------------------------------------------------------------------------
3290 ;; Move instructions
3291 ;; -------------------------------------------------------------------------
3293 ;; define push and pop so it is easy for sh.c
3294 ;; We can't use push and pop on SHcompact because the stack must always
3295 ;; be 8-byte aligned.
3297 (define_expand "push"
3298 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3299 (match_operand:SI 0 "register_operand" "r,l,x"))]
3300 "TARGET_SH1 && ! TARGET_SH5"
3303 (define_expand "pop"
3304 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3305 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3306 "TARGET_SH1 && ! TARGET_SH5"
3309 (define_expand "push_e"
3310 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3311 (match_operand:SF 0 "" ""))
3312 (use (reg:PSI FPSCR_REG))
3313 (clobber (scratch:SI))])]
3314 "TARGET_SH1 && ! TARGET_SH5"
3317 (define_insn "push_fpul"
3318 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3319 "TARGET_SH2E && ! TARGET_SH5"
3321 [(set_attr "type" "store")
3322 (set_attr "late_fp_use" "yes")
3323 (set_attr "hit_stack" "yes")])
3325 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3327 (define_expand "push_4"
3328 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3329 (match_operand:DF 0 "" ""))
3330 (use (reg:PSI FPSCR_REG))
3331 (clobber (scratch:SI))])]
3332 "TARGET_SH1 && ! TARGET_SH5"
3335 (define_expand "pop_e"
3336 [(parallel [(set (match_operand:SF 0 "" "")
3337 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3338 (use (reg:PSI FPSCR_REG))
3339 (clobber (scratch:SI))])]
3340 "TARGET_SH1 && ! TARGET_SH5"
3343 (define_insn "pop_fpul"
3344 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3345 "TARGET_SH2E && ! TARGET_SH5"
3347 [(set_attr "type" "load")
3348 (set_attr "hit_stack" "yes")])
3350 (define_expand "pop_4"
3351 [(parallel [(set (match_operand:DF 0 "" "")
3352 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3353 (use (reg:PSI FPSCR_REG))
3354 (clobber (scratch:SI))])]
3355 "TARGET_SH1 && ! TARGET_SH5"
3358 (define_expand "push_fpscr"
3363 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3364 gen_rtx_PRE_DEC (Pmode,
3365 stack_pointer_rtx)),
3367 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3371 (define_expand "pop_fpscr"
3376 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3377 gen_rtx_MEM (PSImode,
3378 gen_rtx_POST_INC (Pmode,
3379 stack_pointer_rtx))));
3380 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3384 ;; These two patterns can happen as the result of optimization, when
3385 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3386 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3389 [(set (reg:SI T_REG) (const_int 0))]
3394 [(set (reg:SI T_REG) (const_int 1))]
3398 ;; t/r must come after r/r, lest reload will try to reload stuff like
3399 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3400 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3401 (define_insn "movsi_i"
3402 [(set (match_operand:SI 0 "general_movdst_operand"
3403 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3404 (match_operand:SI 1 "general_movsrc_operand"
3405 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3408 && (register_operand (operands[0], SImode)
3409 || register_operand (operands[1], SImode))"
3426 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3427 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3429 ;; t/r must come after r/r, lest reload will try to reload stuff like
3430 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3431 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3432 ;; will require a reload.
3433 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3434 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3435 (define_insn "movsi_ie"
3436 [(set (match_operand:SI 0 "general_movdst_operand"
3437 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3438 (match_operand:SI 1 "general_movsrc_operand"
3439 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3441 && (register_operand (operands[0], SImode)
3442 || register_operand (operands[1], SImode))"
3466 ! move optimized away"
3467 [(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")
3468 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3469 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3471 (define_insn "movsi_i_lowpart"
3472 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3473 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3475 && (register_operand (operands[0], SImode)
3476 || register_operand (operands[1], SImode))"
3486 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3488 (define_insn_and_split "load_ra"
3489 [(set (match_operand:SI 0 "general_movdst_operand" "")
3490 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3493 "&& ! rtx_equal_function_value_matters"
3494 [(set (match_dup 0) (match_dup 1))]
3497 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3498 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3501 (define_insn "*movsi_media"
3502 [(set (match_operand:SI 0 "general_movdst_operand"
3503 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3504 (match_operand:SI 1 "general_movsrc_operand"
3505 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3507 && (register_operand (operands[0], SImode)
3508 || sh_register_operand (operands[1], SImode))"
3523 [(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")
3524 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3526 (define_insn "*movsi_media_nofpu"
3527 [(set (match_operand:SI 0 "general_movdst_operand"
3528 "=r,r,r,r,m,*b,r,b")
3529 (match_operand:SI 1 "general_movsrc_operand"
3530 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3532 && (register_operand (operands[0], SImode)
3533 || sh_register_operand (operands[1], SImode))"
3543 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3544 (set_attr "length" "4,4,8,4,4,4,4,12")])
3547 [(set (match_operand:SI 0 "arith_reg_operand" "")
3548 (match_operand:SI 1 "immediate_operand" ""))]
3549 "TARGET_SHMEDIA && reload_completed
3550 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3551 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3554 operands[2] = shallow_copy_rtx (operands[1]);
3555 PUT_MODE (operands[2], DImode);
3559 [(set (match_operand:SI 0 "register_operand" "")
3560 (match_operand:SI 1 "immediate_operand" ""))]
3561 "TARGET_SHMEDIA && reload_completed
3562 && ((GET_CODE (operands[1]) == CONST_INT
3563 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3564 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3565 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3567 (define_expand "movsi"
3568 [(set (match_operand:SI 0 "general_movdst_operand" "")
3569 (match_operand:SI 1 "general_movsrc_operand" ""))]
3571 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3573 (define_expand "ic_invalidate_line"
3574 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3575 (match_dup 1)] UNSPEC_ICACHE)
3576 (clobber (scratch:SI))])]
3577 "TARGET_HARD_SH4 || TARGET_SH5"
3582 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3585 else if (TARGET_SHCOMPACT)
3587 operands[1] = function_symbol (\"__ic_invalidate\");
3588 operands[1] = force_reg (Pmode, operands[1]);
3589 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3592 operands[0] = force_reg (Pmode, operands[0]);
3593 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3597 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3598 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3599 ;; the requirement *1*00 for associative address writes. The alignment of
3600 ;; %0 implies that its least significant bit is cleared,
3601 ;; thus we clear the V bit of a matching entry if there is one.
3602 (define_insn "ic_invalidate_line_i"
3603 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3604 (match_operand:SI 1 "register_operand" "r")]
3606 (clobber (match_scratch:SI 2 "=&r"))]
3608 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3609 [(set_attr "length" "8")
3610 (set_attr "type" "cwb")])
3612 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3613 ;; an add in the code that calculates the address.
3614 (define_insn "ic_invalidate_line_media"
3615 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3618 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3619 [(set_attr "length" "16")
3620 (set_attr "type" "invalidate_line_media")])
3622 (define_insn "ic_invalidate_line_compact"
3623 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3624 (match_operand:SI 1 "register_operand" "r")]
3626 (clobber (reg:SI PR_REG))]
3629 [(set_attr "type" "sfunc")
3630 (set_attr "needs_delay_slot" "yes")])
3632 (define_expand "initialize_trampoline"
3633 [(match_operand:SI 0 "" "")
3634 (match_operand:SI 1 "" "")
3635 (match_operand:SI 2 "" "")]
3641 tramp = force_reg (Pmode, operands[0]);
3642 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3643 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3644 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3646 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3650 (define_insn "initialize_trampoline_compact"
3651 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3652 (match_operand:SI 1 "register_operand" "r")
3653 (reg:SI R2_REG) (reg:SI R3_REG)]
3656 (clobber (reg:SI PR_REG))]
3659 [(set_attr "type" "sfunc")
3660 (set_attr "needs_delay_slot" "yes")])
3662 (define_insn "movqi_i"
3663 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3664 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3666 && (arith_reg_operand (operands[0], QImode)
3667 || arith_reg_operand (operands[1], QImode))"
3675 [(set_attr "type" "move,load,store,move,move,move")])
3677 (define_insn "*movqi_media"
3678 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3679 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3681 && (arith_reg_operand (operands[0], QImode)
3682 || arith_reg_or_0_operand (operands[1], QImode))"
3688 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3690 (define_expand "movqi"
3691 [(set (match_operand:QI 0 "general_operand" "")
3692 (match_operand:QI 1 "general_operand" ""))]
3694 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3696 (define_expand "reload_inqi"
3697 [(set (match_operand:SI 2 "" "=&r")
3698 (match_operand:QI 1 "inqhi_operand" ""))
3699 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3700 (truncate:QI (match_dup 3)))]
3704 rtx inner = XEXP (operands[1], 0);
3705 int regno = REGNO (inner);
3707 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3708 operands[1] = gen_rtx_REG (SImode, regno);
3709 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3712 /* When storing r0, we have to avoid reg+reg addressing. */
3713 (define_insn "movhi_i"
3714 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3715 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3717 && (arith_reg_operand (operands[0], HImode)
3718 || arith_reg_operand (operands[1], HImode))
3719 && (GET_CODE (operands[0]) != MEM
3720 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3721 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3722 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3732 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3734 (define_insn "*movhi_media"
3735 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3736 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3738 && (arith_reg_operand (operands[0], HImode)
3739 || arith_reg_or_0_operand (operands[1], HImode))"
3746 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3749 [(set (match_operand:HI 0 "register_operand" "")
3750 (match_operand:HI 1 "immediate_operand" ""))]
3751 "TARGET_SHMEDIA && reload_completed
3752 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3753 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3755 (define_expand "movhi"
3756 [(set (match_operand:HI 0 "general_movdst_operand" "")
3757 (match_operand:HI 1 "general_movsrc_operand" ""))]
3759 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3761 (define_expand "reload_inhi"
3762 [(set (match_operand:SI 2 "" "=&r")
3763 (match_operand:HI 1 "inqhi_operand" ""))
3764 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3765 (truncate:HI (match_dup 3)))]
3769 rtx inner = XEXP (operands[1], 0);
3770 int regno = REGNO (inner);
3772 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3773 operands[1] = gen_rtx_REG (SImode, regno);
3774 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3777 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3778 ;; compiled with -m2 -ml -O3 -funroll-loops
3779 (define_insn "*movdi_i"
3780 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3781 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3783 && (arith_reg_operand (operands[0], DImode)
3784 || arith_reg_operand (operands[1], DImode))"
3785 "* return output_movedouble (insn, operands, DImode);"
3786 [(set_attr "length" "4")
3787 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3789 ;; If the output is a register and the input is memory or a register, we have
3790 ;; to be careful and see which word needs to be loaded first.
3793 [(set (match_operand:DI 0 "general_movdst_operand" "")
3794 (match_operand:DI 1 "general_movsrc_operand" ""))]
3795 "TARGET_SH1 && reload_completed"
3796 [(set (match_dup 2) (match_dup 3))
3797 (set (match_dup 4) (match_dup 5))]
3802 if ((GET_CODE (operands[0]) == MEM
3803 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3804 || (GET_CODE (operands[1]) == MEM
3805 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3808 if (GET_CODE (operands[0]) == REG)
3809 regno = REGNO (operands[0]);
3810 else if (GET_CODE (operands[0]) == SUBREG)
3811 regno = subreg_regno (operands[0]);
3812 else if (GET_CODE (operands[0]) == MEM)
3818 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3820 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3821 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3822 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3823 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3827 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3828 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3829 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3830 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3833 if (operands[2] == 0 || operands[3] == 0
3834 || operands[4] == 0 || operands[5] == 0)
3838 (define_insn "*movdi_media"
3839 [(set (match_operand:DI 0 "general_movdst_operand"
3840 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3841 (match_operand:DI 1 "general_movsrc_operand"
3842 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3844 && (register_operand (operands[0], DImode)
3845 || sh_register_operand (operands[1], DImode))"
3860 [(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")
3861 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3863 (define_insn "*movdi_media_nofpu"
3864 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3865 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3867 && (register_operand (operands[0], DImode)
3868 || sh_register_operand (operands[1], DImode))"
3878 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3879 (set_attr "length" "4,4,16,4,4,4,4,*")])
3882 [(set (match_operand:DI 0 "arith_reg_operand" "")
3883 (match_operand:DI 1 "immediate_operand" ""))]
3884 "TARGET_SHMEDIA && reload_completed
3885 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3886 [(set (match_dup 0) (match_dup 1))]
3891 if (TARGET_SHMEDIA64)
3892 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3894 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3896 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3902 (define_expand "movdi_const"
3903 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3904 (const:DI (sign_extend:DI
3907 (match_operand:DI 1 "immediate_operand" "s")
3910 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3918 (const_int 32)))))))))
3920 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3928 (const_int 16)))))))))
3930 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3936 (match_dup 1))))))))]
3937 "TARGET_SHMEDIA64 && reload_completed
3938 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3941 sh_mark_label (operands[1], 4);
3944 (define_expand "movdi_const_32bit"
3945 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3946 (const:DI (sign_extend:DI
3949 (match_operand:DI 1 "immediate_operand" "s")
3952 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3958 (match_dup 1))))))))]
3959 "TARGET_SHMEDIA32 && reload_completed
3960 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3963 sh_mark_label (operands[1], 2);
3966 (define_expand "movdi_const_16bit"
3967 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3968 (const:DI (sign_extend:DI
3970 (match_operand:DI 1 "immediate_operand" "s")))))]
3971 "TARGET_SHMEDIA && flag_pic && reload_completed
3972 && GET_CODE (operands[1]) == SYMBOL_REF"
3976 [(set (match_operand:DI 0 "arith_reg_operand" "")
3977 (match_operand:DI 1 "immediate_operand" ""))]
3978 "TARGET_SHMEDIA && reload_completed
3979 && GET_CODE (operands[1]) == CONST_INT
3980 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3981 [(set (match_dup 0) (match_dup 2))
3985 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3986 unsigned HOST_WIDE_INT low = val;
3987 unsigned HOST_WIDE_INT high = val;
3988 unsigned HOST_WIDE_INT sign;
3989 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3991 /* Sign-extend the 16 least-significant bits. */
3996 /* Arithmetic shift right the word by 16 bits. */
3999 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4004 /* If we can't generate the constant with a two-insn movi / shori
4005 sequence, try some other strategies. */
4006 if (! CONST_OK_FOR_I16 (high))
4008 /* Try constant load / left shift. We know VAL != 0. */
4009 val2 = val ^ (val-1);
4012 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4014 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4015 || (! CONST_OK_FOR_I16 (high >> 16)
4016 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4018 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4019 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4020 GEN_INT (trailing_zeroes));
4024 /* Try constant load / right shift. */
4025 val2 = (val >> 15) + 1;
4026 if (val2 == (val2 & -val2))
4028 int shift = 49 - exact_log2 (val2);
4030 val2 = trunc_int_for_mode (val << shift, DImode);
4031 if (CONST_OK_FOR_I16 (val2))
4033 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4039 val2 = val & 0xffff;
4040 if ((val >> 16 & 0xffff) == val2
4041 && (val >> 32 & 0xffff) == val2
4042 && (val >> 48 & 0xffff) == val2)
4044 val2 = (HOST_WIDE_INT) val >> 48;
4045 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4046 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4049 /* Try movi / mshflo.l */
4050 val2 = (HOST_WIDE_INT) val >> 32;
4051 if (val2 == ((unsigned HOST_WIDE_INT)
4052 trunc_int_for_mode (val, SImode)))
4054 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4058 /* Try movi / mshflo.l w/ r63. */
4059 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4060 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4062 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4068 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4071 operands[2] = GEN_INT (val2);
4075 [(set (match_operand:DI 0 "arith_reg_operand" "")
4076 (match_operand:DI 1 "immediate_operand" ""))]
4077 "TARGET_SHMEDIA && reload_completed
4078 && GET_CODE (operands[1]) == CONST_DOUBLE"
4079 [(set (match_dup 0) (match_dup 2))
4081 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4082 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4085 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4086 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4087 unsigned HOST_WIDE_INT val = low;
4088 unsigned HOST_WIDE_INT sign;
4090 /* Sign-extend the 16 least-significant bits. */
4094 operands[1] = GEN_INT (val);
4096 /* Arithmetic shift right the double-word by 16 bits. */
4098 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4101 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4105 /* This will only be true if high is a sign-extension of low, i.e.,
4106 it must be either 0 or (unsigned)-1, and be zero iff the
4107 most-significant bit of low is set. */
4108 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4109 operands[2] = GEN_INT (low);
4111 operands[2] = immed_double_const (low, high, DImode);
4114 (define_insn "shori_media"
4115 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4116 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4120 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4125 [(set_attr "type" "arith_media,*")])
4127 (define_expand "movdi"
4128 [(set (match_operand:DI 0 "general_movdst_operand" "")
4129 (match_operand:DI 1 "general_movsrc_operand" ""))]
4131 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4133 (define_insn "movdf_media"
4134 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4135 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4137 && (register_operand (operands[0], DFmode)
4138 || sh_register_operand (operands[1], DFmode))"
4149 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4151 (define_insn "movdf_media_nofpu"
4152 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4153 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4155 && (register_operand (operands[0], DFmode)
4156 || sh_register_operand (operands[1], DFmode))"
4162 [(set_attr "type" "arith_media,*,load_media,store_media")])
4165 [(set (match_operand:DF 0 "arith_reg_operand" "")
4166 (match_operand:DF 1 "immediate_operand" ""))]
4167 "TARGET_SHMEDIA && reload_completed"
4168 [(set (match_dup 3) (match_dup 2))]
4171 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4173 REAL_VALUE_TYPE value;
4175 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4176 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4178 if (HOST_BITS_PER_WIDE_INT >= 64)
4179 operands[2] = immed_double_const ((unsigned long) values[endian]
4180 | ((HOST_WIDE_INT) values[1 - endian]
4182 else if (HOST_BITS_PER_WIDE_INT == 32)
4183 operands[2] = immed_double_const (values[endian], values[1 - endian],
4188 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4191 ;; ??? This should be a define expand.
4193 (define_insn "movdf_k"
4194 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4195 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4197 && (! TARGET_SH4 || reload_completed
4198 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4199 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4200 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4201 && (arith_reg_operand (operands[0], DFmode)
4202 || arith_reg_operand (operands[1], DFmode))"
4203 "* return output_movedouble (insn, operands, DFmode);"
4204 [(set_attr "length" "4")
4205 (set_attr "type" "move,pcload,load,store")])
4207 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4208 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4209 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4210 ;; the d/m/c/X alternative, which is split later into single-precision
4211 ;; instructions. And when not optimizing, no splits are done before fixing
4212 ;; up pcloads, so we need usable length information for that.
4213 (define_insn "movdf_i4"
4214 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4215 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4216 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4217 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4219 && (arith_reg_operand (operands[0], DFmode)
4220 || arith_reg_operand (operands[1], DFmode))"
4232 [(set_attr_alternative "length"
4233 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4235 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4236 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4237 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4239 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4240 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4241 ;; increment or decrement r15 explicitly.
4243 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4244 (const_int 10) (const_int 8))
4246 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4247 (const_int 10) (const_int 8))])
4248 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4249 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4250 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4251 (const_string "double")
4252 (const_string "none")))])
4254 ;; Moving DFmode between fp/general registers through memory
4255 ;; (the top of the stack) is faster than moving through fpul even for
4256 ;; little endian. Because the type of an instruction is important for its
4257 ;; scheduling, it is beneficial to split these operations, rather than
4258 ;; emitting them in one single chunk, even if this will expose a stack
4259 ;; use that will prevent scheduling of other stack accesses beyond this
4262 [(set (match_operand:DF 0 "register_operand" "")
4263 (match_operand:DF 1 "register_operand" ""))
4264 (use (match_operand:PSI 2 "fpscr_operand" ""))
4265 (clobber (match_scratch:SI 3 "=X"))]
4266 "TARGET_SH4 && reload_completed
4267 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4273 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4275 emit_move_insn (stack_pointer_rtx,
4276 plus_constant (stack_pointer_rtx, -8));
4277 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4280 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4281 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4282 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4283 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4284 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4285 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4287 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4288 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4289 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4290 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4292 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4296 ;; local-alloc sometimes allocates scratch registers even when not required,
4297 ;; so we must be prepared to handle these.
4299 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4301 [(set (match_operand:DF 0 "general_movdst_operand" "")
4302 (match_operand:DF 1 "general_movsrc_operand" ""))
4303 (use (match_operand:PSI 2 "fpscr_operand" ""))
4304 (clobber (match_scratch:SI 3 ""))]
4307 && true_regnum (operands[0]) < 16
4308 && true_regnum (operands[1]) < 16"
4309 [(set (match_dup 0) (match_dup 1))]
4312 /* If this was a reg <-> mem operation with base + index reg addressing,
4313 we have to handle this in a special way. */
4314 rtx mem = operands[0];
4316 if (! memory_operand (mem, DFmode))
4321 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4322 mem = SUBREG_REG (mem);
4323 if (GET_CODE (mem) == MEM)
4325 rtx addr = XEXP (mem, 0);
4326 if (GET_CODE (addr) == PLUS
4327 && GET_CODE (XEXP (addr, 0)) == REG
4328 && GET_CODE (XEXP (addr, 1)) == REG)
4331 rtx reg0 = gen_rtx_REG (Pmode, 0);
4332 rtx regop = operands[store_p], word0 ,word1;
4334 if (GET_CODE (regop) == SUBREG)
4335 alter_subreg (®op);
4336 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4340 mem = copy_rtx (mem);
4341 PUT_MODE (mem, SImode);
4342 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4343 alter_subreg (&word0);
4344 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4345 alter_subreg (&word1);
4346 if (store_p || ! refers_to_regno_p (REGNO (word0),
4347 REGNO (word0) + 1, addr, 0))
4350 ? gen_movsi_ie (mem, word0)
4351 : gen_movsi_ie (word0, mem));
4352 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4353 mem = copy_rtx (mem);
4355 ? gen_movsi_ie (mem, word1)
4356 : gen_movsi_ie (word1, mem));
4357 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4361 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4362 emit_insn (gen_movsi_ie (word1, mem));
4363 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4364 mem = copy_rtx (mem);
4365 emit_insn (gen_movsi_ie (word0, mem));
4372 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4374 [(set (match_operand:DF 0 "register_operand" "")
4375 (match_operand:DF 1 "memory_operand" ""))
4376 (use (match_operand:PSI 2 "fpscr_operand" ""))
4377 (clobber (reg:SI R0_REG))]
4378 "TARGET_SH4 && reload_completed"
4379 [(parallel [(set (match_dup 0) (match_dup 1))
4381 (clobber (scratch:SI))])]
4384 (define_expand "reload_indf"
4385 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4386 (match_operand:DF 1 "immediate_operand" "FQ"))
4387 (use (reg:PSI FPSCR_REG))
4388 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4392 (define_expand "reload_outdf"
4393 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4394 (match_operand:DF 1 "register_operand" "af,r"))
4395 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4399 ;; Simplify no-op moves.
4401 [(set (match_operand:SF 0 "register_operand" "")
4402 (match_operand:SF 1 "register_operand" ""))
4403 (use (match_operand:PSI 2 "fpscr_operand" ""))
4404 (clobber (match_scratch:SI 3 ""))]
4405 "TARGET_SH2E && reload_completed
4406 && true_regnum (operands[0]) == true_regnum (operands[1])"
4407 [(set (match_dup 0) (match_dup 0))]
4410 ;; fmovd substitute post-reload splits
4412 [(set (match_operand:DF 0 "register_operand" "")
4413 (match_operand:DF 1 "register_operand" ""))
4414 (use (match_operand:PSI 2 "fpscr_operand" ""))
4415 (clobber (match_scratch:SI 3 ""))]
4416 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4417 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4418 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4422 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4423 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4424 gen_rtx_REG (SFmode, src), operands[2]));
4425 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4426 gen_rtx_REG (SFmode, src + 1), operands[2]));
4431 [(set (match_operand:DF 0 "register_operand" "")
4432 (mem:DF (match_operand:SI 1 "register_operand" "")))
4433 (use (match_operand:PSI 2 "fpscr_operand" ""))
4434 (clobber (match_scratch:SI 3 ""))]
4435 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4436 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4437 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4441 int regno = true_regnum (operands[0]);
4443 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4445 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4446 regno + !! TARGET_LITTLE_ENDIAN),
4447 mem2, operands[2]));
4448 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4449 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4450 regno + ! TARGET_LITTLE_ENDIAN),
4451 gen_rtx_MEM (SFmode, operands[1]),
4457 [(set (match_operand:DF 0 "register_operand" "")
4458 (match_operand:DF 1 "memory_operand" ""))
4459 (use (match_operand:PSI 2 "fpscr_operand" ""))
4460 (clobber (match_scratch:SI 3 ""))]
4461 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4462 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4466 int regno = true_regnum (operands[0]);
4467 rtx addr, insn, adjust = NULL_RTX;
4468 rtx mem2 = copy_rtx (operands[1]);
4469 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4470 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4472 PUT_MODE (mem2, SFmode);
4473 operands[1] = copy_rtx (mem2);
4474 addr = XEXP (mem2, 0);
4475 if (GET_CODE (addr) != POST_INC)
4477 /* If we have to modify the stack pointer, the value that we have
4478 read with post-increment might be modified by an interrupt,
4479 so write it back. */
4480 if (REGNO (addr) == STACK_POINTER_REGNUM)
4481 adjust = gen_push_e (reg0);
4483 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4484 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4486 addr = XEXP (addr, 0);
4487 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4488 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4489 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4493 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4498 [(set (match_operand:DF 0 "memory_operand" "")
4499 (match_operand:DF 1 "register_operand" ""))
4500 (use (match_operand:PSI 2 "fpscr_operand" ""))
4501 (clobber (match_scratch:SI 3 ""))]
4502 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4503 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4507 int regno = true_regnum (operands[1]);
4508 rtx insn, addr, adjust = NULL_RTX;
4510 operands[0] = copy_rtx (operands[0]);
4511 PUT_MODE (operands[0], SFmode);
4512 insn = emit_insn (gen_movsf_ie (operands[0],
4513 gen_rtx_REG (SFmode,
4514 regno + ! TARGET_LITTLE_ENDIAN),
4516 operands[0] = copy_rtx (operands[0]);
4517 addr = XEXP (operands[0], 0);
4518 if (GET_CODE (addr) != PRE_DEC)
4520 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4521 emit_insn_before (adjust, insn);
4522 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4524 addr = XEXP (addr, 0);
4526 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4527 insn = emit_insn (gen_movsf_ie (operands[0],
4528 gen_rtx_REG (SFmode,
4529 regno + !! TARGET_LITTLE_ENDIAN),
4531 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4535 ;; If the output is a register and the input is memory or a register, we have
4536 ;; to be careful and see which word needs to be loaded first.
4539 [(set (match_operand:DF 0 "general_movdst_operand" "")
4540 (match_operand:DF 1 "general_movsrc_operand" ""))]
4541 "TARGET_SH1 && reload_completed"
4542 [(set (match_dup 2) (match_dup 3))
4543 (set (match_dup 4) (match_dup 5))]
4548 if ((GET_CODE (operands[0]) == MEM
4549 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4550 || (GET_CODE (operands[1]) == MEM
4551 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4554 if (GET_CODE (operands[0]) == REG)
4555 regno = REGNO (operands[0]);
4556 else if (GET_CODE (operands[0]) == SUBREG)
4557 regno = subreg_regno (operands[0]);
4558 else if (GET_CODE (operands[0]) == MEM)
4564 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4566 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4567 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4568 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4569 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4573 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4574 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4575 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4576 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4579 if (operands[2] == 0 || operands[3] == 0
4580 || operands[4] == 0 || operands[5] == 0)
4584 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4585 ;; used only once, let combine add in the index again.
4588 [(set (match_operand:SI 0 "register_operand" "")
4589 (match_operand:SI 1 "" ""))
4590 (clobber (match_operand 2 "register_operand" ""))]
4591 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4592 [(use (reg:SI R0_REG))]
4595 rtx addr, reg, const_int;
4597 if (GET_CODE (operands[1]) != MEM)
4599 addr = XEXP (operands[1], 0);
4600 if (GET_CODE (addr) != PLUS)
4602 reg = XEXP (addr, 0);
4603 const_int = XEXP (addr, 1);
4604 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4605 && GET_CODE (const_int) == CONST_INT))
4607 emit_move_insn (operands[2], const_int);
4608 emit_move_insn (operands[0],
4609 change_address (operands[1], VOIDmode,
4610 gen_rtx_PLUS (SImode, reg, operands[2])));
4615 [(set (match_operand:SI 1 "" "")
4616 (match_operand:SI 0 "register_operand" ""))
4617 (clobber (match_operand 2 "register_operand" ""))]
4618 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4619 [(use (reg:SI R0_REG))]
4622 rtx addr, reg, const_int;
4624 if (GET_CODE (operands[1]) != MEM)
4626 addr = XEXP (operands[1], 0);
4627 if (GET_CODE (addr) != PLUS)
4629 reg = XEXP (addr, 0);
4630 const_int = XEXP (addr, 1);
4631 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4632 && GET_CODE (const_int) == CONST_INT))
4634 emit_move_insn (operands[2], const_int);
4635 emit_move_insn (change_address (operands[1], VOIDmode,
4636 gen_rtx_PLUS (SImode, reg, operands[2])),
4641 (define_expand "movdf"
4642 [(set (match_operand:DF 0 "general_movdst_operand" "")
4643 (match_operand:DF 1 "general_movsrc_operand" ""))]
4647 if (prepare_move_operands (operands, DFmode)) DONE;
4650 if (TARGET_SHMEDIA_FPU)
4651 emit_insn (gen_movdf_media (operands[0], operands[1]));
4653 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4658 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4663 ;;This is incompatible with the way gcc uses subregs.
4664 ;;(define_insn "movv2sf_i"
4665 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4666 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4667 ;; "TARGET_SHMEDIA_FPU
4668 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4669 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4673 ;; fst%M0.p %m0, %1"
4674 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4676 (define_insn_and_split "movv2sf_i"
4677 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4678 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4679 "TARGET_SHMEDIA_FPU"
4681 "TARGET_SHMEDIA_FPU && reload_completed"
4682 [(set (match_dup 0) (match_dup 1))]
4685 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4686 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4689 (define_expand "movv2sf"
4690 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4691 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4692 "TARGET_SHMEDIA_FPU"
4695 if (prepare_move_operands (operands, V2SFmode))
4699 (define_expand "addv2sf3"
4700 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4701 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4702 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4703 "TARGET_SHMEDIA_FPU"
4706 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4710 (define_expand "subv2sf3"
4711 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4712 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4713 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4714 "TARGET_SHMEDIA_FPU"
4717 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4721 (define_expand "mulv2sf3"
4722 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4723 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4724 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4725 "TARGET_SHMEDIA_FPU"
4728 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4732 (define_expand "divv2sf3"
4733 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4734 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4735 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4736 "TARGET_SHMEDIA_FPU"
4739 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4743 (define_insn_and_split "*movv4sf_i"
4744 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4745 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4746 "TARGET_SHMEDIA_FPU"
4748 "&& reload_completed"
4754 for (i = 0; i < 4/2; i++)
4758 if (GET_CODE (operands[0]) == MEM)
4759 x = gen_rtx_MEM (V2SFmode,
4760 plus_constant (XEXP (operands[0], 0),
4761 i * GET_MODE_SIZE (V2SFmode)));
4763 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4765 if (GET_CODE (operands[1]) == MEM)
4766 y = gen_rtx_MEM (V2SFmode,
4767 plus_constant (XEXP (operands[1], 0),
4768 i * GET_MODE_SIZE (V2SFmode)));
4770 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4772 emit_insn (gen_movv2sf_i (x, y));
4777 [(set_attr "length" "8")])
4779 (define_expand "movv4sf"
4780 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4781 (match_operand:V4SF 1 "general_operand" ""))]
4782 "TARGET_SHMEDIA_FPU"
4785 if (prepare_move_operands (operands, V4SFmode))
4789 (define_insn_and_split "*movv16sf_i"
4790 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4791 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4792 "TARGET_SHMEDIA_FPU"
4794 "&& reload_completed"
4800 for (i = 0; i < 16/2; i++)
4804 if (GET_CODE (operands[0]) == MEM)
4805 x = gen_rtx_MEM (V2SFmode,
4806 plus_constant (XEXP (operands[0], 0),
4807 i * GET_MODE_SIZE (V2SFmode)));
4810 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4814 if (GET_CODE (operands[1]) == MEM)
4815 y = gen_rtx_MEM (V2SFmode,
4816 plus_constant (XEXP (operands[1], 0),
4817 i * GET_MODE_SIZE (V2SFmode)));
4820 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4824 emit_insn (gen_movv2sf_i (x, y));
4829 [(set_attr "length" "32")])
4831 (define_expand "movv16sf"
4832 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4833 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4834 "TARGET_SHMEDIA_FPU"
4837 if (prepare_move_operands (operands, V16SFmode))
4841 (define_insn "movsf_media"
4842 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4843 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4845 && (register_operand (operands[0], SFmode)
4846 || sh_register_operand (operands[1], SFmode))"
4857 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4859 (define_insn "movsf_media_nofpu"
4860 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4861 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4863 && (register_operand (operands[0], SFmode)
4864 || sh_register_operand (operands[1], SFmode))"
4870 [(set_attr "type" "arith_media,*,load_media,store_media")])
4873 [(set (match_operand:SF 0 "arith_reg_operand" "")
4874 (match_operand:SF 1 "immediate_operand" ""))]
4875 "TARGET_SHMEDIA && reload_completed
4876 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4877 [(set (match_dup 3) (match_dup 2))]
4881 REAL_VALUE_TYPE value;
4883 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4884 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4885 operands[2] = GEN_INT (values);
4887 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4890 (define_insn "movsf_i"
4891 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4892 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4895 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4896 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4897 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4898 && (arith_reg_operand (operands[0], SFmode)
4899 || arith_reg_operand (operands[1], SFmode))"
4908 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4910 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4911 ;; update_flow_info would not know where to put REG_EQUAL notes
4912 ;; when the destination changes mode.
4913 (define_insn "movsf_ie"
4914 [(set (match_operand:SF 0 "general_movdst_operand"
4915 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4916 (match_operand:SF 1 "general_movsrc_operand"
4917 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4918 (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"))
4919 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4922 && (arith_reg_operand (operands[0], SFmode)
4923 || arith_reg_operand (operands[1], SFmode)
4924 || arith_reg_operand (operands[3], SImode)
4925 || (fpul_operand (operands[0], SFmode)
4926 && memory_operand (operands[1], SFmode)
4927 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4928 || (fpul_operand (operands[1], SFmode)
4929 && memory_operand (operands[0], SFmode)
4930 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4950 ! move optimized away"
4951 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4952 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4953 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4954 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4955 (const_string "single")
4956 (const_string "none")))])
4959 [(set (match_operand:SF 0 "register_operand" "")
4960 (match_operand:SF 1 "register_operand" ""))
4961 (use (match_operand:PSI 2 "fpscr_operand" ""))
4962 (clobber (reg:SI FPUL_REG))]
4964 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4966 (clobber (scratch:SI))])
4967 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4969 (clobber (scratch:SI))])]
4972 (define_expand "movsf"
4973 [(set (match_operand:SF 0 "general_movdst_operand" "")
4974 (match_operand:SF 1 "general_movsrc_operand" ""))]
4978 if (prepare_move_operands (operands, SFmode))
4982 if (TARGET_SHMEDIA_FPU)
4983 emit_insn (gen_movsf_media (operands[0], operands[1]));
4985 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4990 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4995 (define_insn "mov_nop"
4996 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4999 [(set_attr "length" "0")
5000 (set_attr "type" "nil")])
5002 (define_expand "reload_insf"
5003 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5004 (match_operand:SF 1 "immediate_operand" "FQ"))
5005 (use (reg:PSI FPSCR_REG))
5006 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5010 (define_expand "reload_insi"
5011 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5012 (match_operand:SF 1 "immediate_operand" "FQ"))
5013 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5017 (define_insn "*movsi_y"
5018 [(set (match_operand:SI 0 "register_operand" "=y,y")
5019 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5020 (clobber (match_scratch:SI 2 "=&z,r"))]
5022 && (reload_in_progress || reload_completed)"
5024 [(set_attr "length" "4")
5025 (set_attr "type" "pcload,move")])
5028 [(set (match_operand:SI 0 "register_operand" "")
5029 (match_operand:SI 1 "immediate_operand" ""))
5030 (clobber (match_operand:SI 2 "register_operand" ""))]
5032 [(set (match_dup 2) (match_dup 1))
5033 (set (match_dup 0) (match_dup 2))]
5037 [(set (match_operand:SI 0 "register_operand" "")
5038 (match_operand:SI 1 "memory_operand" ""))
5039 (clobber (reg:SI R0_REG))]
5041 [(set (match_dup 0) (match_dup 1))]
5044 ;; ------------------------------------------------------------------------
5045 ;; Define the real conditional branch instructions.
5046 ;; ------------------------------------------------------------------------
5048 (define_insn "branch_true"
5049 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5050 (label_ref (match_operand 0 "" ""))
5053 "* return output_branch (1, insn, operands);"
5054 [(set_attr "type" "cbranch")])
5056 (define_insn "branch_false"
5057 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5058 (label_ref (match_operand 0 "" ""))
5061 "* return output_branch (0, insn, operands);"
5062 [(set_attr "type" "cbranch")])
5064 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5065 ;; which destination is too far away.
5066 ;; The const_int_operand is distinct for each branch target; it avoids
5067 ;; unwanted matches with redundant_insn.
5068 (define_insn "block_branch_redirect"
5069 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5072 [(set_attr "length" "0")])
5074 ;; This one has the additional purpose to record a possible scratch register
5075 ;; for the following branch.
5076 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5077 ;; because the insn then might be deemed dead and deleted. And we can't
5078 ;; make the use in the jump insn explicit because that would disable
5079 ;; delay slot scheduling from the target.
5080 (define_insn "indirect_jump_scratch"
5081 [(set (match_operand:SI 0 "register_operand" "=r")
5082 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5083 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5086 [(set_attr "length" "0")])
5088 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5089 ;; being pulled into the delay slot of a condbranch that has been made to
5090 ;; jump around the unconditional jump because it was out of range.
5091 (define_insn "stuff_delay_slot"
5093 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5094 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5097 [(set_attr "length" "0")
5098 (set_attr "cond_delay_slot" "yes")])
5100 ;; Conditional branch insns
5102 (define_expand "beq_media"
5104 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5105 (match_operand:DI 2 "arith_operand" "r,I06"))
5106 (label_ref:DI (match_operand 0 "" ""))
5111 (define_insn "*beq_media_i"
5113 (if_then_else (match_operator 3 "equality_comparison_operator"
5114 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5115 (match_operand:DI 2 "arith_operand" "r,I06")])
5116 (match_operand:DI 0 "target_operand" "b,b")
5122 [(set_attr "type" "cbranch_media")])
5124 (define_expand "bne_media"
5126 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5127 (match_operand:DI 2 "arith_operand" "r,I06"))
5128 (label_ref:DI (match_operand 0 "" ""))
5133 (define_expand "bgt_media"
5135 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5136 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5137 (label_ref:DI (match_operand 0 "" ""))
5142 (define_expand "bge_media"
5144 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5145 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5146 (label_ref:DI (match_operand 0 "" ""))
5151 (define_expand "bgtu_media"
5153 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5154 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5155 (label_ref:DI (match_operand 0 "" ""))
5160 (define_expand "bgeu_media"
5162 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5163 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5164 (label_ref:DI (match_operand 0 "" ""))
5169 (define_insn "*bgt_media_i"
5171 (if_then_else (match_operator 3 "greater_comparison_operator"
5172 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5173 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5174 (match_operand:DI 0 "target_operand" "b")
5177 "b%o3%' %N1, %N2, %0"
5178 [(set_attr "type" "cbranch_media")])
5180 ;; These are only needed to make invert_jump() happy.
5181 (define_insn "*blt_media_i"
5183 (if_then_else (match_operator 3 "less_comparison_operator"
5184 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5185 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5186 (match_operand:DI 0 "target_operand" "b")
5189 "b%o3%' %N2, %N1, %0"
5190 [(set_attr "type" "cbranch_media")])
5192 (define_expand "beq"
5194 (if_then_else (ne (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_bne_media (operands[0], tmp, const0_rtx));
5211 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5212 emit_jump_insn (gen_beq_media (operands[0],
5213 sh_compare_op0, sh_compare_op1));
5217 from_compare (operands, EQ);
5220 (define_expand "bne"
5222 (if_then_else (eq (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_seq (tmp));
5235 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5239 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5240 emit_jump_insn (gen_bne_media (operands[0],
5241 sh_compare_op0, sh_compare_op1));
5245 from_compare (operands, EQ);
5248 (define_expand "bgt"
5250 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5251 (label_ref (match_operand 0 "" ""))
5258 if (GET_MODE (sh_compare_op0) != DImode)
5260 rtx tmp = gen_reg_rtx (DImode);
5262 emit_insn (gen_sgt (tmp));
5263 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5267 if (sh_compare_op0 != const0_rtx)
5268 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5269 if (sh_compare_op1 != const0_rtx)
5270 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5271 emit_jump_insn (gen_bgt_media (operands[0],
5272 sh_compare_op0, sh_compare_op1));
5276 from_compare (operands, GT);
5279 (define_expand "blt"
5281 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5282 (label_ref (match_operand 0 "" ""))
5289 if (GET_MODE (sh_compare_op0) != DImode)
5291 rtx tmp = gen_reg_rtx (DImode);
5293 emit_insn (gen_slt (tmp));
5294 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5298 if (sh_compare_op0 != const0_rtx)
5299 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5300 if (sh_compare_op1 != const0_rtx)
5301 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5302 emit_jump_insn (gen_bgt_media (operands[0],
5303 sh_compare_op1, sh_compare_op0));
5307 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5309 rtx tmp = sh_compare_op0;
5310 sh_compare_op0 = sh_compare_op1;
5311 sh_compare_op1 = tmp;
5312 emit_insn (gen_bgt (operands[0]));
5315 from_compare (operands, GE);
5318 (define_expand "ble"
5320 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5321 (label_ref (match_operand 0 "" ""))
5328 if (GET_MODE (sh_compare_op0) != DImode)
5330 rtx tmp = gen_reg_rtx (DImode);
5332 emit_insn (gen_sle (tmp));
5333 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5337 if (sh_compare_op0 != const0_rtx)
5338 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5339 if (sh_compare_op1 != const0_rtx)
5340 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5341 emit_jump_insn (gen_bge_media (operands[0],
5342 sh_compare_op1, sh_compare_op0));
5348 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5350 rtx tmp = sh_compare_op0;
5351 sh_compare_op0 = sh_compare_op1;
5352 sh_compare_op1 = tmp;
5353 emit_insn (gen_bge (operands[0]));
5356 from_compare (operands, GT);
5359 (define_expand "bge"
5361 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5362 (label_ref (match_operand 0 "" ""))
5369 if (GET_MODE (sh_compare_op0) != DImode)
5371 rtx tmp = gen_reg_rtx (DImode);
5373 emit_insn (gen_sge (tmp));
5374 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5378 if (sh_compare_op0 != const0_rtx)
5379 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5380 if (sh_compare_op1 != const0_rtx)
5381 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5382 emit_jump_insn (gen_bge_media (operands[0],
5383 sh_compare_op0, sh_compare_op1));
5389 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5391 rtx tmp = sh_compare_op0;
5392 sh_compare_op0 = sh_compare_op1;
5393 sh_compare_op1 = tmp;
5394 emit_insn (gen_ble (operands[0]));
5397 from_compare (operands, GE);
5400 (define_expand "bgtu"
5402 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5403 (label_ref (match_operand 0 "" ""))
5410 if (sh_compare_op0 != const0_rtx)
5411 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5412 if (sh_compare_op1 != const0_rtx)
5413 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5414 emit_jump_insn (gen_bgtu_media (operands[0],
5415 sh_compare_op0, sh_compare_op1));
5419 from_compare (operands, GTU);
5422 (define_expand "bltu"
5424 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5425 (label_ref (match_operand 0 "" ""))
5432 if (sh_compare_op0 != const0_rtx)
5433 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5434 if (sh_compare_op1 != const0_rtx)
5435 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5436 emit_jump_insn (gen_bgtu_media (operands[0],
5437 sh_compare_op1, sh_compare_op0));
5441 from_compare (operands, GEU);
5444 (define_expand "bgeu"
5446 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5447 (label_ref (match_operand 0 "" ""))
5454 if (sh_compare_op0 != const0_rtx)
5455 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5456 if (sh_compare_op1 != const0_rtx)
5457 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5458 emit_jump_insn (gen_bgeu_media (operands[0],
5459 sh_compare_op0, sh_compare_op1));
5463 from_compare (operands, GEU);
5466 (define_expand "bleu"
5468 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5469 (label_ref (match_operand 0 "" ""))
5476 if (sh_compare_op0 != const0_rtx)
5477 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5478 if (sh_compare_op1 != const0_rtx)
5479 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5480 emit_jump_insn (gen_bgeu_media (operands[0],
5481 sh_compare_op1, sh_compare_op0));
5485 from_compare (operands, GTU);
5488 (define_expand "bunordered"
5489 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5491 (if_then_else (ne (match_dup 1) (const_int 0))
5492 (label_ref:DI (match_operand 0 "" ""))
5497 operands[1] = gen_reg_rtx (DImode);
5498 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5499 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5502 ;; ------------------------------------------------------------------------
5503 ;; Jump and linkage insns
5504 ;; ------------------------------------------------------------------------
5506 (define_insn "jump_compact"
5508 (label_ref (match_operand 0 "" "")))]
5512 /* The length is 16 if the delay slot is unfilled. */
5513 if (get_attr_length(insn) > 4)
5514 return output_far_jump(insn, operands[0]);
5516 return \"bra %l0%#\";
5518 [(set_attr "type" "jump")
5519 (set_attr "needs_delay_slot" "yes")])
5521 ;; ??? It would be much saner to explicitly use the scratch register
5522 ;; in the jump insn, and have indirect_jump_scratch only set it,
5523 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5524 ;; from the target then, as it uses simplejump_p.
5525 ;;(define_insn "jump_compact_far"
5527 ;; (label_ref (match_operand 0 "" "")))
5528 ;; (use (match_operand 1 "register_operand" "r")]
5530 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5531 ;; [(set_attr "type" "jump")
5532 ;; (set_attr "needs_delay_slot" "yes")])
5534 (define_insn "jump_media"
5536 (match_operand:DI 0 "target_operand" "b"))]
5539 [(set_attr "type" "jump_media")])
5541 (define_expand "jump"
5543 (label_ref (match_operand 0 "" "")))]
5548 emit_jump_insn (gen_jump_compact (operands[0]));
5549 else if (TARGET_SHMEDIA)
5551 if (reload_in_progress || reload_completed)
5553 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5559 (define_insn "force_mode_for_call"
5560 [(use (reg:PSI FPSCR_REG))]
5563 [(set_attr "length" "0")
5564 (set (attr "fp_mode")
5565 (if_then_else (eq_attr "fpu_single" "yes")
5566 (const_string "single") (const_string "double")))])
5568 (define_insn "calli"
5569 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5570 (match_operand 1 "" ""))
5571 (use (reg:PSI FPSCR_REG))
5572 (clobber (reg:SI PR_REG))]
5575 [(set_attr "type" "call")
5576 (set (attr "fp_mode")
5577 (if_then_else (eq_attr "fpu_single" "yes")
5578 (const_string "single") (const_string "double")))
5579 (set_attr "needs_delay_slot" "yes")
5580 (set_attr "fp_set" "unknown")])
5582 ;; This is a pc-rel call, using bsrf, for use with PIC.
5584 (define_insn "calli_pcrel"
5585 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5586 (match_operand 1 "" ""))
5587 (use (reg:PSI FPSCR_REG))
5588 (use (reg:SI PIC_REG))
5589 (use (match_operand 2 "" ""))
5590 (clobber (reg:SI PR_REG))]
5593 [(set_attr "type" "call")
5594 (set (attr "fp_mode")
5595 (if_then_else (eq_attr "fpu_single" "yes")
5596 (const_string "single") (const_string "double")))
5597 (set_attr "needs_delay_slot" "yes")
5598 (set_attr "fp_set" "unknown")])
5600 (define_insn_and_split "call_pcrel"
5601 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5602 (match_operand 1 "" ""))
5603 (use (reg:PSI FPSCR_REG))
5604 (use (reg:SI PIC_REG))
5605 (clobber (reg:SI PR_REG))
5606 (clobber (match_scratch:SI 2 "=r"))]
5613 rtx lab = PATTERN (gen_call_site ());
5615 if (SYMBOL_REF_LOCAL_P (operands[0]))
5616 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5618 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5619 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5622 [(set_attr "type" "call")
5623 (set (attr "fp_mode")
5624 (if_then_else (eq_attr "fpu_single" "yes")
5625 (const_string "single") (const_string "double")))
5626 (set_attr "needs_delay_slot" "yes")
5627 (set_attr "fp_set" "unknown")])
5629 (define_insn "call_compact"
5630 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5631 (match_operand 1 "" ""))
5632 (match_operand 2 "immediate_operand" "n")
5633 (use (reg:SI R0_REG))
5634 (use (reg:SI R1_REG))
5635 (use (reg:PSI FPSCR_REG))
5636 (clobber (reg:SI PR_REG))]
5637 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5639 [(set_attr "type" "call")
5640 (set (attr "fp_mode")
5641 (if_then_else (eq_attr "fpu_single" "yes")
5642 (const_string "single") (const_string "double")))
5643 (set_attr "needs_delay_slot" "yes")])
5645 (define_insn "call_compact_rettramp"
5646 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5647 (match_operand 1 "" ""))
5648 (match_operand 2 "immediate_operand" "n")
5649 (use (reg:SI R0_REG))
5650 (use (reg:SI R1_REG))
5651 (use (reg:PSI FPSCR_REG))
5652 (clobber (reg:SI R10_REG))
5653 (clobber (reg:SI PR_REG))]
5654 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5656 [(set_attr "type" "call")
5657 (set (attr "fp_mode")
5658 (if_then_else (eq_attr "fpu_single" "yes")
5659 (const_string "single") (const_string "double")))
5660 (set_attr "needs_delay_slot" "yes")])
5662 (define_insn "call_media"
5663 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5664 (match_operand 1 "" ""))
5665 (clobber (reg:DI PR_MEDIA_REG))]
5668 [(set_attr "type" "jump_media")])
5670 (define_insn "call_valuei"
5671 [(set (match_operand 0 "" "=rf")
5672 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5673 (match_operand 2 "" "")))
5674 (use (reg:PSI FPSCR_REG))
5675 (clobber (reg:SI PR_REG))]
5678 [(set_attr "type" "call")
5679 (set (attr "fp_mode")
5680 (if_then_else (eq_attr "fpu_single" "yes")
5681 (const_string "single") (const_string "double")))
5682 (set_attr "needs_delay_slot" "yes")
5683 (set_attr "fp_set" "unknown")])
5685 (define_insn "call_valuei_pcrel"
5686 [(set (match_operand 0 "" "=rf")
5687 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5688 (match_operand 2 "" "")))
5689 (use (reg:PSI FPSCR_REG))
5690 (use (reg:SI PIC_REG))
5691 (use (match_operand 3 "" ""))
5692 (clobber (reg:SI PR_REG))]
5695 [(set_attr "type" "call")
5696 (set (attr "fp_mode")
5697 (if_then_else (eq_attr "fpu_single" "yes")
5698 (const_string "single") (const_string "double")))
5699 (set_attr "needs_delay_slot" "yes")
5700 (set_attr "fp_set" "unknown")])
5702 (define_insn_and_split "call_value_pcrel"
5703 [(set (match_operand 0 "" "=rf")
5704 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5705 (match_operand 2 "" "")))
5706 (use (reg:PSI FPSCR_REG))
5707 (use (reg:SI PIC_REG))
5708 (clobber (reg:SI PR_REG))
5709 (clobber (match_scratch:SI 3 "=r"))]
5716 rtx lab = PATTERN (gen_call_site ());
5718 if (SYMBOL_REF_LOCAL_P (operands[1]))
5719 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5721 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5722 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5726 [(set_attr "type" "call")
5727 (set (attr "fp_mode")
5728 (if_then_else (eq_attr "fpu_single" "yes")
5729 (const_string "single") (const_string "double")))
5730 (set_attr "needs_delay_slot" "yes")
5731 (set_attr "fp_set" "unknown")])
5733 (define_insn "call_value_compact"
5734 [(set (match_operand 0 "" "=rf")
5735 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5736 (match_operand 2 "" "")))
5737 (match_operand 3 "immediate_operand" "n")
5738 (use (reg:SI R0_REG))
5739 (use (reg:SI R1_REG))
5740 (use (reg:PSI FPSCR_REG))
5741 (clobber (reg:SI PR_REG))]
5742 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5744 [(set_attr "type" "call")
5745 (set (attr "fp_mode")
5746 (if_then_else (eq_attr "fpu_single" "yes")
5747 (const_string "single") (const_string "double")))
5748 (set_attr "needs_delay_slot" "yes")])
5750 (define_insn "call_value_compact_rettramp"
5751 [(set (match_operand 0 "" "=rf")
5752 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5753 (match_operand 2 "" "")))
5754 (match_operand 3 "immediate_operand" "n")
5755 (use (reg:SI R0_REG))
5756 (use (reg:SI R1_REG))
5757 (use (reg:PSI FPSCR_REG))
5758 (clobber (reg:SI R10_REG))
5759 (clobber (reg:SI PR_REG))]
5760 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5762 [(set_attr "type" "call")
5763 (set (attr "fp_mode")
5764 (if_then_else (eq_attr "fpu_single" "yes")
5765 (const_string "single") (const_string "double")))
5766 (set_attr "needs_delay_slot" "yes")])
5768 (define_insn "call_value_media"
5769 [(set (match_operand 0 "" "=rf")
5770 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5771 (match_operand 2 "" "")))
5772 (clobber (reg:DI PR_MEDIA_REG))]
5775 [(set_attr "type" "jump_media")])
5777 (define_expand "call"
5778 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5779 (match_operand 1 "" ""))
5780 (match_operand 2 "" "")
5781 (use (reg:PSI FPSCR_REG))
5782 (clobber (reg:SI PR_REG))])]
5788 operands[0] = XEXP (operands[0], 0);
5789 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5791 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5793 rtx reg = gen_reg_rtx (Pmode);
5795 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5800 operands[0] = gen_sym2PIC (operands[0]);
5801 PUT_MODE (operands[0], Pmode);
5804 if (GET_MODE (operands[0]) == SImode)
5806 if (GET_CODE (operands[0]) == REG)
5807 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5808 else if (GET_CODE (operands[0]) == SUBREG)
5810 operands[0] = SUBREG_REG (operands[0]);
5811 if (GET_MODE (operands[0]) != DImode)
5812 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5816 operands[0] = shallow_copy_rtx (operands[0]);
5817 PUT_MODE (operands[0], DImode);
5820 if (! target_reg_operand (operands[0], DImode))
5821 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5822 emit_call_insn (gen_call_media (operands[0], operands[1]));
5825 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5827 rtx cookie_rtx = operands[2];
5828 long cookie = INTVAL (cookie_rtx);
5829 rtx func = XEXP (operands[0], 0);
5834 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5836 rtx reg = gen_reg_rtx (Pmode);
5838 emit_insn (gen_symGOTPLT2reg (reg, func));
5842 func = legitimize_pic_address (func, Pmode, 0);
5845 r0 = gen_rtx_REG (SImode, R0_REG);
5846 r1 = gen_rtx_REG (SImode, R1_REG);
5848 /* Since such a call function may use all call-clobbered
5849 registers, we force a mode switch earlier, so that we don't
5850 run out of registers when adjusting fpscr for the call. */
5851 emit_insn (gen_force_mode_for_call ());
5853 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5856 rtx reg = gen_reg_rtx (Pmode);
5858 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5861 operands[0] = force_reg (SImode, operands[0]);
5863 emit_move_insn (r0, func);
5864 emit_move_insn (r1, cookie_rtx);
5866 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5867 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5870 emit_call_insn (gen_call_compact (operands[0], operands[1],
5875 else if (TARGET_SHCOMPACT && flag_pic
5876 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5877 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5879 rtx reg = gen_reg_rtx (Pmode);
5881 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5882 XEXP (operands[0], 0) = reg;
5884 if (flag_pic && TARGET_SH2
5885 && GET_CODE (operands[0]) == MEM
5886 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5888 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5893 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5894 operands[1] = operands[2];
5897 emit_call_insn (gen_calli (operands[0], operands[1]));
5901 (define_insn "call_pop_compact"
5902 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5903 (match_operand 1 "" ""))
5904 (match_operand 2 "immediate_operand" "n")
5905 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5906 (match_operand 3 "immediate_operand" "n")))
5907 (use (reg:SI R0_REG))
5908 (use (reg:SI R1_REG))
5909 (use (reg:PSI FPSCR_REG))
5910 (clobber (reg:SI PR_REG))]
5911 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5913 [(set_attr "type" "call")
5914 (set (attr "fp_mode")
5915 (if_then_else (eq_attr "fpu_single" "yes")
5916 (const_string "single") (const_string "double")))
5917 (set_attr "needs_delay_slot" "yes")])
5919 (define_insn "call_pop_compact_rettramp"
5920 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5921 (match_operand 1 "" ""))
5922 (match_operand 2 "immediate_operand" "n")
5923 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5924 (match_operand 3 "immediate_operand" "n")))
5925 (use (reg:SI R0_REG))
5926 (use (reg:SI R1_REG))
5927 (use (reg:PSI FPSCR_REG))
5928 (clobber (reg:SI R10_REG))
5929 (clobber (reg:SI PR_REG))]
5930 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5932 [(set_attr "type" "call")
5933 (set (attr "fp_mode")
5934 (if_then_else (eq_attr "fpu_single" "yes")
5935 (const_string "single") (const_string "double")))
5936 (set_attr "needs_delay_slot" "yes")])
5938 (define_expand "call_pop"
5939 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5940 (match_operand 1 "" ""))
5941 (match_operand 2 "" "")
5942 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5943 (match_operand 3 "" "")))])]
5947 if (operands[2] && INTVAL (operands[2]))
5949 rtx cookie_rtx = operands[2];
5950 long cookie = INTVAL (cookie_rtx);
5951 rtx func = XEXP (operands[0], 0);
5956 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5958 rtx reg = gen_reg_rtx (Pmode);
5960 emit_insn (gen_symGOTPLT2reg (reg, func));
5964 func = legitimize_pic_address (func, Pmode, 0);
5967 r0 = gen_rtx_REG (SImode, R0_REG);
5968 r1 = gen_rtx_REG (SImode, R1_REG);
5970 /* Since such a call function may use all call-clobbered
5971 registers, we force a mode switch earlier, so that we don't
5972 run out of registers when adjusting fpscr for the call. */
5973 emit_insn (gen_force_mode_for_call ());
5975 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5978 rtx reg = gen_reg_rtx (Pmode);
5980 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5983 operands[0] = force_reg (SImode, operands[0]);
5985 emit_move_insn (r0, func);
5986 emit_move_insn (r1, cookie_rtx);
5988 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5989 emit_call_insn (gen_call_pop_compact_rettramp
5990 (operands[0], operands[1], operands[2], operands[3]));
5992 emit_call_insn (gen_call_pop_compact
5993 (operands[0], operands[1], operands[2], operands[3]));
6001 (define_expand "call_value"
6002 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6003 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6004 (match_operand 2 "" "")))
6005 (match_operand 3 "" "")
6006 (use (reg:PSI FPSCR_REG))
6007 (clobber (reg:SI PR_REG))])]
6013 operands[1] = XEXP (operands[1], 0);
6014 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6016 if (! SYMBOL_REF_LOCAL_P (operands[1]))
6018 rtx reg = gen_reg_rtx (Pmode);
6020 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6025 operands[1] = gen_sym2PIC (operands[1]);
6026 PUT_MODE (operands[1], Pmode);
6029 if (GET_MODE (operands[1]) == SImode)
6031 if (GET_CODE (operands[1]) == REG)
6032 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6033 else if (GET_CODE (operands[1]) == SUBREG)
6035 operands[1] = SUBREG_REG (operands[1]);
6036 if (GET_MODE (operands[1]) != DImode)
6037 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6041 operands[1] = shallow_copy_rtx (operands[1]);
6042 PUT_MODE (operands[1], DImode);
6045 if (! target_reg_operand (operands[1], DImode))
6046 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6047 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6051 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6053 rtx cookie_rtx = operands[3];
6054 long cookie = INTVAL (cookie_rtx);
6055 rtx func = XEXP (operands[1], 0);
6060 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6062 rtx reg = gen_reg_rtx (Pmode);
6064 emit_insn (gen_symGOTPLT2reg (reg, func));
6068 func = legitimize_pic_address (func, Pmode, 0);
6071 r0 = gen_rtx_REG (SImode, R0_REG);
6072 r1 = gen_rtx_REG (SImode, R1_REG);
6074 /* Since such a call function may use all call-clobbered
6075 registers, we force a mode switch earlier, so that we don't
6076 run out of registers when adjusting fpscr for the call. */
6077 emit_insn (gen_force_mode_for_call ());
6079 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6082 rtx reg = gen_reg_rtx (Pmode);
6084 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6087 operands[1] = force_reg (SImode, operands[1]);
6089 emit_move_insn (r0, func);
6090 emit_move_insn (r1, cookie_rtx);
6092 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6093 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6098 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6099 operands[2], operands[3]));
6103 else if (TARGET_SHCOMPACT && flag_pic
6104 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6105 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6107 rtx reg = gen_reg_rtx (Pmode);
6109 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6110 XEXP (operands[1], 0) = reg;
6112 if (flag_pic && TARGET_SH2
6113 && GET_CODE (operands[1]) == MEM
6114 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6116 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6121 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6123 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6127 (define_insn "sibcalli"
6128 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6129 (match_operand 1 "" ""))
6130 (use (reg:PSI FPSCR_REG))
6134 [(set_attr "needs_delay_slot" "yes")
6135 (set (attr "fp_mode")
6136 (if_then_else (eq_attr "fpu_single" "yes")
6137 (const_string "single") (const_string "double")))
6138 (set_attr "type" "jump_ind")])
6140 (define_insn "sibcalli_pcrel"
6141 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6142 (match_operand 1 "" ""))
6143 (use (match_operand 2 "" ""))
6144 (use (reg:PSI FPSCR_REG))
6148 [(set_attr "needs_delay_slot" "yes")
6149 (set (attr "fp_mode")
6150 (if_then_else (eq_attr "fpu_single" "yes")
6151 (const_string "single") (const_string "double")))
6152 (set_attr "type" "jump_ind")])
6154 (define_insn_and_split "sibcall_pcrel"
6155 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6156 (match_operand 1 "" ""))
6157 (use (reg:PSI FPSCR_REG))
6158 (clobber (match_scratch:SI 2 "=k"))
6166 rtx lab = PATTERN (gen_call_site ());
6169 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6170 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6172 SIBLING_CALL_P (call_insn) = 1;
6175 [(set_attr "needs_delay_slot" "yes")
6176 (set (attr "fp_mode")
6177 (if_then_else (eq_attr "fpu_single" "yes")
6178 (const_string "single") (const_string "double")))
6179 (set_attr "type" "jump_ind")])
6181 (define_insn "sibcall_compact"
6182 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6183 (match_operand 1 "" ""))
6185 (use (match_operand:SI 2 "register_operand" "z,x"))
6186 (use (reg:SI R1_REG))
6187 (use (reg:PSI FPSCR_REG))
6188 ;; We want to make sure the `x' above will only match MACH_REG
6189 ;; because sibcall_epilogue may clobber MACL_REG.
6190 (clobber (reg:SI MACL_REG))]
6194 jmp @%0\\n sts %2, r0"
6195 [(set_attr "needs_delay_slot" "yes,no")
6196 (set_attr "length" "2,4")
6197 (set (attr "fp_mode") (const_string "single"))
6198 (set_attr "type" "jump_ind")])
6200 (define_insn "sibcall_media"
6201 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6202 (match_operand 1 "" ""))
6203 (use (reg:SI PR_MEDIA_REG))
6207 [(set_attr "type" "jump_media")])
6209 (define_expand "sibcall"
6211 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6212 (match_operand 1 "" ""))
6213 (match_operand 2 "" "")
6214 (use (reg:PSI FPSCR_REG))
6221 operands[0] = XEXP (operands[0], 0);
6222 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6224 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6226 rtx reg = gen_reg_rtx (Pmode);
6228 /* We must not use GOTPLT for sibcalls, because PIC_REG
6229 must be restored before the PLT code gets to run. */
6230 emit_insn (gen_symGOT2reg (reg, operands[0]));
6235 operands[0] = gen_sym2PIC (operands[0]);
6236 PUT_MODE (operands[0], Pmode);
6239 if (GET_MODE (operands[0]) == SImode)
6241 if (GET_CODE (operands[0]) == REG)
6242 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6243 else if (GET_CODE (operands[0]) == SUBREG)
6245 operands[0] = SUBREG_REG (operands[0]);
6246 if (GET_MODE (operands[0]) != DImode)
6247 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6251 operands[0] = shallow_copy_rtx (operands[0]);
6252 PUT_MODE (operands[0], DImode);
6255 if (! target_reg_operand (operands[0], DImode))
6256 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6257 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6260 else if (TARGET_SHCOMPACT && operands[2]
6261 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6263 rtx cookie_rtx = operands[2];
6264 long cookie = INTVAL (cookie_rtx);
6265 rtx func = XEXP (operands[0], 0);
6270 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6272 rtx reg = gen_reg_rtx (Pmode);
6274 emit_insn (gen_symGOT2reg (reg, func));
6278 func = legitimize_pic_address (func, Pmode, 0);
6281 /* FIXME: if we could tell whether all argument registers are
6282 already taken, we could decide whether to force the use of
6283 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6284 simple way to tell. We could use the CALL_COOKIE, but we
6285 can't currently tell a register used for regular argument
6286 passing from one that is unused. If we leave it up to reload
6287 to decide which register to use, it seems to always choose
6288 R0_REG, which leaves no available registers in SIBCALL_REGS
6289 to hold the address of the trampoline. */
6290 mach = gen_rtx_REG (SImode, MACH_REG);
6291 r1 = gen_rtx_REG (SImode, R1_REG);
6293 /* Since such a call function may use all call-clobbered
6294 registers, we force a mode switch earlier, so that we don't
6295 run out of registers when adjusting fpscr for the call. */
6296 emit_insn (gen_force_mode_for_call ());
6298 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6301 rtx reg = gen_reg_rtx (Pmode);
6303 emit_insn (gen_symGOT2reg (reg, operands[0]));
6306 operands[0] = force_reg (SImode, operands[0]);
6308 /* We don't need a return trampoline, since the callee will
6309 return directly to the upper caller. */
6310 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6312 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6313 cookie_rtx = GEN_INT (cookie);
6316 emit_move_insn (mach, func);
6317 emit_move_insn (r1, cookie_rtx);
6319 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6322 else if (TARGET_SHCOMPACT && flag_pic
6323 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6324 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6326 rtx reg = gen_reg_rtx (Pmode);
6328 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6329 XEXP (operands[0], 0) = reg;
6331 if (flag_pic && TARGET_SH2
6332 && GET_CODE (operands[0]) == MEM
6333 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6334 /* The PLT needs the PIC register, but the epilogue would have
6335 to restore it, so we can only use PC-relative PIC calls for
6336 static functions. */
6337 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6339 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6343 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6345 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6349 (define_expand "sibcall_value"
6350 [(set (match_operand 0 "" "")
6351 (call (match_operand 1 "" "")
6352 (match_operand 2 "" "")))
6353 (match_operand 3 "" "")]
6357 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6361 (define_insn "call_value_pop_compact"
6362 [(set (match_operand 0 "" "=rf")
6363 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6364 (match_operand 2 "" "")))
6365 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6366 (match_operand 4 "immediate_operand" "n")))
6367 (match_operand 3 "immediate_operand" "n")
6368 (use (reg:SI R0_REG))
6369 (use (reg:SI R1_REG))
6370 (use (reg:PSI FPSCR_REG))
6371 (clobber (reg:SI PR_REG))]
6372 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6374 [(set_attr "type" "call")
6375 (set (attr "fp_mode")
6376 (if_then_else (eq_attr "fpu_single" "yes")
6377 (const_string "single") (const_string "double")))
6378 (set_attr "needs_delay_slot" "yes")])
6380 (define_insn "call_value_pop_compact_rettramp"
6381 [(set (match_operand 0 "" "=rf")
6382 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6383 (match_operand 2 "" "")))
6384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6385 (match_operand 4 "immediate_operand" "n")))
6386 (match_operand 3 "immediate_operand" "n")
6387 (use (reg:SI R0_REG))
6388 (use (reg:SI R1_REG))
6389 (use (reg:PSI FPSCR_REG))
6390 (clobber (reg:SI R10_REG))
6391 (clobber (reg:SI PR_REG))]
6392 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6394 [(set_attr "type" "call")
6395 (set (attr "fp_mode")
6396 (if_then_else (eq_attr "fpu_single" "yes")
6397 (const_string "single") (const_string "double")))
6398 (set_attr "needs_delay_slot" "yes")])
6400 (define_expand "call_value_pop"
6401 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6402 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6403 (match_operand 2 "" "")))
6404 (match_operand 3 "" "")
6405 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6406 (match_operand 4 "" "")))])]
6410 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6412 rtx cookie_rtx = operands[3];
6413 long cookie = INTVAL (cookie_rtx);
6414 rtx func = XEXP (operands[1], 0);
6419 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6421 rtx reg = gen_reg_rtx (Pmode);
6423 emit_insn (gen_symGOTPLT2reg (reg, func));
6427 func = legitimize_pic_address (func, Pmode, 0);
6430 r0 = gen_rtx_REG (SImode, R0_REG);
6431 r1 = gen_rtx_REG (SImode, R1_REG);
6433 /* Since such a call function may use all call-clobbered
6434 registers, we force a mode switch earlier, so that we don't
6435 run out of registers when adjusting fpscr for the call. */
6436 emit_insn (gen_force_mode_for_call ());
6438 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6441 rtx reg = gen_reg_rtx (Pmode);
6443 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6446 operands[1] = force_reg (SImode, operands[1]);
6448 emit_move_insn (r0, func);
6449 emit_move_insn (r1, cookie_rtx);
6451 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6452 emit_call_insn (gen_call_value_pop_compact_rettramp
6453 (operands[0], operands[1], operands[2],
6454 operands[3], operands[4]));
6456 emit_call_insn (gen_call_value_pop_compact
6457 (operands[0], operands[1], operands[2],
6458 operands[3], operands[4]));
6466 (define_expand "sibcall_epilogue"
6471 sh_expand_epilogue (1);
6472 if (TARGET_SHCOMPACT)
6476 /* If epilogue clobbers r0, preserve it in macl. */
6477 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6478 if ((set = single_set (insn))
6479 && GET_CODE (SET_DEST (set)) == REG
6480 && REGNO (SET_DEST (set)) == R0_REG)
6482 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6483 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6486 /* We can't tell at this point whether the sibcall is a
6487 sibcall_compact and, if it is, whether it uses r0 or
6488 mach as operand 2, so let the instructions that
6489 preserve r0 be optimized away if r0 turns out to be
6491 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6492 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6494 i = emit_move_insn (r0, tmp);
6495 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6503 (define_insn "indirect_jump_compact"
6505 (match_operand:SI 0 "arith_reg_operand" "r"))]
6508 [(set_attr "needs_delay_slot" "yes")
6509 (set_attr "type" "jump_ind")])
6511 (define_expand "indirect_jump"
6513 (match_operand 0 "register_operand" ""))]
6517 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6518 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6521 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6522 ;; which can be present in structured code from indirect jumps which can not
6523 ;; be present in structured code. This allows -fprofile-arcs to work.
6525 ;; For SH1 processors.
6526 (define_insn "casesi_jump_1"
6528 (match_operand:SI 0 "register_operand" "r"))
6529 (use (label_ref (match_operand 1 "" "")))]
6532 [(set_attr "needs_delay_slot" "yes")
6533 (set_attr "type" "jump_ind")])
6535 ;; For all later processors.
6536 (define_insn "casesi_jump_2"
6537 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6538 (label_ref (match_operand 1 "" ""))))
6539 (use (label_ref (match_operand 2 "" "")))]
6541 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6543 [(set_attr "needs_delay_slot" "yes")
6544 (set_attr "type" "jump_ind")])
6546 (define_insn "casesi_jump_media"
6547 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6548 (use (label_ref (match_operand 1 "" "")))]
6551 [(set_attr "type" "jump_media")])
6553 ;; Call subroutine returning any type.
6554 ;; ??? This probably doesn't work.
6556 (define_expand "untyped_call"
6557 [(parallel [(call (match_operand 0 "" "")
6559 (match_operand 1 "" "")
6560 (match_operand 2 "" "")])]
6561 "TARGET_SH2E || TARGET_SHMEDIA"
6566 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6568 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6570 rtx set = XVECEXP (operands[2], 0, i);
6571 emit_move_insn (SET_DEST (set), SET_SRC (set));
6574 /* The optimizer does not know that the call sets the function value
6575 registers we stored in the result block. We avoid problems by
6576 claiming that all hard registers are used and clobbered at this
6578 emit_insn (gen_blockage ());
6583 ;; ------------------------------------------------------------------------
6585 ;; ------------------------------------------------------------------------
6588 [(set (reg:SI T_REG)
6589 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6590 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6593 [(set_attr "type" "arith")])
6600 ;; Load address of a label. This is only generated by the casesi expand,
6601 ;; and by machine_dependent_reorg (fixing up fp moves).
6602 ;; This must use unspec, because this only works for labels that are
6606 [(set (reg:SI R0_REG)
6607 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6610 [(set_attr "in_delay_slot" "no")
6611 (set_attr "type" "arith")])
6613 ;; machine_dependent_reorg will make this a `mova'.
6614 (define_insn "mova_const"
6615 [(set (reg:SI R0_REG)
6616 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6619 [(set_attr "in_delay_slot" "no")
6620 (set_attr "type" "arith")])
6622 (define_expand "GOTaddr2picreg"
6623 [(set (reg:SI R0_REG)
6624 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6626 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6627 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6630 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6631 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6634 operands[1] = gen_datalabel_ref (operands[1]);
6638 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6639 rtx dipic = operands[0];
6640 rtx lab = PATTERN (gen_call_site ());
6643 equiv = operands[1];
6644 operands[1] = gen_rtx_MINUS (DImode,
6648 gen_rtx_MINUS (DImode,
6649 gen_rtx_CONST (DImode,
6652 operands[1] = gen_sym2PIC (operands[1]);
6653 PUT_MODE (operands[1], DImode);
6655 if (GET_MODE (dipic) != DImode)
6656 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6658 if (TARGET_SHMEDIA64)
6659 emit_insn (gen_movdi_const (dipic, operands[1]));
6661 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6663 emit_insn (gen_ptrel (tr, dipic, lab));
6665 if (GET_MODE (operands[0]) != GET_MODE (tr))
6666 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6668 insn = emit_move_insn (operands[0], tr);
6670 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6679 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6680 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6681 UNSPEC_DATALABEL)))]
6682 "TARGET_SHMEDIA && flag_pic
6683 && EXTRA_CONSTRAINT_Csy (operands[1])"
6684 "ptb/u datalabel %1, %0"
6685 [(set_attr "type" "pt_media")
6686 (set_attr "length" "*")])
6688 (define_insn "ptrel"
6689 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6690 (plus:DI (match_operand:DI 1 "register_operand" "r")
6692 (match_operand:DI 2 "" "")]
6694 "%O2: ptrel/u %1, %0"
6695 [(set_attr "type" "ptabs_media")])
6697 (define_expand "builtin_setjmp_receiver"
6698 [(match_operand 0 "" "")]
6702 emit_insn (gen_GOTaddr2picreg ());
6706 (define_expand "call_site"
6707 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6711 static HOST_WIDE_INT i = 0;
6712 operands[0] = GEN_INT (i);
6716 (define_expand "sym_label2reg"
6717 [(set (match_operand:SI 0 "" "")
6720 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6723 (match_operand:SI 2 "" "")
6727 (define_expand "symGOT_load"
6728 [(set (match_dup 2) (match_operand 1 "" ""))
6729 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6730 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6736 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6737 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6741 rtx reg = operands[2];
6743 if (GET_MODE (reg) != DImode)
6744 reg = gen_rtx_SUBREG (DImode, reg, 0);
6747 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6749 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6752 emit_move_insn (operands[2], operands[1]);
6754 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6756 gen_rtx_REG (Pmode, PIC_REG)));
6758 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6760 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6767 (define_expand "sym2GOT"
6768 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6772 (define_expand "symGOT2reg"
6773 [(match_operand 0 "" "") (match_operand 1 "" "")]
6779 gotsym = gen_sym2GOT (operands[1]);
6780 PUT_MODE (gotsym, Pmode);
6781 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6783 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6788 (define_expand "sym2GOTPLT"
6789 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6793 (define_expand "symGOTPLT2reg"
6794 [(match_operand 0 "" "") (match_operand 1 "" "")]
6798 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6802 (define_expand "sym2GOTOFF"
6803 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6807 (define_expand "symGOTOFF2reg"
6808 [(match_operand 0 "" "") (match_operand 1 "" "")]
6812 rtx gotoffsym, insn;
6813 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6815 gotoffsym = gen_sym2GOTOFF (operands[1]);
6816 PUT_MODE (gotoffsym, Pmode);
6817 emit_move_insn (t, gotoffsym);
6818 insn = emit_move_insn (operands[0],
6819 gen_rtx_PLUS (Pmode, t,
6820 gen_rtx_REG (Pmode, PIC_REG)));
6822 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6828 (define_expand "symPLT_label2reg"
6829 [(set (match_operand:SI 0 "" "")
6832 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6836 (match_operand:SI 2 "" "")
6838 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6839 ;; Even though the PIC register is not really used by the call
6840 ;; sequence in which this is expanded, the PLT code assumes the PIC
6841 ;; register is set, so we must not skip its initialization. Since
6842 ;; we only use this expand as part of calling sequences, and never
6843 ;; to take the address of a function, this is the best point to
6844 ;; insert the (use). Using the PLT to take the address of a
6845 ;; function would be wrong, not only because the PLT entry could
6846 ;; then be called from a function that doesn't initialize the PIC
6847 ;; register to the proper GOT, but also because pointers to the
6848 ;; same function might not compare equal, should they be set by
6849 ;; different shared libraries.
6850 (use (reg:SI PIC_REG))]
6854 (define_expand "sym2PIC"
6855 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6859 ;; TLS code generation.
6860 ;; ??? this should be a define_insn_and_split
6861 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6862 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6865 (define_insn "tls_global_dynamic"
6866 [(set (match_operand:SI 0 "register_operand" "=&z")
6867 (call (unspec:SI [(match_operand:SI 1 "" "")]
6870 (use (reg:PSI FPSCR_REG))
6871 (use (reg:SI PIC_REG))
6872 (clobber (reg:SI PR_REG))
6873 (clobber (scratch:SI))]
6879 \\tmova\\t2f,r0\\n\\
6880 \\tmov.l\\t2f,r1\\n\\
6883 \\tadd\\tr12,r4\\n\\
6887 1:\\t.long\\t%a1@TLSGD\\n\\
6888 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6891 [(set_attr "type" "tls_load")
6892 (set_attr "length" "26")])
6894 (define_insn "tls_local_dynamic"
6895 [(set (match_operand:SI 0 "register_operand" "=&z")
6896 (call (unspec:SI [(match_operand:SI 1 "" "")]
6899 (use (reg:PSI FPSCR_REG))
6900 (use (reg:SI PIC_REG))
6901 (clobber (reg:SI PR_REG))
6902 (clobber (scratch:SI))]
6908 \\tmova\\t2f,r0\\n\\
6909 \\tmov.l\\t2f,r1\\n\\
6912 \\tadd\\tr12,r4\\n\\
6916 1:\\t.long\\t%a1@TLSLDM\\n\\
6917 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6920 [(set_attr "type" "tls_load")
6921 (set_attr "length" "26")])
6923 (define_expand "sym2DTPOFF"
6924 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6928 (define_expand "symDTPOFF2reg"
6929 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6933 rtx dtpoffsym, insn;
6934 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6936 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6937 PUT_MODE (dtpoffsym, Pmode);
6938 emit_move_insn (t, dtpoffsym);
6939 insn = emit_move_insn (operands[0],
6940 gen_rtx_PLUS (Pmode, t, operands[2]));
6944 (define_expand "sym2GOTTPOFF"
6945 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6949 (define_insn "tls_initial_exec"
6950 [(set (match_operand:SI 0 "register_operand" "=&r")
6951 (unspec:SI [(match_operand:SI 1 "" "")]
6953 (use (reg:SI GBR_REG))
6954 (use (reg:SI PIC_REG))
6955 (clobber (reg:SI R0_REG))]
6961 \\tstc\\tgbr,%0\\n\\
6962 \\tmov.l\\t@(r0,r12),r0\\n\\
6966 1:\\t.long\\t%a1\\n\\
6969 [(set_attr "type" "tls_load")
6970 (set_attr "length" "16")])
6972 (define_expand "sym2TPOFF"
6973 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6977 (define_expand "symTPOFF2reg"
6978 [(match_operand 0 "" "") (match_operand 1 "" "")]
6984 tpoffsym = gen_sym2TPOFF (operands[1]);
6985 PUT_MODE (tpoffsym, Pmode);
6986 insn = emit_move_insn (operands[0], tpoffsym);
6990 (define_insn "load_gbr"
6991 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6992 (use (reg:SI GBR_REG))]
6995 [(set_attr "type" "tls_load")])
6997 ;; case instruction for switch statements.
6999 ;; Operand 0 is index
7000 ;; operand 1 is the minimum bound
7001 ;; operand 2 is the maximum bound - minimum bound + 1
7002 ;; operand 3 is CODE_LABEL for the table;
7003 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7005 (define_expand "casesi"
7006 [(match_operand:SI 0 "arith_reg_operand" "")
7007 (match_operand:SI 1 "arith_reg_operand" "")
7008 (match_operand:SI 2 "arith_reg_operand" "")
7009 (match_operand 3 "" "") (match_operand 4 "" "")]
7013 rtx reg = gen_reg_rtx (SImode);
7014 rtx reg2 = gen_reg_rtx (SImode);
7017 rtx reg = gen_reg_rtx (DImode);
7018 rtx reg2 = gen_reg_rtx (DImode);
7019 rtx reg3 = gen_reg_rtx (DImode);
7020 rtx reg4 = gen_reg_rtx (DImode);
7021 rtx reg5 = gen_reg_rtx (DImode);
7023 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7024 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7025 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7027 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7028 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7029 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7030 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7031 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7032 (DImode, operands[3])));
7033 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7034 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7035 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7039 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7040 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7041 /* If optimizing, casesi_worker depends on the mode of the instruction
7042 before label it 'uses' - operands[3]. */
7043 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7045 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7047 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7049 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7050 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7051 operands[3], but to lab. We will fix this up in
7052 machine_dependent_reorg. */
7057 (define_expand "casesi_0"
7058 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7059 (set (match_dup 4) (minus:SI (match_dup 4)
7060 (match_operand:SI 1 "arith_operand" "")))
7062 (gtu:SI (match_dup 4)
7063 (match_operand:SI 2 "arith_reg_operand" "")))
7065 (if_then_else (ne (reg:SI T_REG)
7067 (label_ref (match_operand 3 "" ""))
7072 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7073 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7074 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7076 (define_insn "casesi_worker_0"
7077 [(set (match_operand:SI 0 "register_operand" "=r,r")
7078 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7079 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7080 (clobber (match_scratch:SI 3 "=X,1"))
7081 (clobber (match_scratch:SI 4 "=&z,z"))]
7086 [(set (match_operand:SI 0 "register_operand" "")
7087 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7088 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7089 (clobber (match_scratch:SI 3 ""))
7090 (clobber (match_scratch:SI 4 ""))]
7091 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7092 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7093 (parallel [(set (match_dup 0)
7094 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7095 (label_ref (match_dup 2))] UNSPEC_CASESI))
7096 (clobber (match_dup 3))])
7097 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7098 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7101 [(set (match_operand:SI 0 "register_operand" "")
7102 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7103 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7104 (clobber (match_scratch:SI 3 ""))
7105 (clobber (match_scratch:SI 4 ""))]
7106 "TARGET_SH2 && reload_completed"
7107 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7108 (parallel [(set (match_dup 0)
7109 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7110 (label_ref (match_dup 2))] UNSPEC_CASESI))
7111 (clobber (match_dup 3))])]
7112 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7114 (define_insn "casesi_worker_1"
7115 [(set (match_operand:SI 0 "register_operand" "=r,r")
7116 (unspec:SI [(reg:SI R0_REG)
7117 (match_operand:SI 1 "register_operand" "0,r")
7118 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7119 (clobber (match_scratch:SI 3 "=X,1"))]
7123 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7125 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7128 switch (GET_MODE (diff_vec))
7131 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7133 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7135 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7136 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7137 return \"mov.b @(r0,%1),%0\";
7142 [(set_attr "length" "4")])
7144 (define_insn "casesi_worker_2"
7145 [(set (match_operand:SI 0 "register_operand" "=r,r")
7146 (unspec:SI [(reg:SI R0_REG)
7147 (match_operand:SI 1 "register_operand" "0,r")
7148 (label_ref (match_operand 2 "" ""))
7149 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7150 (clobber (match_operand:SI 4 "" "=X,1"))]
7151 "TARGET_SH2 && reload_completed && flag_pic"
7154 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7157 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7160 switch (GET_MODE (diff_vec))
7163 output_asm_insn (\"shll2 %1\", operands);
7164 load = \"mov.l @(r0,%1),%0\"; break;
7166 output_asm_insn (\"add %1,%1\", operands);
7167 load = \"mov.w @(r0,%1),%0\"; break;
7169 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7170 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7172 load = \"mov.b @(r0,%1),%0\";
7177 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7180 [(set_attr "length" "8")])
7182 (define_insn "casesi_shift_media"
7183 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7184 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7185 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7190 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7192 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7195 switch (GET_MODE (diff_vec))
7198 return \"shlli %1, 2, %0\";
7200 return \"shlli %1, 1, %0\";
7202 if (rtx_equal_p (operands[0], operands[1]))
7204 return \"add %1, r63, %0\";
7209 [(set_attr "type" "arith_media")])
7211 (define_insn "casesi_load_media"
7212 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7213 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7214 (match_operand 2 "arith_reg_operand" "r")
7215 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7219 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7221 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7224 switch (GET_MODE (diff_vec))
7227 return \"ldx.l %1, %2, %0\";
7230 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7231 return \"ldx.uw %1, %2, %0\";
7233 return \"ldx.w %1, %2, %0\";
7235 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7236 return \"ldx.ub %1, %2, %0\";
7237 return \"ldx.b %1, %2, %0\";
7242 [(set_attr "type" "load_media")])
7244 (define_expand "return"
7246 "reload_completed && ! sh_need_epilogue ()"
7251 emit_jump_insn (gen_return_media ());
7255 if (TARGET_SHCOMPACT
7256 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7258 emit_jump_insn (gen_shcompact_return_tramp ());
7263 (define_insn "*return_i"
7265 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7266 && (current_function_args_info.call_cookie
7267 & CALL_COOKIE_RET_TRAMP (1)))
7268 && reload_completed"
7270 [(set_attr "type" "return")
7271 (set_attr "needs_delay_slot" "yes")])
7273 (define_expand "shcompact_return_tramp"
7276 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7279 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7280 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7283 emit_insn (gen_symGOTPLT2reg (reg, sym));
7285 emit_move_insn (reg, sym);
7287 emit_jump_insn (gen_shcompact_return_tramp_i ());
7291 (define_insn "shcompact_return_tramp_i"
7292 [(parallel [(return) (use (reg:SI R0_REG))])]
7294 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7296 [(set_attr "type" "jump_ind")
7297 (set_attr "needs_delay_slot" "yes")])
7299 (define_insn "return_media_i"
7300 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7301 "TARGET_SHMEDIA && reload_completed"
7303 [(set_attr "type" "jump_media")])
7305 (define_insn "return_media_rte"
7307 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7309 [(set_attr "type" "jump_media")])
7311 (define_expand "return_media"
7313 "TARGET_SHMEDIA && reload_completed"
7316 int tr_regno = sh_media_register_for_return ();
7319 if (current_function_interrupt)
7321 emit_jump_insn (gen_return_media_rte ());
7326 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7328 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7331 tr = gen_rtx_REG (DImode, tr_regno);
7332 emit_move_insn (tr, r18);
7335 tr = gen_rtx_REG (DImode, tr_regno);
7337 emit_jump_insn (gen_return_media_i (tr));
7341 (define_insn "shcompact_preserve_incoming_args"
7342 [(set (match_operand:SI 0 "register_operand" "+r")
7343 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7346 [(set_attr "length" "0")])
7348 (define_insn "shcompact_incoming_args"
7349 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7350 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7351 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7352 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7353 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7354 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7355 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7356 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7357 (set (mem:BLK (reg:SI MACL_REG))
7358 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7359 (use (reg:SI R0_REG))
7360 (clobber (reg:SI R0_REG))
7361 (clobber (reg:SI MACL_REG))
7362 (clobber (reg:SI MACH_REG))
7363 (clobber (reg:SI PR_REG))]
7366 [(set_attr "needs_delay_slot" "yes")])
7368 (define_insn "shmedia_save_restore_regs_compact"
7369 [(set (reg:SI SP_REG)
7370 (plus:SI (reg:SI SP_REG)
7371 (match_operand:SI 0 "immediate_operand" "i")))
7372 (use (reg:SI R0_REG))
7373 (clobber (reg:SI PR_REG))]
7375 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7376 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7378 [(set_attr "needs_delay_slot" "yes")])
7380 (define_expand "prologue"
7383 "sh_expand_prologue (); DONE;")
7385 (define_expand "epilogue"
7390 sh_expand_epilogue (0);
7391 emit_jump_insn (gen_return ());
7395 (define_expand "eh_return"
7396 [(use (match_operand 0 "register_operand" ""))]
7399 rtx ra = operands[0];
7401 if (TARGET_SHMEDIA64)
7402 emit_insn (gen_eh_set_ra_di (ra));
7404 emit_insn (gen_eh_set_ra_si (ra));
7409 ;; Clobber the return address on the stack. We can't expand this
7410 ;; until we know where it will be put in the stack frame.
7412 (define_insn "eh_set_ra_si"
7413 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7414 (clobber (match_scratch:SI 1 "=&r"))]
7415 "! TARGET_SHMEDIA64"
7418 (define_insn "eh_set_ra_di"
7419 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7420 (clobber (match_scratch:DI 1 "=&r"))]
7425 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7426 (clobber (match_scratch 1 ""))]
7431 sh_set_return_address (operands[0], operands[1]);
7435 (define_insn "blockage"
7436 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7439 [(set_attr "length" "0")])
7441 ;; ------------------------------------------------------------------------
7443 ;; ------------------------------------------------------------------------
7446 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7447 (eq:SI (reg:SI T_REG) (const_int 1)))]
7450 [(set_attr "type" "arith")])
7452 (define_expand "seq"
7453 [(set (match_operand:SI 0 "arith_reg_operand" "")
7460 if (GET_MODE (operands[0]) != DImode)
7461 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7462 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7463 if (sh_compare_op1 != const0_rtx)
7464 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7465 ? GET_MODE (sh_compare_op0)
7466 : GET_MODE (sh_compare_op1),
7469 switch (GET_MODE (sh_compare_op0))
7472 emit_insn (gen_cmpeqdi_media (operands[0],
7473 sh_compare_op0, sh_compare_op1));
7477 if (! TARGET_SHMEDIA_FPU)
7479 emit_insn (gen_cmpeqsf_media (operands[0],
7480 sh_compare_op0, sh_compare_op1));
7484 if (! TARGET_SHMEDIA_FPU)
7486 emit_insn (gen_cmpeqdf_media (operands[0],
7487 sh_compare_op0, sh_compare_op1));
7495 if (sh_expand_t_scc (EQ, operands[0]))
7497 if (! rtx_equal_function_value_matters)
7499 operands[1] = prepare_scc_operands (EQ);
7502 (define_expand "slt"
7503 [(set (match_operand:SI 0 "arith_reg_operand" "")
7510 if (GET_MODE (operands[0]) != DImode)
7511 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7512 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7513 if (sh_compare_op1 != const0_rtx)
7514 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7515 ? GET_MODE (sh_compare_op0)
7516 : GET_MODE (sh_compare_op1),
7519 switch (GET_MODE (sh_compare_op0))
7522 emit_insn (gen_cmpgtdi_media (operands[0],
7523 sh_compare_op1, sh_compare_op0));
7527 if (! TARGET_SHMEDIA_FPU)
7529 emit_insn (gen_cmpgtsf_media (operands[0],
7530 sh_compare_op1, sh_compare_op0));
7534 if (! TARGET_SHMEDIA_FPU)
7536 emit_insn (gen_cmpgtdf_media (operands[0],
7537 sh_compare_op1, sh_compare_op0));
7545 if (! rtx_equal_function_value_matters)
7547 operands[1] = prepare_scc_operands (LT);
7550 (define_expand "sle"
7551 [(match_operand:SI 0 "arith_reg_operand" "")]
7555 rtx tmp = sh_compare_op0;
7559 if (GET_MODE (operands[0]) != DImode)
7560 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7561 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7562 if (sh_compare_op1 != const0_rtx)
7563 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7564 ? GET_MODE (sh_compare_op0)
7565 : GET_MODE (sh_compare_op1),
7568 switch (GET_MODE (sh_compare_op0))
7572 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7574 emit_insn (gen_cmpgtdi_media (tmp,
7575 sh_compare_op0, sh_compare_op1));
7576 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7581 if (! TARGET_SHMEDIA_FPU)
7583 emit_insn (gen_cmpgesf_media (operands[0],
7584 sh_compare_op1, sh_compare_op0));
7588 if (! TARGET_SHMEDIA_FPU)
7590 emit_insn (gen_cmpgedf_media (operands[0],
7591 sh_compare_op1, sh_compare_op0));
7600 sh_compare_op0 = sh_compare_op1;
7601 sh_compare_op1 = tmp;
7602 emit_insn (gen_sge (operands[0]));
7606 (define_expand "sgt"
7607 [(set (match_operand:SI 0 "arith_reg_operand" "")
7614 if (GET_MODE (operands[0]) != DImode)
7615 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7616 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7617 if (sh_compare_op1 != const0_rtx)
7618 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7619 ? GET_MODE (sh_compare_op0)
7620 : GET_MODE (sh_compare_op1),
7623 switch (GET_MODE (sh_compare_op0))
7626 emit_insn (gen_cmpgtdi_media (operands[0],
7627 sh_compare_op0, sh_compare_op1));
7631 if (! TARGET_SHMEDIA_FPU)
7633 emit_insn (gen_cmpgtsf_media (operands[0],
7634 sh_compare_op0, sh_compare_op1));
7638 if (! TARGET_SHMEDIA_FPU)
7640 emit_insn (gen_cmpgtdf_media (operands[0],
7641 sh_compare_op0, sh_compare_op1));
7649 if (! rtx_equal_function_value_matters)
7651 operands[1] = prepare_scc_operands (GT);
7654 (define_expand "sge"
7655 [(set (match_operand:SI 0 "arith_reg_operand" "")
7662 if (GET_MODE (operands[0]) != DImode)
7663 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7664 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7665 if (sh_compare_op1 != const0_rtx)
7666 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7667 ? GET_MODE (sh_compare_op0)
7668 : GET_MODE (sh_compare_op1),
7671 switch (GET_MODE (sh_compare_op0))
7675 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7677 emit_insn (gen_cmpgtdi_media (tmp,
7678 sh_compare_op1, sh_compare_op0));
7679 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7684 if (! TARGET_SHMEDIA_FPU)
7686 emit_insn (gen_cmpgesf_media (operands[0],
7687 sh_compare_op0, sh_compare_op1));
7691 if (! TARGET_SHMEDIA_FPU)
7693 emit_insn (gen_cmpgedf_media (operands[0],
7694 sh_compare_op0, sh_compare_op1));
7703 if (! rtx_equal_function_value_matters)
7705 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7709 rtx lab = gen_label_rtx ();
7710 prepare_scc_operands (EQ);
7711 emit_jump_insn (gen_branch_true (lab));
7712 prepare_scc_operands (GT);
7714 emit_insn (gen_movt (operands[0]));
7717 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7720 operands[1] = prepare_scc_operands (GE);
7723 (define_expand "sgtu"
7724 [(set (match_operand:SI 0 "arith_reg_operand" "")
7731 if (GET_MODE (operands[0]) != DImode)
7732 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7733 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7734 if (sh_compare_op1 != const0_rtx)
7735 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7736 ? GET_MODE (sh_compare_op0)
7737 : GET_MODE (sh_compare_op1),
7740 emit_insn (gen_cmpgtudi_media (operands[0],
7741 sh_compare_op0, sh_compare_op1));
7744 if (! rtx_equal_function_value_matters)
7746 operands[1] = prepare_scc_operands (GTU);
7749 (define_expand "sltu"
7750 [(set (match_operand:SI 0 "arith_reg_operand" "")
7757 if (GET_MODE (operands[0]) != DImode)
7758 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7759 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7760 if (sh_compare_op1 != const0_rtx)
7761 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7762 ? GET_MODE (sh_compare_op0)
7763 : GET_MODE (sh_compare_op1),
7766 emit_insn (gen_cmpgtudi_media (operands[0],
7767 sh_compare_op1, sh_compare_op0));
7770 if (! rtx_equal_function_value_matters)
7772 operands[1] = prepare_scc_operands (LTU);
7775 (define_expand "sleu"
7776 [(set (match_operand:SI 0 "arith_reg_operand" "")
7785 if (GET_MODE (operands[0]) != DImode)
7786 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7787 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7788 if (sh_compare_op1 != const0_rtx)
7789 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7790 ? GET_MODE (sh_compare_op0)
7791 : GET_MODE (sh_compare_op1),
7794 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7796 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7797 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7801 if (! rtx_equal_function_value_matters)
7803 operands[1] = prepare_scc_operands (LEU);
7806 (define_expand "sgeu"
7807 [(set (match_operand:SI 0 "arith_reg_operand" "")
7816 if (GET_MODE (operands[0]) != DImode)
7817 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7818 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7819 if (sh_compare_op1 != const0_rtx)
7820 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7821 ? GET_MODE (sh_compare_op0)
7822 : GET_MODE (sh_compare_op1),
7825 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7827 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7828 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7833 if (! rtx_equal_function_value_matters)
7835 operands[1] = prepare_scc_operands (GEU);
7838 ;; sne moves the complement of the T reg to DEST like this:
7842 ;; This is better than xoring compare result with 1 because it does
7843 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7846 (define_expand "sne"
7847 [(set (match_dup 2) (const_int -1))
7848 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7849 (neg:SI (plus:SI (match_dup 1)
7852 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7861 if (GET_MODE (operands[0]) != DImode)
7862 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7864 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7867 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7868 if (sh_compare_op1 != const0_rtx)
7869 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7870 ? GET_MODE (sh_compare_op0)
7871 : GET_MODE (sh_compare_op1),
7874 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7876 emit_insn (gen_seq (tmp));
7877 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7882 if (sh_expand_t_scc (NE, operands[0]))
7884 if (! rtx_equal_function_value_matters)
7886 operands[1] = prepare_scc_operands (EQ);
7887 operands[2] = gen_reg_rtx (SImode);
7890 (define_expand "sunordered"
7891 [(set (match_operand:DI 0 "arith_reg_operand" "")
7892 (unordered:DI (match_dup 1) (match_dup 2)))]
7893 "TARGET_SHMEDIA_FPU"
7896 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7897 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7900 ;; Use the same trick for FP sle / sge
7901 (define_expand "movnegt"
7902 [(set (match_dup 2) (const_int -1))
7903 (parallel [(set (match_operand 0 "" "")
7904 (neg:SI (plus:SI (match_dup 1)
7907 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7910 "operands[2] = gen_reg_rtx (SImode);")
7912 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7913 ;; This prevents a regression that occurred when we switched from xor to
7917 [(set (match_operand:SI 0 "arith_reg_operand" "")
7918 (plus:SI (reg:SI T_REG)
7921 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7922 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7925 ;; -------------------------------------------------------------------------
7926 ;; Instructions to cope with inline literal tables
7927 ;; -------------------------------------------------------------------------
7929 ; 2 byte integer in line
7931 (define_insn "consttable_2"
7932 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7933 (match_operand 1 "" "")]
7938 if (operands[1] != const0_rtx)
7939 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7942 [(set_attr "length" "2")
7943 (set_attr "in_delay_slot" "no")])
7945 ; 4 byte integer in line
7947 (define_insn "consttable_4"
7948 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7949 (match_operand 1 "" "")]
7954 if (operands[1] != const0_rtx)
7955 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7958 [(set_attr "length" "4")
7959 (set_attr "in_delay_slot" "no")])
7961 ; 8 byte integer in line
7963 (define_insn "consttable_8"
7964 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7965 (match_operand 1 "" "")]
7970 if (operands[1] != const0_rtx)
7971 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7974 [(set_attr "length" "8")
7975 (set_attr "in_delay_slot" "no")])
7977 ; 4 byte floating point
7979 (define_insn "consttable_sf"
7980 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7981 (match_operand 1 "" "")]
7986 if (operands[1] != const0_rtx)
7989 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7990 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7994 [(set_attr "length" "4")
7995 (set_attr "in_delay_slot" "no")])
7997 ; 8 byte floating point
7999 (define_insn "consttable_df"
8000 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
8001 (match_operand 1 "" "")]
8006 if (operands[1] != const0_rtx)
8009 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8010 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8014 [(set_attr "length" "8")
8015 (set_attr "in_delay_slot" "no")])
8017 ;; Alignment is needed for some constant tables; it may also be added for
8018 ;; Instructions at the start of loops, or after unconditional branches.
8019 ;; ??? We would get more accurate lengths if we did instruction
8020 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8021 ;; here is too conservative.
8023 ; align to a two byte boundary
8025 (define_expand "align_2"
8026 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8030 ; align to a four byte boundary
8031 ;; align_4 and align_log are instructions for the starts of loops, or
8032 ;; after unconditional branches, which may take up extra room.
8034 (define_expand "align_4"
8035 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8039 ; align to a cache line boundary
8041 (define_insn "align_log"
8042 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8045 [(set_attr "length" "0")
8046 (set_attr "in_delay_slot" "no")])
8048 ; emitted at the end of the literal table, used to emit the
8049 ; 32bit branch labels if needed.
8051 (define_insn "consttable_end"
8052 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8054 "* return output_jump_label_table ();"
8055 [(set_attr "in_delay_slot" "no")])
8057 ; emitted at the end of the window in the literal table.
8059 (define_insn "consttable_window_end"
8060 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8063 [(set_attr "length" "0")
8064 (set_attr "in_delay_slot" "no")])
8066 ;; -------------------------------------------------------------------------
8068 ;; -------------------------------------------------------------------------
8070 ;; String/block move insn.
8072 (define_expand "movstrsi"
8073 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8074 (mem:BLK (match_operand:BLK 1 "" "")))
8075 (use (match_operand:SI 2 "nonmemory_operand" ""))
8076 (use (match_operand:SI 3 "immediate_operand" ""))
8077 (clobber (reg:SI PR_REG))
8078 (clobber (reg:SI R4_REG))
8079 (clobber (reg:SI R5_REG))
8080 (clobber (reg:SI R0_REG))])]
8081 "TARGET_SH1 && ! TARGET_SH5"
8084 if(expand_block_move (operands))
8089 (define_insn "block_move_real"
8090 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8091 (mem:BLK (reg:SI R5_REG)))
8092 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8093 (clobber (reg:SI PR_REG))
8094 (clobber (reg:SI R0_REG))])]
8095 "TARGET_SH1 && ! TARGET_HARD_SH4"
8097 [(set_attr "type" "sfunc")
8098 (set_attr "needs_delay_slot" "yes")])
8100 (define_insn "block_lump_real"
8101 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8102 (mem:BLK (reg:SI R5_REG)))
8103 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8104 (use (reg:SI R6_REG))
8105 (clobber (reg:SI PR_REG))
8106 (clobber (reg:SI T_REG))
8107 (clobber (reg:SI R4_REG))
8108 (clobber (reg:SI R5_REG))
8109 (clobber (reg:SI R6_REG))
8110 (clobber (reg:SI R0_REG))])]
8111 "TARGET_SH1 && ! TARGET_HARD_SH4"
8113 [(set_attr "type" "sfunc")
8114 (set_attr "needs_delay_slot" "yes")])
8116 (define_insn "block_move_real_i4"
8117 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8118 (mem:BLK (reg:SI R5_REG)))
8119 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8120 (clobber (reg:SI PR_REG))
8121 (clobber (reg:SI R0_REG))
8122 (clobber (reg:SI R1_REG))
8123 (clobber (reg:SI R2_REG))])]
8126 [(set_attr "type" "sfunc")
8127 (set_attr "needs_delay_slot" "yes")])
8129 (define_insn "block_lump_real_i4"
8130 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8131 (mem:BLK (reg:SI R5_REG)))
8132 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8133 (use (reg:SI R6_REG))
8134 (clobber (reg:SI PR_REG))
8135 (clobber (reg:SI T_REG))
8136 (clobber (reg:SI R4_REG))
8137 (clobber (reg:SI R5_REG))
8138 (clobber (reg:SI R6_REG))
8139 (clobber (reg:SI R0_REG))
8140 (clobber (reg:SI R1_REG))
8141 (clobber (reg:SI R2_REG))
8142 (clobber (reg:SI R3_REG))])]
8145 [(set_attr "type" "sfunc")
8146 (set_attr "needs_delay_slot" "yes")])
8148 ;; -------------------------------------------------------------------------
8149 ;; Floating point instructions.
8150 ;; -------------------------------------------------------------------------
8152 ;; ??? All patterns should have a type attribute.
8154 (define_expand "fpu_switch0"
8155 [(set (match_operand:SI 0 "" "") (match_dup 2))
8156 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8160 operands[1] = get_fpscr_rtx ();
8161 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8163 operands[2] = legitimize_pic_address (operands[2], SImode,
8164 no_new_pseudos ? operands[0] : 0);
8167 (define_expand "fpu_switch1"
8168 [(set (match_operand:SI 0 "" "") (match_dup 2))
8169 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8170 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8174 operands[1] = get_fpscr_rtx ();
8175 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8177 operands[2] = legitimize_pic_address (operands[2], SImode,
8178 no_new_pseudos ? operands[0] : 0);
8179 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8182 (define_expand "movpsi"
8183 [(set (match_operand:PSI 0 "register_operand" "")
8184 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8188 ;; The c / m alternative is a fake to guide reload to load directly into
8189 ;; fpscr, since reload doesn't know how to use post-increment.
8190 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8191 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8192 ;; predicate after reload.
8193 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8194 ;; like a mac -> gpr move.
8195 (define_insn "fpu_switch"
8196 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8197 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8199 && (! reload_completed
8200 || true_regnum (operands[0]) != FPSCR_REG
8201 || GET_CODE (operands[1]) != MEM
8202 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8204 ! precision stays the same
8213 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8214 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8217 [(set (reg:PSI FPSCR_REG)
8218 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8219 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8220 [(set (match_dup 0) (match_dup 0))]
8223 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8224 gen_rtx_MEM (PSImode,
8225 gen_rtx_POST_INC (Pmode,
8227 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8231 [(set (reg:PSI FPSCR_REG)
8232 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8234 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8237 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8238 gen_rtx_MEM (PSImode,
8239 gen_rtx_POST_INC (Pmode,
8241 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8244 ;; ??? This uses the fp unit, but has no type indicating that.
8245 ;; If we did that, this would either give a bogus latency or introduce
8246 ;; a bogus FIFO constraint.
8247 ;; Since this insn is currently only used for prologues/epilogues,
8248 ;; it is probably best to claim no function unit, which matches the
8250 (define_insn "toggle_sz"
8251 [(set (reg:PSI FPSCR_REG)
8252 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8255 [(set_attr "fp_set" "unknown")])
8257 (define_expand "addsf3"
8258 [(set (match_operand:SF 0 "arith_reg_operand" "")
8259 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8260 (match_operand:SF 2 "arith_reg_operand" "")))]
8261 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8266 expand_sf_binop (&gen_addsf3_i, operands);
8271 (define_insn "*addsf3_media"
8272 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8273 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8274 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8275 "TARGET_SHMEDIA_FPU"
8277 [(set_attr "type" "fparith_media")])
8279 (define_insn_and_split "unary_sf_op"
8280 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8285 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8286 (match_operator:SF 2 "unary_float_operator"
8287 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8288 (parallel [(match_operand 4
8289 "const_int_operand" "n")]))]))
8290 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8291 "TARGET_SHMEDIA_FPU"
8293 "TARGET_SHMEDIA_FPU && reload_completed"
8294 [(set (match_dup 5) (match_dup 6))]
8297 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8298 rtx op1 = gen_rtx_REG (SFmode,
8299 (true_regnum (operands[1])
8300 + (INTVAL (operands[4]) ^ endian)));
8302 operands[7] = gen_rtx_REG (SFmode,
8303 (true_regnum (operands[0])
8304 + (INTVAL (operands[3]) ^ endian)));
8305 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8307 [(set_attr "type" "fparith_media")])
8309 (define_insn_and_split "binary_sf_op"
8310 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8315 (parallel [(match_operand 7 "const_int_operand" "n")]))
8316 (match_operator:SF 3 "binary_float_operator"
8317 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8318 (parallel [(match_operand 5
8319 "const_int_operand" "n")]))
8320 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8321 (parallel [(match_operand 6
8322 "const_int_operand" "n")]))]))
8323 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8324 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8326 "&& reload_completed"
8327 [(set (match_dup 8) (match_dup 9))]
8330 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8331 rtx op1 = gen_rtx_REG (SFmode,
8332 (true_regnum (operands[1])
8333 + (INTVAL (operands[5]) ^ endian)));
8334 rtx op2 = gen_rtx_REG (SFmode,
8335 (true_regnum (operands[2])
8336 + (INTVAL (operands[6]) ^ endian)));
8338 operands[8] = gen_rtx_REG (SFmode,
8339 (true_regnum (operands[0])
8340 + (INTVAL (operands[4]) ^ endian)));
8341 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8343 [(set_attr "type" "fparith_media")])
8345 (define_insn "addsf3_i"
8346 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8347 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8348 (match_operand:SF 2 "arith_reg_operand" "f")))
8349 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8352 [(set_attr "type" "fp")
8353 (set_attr "fp_mode" "single")])
8355 (define_expand "subsf3"
8356 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8357 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8358 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8359 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8364 expand_sf_binop (&gen_subsf3_i, operands);
8369 (define_insn "*subsf3_media"
8370 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8371 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8372 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8373 "TARGET_SHMEDIA_FPU"
8375 [(set_attr "type" "fparith_media")])
8377 (define_insn "subsf3_i"
8378 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8379 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8380 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8381 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8384 [(set_attr "type" "fp")
8385 (set_attr "fp_mode" "single")])
8387 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8388 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8389 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8390 ;; SH3E, we use a separate insn for SH3E mulsf3.
8392 (define_expand "mulsf3"
8393 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8394 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8395 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8396 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8400 expand_sf_binop (&gen_mulsf3_i4, operands);
8401 else if (TARGET_SH2E)
8402 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8403 if (! TARGET_SHMEDIA)
8407 (define_insn "*mulsf3_media"
8408 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8409 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8410 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8411 "TARGET_SHMEDIA_FPU"
8413 [(set_attr "type" "fparith_media")])
8415 (define_insn "mulsf3_i4"
8416 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8417 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8418 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8419 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8422 [(set_attr "type" "fp")
8423 (set_attr "fp_mode" "single")])
8425 (define_insn "mulsf3_ie"
8426 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8427 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8428 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8429 "TARGET_SH2E && ! TARGET_SH4"
8431 [(set_attr "type" "fp")])
8433 (define_insn "*mac_media"
8434 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8435 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8436 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8437 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8438 "TARGET_SHMEDIA_FPU"
8440 [(set_attr "type" "fparith_media")])
8442 (define_insn "*macsf3"
8443 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8445 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8446 (match_operand:SF 3 "arith_reg_operand" "0")))
8447 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8448 "TARGET_SH2E && ! TARGET_SH4"
8450 [(set_attr "type" "fp")
8451 (set_attr "fp_mode" "single")])
8453 (define_expand "divsf3"
8454 [(set (match_operand:SF 0 "arith_reg_operand" "")
8455 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8456 (match_operand:SF 2 "arith_reg_operand" "")))]
8457 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8462 expand_sf_binop (&gen_divsf3_i, operands);
8467 (define_insn "*divsf3_media"
8468 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8469 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8470 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8471 "TARGET_SHMEDIA_FPU"
8473 [(set_attr "type" "fdiv_media")])
8475 (define_insn "divsf3_i"
8476 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8477 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8478 (match_operand:SF 2 "arith_reg_operand" "f")))
8479 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8482 [(set_attr "type" "fdiv")
8483 (set_attr "fp_mode" "single")])
8485 (define_insn "floatdisf2"
8486 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8487 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8488 "TARGET_SHMEDIA_FPU"
8490 [(set_attr "type" "fpconv_media")])
8492 (define_expand "floatsisf2"
8493 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8494 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8495 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8500 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8505 (define_insn "*floatsisf2_media"
8506 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8507 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8508 "TARGET_SHMEDIA_FPU"
8510 [(set_attr "type" "fpconv_media")])
8512 (define_insn "floatsisf2_i4"
8513 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8514 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8515 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8518 [(set_attr "type" "fp")
8519 (set_attr "fp_mode" "single")])
8521 (define_insn "*floatsisf2_ie"
8522 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8523 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8524 "TARGET_SH2E && ! TARGET_SH4"
8526 [(set_attr "type" "fp")])
8528 (define_insn "fix_truncsfdi2"
8529 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8530 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8531 "TARGET_SHMEDIA_FPU"
8533 [(set_attr "type" "fpconv_media")])
8535 (define_expand "fix_truncsfsi2"
8536 [(set (match_operand:SI 0 "fpul_operand" "=y")
8537 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8538 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8543 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8548 (define_insn "*fix_truncsfsi2_media"
8549 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8550 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8551 "TARGET_SHMEDIA_FPU"
8553 [(set_attr "type" "fpconv_media")])
8555 (define_insn "fix_truncsfsi2_i4"
8556 [(set (match_operand:SI 0 "fpul_operand" "=y")
8557 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8558 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8561 [(set_attr "type" "ftrc_s")
8562 (set_attr "fp_mode" "single")])
8564 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8565 ;; fix_truncsfsi2_i4.
8566 ;; (define_insn "fix_truncsfsi2_i4_2"
8567 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8568 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8569 ;; (use (reg:PSI FPSCR_REG))
8570 ;; (clobber (reg:SI FPUL_REG))]
8573 ;; [(set_attr "length" "4")
8574 ;; (set_attr "fp_mode" "single")])
8577 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8578 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8579 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8580 ;; (clobber (reg:SI FPUL_REG))]
8582 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8583 ;; (use (match_dup 2))])
8584 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8586 (define_insn "*fixsfsi"
8587 [(set (match_operand:SI 0 "fpul_operand" "=y")
8588 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8589 "TARGET_SH2E && ! TARGET_SH4"
8591 [(set_attr "type" "fp")])
8593 (define_insn "cmpgtsf_t"
8594 [(set (reg:SI T_REG)
8595 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8596 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8597 "TARGET_SH2E && ! TARGET_SH4"
8599 [(set_attr "type" "fp")
8600 (set_attr "fp_mode" "single")])
8602 (define_insn "cmpeqsf_t"
8603 [(set (reg:SI T_REG)
8604 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8605 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8606 "TARGET_SH2E && ! TARGET_SH4"
8608 [(set_attr "type" "fp")
8609 (set_attr "fp_mode" "single")])
8611 (define_insn "ieee_ccmpeqsf_t"
8612 [(set (reg:SI T_REG)
8613 (ior:SI (reg:SI T_REG)
8614 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8615 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8616 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8617 "* return output_ieee_ccmpeq (insn, operands);"
8618 [(set_attr "length" "4")])
8621 (define_insn "cmpgtsf_t_i4"
8622 [(set (reg:SI T_REG)
8623 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8624 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8625 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8628 [(set_attr "type" "fp")
8629 (set_attr "fp_mode" "single")])
8631 (define_insn "cmpeqsf_t_i4"
8632 [(set (reg:SI T_REG)
8633 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8634 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8635 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8638 [(set_attr "type" "fp")
8639 (set_attr "fp_mode" "single")])
8641 (define_insn "*ieee_ccmpeqsf_t_4"
8642 [(set (reg:SI T_REG)
8643 (ior:SI (reg:SI T_REG)
8644 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8645 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8646 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8647 "TARGET_IEEE && TARGET_SH4"
8648 "* return output_ieee_ccmpeq (insn, operands);"
8649 [(set_attr "length" "4")
8650 (set_attr "fp_mode" "single")])
8652 (define_insn "cmpeqsf_media"
8653 [(set (match_operand:DI 0 "register_operand" "=r")
8654 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8655 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8656 "TARGET_SHMEDIA_FPU"
8657 "fcmpeq.s %1, %2, %0"
8658 [(set_attr "type" "fcmp_media")])
8660 (define_insn "cmpgtsf_media"
8661 [(set (match_operand:DI 0 "register_operand" "=r")
8662 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8663 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8664 "TARGET_SHMEDIA_FPU"
8665 "fcmpgt.s %1, %2, %0"
8666 [(set_attr "type" "fcmp_media")])
8668 (define_insn "cmpgesf_media"
8669 [(set (match_operand:DI 0 "register_operand" "=r")
8670 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8671 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8672 "TARGET_SHMEDIA_FPU"
8673 "fcmpge.s %1, %2, %0"
8674 [(set_attr "type" "fcmp_media")])
8676 (define_insn "cmpunsf_media"
8677 [(set (match_operand:DI 0 "register_operand" "=r")
8678 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8679 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8680 "TARGET_SHMEDIA_FPU"
8681 "fcmpun.s %1, %2, %0"
8682 [(set_attr "type" "fcmp_media")])
8684 (define_expand "cmpsf"
8685 [(set (reg:SI T_REG)
8686 (compare (match_operand:SF 0 "arith_operand" "")
8687 (match_operand:SF 1 "arith_operand" "")))]
8688 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8691 sh_compare_op0 = operands[0];
8692 sh_compare_op1 = operands[1];
8696 (define_expand "negsf2"
8697 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8698 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8699 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8704 expand_sf_unop (&gen_negsf2_i, operands);
8709 (define_insn "*negsf2_media"
8710 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8711 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8712 "TARGET_SHMEDIA_FPU"
8714 [(set_attr "type" "fmove_media")])
8716 (define_insn "negsf2_i"
8717 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8718 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8719 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8722 [(set_attr "type" "fmove")
8723 (set_attr "fp_mode" "single")])
8725 (define_expand "sqrtsf2"
8726 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8727 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8728 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8733 expand_sf_unop (&gen_sqrtsf2_i, operands);
8738 (define_insn "*sqrtsf2_media"
8739 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8740 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8741 "TARGET_SHMEDIA_FPU"
8743 [(set_attr "type" "fdiv_media")])
8745 (define_insn "sqrtsf2_i"
8746 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8747 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8748 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8751 [(set_attr "type" "fdiv")
8752 (set_attr "fp_mode" "single")])
8754 (define_expand "abssf2"
8755 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8756 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8757 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8762 expand_sf_unop (&gen_abssf2_i, operands);
8767 (define_insn "*abssf2_media"
8768 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8769 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8770 "TARGET_SHMEDIA_FPU"
8772 [(set_attr "type" "fmove_media")])
8774 (define_insn "abssf2_i"
8775 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8776 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8777 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8780 [(set_attr "type" "fmove")
8781 (set_attr "fp_mode" "single")])
8783 (define_expand "adddf3"
8784 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8785 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8786 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8787 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8792 expand_df_binop (&gen_adddf3_i, operands);
8797 (define_insn "*adddf3_media"
8798 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8799 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8800 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8801 "TARGET_SHMEDIA_FPU"
8803 [(set_attr "type" "dfparith_media")])
8805 (define_insn "adddf3_i"
8806 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8807 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8808 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8809 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8812 [(set_attr "type" "dfp_arith")
8813 (set_attr "fp_mode" "double")])
8815 (define_expand "subdf3"
8816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8817 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8818 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8819 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8824 expand_df_binop (&gen_subdf3_i, operands);
8829 (define_insn "*subdf3_media"
8830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8832 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8833 "TARGET_SHMEDIA_FPU"
8835 [(set_attr "type" "dfparith_media")])
8837 (define_insn "subdf3_i"
8838 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8839 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8840 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8841 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8844 [(set_attr "type" "dfp_arith")
8845 (set_attr "fp_mode" "double")])
8847 (define_expand "muldf3"
8848 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8849 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8850 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8851 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8856 expand_df_binop (&gen_muldf3_i, operands);
8861 (define_insn "*muldf3_media"
8862 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8863 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8864 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8865 "TARGET_SHMEDIA_FPU"
8867 [(set_attr "type" "dfmul_media")])
8869 (define_insn "muldf3_i"
8870 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8871 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8872 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8873 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8876 [(set_attr "type" "dfp_arith")
8877 (set_attr "fp_mode" "double")])
8879 (define_expand "divdf3"
8880 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8881 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8882 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8883 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8888 expand_df_binop (&gen_divdf3_i, operands);
8893 (define_insn "*divdf3_media"
8894 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8895 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8896 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8897 "TARGET_SHMEDIA_FPU"
8899 [(set_attr "type" "dfdiv_media")])
8901 (define_insn "divdf3_i"
8902 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8903 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8904 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8905 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8908 [(set_attr "type" "dfdiv")
8909 (set_attr "fp_mode" "double")])
8911 (define_insn "floatdidf2"
8912 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8913 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8914 "TARGET_SHMEDIA_FPU"
8916 [(set_attr "type" "dfpconv_media")])
8918 (define_expand "floatsidf2"
8919 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8920 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8921 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8926 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8932 (define_insn "*floatsidf2_media"
8933 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8934 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8935 "TARGET_SHMEDIA_FPU"
8937 [(set_attr "type" "dfpconv_media")])
8939 (define_insn "floatsidf2_i"
8940 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8941 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8942 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8945 [(set_attr "type" "dfp_conv")
8946 (set_attr "fp_mode" "double")])
8948 (define_insn "fix_truncdfdi2"
8949 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8950 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8951 "TARGET_SHMEDIA_FPU"
8953 [(set_attr "type" "dfpconv_media")])
8955 (define_expand "fix_truncdfsi2"
8956 [(set (match_operand:SI 0 "fpul_operand" "")
8957 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8958 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8963 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8969 (define_insn "*fix_truncdfsi2_media"
8970 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8971 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8972 "TARGET_SHMEDIA_FPU"
8974 [(set_attr "type" "dfpconv_media")])
8976 (define_insn "fix_truncdfsi2_i"
8977 [(set (match_operand:SI 0 "fpul_operand" "=y")
8978 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8979 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8982 [(set_attr "type" "dfp_conv")
8983 (set_attr "dfp_comp" "no")
8984 (set_attr "fp_mode" "double")])
8986 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8987 ;; fix_truncdfsi2_i.
8988 ;; (define_insn "fix_truncdfsi2_i4"
8989 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8990 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8991 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8992 ;; (clobber (reg:SI FPUL_REG))]
8995 ;; [(set_attr "length" "4")
8996 ;; (set_attr "fp_mode" "double")])
8999 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9000 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9001 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9002 ;; (clobber (reg:SI FPUL_REG))]
9004 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9005 ;; (use (match_dup 2))])
9006 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9008 (define_insn "cmpgtdf_t"
9009 [(set (reg:SI T_REG)
9010 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9011 (match_operand:DF 1 "arith_reg_operand" "f")))
9012 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9015 [(set_attr "type" "dfp_cmp")
9016 (set_attr "fp_mode" "double")])
9018 (define_insn "cmpeqdf_t"
9019 [(set (reg:SI T_REG)
9020 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9021 (match_operand:DF 1 "arith_reg_operand" "f")))
9022 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9025 [(set_attr "type" "dfp_cmp")
9026 (set_attr "fp_mode" "double")])
9028 (define_insn "*ieee_ccmpeqdf_t"
9029 [(set (reg:SI T_REG)
9030 (ior:SI (reg:SI T_REG)
9031 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9032 (match_operand:DF 1 "arith_reg_operand" "f"))))
9033 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9034 "TARGET_IEEE && TARGET_SH4"
9035 "* return output_ieee_ccmpeq (insn, operands);"
9036 [(set_attr "length" "4")
9037 (set_attr "fp_mode" "double")])
9039 (define_insn "cmpeqdf_media"
9040 [(set (match_operand:DI 0 "register_operand" "=r")
9041 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9042 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9043 "TARGET_SHMEDIA_FPU"
9045 [(set_attr "type" "fcmp_media")])
9047 (define_insn "cmpgtdf_media"
9048 [(set (match_operand:DI 0 "register_operand" "=r")
9049 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9050 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9051 "TARGET_SHMEDIA_FPU"
9053 [(set_attr "type" "fcmp_media")])
9055 (define_insn "cmpgedf_media"
9056 [(set (match_operand:DI 0 "register_operand" "=r")
9057 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9058 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9059 "TARGET_SHMEDIA_FPU"
9061 [(set_attr "type" "fcmp_media")])
9063 (define_insn "cmpundf_media"
9064 [(set (match_operand:DI 0 "register_operand" "=r")
9065 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9066 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9067 "TARGET_SHMEDIA_FPU"
9069 [(set_attr "type" "fcmp_media")])
9071 (define_expand "cmpdf"
9072 [(set (reg:SI T_REG)
9073 (compare (match_operand:DF 0 "arith_operand" "")
9074 (match_operand:DF 1 "arith_operand" "")))]
9075 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9078 sh_compare_op0 = operands[0];
9079 sh_compare_op1 = operands[1];
9083 (define_expand "negdf2"
9084 [(set (match_operand:DF 0 "arith_reg_operand" "")
9085 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9086 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9091 expand_df_unop (&gen_negdf2_i, operands);
9096 (define_insn "*negdf2_media"
9097 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9098 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9099 "TARGET_SHMEDIA_FPU"
9101 [(set_attr "type" "fmove_media")])
9103 (define_insn "negdf2_i"
9104 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9105 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9106 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9109 [(set_attr "type" "fmove")
9110 (set_attr "fp_mode" "double")])
9112 (define_expand "sqrtdf2"
9113 [(set (match_operand:DF 0 "arith_reg_operand" "")
9114 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9115 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9120 expand_df_unop (&gen_sqrtdf2_i, operands);
9125 (define_insn "*sqrtdf2_media"
9126 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9127 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9128 "TARGET_SHMEDIA_FPU"
9130 [(set_attr "type" "dfdiv_media")])
9132 (define_insn "sqrtdf2_i"
9133 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9134 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9135 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9138 [(set_attr "type" "dfdiv")
9139 (set_attr "fp_mode" "double")])
9141 (define_expand "absdf2"
9142 [(set (match_operand:DF 0 "arith_reg_operand" "")
9143 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9144 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9149 expand_df_unop (&gen_absdf2_i, operands);
9154 (define_insn "*absdf2_media"
9155 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9156 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9157 "TARGET_SHMEDIA_FPU"
9159 [(set_attr "type" "fmove_media")])
9161 (define_insn "absdf2_i"
9162 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9163 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9164 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9167 [(set_attr "type" "fmove")
9168 (set_attr "fp_mode" "double")])
9170 (define_expand "extendsfdf2"
9171 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9172 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9173 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9178 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9184 (define_insn "*extendsfdf2_media"
9185 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9186 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9187 "TARGET_SHMEDIA_FPU"
9189 [(set_attr "type" "dfpconv_media")])
9191 (define_insn "extendsfdf2_i4"
9192 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9193 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9194 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9197 [(set_attr "type" "fp")
9198 (set_attr "fp_mode" "double")])
9200 (define_expand "truncdfsf2"
9201 [(set (match_operand:SF 0 "fpul_operand" "")
9202 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9203 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9208 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9214 (define_insn "*truncdfsf2_media"
9215 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9216 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9217 "TARGET_SHMEDIA_FPU"
9219 [(set_attr "type" "dfpconv_media")])
9221 (define_insn "truncdfsf2_i4"
9222 [(set (match_operand:SF 0 "fpul_operand" "=y")
9223 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9224 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9227 [(set_attr "type" "fp")
9228 (set_attr "fp_mode" "double")])
9230 ;; Bit field extract patterns. These give better code for packed bitfields,
9231 ;; because they allow auto-increment addresses to be generated.
9233 (define_expand "insv"
9234 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9235 (match_operand:SI 1 "immediate_operand" "")
9236 (match_operand:SI 2 "immediate_operand" ""))
9237 (match_operand:SI 3 "general_operand" ""))]
9238 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9241 rtx addr_target, orig_address, shift_reg, qi_val;
9242 HOST_WIDE_INT bitsize, size, v = 0;
9243 rtx x = operands[3];
9245 /* ??? expmed doesn't care for non-register predicates. */
9246 if (! memory_operand (operands[0], VOIDmode)
9247 || ! immediate_operand (operands[1], VOIDmode)
9248 || ! immediate_operand (operands[2], VOIDmode)
9249 || ! general_operand (x, VOIDmode))
9251 /* If this isn't a 16 / 24 / 32 bit field, or if
9252 it doesn't start on a byte boundary, then fail. */
9253 bitsize = INTVAL (operands[1]);
9254 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9255 || (INTVAL (operands[2]) % 8) != 0)
9259 orig_address = XEXP (operands[0], 0);
9260 shift_reg = gen_reg_rtx (SImode);
9261 if (GET_CODE (x) == CONST_INT)
9264 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9268 emit_insn (gen_movsi (shift_reg, operands[3]));
9269 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9271 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9273 operands[0] = replace_equiv_address (operands[0], addr_target);
9274 emit_insn (gen_movqi (operands[0], qi_val));
9278 if (GET_CODE (x) == CONST_INT)
9280 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9283 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9284 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9286 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9287 emit_insn (gen_movqi (operands[0], qi_val));
9293 ;; -------------------------------------------------------------------------
9295 ;; -------------------------------------------------------------------------
9297 ;; This matches cases where a stack pointer increment at the start of the
9298 ;; epilogue combines with a stack slot read loading the return value.
9301 [(set (match_operand:SI 0 "arith_reg_operand" "")
9302 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9303 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9304 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9307 ;; See the comment on the dt combiner pattern above.
9310 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9311 (plus:SI (match_dup 0)
9314 (eq:SI (match_dup 0)
9319 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9320 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9321 ;; reload when the constant is too large for a reg+offset address.
9323 ;; ??? We would get much better code if this was done in reload. This would
9324 ;; require modifying find_reloads_address to recognize that if the constant
9325 ;; is out-of-range for an immediate add, then we get better code by reloading
9326 ;; the constant into a register than by reloading the sum into a register,
9327 ;; since the former is one instruction shorter if the address does not need
9328 ;; to be offsettable. Unfortunately this does not work, because there is
9329 ;; only one register, r0, that can be used as an index register. This register
9330 ;; is also the function return value register. So, if we try to force reload
9331 ;; to use double-reg addresses, then we end up with some instructions that
9332 ;; need to use r0 twice. The only way to fix this is to change the calling
9333 ;; convention so that r0 is not used to return values.
9336 [(set (match_operand:SI 0 "register_operand" "=r")
9337 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9338 (set (mem:SI (match_dup 0))
9339 (match_operand:SI 2 "general_movsrc_operand" ""))]
9340 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9341 "mov.l %2,@(%0,%1)")
9344 [(set (match_operand:SI 0 "register_operand" "=r")
9345 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9346 (set (match_operand:SI 2 "general_movdst_operand" "")
9347 (mem:SI (match_dup 0)))]
9348 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9349 "mov.l @(%0,%1),%2")
9352 [(set (match_operand:SI 0 "register_operand" "=r")
9353 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9354 (set (mem:HI (match_dup 0))
9355 (match_operand:HI 2 "general_movsrc_operand" ""))]
9356 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9357 "mov.w %2,@(%0,%1)")
9360 [(set (match_operand:SI 0 "register_operand" "=r")
9361 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9362 (set (match_operand:HI 2 "general_movdst_operand" "")
9363 (mem:HI (match_dup 0)))]
9364 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9365 "mov.w @(%0,%1),%2")
9368 [(set (match_operand:SI 0 "register_operand" "=r")
9369 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9370 (set (mem:QI (match_dup 0))
9371 (match_operand:QI 2 "general_movsrc_operand" ""))]
9372 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9373 "mov.b %2,@(%0,%1)")
9376 [(set (match_operand:SI 0 "register_operand" "=r")
9377 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9378 (set (match_operand:QI 2 "general_movdst_operand" "")
9379 (mem:QI (match_dup 0)))]
9380 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9381 "mov.b @(%0,%1),%2")
9384 [(set (match_operand:SI 0 "register_operand" "=r")
9385 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9386 (set (mem:SF (match_dup 0))
9387 (match_operand:SF 2 "general_movsrc_operand" ""))]
9388 "TARGET_SH1 && REGNO (operands[0]) == 0
9389 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9390 || (GET_CODE (operands[2]) == SUBREG
9391 && REGNO (SUBREG_REG (operands[2])) < 16))
9392 && reg_unused_after (operands[0], insn)"
9393 "mov.l %2,@(%0,%1)")
9396 [(set (match_operand:SI 0 "register_operand" "=r")
9397 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9398 (set (match_operand:SF 2 "general_movdst_operand" "")
9400 (mem:SF (match_dup 0)))]
9401 "TARGET_SH1 && REGNO (operands[0]) == 0
9402 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9403 || (GET_CODE (operands[2]) == SUBREG
9404 && REGNO (SUBREG_REG (operands[2])) < 16))
9405 && reg_unused_after (operands[0], insn)"
9406 "mov.l @(%0,%1),%2")
9409 [(set (match_operand:SI 0 "register_operand" "=r")
9410 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9411 (set (mem:SF (match_dup 0))
9412 (match_operand:SF 2 "general_movsrc_operand" ""))]
9413 "TARGET_SH2E && REGNO (operands[0]) == 0
9414 && ((GET_CODE (operands[2]) == REG
9415 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9416 || (GET_CODE (operands[2]) == SUBREG
9417 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9418 && reg_unused_after (operands[0], insn)"
9419 "fmov{.s|} %2,@(%0,%1)")
9422 [(set (match_operand:SI 0 "register_operand" "=r")
9423 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9424 (set (match_operand:SF 2 "general_movdst_operand" "")
9426 (mem:SF (match_dup 0)))]
9427 "TARGET_SH2E && REGNO (operands[0]) == 0
9428 && ((GET_CODE (operands[2]) == REG
9429 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9430 || (GET_CODE (operands[2]) == SUBREG
9431 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9432 && reg_unused_after (operands[0], insn)"
9433 "fmov{.s|} @(%0,%1),%2")
9435 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9436 (define_insn "sp_switch_1"
9443 xoperands[0] = sp_switch;
9444 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9445 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9446 return \"mov r0,r15\";
9448 [(set_attr "length" "10")])
9450 ;; Switch back to the original stack for interrupt functions with the
9451 ;; sp_switch attribute. */
9452 (define_insn "sp_switch_2"
9455 "mov.l @r15+,r15\;mov.l @r15+,r0"
9456 [(set_attr "length" "4")])
9458 ;; Integer vector moves
9460 (define_expand "movv8qi"
9461 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9462 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9464 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9466 (define_insn "movv8qi_i"
9467 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9468 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9470 && (register_operand (operands[0], V8QImode)
9471 || sh_register_operand (operands[1], V8QImode))"
9478 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9479 (set_attr "length" "4,4,16,4,4")])
9482 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9483 (subreg:V8QI (const_int 0) 0))]
9486 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9487 (const_int 0) (const_int 0) (const_int 0)
9488 (const_int 0) (const_int 0)]))])
9491 [(set (match_operand 0 "arith_reg_dest" "")
9492 (match_operand 1 "sh_rep_vec" ""))]
9493 "TARGET_SHMEDIA && reload_completed
9494 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9495 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9496 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9497 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9498 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9499 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9500 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9501 [(set (match_dup 0) (match_dup 1))
9505 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9506 rtx elt1 = XVECEXP (operands[1], 0, 1);
9509 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9513 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9514 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9516 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9517 operands[1] = XVECEXP (operands[1], 0, 0);
9520 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9522 = GEN_INT (TARGET_LITTLE_ENDIAN
9523 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9524 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9527 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9529 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9535 [(set (match_operand 0 "arith_reg_dest" "")
9536 (match_operand 1 "sh_const_vec" ""))]
9537 "TARGET_SHMEDIA && reload_completed
9538 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9539 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9540 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9541 [(set (match_dup 0) (match_dup 1))]
9544 rtx v = operands[1];
9545 enum machine_mode new_mode
9546 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9548 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9550 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9553 (define_expand "movv2hi"
9554 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9555 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9557 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9559 (define_insn "movv2hi_i"
9560 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9561 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9563 && (register_operand (operands[0], V2HImode)
9564 || sh_register_operand (operands[1], V2HImode))"
9571 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9572 (set_attr "length" "4,4,16,4,4")])
9574 (define_expand "movv4hi"
9575 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9576 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9578 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9580 (define_insn "movv4hi_i"
9581 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9582 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9584 && (register_operand (operands[0], V4HImode)
9585 || sh_register_operand (operands[1], V4HImode))"
9592 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9593 (set_attr "length" "4,4,16,4,4")])
9595 (define_expand "movv2si"
9596 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9597 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9599 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9601 (define_insn "movv2si_i"
9602 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9603 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9605 && (register_operand (operands[0], V2SImode)
9606 || sh_register_operand (operands[1], V2SImode))"
9613 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9614 (set_attr "length" "4,4,16,4,4")])
9616 ;; Multimedia Intrinsics
9618 (define_insn "absv2si2"
9619 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9620 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9623 [(set_attr "type" "mcmp_media")])
9625 (define_insn "absv4hi2"
9626 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9627 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9630 [(set_attr "type" "mcmp_media")])
9632 (define_insn "addv2si3"
9633 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9634 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9635 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9638 [(set_attr "type" "arith_media")])
9640 (define_insn "addv4hi3"
9641 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9642 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9643 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9646 [(set_attr "type" "arith_media")])
9648 (define_insn "ssaddv2si3"
9649 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9650 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9651 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9653 "madds.l %1, %2, %0"
9654 [(set_attr "type" "mcmp_media")])
9656 (define_insn "usaddv8qi3"
9657 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9658 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9659 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9661 "madds.ub %1, %2, %0"
9662 [(set_attr "type" "mcmp_media")])
9664 (define_insn "ssaddv4hi3"
9665 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9666 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9667 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9669 "madds.w %1, %2, %0"
9670 [(set_attr "type" "mcmp_media")])
9672 (define_insn "negcmpeqv8qi"
9673 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9674 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9675 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9677 "mcmpeq.b %N1, %N2, %0"
9678 [(set_attr "type" "mcmp_media")])
9680 (define_insn "negcmpeqv2si"
9681 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9682 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9683 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9685 "mcmpeq.l %N1, %N2, %0"
9686 [(set_attr "type" "mcmp_media")])
9688 (define_insn "negcmpeqv4hi"
9689 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9690 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9691 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9693 "mcmpeq.w %N1, %N2, %0"
9694 [(set_attr "type" "mcmp_media")])
9696 (define_insn "negcmpgtuv8qi"
9697 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9698 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9699 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9701 "mcmpgt.ub %N1, %N2, %0"
9702 [(set_attr "type" "mcmp_media")])
9704 (define_insn "negcmpgtv2si"
9705 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9706 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9707 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9709 "mcmpgt.l %N1, %N2, %0"
9710 [(set_attr "type" "mcmp_media")])
9712 (define_insn "negcmpgtv4hi"
9713 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9714 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9715 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9717 "mcmpgt.w %N1, %N2, %0"
9718 [(set_attr "type" "mcmp_media")])
9721 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9722 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9723 (match_operand:DI 2 "arith_reg_operand" "r"))
9724 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9725 (not:DI (match_dup 2)))))]
9728 [(set_attr "type" "arith_media")])
9730 (define_insn "mcnvs_lw"
9731 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9733 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9734 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9736 "mcnvs.lw %N1, %N2, %0"
9737 [(set_attr "type" "mcmp_media")])
9739 (define_insn "mcnvs_wb"
9740 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9742 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9743 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9745 "mcnvs.wb %N1, %N2, %0"
9746 [(set_attr "type" "mcmp_media")])
9748 (define_insn "mcnvs_wub"
9749 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9751 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9752 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9754 "mcnvs.wub %N1, %N2, %0"
9755 [(set_attr "type" "mcmp_media")])
9757 (define_insn "mextr_rl"
9758 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9759 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9760 (match_operand:HI 3 "mextr_bit_offset" "i"))
9761 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9762 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9763 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9766 static char templ[16];
9768 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9769 (int) INTVAL (operands[3]) >> 3);
9772 [(set_attr "type" "arith_media")])
9774 (define_insn "*mextr_lr"
9775 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9776 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9777 (match_operand:HI 3 "mextr_bit_offset" "i"))
9778 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9779 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9780 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9783 static char templ[16];
9785 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9786 (int) INTVAL (operands[4]) >> 3);
9789 [(set_attr "type" "arith_media")])
9791 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9792 ; vector then varies depending on endianness.
9793 (define_expand "mextr1"
9794 [(match_operand:DI 0 "arith_reg_dest" "")
9795 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9796 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9800 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9801 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9805 (define_expand "mextr2"
9806 [(match_operand:DI 0 "arith_reg_dest" "")
9807 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9808 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9812 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9813 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9817 (define_expand "mextr3"
9818 [(match_operand:DI 0 "arith_reg_dest" "")
9819 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9820 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9824 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9825 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9829 (define_expand "mextr4"
9830 [(match_operand:DI 0 "arith_reg_dest" "")
9831 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9832 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9836 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9837 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9841 (define_expand "mextr5"
9842 [(match_operand:DI 0 "arith_reg_dest" "")
9843 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9844 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9848 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9849 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9853 (define_expand "mextr6"
9854 [(match_operand:DI 0 "arith_reg_dest" "")
9855 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9856 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9860 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9861 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9865 (define_expand "mextr7"
9866 [(match_operand:DI 0 "arith_reg_dest" "")
9867 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9868 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9872 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9873 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9877 (define_expand "mmacfx_wl"
9878 [(match_operand:V2SI 0 "arith_reg_dest" "")
9879 (match_operand:V2HI 1 "extend_reg_operand" "")
9880 (match_operand:V2HI 2 "extend_reg_operand" "")
9881 (match_operand:V2SI 3 "arith_reg_operand" "")]
9885 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9886 operands[1], operands[2]));
9890 (define_insn "mmacfx_wl_i"
9891 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9893 (match_operand:V2SI 1 "arith_reg_operand" "0")
9898 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9899 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9902 "mmacfx.wl %2, %3, %0"
9903 [(set_attr "type" "mac_media")])
9905 (define_expand "mmacnfx_wl"
9906 [(match_operand:V2SI 0 "arith_reg_dest" "")
9907 (match_operand:V2HI 1 "extend_reg_operand" "")
9908 (match_operand:V2HI 2 "extend_reg_operand" "")
9909 (match_operand:V2SI 3 "arith_reg_operand" "")]
9913 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9914 operands[1], operands[2]));
9918 (define_insn "mmacnfx_wl_i"
9919 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9921 (match_operand:V2SI 1 "arith_reg_operand" "0")
9926 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9927 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9930 "mmacnfx.wl %2, %3, %0"
9931 [(set_attr "type" "mac_media")])
9933 (define_insn "mulv2si3"
9934 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9935 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9936 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9939 [(set_attr "type" "d2mpy_media")])
9941 (define_insn "mulv4hi3"
9942 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9943 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9944 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9947 [(set_attr "type" "dmpy_media")])
9949 (define_insn "mmulfx_l"
9950 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9954 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9955 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9958 "mmulfx.l %1, %2, %0"
9959 [(set_attr "type" "d2mpy_media")])
9961 (define_insn "mmulfx_w"
9962 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9966 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9967 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9970 "mmulfx.w %1, %2, %0"
9971 [(set_attr "type" "dmpy_media")])
9973 (define_insn "mmulfxrp_w"
9974 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9979 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9980 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9984 "mmulfxrp.w %1, %2, %0"
9985 [(set_attr "type" "dmpy_media")])
9987 (define_expand "mmulhi_wl"
9988 [(match_operand:V2SI 0 "arith_reg_dest" "")
9989 (match_operand:V4HI 1 "arith_reg_operand" "")
9990 (match_operand:V4HI 2 "arith_reg_operand" "")]
9994 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9995 (operands[0], operands[1], operands[2]));
9999 (define_expand "mmullo_wl"
10000 [(match_operand:V2SI 0 "arith_reg_dest" "")
10001 (match_operand:V4HI 1 "arith_reg_operand" "")
10002 (match_operand:V4HI 2 "arith_reg_operand" "")]
10006 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10007 (operands[0], operands[1], operands[2]));
10011 (define_insn "mmul23_wl"
10012 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10015 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10016 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10017 (parallel [(const_int 2) (const_int 3)])))]
10019 "* return (TARGET_LITTLE_ENDIAN
10020 ? \"mmulhi.wl %1, %2, %0\"
10021 : \"mmullo.wl %1, %2, %0\");"
10022 [(set_attr "type" "dmpy_media")])
10024 (define_insn "mmul01_wl"
10025 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10028 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10029 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10030 (parallel [(const_int 0) (const_int 1)])))]
10032 "* return (TARGET_LITTLE_ENDIAN
10033 ? \"mmullo.wl %1, %2, %0\"
10034 : \"mmulhi.wl %1, %2, %0\");"
10035 [(set_attr "type" "dmpy_media")])
10037 (define_expand "mmulsum_wq"
10038 [(match_operand:DI 0 "arith_reg_dest" "")
10039 (match_operand:V4HI 1 "arith_reg_operand" "")
10040 (match_operand:V4HI 2 "arith_reg_operand" "")
10041 (match_operand:DI 3 "arith_reg_operand" "")]
10045 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10046 operands[1], operands[2]));
10050 (define_insn "mmulsum_wq_i"
10051 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10052 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10057 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10058 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10059 (parallel [(const_int 0)]))
10060 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10061 (sign_extend:V4DI (match_dup 3)))
10062 (parallel [(const_int 1)])))
10064 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10065 (sign_extend:V4DI (match_dup 3)))
10066 (parallel [(const_int 2)]))
10067 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10068 (sign_extend:V4DI (match_dup 3)))
10069 (parallel [(const_int 3)]))))))]
10071 "mmulsum.wq %2, %3, %0"
10072 [(set_attr "type" "mac_media")])
10074 (define_expand "mperm_w"
10075 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10076 (match_operand:V4HI 1 "arith_reg_operand" "r")
10077 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10081 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10082 (operands[0], operands[1], operands[2]));
10086 ; This use of vec_select isn't exactly correct according to rtl.texi
10087 ; (because not constant), but it seems a straightforward extension.
10088 (define_insn "mperm_w_little"
10089 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10091 (match_operand:V4HI 1 "arith_reg_operand" "r")
10093 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10094 (const_int 2) (const_int 0))
10095 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10096 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10097 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10098 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10099 "mperm.w %1, %N2, %0"
10100 [(set_attr "type" "arith_media")])
10102 (define_insn "mperm_w_big"
10103 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10105 (match_operand:V4HI 1 "arith_reg_operand" "r")
10107 [(zero_extract:QI (not:QI (match_operand:QI 2
10108 "extend_reg_or_0_operand" "rZ"))
10109 (const_int 2) (const_int 0))
10110 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10111 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10112 (zero_extract:QI (not:QI (match_dup 2))
10113 (const_int 2) (const_int 6))])))]
10114 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10115 "mperm.w %1, %N2, %0"
10116 [(set_attr "type" "arith_media")])
10118 (define_insn "mperm_w0"
10119 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10120 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10121 "trunc_hi_operand" "r"))))]
10123 "mperm.w %1, r63, %0"
10124 [(set_attr "type" "arith_media")])
10126 (define_expand "msad_ubq"
10127 [(match_operand:DI 0 "arith_reg_dest" "")
10128 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10129 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10130 (match_operand:DI 3 "arith_reg_operand" "")]
10134 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10135 operands[1], operands[2]));
10139 (define_insn "msad_ubq_i"
10140 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145 (match_operand:DI 1 "arith_reg_operand" "0")
10146 (abs:DI (vec_select:DI
10149 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10151 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10152 (parallel [(const_int 0)]))))
10153 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10154 (zero_extend:V8DI (match_dup 3)))
10155 (parallel [(const_int 1)]))))
10157 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10158 (zero_extend:V8DI (match_dup 3)))
10159 (parallel [(const_int 2)])))
10160 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10161 (zero_extend:V8DI (match_dup 3)))
10162 (parallel [(const_int 3)])))))
10165 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10166 (zero_extend:V8DI (match_dup 3)))
10167 (parallel [(const_int 4)])))
10168 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10169 (zero_extend:V8DI (match_dup 3)))
10170 (parallel [(const_int 5)]))))
10172 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10173 (zero_extend:V8DI (match_dup 3)))
10174 (parallel [(const_int 6)])))
10175 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10176 (zero_extend:V8DI (match_dup 3)))
10177 (parallel [(const_int 7)])))))))]
10179 "msad.ubq %N2, %N3, %0"
10180 [(set_attr "type" "mac_media")])
10182 (define_insn "mshalds_l"
10183 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10186 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10187 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10188 (const_int 31)))))]
10190 "mshalds.l %1, %2, %0"
10191 [(set_attr "type" "mcmp_media")])
10193 (define_insn "mshalds_w"
10194 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10197 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10198 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10199 (const_int 15)))))]
10201 "mshalds.w %1, %2, %0"
10202 [(set_attr "type" "mcmp_media")])
10204 (define_insn "ashrv2si3"
10205 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10206 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10207 (match_operand:DI 2 "arith_reg_operand" "r")))]
10209 "mshard.l %1, %2, %0"
10210 [(set_attr "type" "arith_media")])
10212 (define_insn "ashrv4hi3"
10213 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10214 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10215 (match_operand:DI 2 "arith_reg_operand" "r")))]
10217 "mshard.w %1, %2, %0"
10218 [(set_attr "type" "arith_media")])
10220 (define_insn "mshards_q"
10221 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10223 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10224 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10226 "mshards.q %1, %N2, %0"
10227 [(set_attr "type" "mcmp_media")])
10229 (define_expand "mshfhi_b"
10230 [(match_operand:V8QI 0 "arith_reg_dest" "")
10231 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10232 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10236 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10237 (operands[0], operands[1], operands[2]));
10241 (define_expand "mshflo_b"
10242 [(match_operand:V8QI 0 "arith_reg_dest" "")
10243 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10244 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10248 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10249 (operands[0], operands[1], operands[2]));
10253 (define_insn "mshf4_b"
10255 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10257 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10258 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10259 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10260 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10262 "* return (TARGET_LITTLE_ENDIAN
10263 ? \"mshfhi.b %N1, %N2, %0\"
10264 : \"mshflo.b %N1, %N2, %0\");"
10265 [(set_attr "type" "arith_media")])
10267 (define_insn "mshf0_b"
10269 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10271 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10272 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10273 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10274 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10276 "* return (TARGET_LITTLE_ENDIAN
10277 ? \"mshflo.b %N1, %N2, %0\"
10278 : \"mshfhi.b %N1, %N2, %0\");"
10279 [(set_attr "type" "arith_media")])
10281 (define_expand "mshfhi_l"
10282 [(match_operand:V2SI 0 "arith_reg_dest" "")
10283 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10284 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10288 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10289 (operands[0], operands[1], operands[2]));
10293 (define_expand "mshflo_l"
10294 [(match_operand:V2SI 0 "arith_reg_dest" "")
10295 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10296 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10300 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10301 (operands[0], operands[1], operands[2]));
10305 (define_insn "mshf4_l"
10306 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10308 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10309 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10310 (parallel [(const_int 1) (const_int 3)])))]
10312 "* return (TARGET_LITTLE_ENDIAN
10313 ? \"mshfhi.l %N1, %N2, %0\"
10314 : \"mshflo.l %N1, %N2, %0\");"
10315 [(set_attr "type" "arith_media")])
10317 (define_insn "mshf0_l"
10318 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10320 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10321 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10322 (parallel [(const_int 0) (const_int 2)])))]
10324 "* return (TARGET_LITTLE_ENDIAN
10325 ? \"mshflo.l %N1, %N2, %0\"
10326 : \"mshfhi.l %N1, %N2, %0\");"
10327 [(set_attr "type" "arith_media")])
10329 (define_expand "mshfhi_w"
10330 [(match_operand:V4HI 0 "arith_reg_dest" "")
10331 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10332 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10336 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10337 (operands[0], operands[1], operands[2]));
10341 (define_expand "mshflo_w"
10342 [(match_operand:V4HI 0 "arith_reg_dest" "")
10343 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10344 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10348 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10349 (operands[0], operands[1], operands[2]));
10353 (define_insn "mshf4_w"
10354 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10356 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10357 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10358 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10360 "* return (TARGET_LITTLE_ENDIAN
10361 ? \"mshfhi.w %N1, %N2, %0\"
10362 : \"mshflo.w %N1, %N2, %0\");"
10363 [(set_attr "type" "arith_media")])
10365 (define_insn "mshf0_w"
10366 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10368 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10369 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10370 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10372 "* return (TARGET_LITTLE_ENDIAN
10373 ? \"mshflo.w %N1, %N2, %0\"
10374 : \"mshfhi.w %N1, %N2, %0\");"
10375 [(set_attr "type" "arith_media")])
10377 (define_insn "mshflo_w_x"
10378 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10380 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10381 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10382 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10384 "mshflo.w %N1, %N2, %0"
10385 [(set_attr "type" "arith_media")])
10387 /* These are useful to expand ANDs and as combiner patterns. */
10388 (define_insn_and_split "mshfhi_l_di"
10389 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10390 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10392 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10393 (const_int -4294967296))))]
10396 mshfhi.l %N1, %N2, %0
10398 "TARGET_SHMEDIA && reload_completed
10399 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10400 [(set (match_dup 3) (match_dup 4))
10401 (set (match_dup 5) (match_dup 6))]
10404 operands[3] = gen_lowpart (SImode, operands[0]);
10405 operands[4] = gen_highpart (SImode, operands[1]);
10406 operands[5] = gen_highpart (SImode, operands[0]);
10407 operands[6] = gen_highpart (SImode, operands[2]);
10409 [(set_attr "type" "arith_media")])
10411 (define_insn "*mshfhi_l_di_rev"
10412 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10413 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10414 (const_int -4294967296))
10415 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10418 "mshfhi.l %N2, %N1, %0"
10419 [(set_attr "type" "arith_media")])
10422 [(set (match_operand:DI 0 "arith_reg_dest" "")
10423 (ior:DI (zero_extend:DI (match_operand:SI 1
10424 "extend_reg_or_0_operand" ""))
10425 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10426 (const_int -4294967296))))
10427 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10432 emit_insn (gen_ashldi3_media (operands[3],
10433 simplify_gen_subreg (DImode, operands[1],
10436 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10440 (define_insn "mshflo_l_di"
10441 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10442 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10443 (const_int 4294967295))
10444 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10448 "mshflo.l %N1, %N2, %0"
10449 [(set_attr "type" "arith_media")])
10451 (define_insn "*mshflo_l_di_rev"
10452 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10453 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10455 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10456 (const_int 4294967295))))]
10459 "mshflo.l %N2, %N1, %0"
10460 [(set_attr "type" "arith_media")])
10462 ;; Combiner pattern for trampoline initialization.
10463 (define_insn_and_split "*double_shori"
10464 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10465 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10467 (match_operand:DI 2 "const_int_operand" "n")))]
10469 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10471 "rtx_equal_p (operands[0], operands[1])"
10475 HOST_WIDE_INT v = INTVAL (operands[2]);
10477 emit_insn (gen_shori_media (operands[0], operands[0],
10478 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10479 emit_insn (gen_shori_media (operands[0], operands[0],
10480 gen_int_mode (v, HImode)));
10485 (define_insn "*mshflo_l_di_x"
10486 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10487 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10489 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10493 "mshflo.l %N1, %N2, %0"
10494 [(set_attr "type" "arith_media")])
10496 (define_insn_and_split "concat_v2sf"
10497 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10498 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10499 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10500 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10504 mshflo.l %N1, %N2, %0
10507 "TARGET_SHMEDIA && reload_completed
10508 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10509 [(set (match_dup 3) (match_dup 1))
10510 (set (match_dup 4) (match_dup 2))]
10513 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10514 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10516 [(set_attr "type" "arith_media")])
10518 (define_insn "*mshflo_l_di_x_rev"
10519 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10520 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10522 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10525 "mshflo.l %N2, %N1, %0"
10526 [(set_attr "type" "arith_media")])
10528 (define_insn "ashlv2si3"
10529 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10530 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10531 (match_operand:DI 2 "arith_reg_operand" "r")))]
10533 "mshlld.l %1, %2, %0"
10534 [(set_attr "type" "arith_media")])
10536 (define_insn "ashlv4hi3"
10537 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10538 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10539 (match_operand:DI 2 "arith_reg_operand" "r")))]
10541 "mshlld.w %1, %2, %0"
10542 [(set_attr "type" "arith_media")])
10544 (define_insn "lshrv2si3"
10545 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10546 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10547 (match_operand:DI 2 "arith_reg_operand" "r")))]
10549 "mshlrd.l %1, %2, %0"
10550 [(set_attr "type" "arith_media")])
10552 (define_insn "lshrv4hi3"
10553 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10554 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10555 (match_operand:DI 2 "arith_reg_operand" "r")))]
10557 "mshlrd.w %1, %2, %0"
10558 [(set_attr "type" "arith_media")])
10560 (define_insn "subv2si3"
10561 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10562 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10563 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10565 "msub.l %N1, %2, %0"
10566 [(set_attr "type" "arith_media")])
10568 (define_insn "subv4hi3"
10569 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10570 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10571 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10573 "msub.w %N1, %2, %0"
10574 [(set_attr "type" "arith_media")])
10576 (define_insn "sssubv2si3"
10577 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10578 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10579 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10581 "msubs.l %N1, %2, %0"
10582 [(set_attr "type" "mcmp_media")])
10584 (define_insn "ussubv8qi3"
10585 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10586 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10587 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10589 "msubs.ub %1, %2, %0"
10590 [(set_attr "type" "mcmp_media")])
10592 (define_insn "sssubv4hi3"
10593 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10594 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10595 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10597 "msubs.w %N1, %2, %0"
10598 [(set_attr "type" "mcmp_media")])
10600 ;; Floating Point Intrinsics
10602 (define_insn "fcosa_s"
10603 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10604 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10608 [(set_attr "type" "atrans_media")])
10610 (define_insn "fsina_s"
10611 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10612 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10616 [(set_attr "type" "atrans_media")])
10618 (define_insn "fipr"
10619 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10620 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10621 "fp_arith_reg_operand" "f")
10622 (match_operand:V4SF 2
10623 "fp_arith_reg_operand" "f"))
10624 (parallel [(const_int 0)]))
10625 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10626 (parallel [(const_int 1)])))
10627 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10628 (parallel [(const_int 2)]))
10629 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10630 (parallel [(const_int 3)])))))]
10632 "fipr.s %1, %2, %0"
10633 [(set_attr "type" "fparith_media")])
10635 (define_insn "fsrra_s"
10636 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10637 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10641 [(set_attr "type" "atrans_media")])
10643 (define_insn "ftrv"
10644 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10648 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10649 (parallel [(const_int 0) (const_int 5)
10650 (const_int 10) (const_int 15)]))
10651 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10653 (vec_select:V4SF (match_dup 1)
10654 (parallel [(const_int 4) (const_int 9)
10655 (const_int 14) (const_int 3)]))
10656 (vec_select:V4SF (match_dup 2)
10657 (parallel [(const_int 1) (const_int 2)
10658 (const_int 3) (const_int 0)]))))
10661 (vec_select:V4SF (match_dup 1)
10662 (parallel [(const_int 8) (const_int 13)
10663 (const_int 2) (const_int 7)]))
10664 (vec_select:V4SF (match_dup 2)
10665 (parallel [(const_int 2) (const_int 3)
10666 (const_int 0) (const_int 1)])))
10668 (vec_select:V4SF (match_dup 1)
10669 (parallel [(const_int 12) (const_int 1)
10670 (const_int 6) (const_int 11)]))
10671 (vec_select:V4SF (match_dup 2)
10672 (parallel [(const_int 3) (const_int 0)
10673 (const_int 1) (const_int 2)]))))))]
10675 "ftrv.s %1, %2, %0"
10676 [(set_attr "type" "fparith_media")])
10679 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10680 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10684 [(set_attr "type" "arith_media")])
10686 (define_insn "nsbsi"
10687 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10689 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10693 [(set_attr "type" "arith_media")])
10695 (define_insn "nsbdi"
10696 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10698 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10702 [(set_attr "type" "arith_media")])
10704 (define_expand "ffsdi2"
10705 [(set (match_operand:DI 0 "arith_reg_dest" "")
10706 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10710 rtx scratch = gen_reg_rtx (DImode);
10713 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10714 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10715 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10716 emit_insn (gen_nsbdi (scratch, scratch));
10717 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10718 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10719 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10721 = gen_rtx_EXPR_LIST (REG_EQUAL,
10722 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10726 (define_expand "ffssi2"
10727 [(set (match_operand:SI 0 "arith_reg_dest" "")
10728 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10732 rtx scratch = gen_reg_rtx (SImode);
10733 rtx discratch = gen_reg_rtx (DImode);
10736 emit_insn (gen_adddi3 (discratch,
10737 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10739 emit_insn (gen_andcdi3 (discratch,
10740 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10742 emit_insn (gen_nsbsi (scratch, discratch));
10743 last = emit_insn (gen_subsi3 (operands[0],
10744 force_reg (SImode, GEN_INT (63)), scratch));
10746 = gen_rtx_EXPR_LIST (REG_EQUAL,
10747 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10751 (define_insn "byterev"
10752 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10753 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10754 (parallel [(const_int 7) (const_int 6) (const_int 5)
10755 (const_int 4) (const_int 3) (const_int 2)
10756 (const_int 1) (const_int 0)])))]
10759 [(set_attr "type" "arith_media")])
10761 (define_insn "prefetch"
10762 [(prefetch (match_operand:QI 0 "address_operand" "p")
10763 (match_operand:SI 1 "const_int_operand" "n")
10764 (match_operand:SI 2 "const_int_operand" "n"))]
10768 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10769 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10772 [(set_attr "type" "other")])
10774 ;; The following description models the
10775 ;; SH4 pipeline using the DFA based scheduler.
10776 ;; The DFA based description is better way to model
10777 ;; a superscalar pipeline as compared to function unit
10778 ;; reservation model.
10779 ;; 1. The function unit based model is oriented to describe at most one
10780 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10781 ;; pipeline units by same insn. This can be done using DFA based description.
10782 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10783 ;; 3. Writing all unit reservations for an instruction class is more natural description
10784 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10785 ;; old function unit based model.
10786 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10789 ;; Two automata are defined to reduce number of states
10790 ;; which a single large automaton will have.(Factoring)
10792 (define_automaton "inst_pipeline,fpu_pipe")
10794 ;; This unit is basically the decode unit of the processor.
10795 ;; Since SH4 is a dual issue machine,it is as if there are two
10796 ;; units so that any insn can be processed by either one
10797 ;; of the decoding unit.
10799 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10802 ;; The fixed point arithmetic calculator(?? EX Unit).
10804 (define_cpu_unit "int" "inst_pipeline")
10806 ;; f1_1 and f1_2 are floating point units.Actually there is
10807 ;; a f1 unit which can overlap with other f1 unit but
10808 ;; not another F1 unit.It is as though there were two
10811 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10813 ;; The floating point units (except FS - F2 always precedes it.)
10815 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10817 ;; This is basically the MA unit of SH4
10818 ;; used in LOAD/STORE pipeline.
10820 (define_cpu_unit "memory" "inst_pipeline")
10822 ;; However, there are LS group insns that don't use it, even ones that
10823 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10824 (define_cpu_unit "load_store" "inst_pipeline")
10826 ;; The address calculator used for branch instructions.
10827 ;; This will be reserved after "issue" of branch instructions
10828 ;; and this is to make sure that no two branch instructions
10829 ;; can be issued in parallel.
10831 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10833 ;; ----------------------------------------------------
10834 ;; This reservation is to simplify the dual issue description.
10836 (define_reservation "issue" "pipe_01|pipe_02")
10838 ;; This is to express the locking of D stage.
10839 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10841 (define_reservation "d_lock" "pipe_01+pipe_02")
10843 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10844 (define_reservation "F01" "F0+F1")
10846 ;; This is to simplify description where F1,F2,FS
10847 ;; are used simultaneously.
10849 (define_reservation "fpu" "F1+F2")
10851 ;; This is to highlight the fact that f1
10852 ;; cannot overlap with F1.
10854 (exclusion_set "f1_1,f1_2" "F1")
10856 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10858 ;; Although reg moves have a latency of zero
10859 ;; we need to highlight that they use D stage
10864 (define_insn_reservation "reg_mov" 0
10865 (and (eq_attr "pipe_model" "sh4")
10866 (eq_attr "type" "move"))
10871 (define_insn_reservation "freg_mov" 0
10872 (and (eq_attr "pipe_model" "sh4")
10873 (eq_attr "type" "fmove"))
10874 "issue+load_store")
10876 ;; We don't model all pipeline stages; we model the issue ('D') stage
10877 ;; inasmuch as we allow only two instructions to issue simultaneously,
10878 ;; and CO instructions prevent any simultaneous issue of another instruction.
10879 ;; (This uses pipe_01 and pipe_02).
10880 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10881 ;; Double issue of EX / BR insns is prevented by using the int unit /
10882 ;; pcr_addrcalc unit in the EX stage.
10883 ;; Double issue of BR / LS instructions is prevented by using the
10884 ;; pcr_addrcalc / load_store unit in the issue cycle.
10885 ;; Double issue of FE instructions is prevented by using F0 in the first
10886 ;; pipeline stage after the first D stage.
10887 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10888 ;; (except in the cases outlined above), nor to describe the FS stage after
10891 ;; Other MT group instructions(1 step operations)
10896 (define_insn_reservation "mt" 1
10897 (and (eq_attr "pipe_model" "sh4")
10898 (eq_attr "type" "mt_group"))
10901 ;; Fixed Point Arithmetic Instructions(1 step operations)
10906 (define_insn_reservation "sh4_simple_arith" 1
10907 (and (eq_attr "pipe_model" "sh4")
10908 (eq_attr "insn_class" "ex_group"))
10911 ;; Load and store instructions have no alignment peculiarities for the SH4,
10912 ;; but they use the load-store unit, which they share with the fmove type
10913 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10914 ;; Loads have a latency of two.
10915 ;; However, call insns can only paired with a preceding insn, and have
10916 ;; a delay slot, so that we want two more insns to be scheduled between the
10917 ;; load of the function address and the call. This is equivalent to a
10918 ;; latency of three.
10919 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10920 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10921 ;; We only do this for SImode loads of general registers, to make the work
10922 ;; for ADJUST_COST easier.
10924 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10929 (define_insn_reservation "sh4_load" 2
10930 (and (eq_attr "pipe_model" "sh4")
10931 (eq_attr "type" "load,pcload"))
10932 "issue+load_store,nothing,memory")
10934 ;; calls / sfuncs need an extra instruction for their delay slot.
10935 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10936 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10937 ;; count of a dynamic shift.
10938 (define_insn_reservation "sh4_load_si" 3
10939 (and (eq_attr "pipe_model" "sh4")
10940 (eq_attr "type" "load_si,pcload_si"))
10941 "issue+load_store,nothing,memory")
10943 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10945 ;; The load latency is upped to three higher if the dependent insn does
10946 ;; double precision computation. We want the 'default' latency to reflect
10947 ;; that increased latency because otherwise the insn priorities won't
10948 ;; allow proper scheduling.
10949 (define_insn_reservation "sh4_fload" 3
10950 (and (eq_attr "pipe_model" "sh4")
10951 (eq_attr "type" "fload,pcfload"))
10952 "issue+load_store,nothing,memory")
10954 ;; (define_bypass 2 "sh4_fload" "!")
10956 (define_insn_reservation "sh4_store" 1
10957 (and (eq_attr "pipe_model" "sh4")
10958 (eq_attr "type" "store"))
10959 "issue+load_store,nothing,memory")
10961 ;; Load Store instructions.
10966 (define_insn_reservation "sh4_gp_fpul" 1
10967 (and (eq_attr "pipe_model" "sh4")
10968 (eq_attr "type" "gp_fpul"))
10969 "issue+load_store")
10971 ;; Load Store instructions.
10976 (define_insn_reservation "sh4_fpul_gp" 3
10977 (and (eq_attr "pipe_model" "sh4")
10978 (eq_attr "type" "fpul_gp"))
10979 "issue+load_store")
10981 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10983 ;; Latency when taken: 2 (or 1)
10985 ;; The latency is 1 when displacement is 0.
10986 ;; We can't really do much with the latency, even if we could express it,
10987 ;; but the pairing restrictions are useful to take into account.
10988 ;; ??? If the branch is likely, we might want to fill the delay slot;
10989 ;; if the branch is likely, but not very likely, should we pretend to use
10990 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10992 (define_insn_reservation "sh4_branch" 1
10993 (and (eq_attr "pipe_model" "sh4")
10994 (eq_attr "type" "cbranch,jump"))
10995 "issue+pcr_addrcalc")
10997 ;; Branch Far (JMP,RTS,BRAF)
11001 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
11002 ;; can't be distinguished from bra for the "jump" pattern.
11004 (define_insn_reservation "sh4_return" 3
11005 (and (eq_attr "pipe_model" "sh4")
11006 (eq_attr "type" "return,jump_ind"))
11013 ;; this instruction can be executed in any of the pipelines
11014 ;; and blocks the pipeline for next 4 stages.
11016 (define_insn_reservation "sh4_return_from_exp" 5
11017 (and (eq_attr "pipe_model" "sh4")
11018 (eq_attr "type" "rte"))
11026 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
11027 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
11028 (define_insn_reservation "ocbwb" 6
11029 (and (eq_attr "pipe_model" "sh4")
11030 (eq_attr "type" "cwb"))
11031 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
11037 ;; The SX stage is blocked for last 2 cycles.
11038 ;; OTOH, the only time that has an effect for insns generated by the compiler
11039 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
11040 ;; or when we are doing a function call - and we don't do inter-function
11041 ;; scheduling. For the function call case, it's really best that we end with
11042 ;; something that models an rts.
11044 (define_insn_reservation "sh4_lds_to_pr" 3
11045 (and (eq_attr "pipe_model" "sh4")
11046 (eq_attr "type" "prset") )
11049 ;; calls introduce a longisch delay that is likely to flush the pipelines
11050 ;; of the caller's instructions. Ordinary functions tend to end with a
11051 ;; load to restore a register (in the delay slot of rts), while sfuncs
11052 ;; tend to end with an EX or MT insn. But that is not actually relevant,
11053 ;; since there are no instructions that contend for memory access early.
11054 ;; We could, of course, provide exact scheduling information for specific
11055 ;; sfuncs, if that should prove useful.
11057 (define_insn_reservation "sh4_call" 16
11058 (and (eq_attr "pipe_model" "sh4")
11059 (eq_attr "type" "call,sfunc"))
11066 ;; The SX unit is blocked for last 2 cycles.
11068 (define_insn_reservation "ldsmem_to_pr" 3
11069 (and (eq_attr "pipe_model" "sh4")
11070 (eq_attr "type" "pload"))
11077 ;; The SX unit in second and third cycles.
11079 (define_insn_reservation "sts_from_pr" 2
11080 (and (eq_attr "pipe_model" "sh4")
11081 (eq_attr "type" "prget"))
11089 (define_insn_reservation "sh4_prstore_mem" 2
11090 (and (eq_attr "pipe_model" "sh4")
11091 (eq_attr "type" "pstore"))
11092 "d_lock*2,nothing,memory")
11098 ;; F1 is blocked for last three cycles.
11100 (define_insn_reservation "fpscr_load" 4
11101 (and (eq_attr "pipe_model" "sh4")
11102 (eq_attr "type" "gp_fpscr"))
11103 "d_lock,nothing,F1*3")
11108 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11110 ;; F1 is blocked for last three cycles.
11112 (define_insn_reservation "fpscr_load_mem" 4
11113 (and (eq_attr "pipe_model" "sh4")
11114 (eq_attr "type" "mem_fpscr"))
11115 "d_lock,nothing,(F1+memory),F1*2")
11118 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11123 (define_insn_reservation "multi" 4
11124 (and (eq_attr "pipe_model" "sh4")
11125 (eq_attr "type" "smpy,dmpy"))
11126 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11128 ;; Fixed STS from MACL / MACH
11133 (define_insn_reservation "sh4_mac_gp" 3
11134 (and (eq_attr "pipe_model" "sh4")
11135 (eq_attr "type" "mac_gp"))
11139 ;; Single precision floating point computation FCMP/EQ,
11140 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11145 (define_insn_reservation "fp_arith" 3
11146 (and (eq_attr "pipe_model" "sh4")
11147 (eq_attr "type" "fp"))
11150 (define_insn_reservation "fp_arith_ftrc" 3
11151 (and (eq_attr "pipe_model" "sh4")
11152 (eq_attr "type" "ftrc_s"))
11155 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11157 ;; Single Precision FDIV/SQRT
11159 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
11161 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11163 (define_insn_reservation "fp_div" 12
11164 (and (eq_attr "pipe_model" "sh4")
11165 (eq_attr "type" "fdiv"))
11166 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11168 ;; Double Precision floating point computation
11169 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11171 ;; Latency: (3,4)/5
11174 (define_insn_reservation "dp_float" 4
11175 (and (eq_attr "pipe_model" "sh4")
11176 (eq_attr "type" "dfp_conv"))
11177 "issue,F01,F1+F2,F2")
11179 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11181 ;; Latency: (7,8)/9
11184 (define_insn_reservation "fp_double_arith" 8
11185 (and (eq_attr "pipe_model" "sh4")
11186 (eq_attr "type" "dfp_arith"))
11187 "issue,F01,F1+F2,fpu*4,F2")
11189 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11194 (define_insn_reservation "fp_double_cmp" 3
11195 (and (eq_attr "pipe_model" "sh4")
11196 (eq_attr "type" "dfp_cmp"))
11197 "d_lock,(d_lock+F01),F1+F2,F2")
11199 ;; Double precision FDIV/SQRT
11201 ;; Latency: (24,25)/26
11204 (define_insn_reservation "dp_div" 25
11205 (and (eq_attr "pipe_model" "sh4")
11206 (eq_attr "type" "dfdiv"))
11207 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11210 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11211 ;; case, we'd get a d_lock instead of issue at the end.
11212 (define_insn_reservation "arith3" 3
11213 (and (eq_attr "pipe_model" "sh4")
11214 (eq_attr "type" "arith3"))
11215 "issue,d_lock+pcr_addrcalc,issue")
11217 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11218 (define_insn_reservation "arith3b" 2
11219 (and (eq_attr "pipe_model" "sh4")
11220 (eq_attr "type" "arith3"))
11221 "issue,d_lock+pcr_addrcalc")