1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
138 (UNSPEC_EH_RETURN 19)
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 ; If a conditional branch destination is within -252..258 bytes away
284 ; from the instruction it can be 2 bytes long. Something in the
285 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
286 ; branches are initially assumed to be 16 bytes long.
287 ; In machine_dependent_reorg, we split all branches that are longer than
290 ;; The maximum range used for SImode constant pool entries is 1018. A final
291 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
292 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
293 ;; instruction around the pool table, 2 bytes of alignment before the table,
294 ;; and 30 bytes of alignment after the table. That gives a maximum total
295 ;; pool size of 1058 bytes.
296 ;; Worst case code/pool content size ratio is 1:2 (using asms).
297 ;; Thus, in the worst case, there is one instruction in front of a maximum
298 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
299 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
300 ;; If we have a forward branch, the initial table will be put after the
301 ;; unconditional branch.
303 ;; ??? We could do much better by keeping track of the actual pcloads within
304 ;; the branch range and in the pcload range in front of the branch range.
306 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
308 (define_attr "short_cbranch_p" "no,yes"
309 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
311 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
313 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
315 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
317 ] (const_string "no")))
319 (define_attr "med_branch_p" "no,yes"
320 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
323 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
325 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
328 ] (const_string "no")))
330 (define_attr "med_cbranch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
339 ] (const_string "no")))
341 (define_attr "braf_branch_p" "no,yes"
342 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
347 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
352 ] (const_string "no")))
354 (define_attr "braf_cbranch_p" "no,yes"
355 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
360 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
365 ] (const_string "no")))
367 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
368 ; For wider ranges, we need a combination of a code and a data part.
369 ; If we can get a scratch register for a long range jump, the code
370 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
371 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
372 ; long; otherwise, it must be 6 bytes long.
374 ; All other instructions are two bytes long by default.
376 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
377 ;; but getattrtab doesn't understand this.
378 (define_attr "length" ""
379 (cond [(eq_attr "type" "cbranch")
380 (cond [(eq_attr "short_cbranch_p" "yes")
382 (eq_attr "med_cbranch_p" "yes")
384 (eq_attr "braf_cbranch_p" "yes")
386 ;; ??? using pc is not computed transitively.
387 (ne (match_dup 0) (match_dup 0))
389 (ne (symbol_ref ("flag_pic")) (const_int 0))
392 (eq_attr "type" "jump")
393 (cond [(eq_attr "med_branch_p" "yes")
395 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
397 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
398 (symbol_ref "code_for_indirect_jump_scratch")))
399 (if_then_else (eq_attr "braf_branch_p" "yes")
402 (eq_attr "braf_branch_p" "yes")
404 ;; ??? using pc is not computed transitively.
405 (ne (match_dup 0) (match_dup 0))
407 (ne (symbol_ref ("flag_pic")) (const_int 0))
410 (eq_attr "type" "pt_media")
411 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
412 (const_int 20) (const_int 12))
413 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
417 ;; (define_function_unit {name} {num-units} {n-users} {test}
418 ;; {ready-delay} {issue-delay} [{conflict-list}])
420 ;; Load and store instructions save a cycle if they are aligned on a
421 ;; four byte boundary. Using a function unit for stores encourages
422 ;; gcc to separate load and store instructions by one instruction,
423 ;; which makes it more likely that the linker will be able to word
424 ;; align them when relaxing.
426 ;; Loads have a latency of two.
427 ;; However, call insns can have a delay slot, so that we want one more
428 ;; insn to be scheduled between the load of the function address and the call.
429 ;; This is equivalent to a latency of three.
430 ;; We cannot use a conflict list for this, because we need to distinguish
431 ;; between the actual call address and the function arguments.
432 ;; ADJUST_COST can only properly handle reductions of the cost, so we
433 ;; use a latency of three here.
434 ;; We only do this for SImode loads of general registers, to make the work
435 ;; for ADJUST_COST easier.
436 (define_function_unit "memory" 1 0
437 (and (eq_attr "pipe_model" "sh1")
438 (eq_attr "type" "load_si,pcload_si"))
440 (define_function_unit "memory" 1 0
441 (and (eq_attr "pipe_model" "sh1")
442 (eq_attr "type" "load,pcload,pload,store,pstore"))
445 (define_function_unit "int" 1 0
446 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
448 (define_function_unit "int" 1 0
449 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
451 (define_function_unit "int" 1 0
452 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
454 ;; ??? These are approximations.
455 (define_function_unit "mpy" 1 0
456 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
457 (define_function_unit "mpy" 1 0
458 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
460 (define_function_unit "fp" 1 0
461 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
462 (define_function_unit "fp" 1 0
463 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
466 ;; SH-5 SHmedia scheduling
467 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
468 ;; single-issue machine. It has four pipelines, the branch unit (br),
469 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
470 ;; the floating point unit (fpu).
471 ;; Here model the instructions with a latency greater than one cycle.
473 ;; Every instruction on SH-5 occupies the issue resource for at least one
475 (define_function_unit "sh5issue" 1 0
476 (and (eq_attr "pipe_model" "sh5media")
477 (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)
479 ;; Specify the various types of instruction which have latency > 1
480 (define_function_unit "sh5issue" 1 0
481 (and (eq_attr "pipe_model" "sh5media")
482 (eq_attr "type" "mcmp_media")) 2 1)
484 (define_function_unit "sh5issue" 1 0
485 (and (eq_attr "pipe_model" "sh5media")
486 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
487 ;; but see sh_adjust_cost for mac_media exception.
489 (define_function_unit "sh5issue" 1 0
490 (and (eq_attr "pipe_model" "sh5media")
491 (eq_attr "type" "fload_media,fmove_media")) 4 1)
493 (define_function_unit "sh5issue" 1 0
494 (and (eq_attr "pipe_model" "sh5media")
495 (eq_attr "type" "d2mpy_media")) 4 2)
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
505 (define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "invalidate_line_media")) 7 7)
509 (define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
512 (define_function_unit "sh5issue" 1 0
513 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
515 ;; Floating-point divide and square-root occupy an additional resource,
516 ;; which is not internally pipelined. However, other instructions
517 ;; can continue to issue.
518 (define_function_unit "sh5fds" 1 0
519 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
521 (define_function_unit "sh5fds" 1 0
522 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
524 ; Definitions for filling branch delay slots.
526 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
528 ;; ??? This should be (nil) instead of (const_int 0)
529 (define_attr "hit_stack" "yes,no"
530 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
533 (const_string "yes")))
535 (define_attr "interrupt_function" "no,yes"
536 (const (symbol_ref "current_function_interrupt")))
538 (define_attr "in_delay_slot" "yes,no"
539 (cond [(eq_attr "type" "cbranch") (const_string "no")
540 (eq_attr "type" "pcload,pcload_si") (const_string "no")
541 (eq_attr "needs_delay_slot" "yes") (const_string "no")
542 (eq_attr "length" "2") (const_string "yes")
543 ] (const_string "no")))
545 (define_attr "cond_delay_slot" "yes,no"
546 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
547 ] (const_string "no")))
549 (define_attr "is_sfunc" ""
550 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
552 (define_attr "is_mac_media" ""
553 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
555 (define_attr "branch_zero" "yes,no"
556 (cond [(eq_attr "type" "!cbranch") (const_string "no")
557 (ne (symbol_ref "(next_active_insn (insn)\
558 == (prev_active_insn\
559 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
560 && get_attr_length (next_active_insn (insn)) == 2")
562 (const_string "yes")]
563 (const_string "no")))
565 ;; SH4 Double-precision computation with double-precision result -
566 ;; the two halves are ready at different times.
567 (define_attr "dfp_comp" "yes,no"
568 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
569 (const_string "no")))
571 ;; Insns for which the latency of a preceding fp insn is decreased by one.
572 (define_attr "late_fp_use" "yes,no" (const_string "no"))
573 ;; And feeding insns for which this relevant.
574 (define_attr "any_fp_comp" "yes,no"
575 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
576 (const_string "yes")]
577 (const_string "no")))
579 (define_attr "any_int_load" "yes,no"
580 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
581 (const_string "yes")]
582 (const_string "no")))
585 (eq_attr "needs_delay_slot" "yes")
586 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
588 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
589 ;; and thus we can't put a pop instruction in its delay slot.
590 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
591 ;; instruction can go in the delay slot.
593 ;; Since a normal return (rts) implicitly uses the PR register,
594 ;; we can't allow PR register loads in an rts delay slot.
597 (eq_attr "type" "return")
598 [(and (eq_attr "in_delay_slot" "yes")
599 (ior (and (eq_attr "interrupt_function" "no")
600 (eq_attr "type" "!pload,prset"))
601 (and (eq_attr "interrupt_function" "yes")
603 (ne (symbol_ref "TARGET_SH3") (const_int 0))
604 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
606 ;; Since a call implicitly uses the PR register, we can't allow
607 ;; a PR register store in a jsr delay slot.
610 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
611 [(and (eq_attr "in_delay_slot" "yes")
612 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
614 ;; Say that we have annulled true branches, since this gives smaller and
615 ;; faster code when branches are predicted as not taken.
618 (and (eq_attr "type" "cbranch")
619 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
620 ;; SH2e has a hardware bug that pretty much prohibits the use of
621 ;; annuled delay slots.
622 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
623 (not (eq_attr "cpu" "sh2e"))) (nil)])
625 ;; -------------------------------------------------------------------------
626 ;; SImode signed integer comparisons
627 ;; -------------------------------------------------------------------------
631 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
632 (match_operand:SI 1 "arith_operand" "K08,r"))
636 [(set_attr "type" "mt_group")])
638 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
639 ;; That would still allow reload to create cmpi instructions, but would
640 ;; perhaps allow forcing the constant into a register when that is better.
641 ;; Probably should use r0 for mem/imm compares, but force constant into a
642 ;; register for pseudo/imm compares.
644 (define_insn "cmpeqsi_t"
646 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
647 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
653 [(set_attr "type" "mt_group")])
655 (define_insn "cmpgtsi_t"
657 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
658 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
663 [(set_attr "type" "mt_group")])
665 (define_insn "cmpgesi_t"
667 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
668 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
673 [(set_attr "type" "mt_group")])
675 ;; -------------------------------------------------------------------------
676 ;; SImode unsigned integer comparisons
677 ;; -------------------------------------------------------------------------
679 (define_insn "cmpgeusi_t"
681 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
682 (match_operand:SI 1 "arith_reg_operand" "r")))]
685 [(set_attr "type" "mt_group")])
687 (define_insn "cmpgtusi_t"
689 (gtu: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 ;; We save the compare operands in the cmpxx patterns and use them when
696 ;; we generate the branch.
698 (define_expand "cmpsi"
700 (compare (match_operand:SI 0 "arith_operand" "")
701 (match_operand:SI 1 "arith_operand" "")))]
705 sh_compare_op0 = operands[0];
706 sh_compare_op1 = operands[1];
710 ;; -------------------------------------------------------------------------
711 ;; DImode signed integer comparisons
712 ;; -------------------------------------------------------------------------
714 ;; ??? Could get better scheduling by splitting the initial test from the
715 ;; rest of the insn after reload. However, the gain would hardly justify
716 ;; the sh.md size increase necessary to do that.
720 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
721 (match_operand:DI 1 "arith_operand" "r"))
724 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
726 [(set_attr "length" "6")
727 (set_attr "type" "arith3b")])
729 (define_insn "cmpeqdi_t"
731 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
732 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
735 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
736 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
737 [(set_attr "length" "6")
738 (set_attr "type" "arith3b")])
742 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
743 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
744 ;; If we applied this split when not optimizing, it would only be
745 ;; applied during the machine-dependent reorg, when no new basic blocks
747 "TARGET_SH1 && reload_completed && optimize"
748 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
749 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
750 (label_ref (match_dup 6))
752 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
757 = gen_rtx_REG (SImode,
758 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
760 = (operands[1] == const0_rtx
762 : gen_rtx_REG (SImode,
763 true_regnum (operands[1])
764 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
765 operands[4] = gen_lowpart (SImode, operands[0]);
766 operands[5] = gen_lowpart (SImode, operands[1]);
767 operands[6] = gen_label_rtx ();
770 (define_insn "cmpgtdi_t"
772 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
776 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
777 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
778 [(set_attr "length" "8")
779 (set_attr "type" "arith3")])
781 (define_insn "cmpgedi_t"
783 (ge: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/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
789 [(set_attr "length" "8,2")
790 (set_attr "type" "arith3,mt_group")])
792 ;; -------------------------------------------------------------------------
793 ;; DImode unsigned integer comparisons
794 ;; -------------------------------------------------------------------------
796 (define_insn "cmpgeudi_t"
798 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
799 (match_operand:DI 1 "arith_reg_operand" "r")))]
801 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
802 [(set_attr "length" "8")
803 (set_attr "type" "arith3")])
805 (define_insn "cmpgtudi_t"
807 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
808 (match_operand:DI 1 "arith_reg_operand" "r")))]
810 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
811 [(set_attr "length" "8")
812 (set_attr "type" "arith3")])
814 (define_insn "cmpeqdi_media"
815 [(set (match_operand:DI 0 "register_operand" "=r")
816 (eq:DI (match_operand:DI 1 "register_operand" "%r")
817 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
820 [(set_attr "type" "cmp_media")])
822 (define_insn "cmpgtdi_media"
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
825 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
828 [(set_attr "type" "cmp_media")])
830 (define_insn "cmpgtudi_media"
831 [(set (match_operand:DI 0 "register_operand" "=r")
832 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
835 "cmpgtu %N1, %N2, %0"
836 [(set_attr "type" "cmp_media")])
838 ;; We save the compare operands in the cmpxx patterns and use them when
839 ;; we generate the branch.
841 (define_expand "cmpdi"
843 (compare (match_operand:DI 0 "arith_operand" "")
844 (match_operand:DI 1 "arith_operand" "")))]
845 "TARGET_SH2 || TARGET_SHMEDIA"
848 sh_compare_op0 = operands[0];
849 sh_compare_op1 = operands[1];
852 ;; -------------------------------------------------------------------------
853 ;; Conditional move instructions
854 ;; -------------------------------------------------------------------------
856 ;; The insn names may seem reversed, but note that cmveq performs the move
857 ;; if op1 == 0, and cmvne does it if op1 != 0.
859 (define_insn "movdicc_false"
860 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
861 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
863 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
864 (match_operand:DI 3 "arith_reg_operand" "0")))]
867 [(set_attr "type" "arith_media")])
869 (define_insn "movdicc_true"
870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
871 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
873 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
874 (match_operand:DI 3 "arith_reg_operand" "0")))]
877 [(set_attr "type" "arith_media")])
879 (define_expand "movdicc"
880 [(set (match_operand:DI 0 "register_operand" "")
881 (if_then_else:DI (match_operand 1 "comparison_operator" "")
882 (match_operand:DI 2 "register_operand" "")
883 (match_operand:DI 3 "register_operand" "")))]
887 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
888 && GET_MODE (sh_compare_op0) == DImode
889 && sh_compare_op1 == const0_rtx)
890 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
891 sh_compare_op0, sh_compare_op1);
899 tmp = gen_reg_rtx (DImode);
901 switch (GET_CODE (operands[1]))
904 emit_insn (gen_seq (tmp));
905 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
909 emit_insn (gen_seq (tmp));
910 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
914 emit_insn (gen_sgt (tmp));
915 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
919 emit_insn (gen_slt (tmp));
920 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924 emit_insn (gen_slt (tmp));
925 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
929 emit_insn (gen_sgt (tmp));
930 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934 emit_insn (gen_sgtu (tmp));
935 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
939 emit_insn (gen_sltu (tmp));
940 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944 emit_insn (gen_sltu (tmp));
945 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
949 emit_insn (gen_sgtu (tmp));
950 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
954 emit_insn (gen_sunordered (tmp));
955 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
959 emit_insn (gen_sunordered (tmp));
960 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
977 ;; -------------------------------------------------------------------------
978 ;; Addition instructions
979 ;; -------------------------------------------------------------------------
981 (define_expand "adddi3"
982 [(set (match_operand:DI 0 "arith_reg_operand" "")
983 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
984 (match_operand:DI 2 "arith_operand" "")))]
990 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
992 operands[2] = force_reg (DImode, operands[2]);
993 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
998 (define_insn "*adddi3_media"
999 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1000 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1001 (match_operand:DI 2 "arith_operand" "r,I10")))]
1006 [(set_attr "type" "arith_media")])
1008 (define_insn "adddi3z_media"
1009 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1011 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1012 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1014 "addz.l %1, %N2, %0"
1015 [(set_attr "type" "arith_media")])
1017 (define_insn "adddi3_compact"
1018 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1019 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1020 (match_operand:DI 2 "arith_reg_operand" "r")))
1021 (clobber (reg:SI T_REG))]
1024 [(set_attr "length" "6")])
1027 [(set (match_operand:DI 0 "arith_reg_operand" "")
1028 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1029 (match_operand:DI 2 "arith_reg_operand" "")))
1030 (clobber (reg:SI T_REG))]
1031 "TARGET_SH1 && reload_completed"
1035 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1036 high0 = gen_rtx_REG (SImode,
1037 true_regnum (operands[0])
1038 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1039 high2 = gen_rtx_REG (SImode,
1040 true_regnum (operands[2])
1041 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1042 emit_insn (gen_clrt ());
1043 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1044 emit_insn (gen_addc1 (high0, high0, high2));
1049 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1051 (match_operand:SI 2 "arith_reg_operand" "r"))
1054 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1057 [(set_attr "type" "arith")])
1059 (define_insn "addc1"
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"))
1064 (clobber (reg:SI T_REG))]
1067 [(set_attr "type" "arith")])
1069 (define_expand "addsi3"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "")
1071 (plus:SI (match_operand:SI 1 "arith_operand" "")
1072 (match_operand:SI 2 "arith_operand" "")))]
1077 operands[1] = force_reg (SImode, operands[1]);
1080 (define_insn "addsi3_media"
1081 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1082 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1083 (match_operand:SI 2 "arith_operand" "r,I10")))]
1088 [(set_attr "type" "arith_media")])
1090 (define_insn "*addsi3_compact"
1091 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1092 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1093 (match_operand:SI 2 "arith_operand" "rI08")))]
1096 [(set_attr "type" "arith")])
1098 ;; -------------------------------------------------------------------------
1099 ;; Subtraction instructions
1100 ;; -------------------------------------------------------------------------
1102 (define_expand "subdi3"
1103 [(set (match_operand:DI 0 "arith_reg_operand" "")
1104 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1105 (match_operand:DI 2 "arith_reg_operand" "")))]
1111 operands[1] = force_reg (DImode, operands[1]);
1112 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1117 (define_insn "*subdi3_media"
1118 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1119 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1120 (match_operand:DI 2 "arith_reg_operand" "r")))]
1123 [(set_attr "type" "arith_media")])
1125 (define_insn "subdi3_compact"
1126 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1127 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1128 (match_operand:DI 2 "arith_reg_operand" "r")))
1129 (clobber (reg:SI T_REG))]
1132 [(set_attr "length" "6")])
1135 [(set (match_operand:DI 0 "arith_reg_operand" "")
1136 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1137 (match_operand:DI 2 "arith_reg_operand" "")))
1138 (clobber (reg:SI T_REG))]
1139 "TARGET_SH1 && reload_completed"
1143 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1144 high0 = gen_rtx_REG (SImode,
1145 true_regnum (operands[0])
1146 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1147 high2 = gen_rtx_REG (SImode,
1148 true_regnum (operands[2])
1149 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1150 emit_insn (gen_clrt ());
1151 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1152 emit_insn (gen_subc1 (high0, high0, high2));
1157 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1158 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1159 (match_operand:SI 2 "arith_reg_operand" "r"))
1162 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1165 [(set_attr "type" "arith")])
1167 (define_insn "subc1"
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"))
1172 (clobber (reg:SI T_REG))]
1175 [(set_attr "type" "arith")])
1177 (define_insn "*subsi3_internal"
1178 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1179 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1180 (match_operand:SI 2 "arith_reg_operand" "r")))]
1183 [(set_attr "type" "arith")])
1185 (define_insn "*subsi3_media"
1186 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1188 (match_operand:SI 2 "extend_reg_operand" "r")))]
1191 [(set_attr "type" "arith_media")])
1193 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1194 ;; will sometimes save one instruction. Otherwise we might get
1195 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1198 (define_expand "subsi3"
1199 [(set (match_operand:SI 0 "arith_reg_operand" "")
1200 (minus:SI (match_operand:SI 1 "arith_operand" "")
1201 (match_operand:SI 2 "arith_reg_operand" "")))]
1205 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1207 emit_insn (gen_negsi2 (operands[0], operands[2]));
1208 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1213 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1215 if (operands[1] != const0_rtx)
1216 operands[1] = force_reg (SImode, operands[1]);
1220 ;; -------------------------------------------------------------------------
1221 ;; Division instructions
1222 ;; -------------------------------------------------------------------------
1224 ;; We take advantage of the library routines which don't clobber as many
1225 ;; registers as a normal function call would.
1227 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1228 ;; also has an effect on the register that holds the address of the sfunc.
1229 ;; To make this work, we have an extra dummy insn that shows the use
1230 ;; of this register for reorg.
1232 (define_insn "use_sfunc_addr"
1233 [(set (reg:SI PR_REG)
1234 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1237 [(set_attr "length" "0")])
1239 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1240 ;; hard register 0. If we used hard register 0, then the next instruction
1241 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1242 ;; gets allocated to a stack slot that needs its address reloaded, then
1243 ;; there is nothing to prevent reload from using r0 to reload the address.
1244 ;; This reload would clobber the value in r0 we are trying to store.
1245 ;; If we let reload allocate r0, then this problem can never happen.
1247 (define_insn "udivsi3_i1"
1248 [(set (match_operand:SI 0 "register_operand" "=z")
1249 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1250 (clobber (reg:SI T_REG))
1251 (clobber (reg:SI PR_REG))
1252 (clobber (reg:SI R4_REG))
1253 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1254 "TARGET_SH1 && ! TARGET_SH4"
1256 [(set_attr "type" "sfunc")
1257 (set_attr "needs_delay_slot" "yes")])
1259 ; Since shmedia-nofpu code could be linked against shcompact code, and
1260 ; the udivsi3 libcall has the same name, we must consider all registers
1261 ; clobbered that are in the union of the registers clobbered by the
1262 ; shmedia and the shcompact implementation. Note, if the shcompact
1263 ; implementation actually used shcompact code, we'd need to clobber
1264 ; also r23 and fr23.
1265 (define_insn "udivsi3_i1_media"
1266 [(set (match_operand:SI 0 "register_operand" "=z")
1267 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1268 (clobber (reg:SI T_MEDIA_REG))
1269 (clobber (reg:SI PR_MEDIA_REG))
1270 (clobber (reg:SI R20_REG))
1271 (clobber (reg:SI R21_REG))
1272 (clobber (reg:SI R22_REG))
1273 (clobber (reg:DI TR0_REG))
1274 (clobber (reg:DI TR1_REG))
1275 (clobber (reg:DI TR2_REG))
1276 (use (match_operand:DI 1 "target_operand" "b"))]
1277 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1279 [(set_attr "type" "sfunc")
1280 (set_attr "needs_delay_slot" "yes")])
1282 (define_expand "udivsi3_i4_media"
1284 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1286 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1287 (set (match_dup 5) (float:DF (match_dup 3)))
1288 (set (match_dup 6) (float:DF (match_dup 4)))
1289 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1290 (set (match_dup 8) (fix:DI (match_dup 7)))
1291 (set (match_operand:SI 0 "register_operand" "")
1292 (truncate:SI (match_dup 8)))]
1293 "TARGET_SHMEDIA_FPU"
1296 operands[3] = gen_reg_rtx (DImode);
1297 operands[4] = gen_reg_rtx (DImode);
1298 operands[5] = gen_reg_rtx (DFmode);
1299 operands[6] = gen_reg_rtx (DFmode);
1300 operands[7] = gen_reg_rtx (DFmode);
1301 operands[8] = gen_reg_rtx (DImode);
1304 (define_insn "udivsi3_i4"
1305 [(set (match_operand:SI 0 "register_operand" "=y")
1306 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1307 (clobber (reg:SI T_REG))
1308 (clobber (reg:SI PR_REG))
1309 (clobber (reg:DF DR0_REG))
1310 (clobber (reg:DF DR2_REG))
1311 (clobber (reg:DF DR4_REG))
1312 (clobber (reg:SI R0_REG))
1313 (clobber (reg:SI R1_REG))
1314 (clobber (reg:SI R4_REG))
1315 (clobber (reg:SI R5_REG))
1316 (use (reg:PSI FPSCR_REG))
1317 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1318 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1320 [(set_attr "type" "sfunc")
1321 (set_attr "fp_mode" "double")
1322 (set_attr "needs_delay_slot" "yes")])
1324 (define_insn "udivsi3_i4_single"
1325 [(set (match_operand:SI 0 "register_operand" "=y")
1326 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1327 (clobber (reg:SI T_REG))
1328 (clobber (reg:SI PR_REG))
1329 (clobber (reg:DF DR0_REG))
1330 (clobber (reg:DF DR2_REG))
1331 (clobber (reg:DF DR4_REG))
1332 (clobber (reg:SI R0_REG))
1333 (clobber (reg:SI R1_REG))
1334 (clobber (reg:SI R4_REG))
1335 (clobber (reg:SI R5_REG))
1336 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1337 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1339 [(set_attr "type" "sfunc")
1340 (set_attr "needs_delay_slot" "yes")])
1342 (define_expand "udivsi3"
1343 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1344 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1345 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1346 (parallel [(set (match_operand:SI 0 "register_operand" "")
1347 (udiv:SI (reg:SI R4_REG)
1349 (clobber (reg:SI T_REG))
1350 (clobber (reg:SI PR_REG))
1351 (clobber (reg:SI R4_REG))
1352 (use (match_dup 3))])]
1358 operands[3] = gen_reg_rtx (Pmode);
1359 /* Emit the move of the address to a pseudo outside of the libcall. */
1360 if (TARGET_HARD_SH4 && TARGET_SH2E)
1362 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1363 if (TARGET_FPU_SINGLE)
1364 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1366 last = gen_udivsi3_i4 (operands[0], operands[3]);
1368 else if (TARGET_SHMEDIA_FPU)
1370 operands[1] = force_reg (SImode, operands[1]);
1371 operands[2] = force_reg (SImode, operands[2]);
1372 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1375 else if (TARGET_SH5)
1377 emit_move_insn (operands[3],
1378 function_symbol (TARGET_FPU_ANY
1383 last = gen_udivsi3_i1_media (operands[0],
1386 : gen_rtx_SUBREG (DImode, operands[3],
1388 else if (TARGET_FPU_ANY)
1389 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1391 last = gen_udivsi3_i1 (operands[0], operands[3]);
1395 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1396 last = gen_udivsi3_i1 (operands[0], operands[3]);
1398 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1399 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1400 last = emit_insn (last);
1401 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1402 invariant code motion can move it. */
1403 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1404 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1408 (define_insn "divsi3_i1"
1409 [(set (match_operand:SI 0 "register_operand" "=z")
1410 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1411 (clobber (reg:SI T_REG))
1412 (clobber (reg:SI PR_REG))
1413 (clobber (reg:SI R1_REG))
1414 (clobber (reg:SI R2_REG))
1415 (clobber (reg:SI R3_REG))
1416 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1417 "TARGET_SH1 && ! TARGET_SH4"
1419 [(set_attr "type" "sfunc")
1420 (set_attr "needs_delay_slot" "yes")])
1422 ; Since shmedia-nofpu code could be linked against shcompact code, and
1423 ; the sdivsi3 libcall has the same name, we must consider all registers
1424 ; clobbered that are in the union of the registers clobbered by the
1425 ; shmedia and the shcompact implementation. Note, if the shcompact
1426 ; implementation actually used shcompact code, we'd need to clobber
1427 ; also r22, r23 and fr23.
1428 (define_insn "divsi3_i1_media"
1429 [(set (match_operand:SI 0 "register_operand" "=z")
1430 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1431 (clobber (reg:SI T_MEDIA_REG))
1432 (clobber (reg:SI PR_MEDIA_REG))
1433 (clobber (reg:SI R1_REG))
1434 (clobber (reg:SI R2_REG))
1435 (clobber (reg:SI R3_REG))
1436 (clobber (reg:SI R20_REG))
1437 (clobber (reg:SI R21_REG))
1438 (clobber (reg:DI TR0_REG))
1439 (clobber (reg:DI TR1_REG))
1440 (clobber (reg:DI TR2_REG))
1441 (use (match_operand:DI 1 "target_operand" "b"))]
1442 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1444 [(set_attr "type" "sfunc")])
1446 (define_expand "divsi3_i4_media"
1447 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1448 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1449 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1450 (set (match_operand:SI 0 "register_operand" "=r")
1451 (fix:SI (match_dup 5)))]
1452 "TARGET_SHMEDIA_FPU"
1455 operands[3] = gen_reg_rtx (DFmode);
1456 operands[4] = gen_reg_rtx (DFmode);
1457 operands[5] = gen_reg_rtx (DFmode);
1460 (define_insn "divsi3_i4"
1461 [(set (match_operand:SI 0 "register_operand" "=y")
1462 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1463 (clobber (reg:SI PR_REG))
1464 (clobber (reg:DF DR0_REG))
1465 (clobber (reg:DF DR2_REG))
1466 (use (reg:PSI FPSCR_REG))
1467 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1468 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1470 [(set_attr "type" "sfunc")
1471 (set_attr "fp_mode" "double")
1472 (set_attr "needs_delay_slot" "yes")])
1474 (define_insn "divsi3_i4_single"
1475 [(set (match_operand:SI 0 "register_operand" "=y")
1476 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1477 (clobber (reg:SI PR_REG))
1478 (clobber (reg:DF DR0_REG))
1479 (clobber (reg:DF DR2_REG))
1480 (clobber (reg:SI R2_REG))
1481 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1482 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1484 [(set_attr "type" "sfunc")
1485 (set_attr "needs_delay_slot" "yes")])
1487 (define_expand "divsi3"
1488 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1489 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1490 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1491 (parallel [(set (match_operand:SI 0 "register_operand" "")
1492 (div:SI (reg:SI R4_REG)
1494 (clobber (reg:SI T_REG))
1495 (clobber (reg:SI PR_REG))
1496 (clobber (reg:SI R1_REG))
1497 (clobber (reg:SI R2_REG))
1498 (clobber (reg:SI R3_REG))
1499 (use (match_dup 3))])]
1505 operands[3] = gen_reg_rtx (Pmode);
1506 /* Emit the move of the address to a pseudo outside of the libcall. */
1507 if (TARGET_HARD_SH4 && TARGET_SH2E)
1509 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1510 if (TARGET_FPU_SINGLE)
1511 last = gen_divsi3_i4_single (operands[0], operands[3]);
1513 last = gen_divsi3_i4 (operands[0], operands[3]);
1515 else if (TARGET_SHMEDIA_FPU)
1517 operands[1] = force_reg (SImode, operands[1]);
1518 operands[2] = force_reg (SImode, operands[2]);
1519 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1522 else if (TARGET_SH5)
1524 emit_move_insn (operands[3],
1525 function_symbol (TARGET_FPU_ANY
1530 last = gen_divsi3_i1_media (operands[0],
1533 : gen_rtx_SUBREG (DImode, operands[3],
1535 else if (TARGET_FPU_ANY)
1536 last = gen_divsi3_i4_single (operands[0], operands[3]);
1538 last = gen_divsi3_i1 (operands[0], operands[3]);
1542 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1543 last = gen_divsi3_i1 (operands[0], operands[3]);
1545 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1546 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1547 last = emit_insn (last);
1548 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549 invariant code motion can move it. */
1550 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1555 ;; -------------------------------------------------------------------------
1556 ;; Multiplication instructions
1557 ;; -------------------------------------------------------------------------
1559 (define_insn "umulhisi3_i"
1560 [(set (reg:SI MACL_REG)
1561 (mult:SI (zero_extend:SI
1562 (match_operand:HI 0 "arith_reg_operand" "r"))
1564 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1567 [(set_attr "type" "smpy")])
1569 (define_insn "mulhisi3_i"
1570 [(set (reg:SI MACL_REG)
1571 (mult:SI (sign_extend:SI
1572 (match_operand:HI 0 "arith_reg_operand" "r"))
1574 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1577 [(set_attr "type" "smpy")])
1579 (define_expand "mulhisi3"
1580 [(set (reg:SI MACL_REG)
1581 (mult:SI (sign_extend:SI
1582 (match_operand:HI 1 "arith_reg_operand" ""))
1584 (match_operand:HI 2 "arith_reg_operand" ""))))
1585 (set (match_operand:SI 0 "arith_reg_operand" "")
1592 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1593 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1594 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1595 invariant code motion can move it. */
1596 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1597 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1598 /* expand_binop can't find a suitable code in umul_widen_optab to
1599 make a REG_EQUAL note from, so make one here.
1600 See also smulsi3_highpart.
1601 ??? Alternatively, we could put this at the calling site of expand_binop,
1602 i.e. expand_expr. */
1604 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1609 (define_expand "umulhisi3"
1610 [(set (reg:SI MACL_REG)
1611 (mult:SI (zero_extend:SI
1612 (match_operand:HI 1 "arith_reg_operand" ""))
1614 (match_operand:HI 2 "arith_reg_operand" ""))))
1615 (set (match_operand:SI 0 "arith_reg_operand" "")
1622 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1623 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1624 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1625 invariant code motion can move it. */
1626 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1627 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1628 /* expand_binop can't find a suitable code in umul_widen_optab to
1629 make a REG_EQUAL note from, so make one here.
1630 See also smulsi3_highpart.
1631 ??? Alternatively, we could put this at the calling site of expand_binop,
1632 i.e. expand_expr. */
1634 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1639 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1640 ;; a call to a routine which clobbers known registers.
1643 [(set (match_operand:SI 1 "register_operand" "=z")
1644 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1645 (clobber (reg:SI MACL_REG))
1646 (clobber (reg:SI T_REG))
1647 (clobber (reg:SI PR_REG))
1648 (clobber (reg:SI R3_REG))
1649 (clobber (reg:SI R2_REG))
1650 (clobber (reg:SI R1_REG))
1651 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1654 [(set_attr "type" "sfunc")
1655 (set_attr "needs_delay_slot" "yes")])
1657 (define_expand "mulsi3_call"
1658 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1659 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1660 (parallel[(set (match_operand:SI 0 "register_operand" "")
1661 (mult:SI (reg:SI R4_REG)
1663 (clobber (reg:SI MACL_REG))
1664 (clobber (reg:SI T_REG))
1665 (clobber (reg:SI PR_REG))
1666 (clobber (reg:SI R3_REG))
1667 (clobber (reg:SI R2_REG))
1668 (clobber (reg:SI R1_REG))
1669 (use (match_operand:SI 3 "register_operand" ""))])]
1673 (define_insn "mul_l"
1674 [(set (reg:SI MACL_REG)
1675 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1676 (match_operand:SI 1 "arith_reg_operand" "r")))]
1679 [(set_attr "type" "dmpy")])
1681 (define_expand "mulsi3"
1682 [(set (reg:SI MACL_REG)
1683 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1684 (match_operand:SI 2 "arith_reg_operand" "")))
1685 (set (match_operand:SI 0 "arith_reg_operand" "")
1694 /* The address must be set outside the libcall,
1695 since it goes into a pseudo. */
1696 rtx sym = function_symbol (\"__mulsi3\");
1697 rtx addr = force_reg (SImode, sym);
1698 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1701 last = emit_insn (insns);
1705 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1707 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1708 /* consec_sets_giv can only recognize the first insn that sets a
1709 giv as the giv insn. So we must tag this also with a REG_EQUAL
1711 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1713 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1714 invariant code motion can move it. */
1715 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1716 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1720 (define_insn "mulsidi3_i"
1721 [(set (reg:SI MACH_REG)
1725 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1726 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1728 (set (reg:SI MACL_REG)
1729 (mult:SI (match_dup 0)
1733 [(set_attr "type" "dmpy")])
1735 (define_expand "mulsidi3"
1736 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1737 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1738 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1739 "TARGET_SH2 || TARGET_SHMEDIA"
1744 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1750 (define_insn "mulsidi3_media"
1751 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1752 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1753 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1756 [(set_attr "type" "dmpy_media")])
1758 (define_insn "mulsidi3_compact"
1759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1761 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1762 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1763 (clobber (reg:SI MACH_REG))
1764 (clobber (reg:SI MACL_REG))]
1769 [(set (match_operand:DI 0 "arith_reg_operand" "")
1771 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1772 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1773 (clobber (reg:SI MACH_REG))
1774 (clobber (reg:SI MACL_REG))]
1779 rtx low_dst = gen_lowpart (SImode, operands[0]);
1780 rtx high_dst = gen_highpart (SImode, operands[0]);
1782 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1784 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1785 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1786 /* We need something to tag the possible REG_EQUAL notes on to. */
1787 emit_move_insn (operands[0], operands[0]);
1791 (define_insn "umulsidi3_i"
1792 [(set (reg:SI MACH_REG)
1796 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1797 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1799 (set (reg:SI MACL_REG)
1800 (mult:SI (match_dup 0)
1804 [(set_attr "type" "dmpy")])
1806 (define_expand "umulsidi3"
1807 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1808 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1809 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1810 "TARGET_SH2 || TARGET_SHMEDIA"
1815 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1821 (define_insn "umulsidi3_media"
1822 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1823 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1824 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1827 [(set_attr "type" "dmpy_media")])
1829 (define_insn "umulsidi3_compact"
1830 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1832 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1833 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1834 (clobber (reg:SI MACH_REG))
1835 (clobber (reg:SI MACL_REG))]
1840 [(set (match_operand:DI 0 "arith_reg_operand" "")
1841 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1842 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1843 (clobber (reg:SI MACH_REG))
1844 (clobber (reg:SI MACL_REG))]
1849 rtx low_dst = gen_lowpart (SImode, operands[0]);
1850 rtx high_dst = gen_highpart (SImode, operands[0]);
1852 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1854 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1855 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1856 /* We need something to tag the possible REG_EQUAL notes on to. */
1857 emit_move_insn (operands[0], operands[0]);
1861 (define_insn "smulsi3_highpart_i"
1862 [(set (reg:SI MACH_REG)
1866 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1867 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1869 (clobber (reg:SI MACL_REG))]
1872 [(set_attr "type" "dmpy")])
1874 (define_expand "smulsi3_highpart"
1876 [(set (reg:SI MACH_REG)
1880 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1881 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1883 (clobber (reg:SI MACL_REG))])
1884 (set (match_operand:SI 0 "arith_reg_operand" "")
1891 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1892 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1893 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1894 invariant code motion can move it. */
1895 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1896 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1897 /* expand_binop can't find a suitable code in mul_highpart_optab to
1898 make a REG_EQUAL note from, so make one here.
1899 See also {,u}mulhisi.
1900 ??? Alternatively, we could put this at the calling site of expand_binop,
1901 i.e. expand_mult_highpart. */
1903 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1908 (define_insn "umulsi3_highpart_i"
1909 [(set (reg:SI MACH_REG)
1913 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1914 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1916 (clobber (reg:SI MACL_REG))]
1919 [(set_attr "type" "dmpy")])
1921 (define_expand "umulsi3_highpart"
1923 [(set (reg:SI MACH_REG)
1927 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1928 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1930 (clobber (reg:SI MACL_REG))])
1931 (set (match_operand:SI 0 "arith_reg_operand" "")
1938 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1939 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1940 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1941 invariant code motion can move it. */
1942 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1943 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1947 ;; -------------------------------------------------------------------------
1948 ;; Logical operations
1949 ;; -------------------------------------------------------------------------
1951 (define_insn "*andsi3_compact"
1952 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1953 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1954 (match_operand:SI 2 "logical_operand" "r,K08")))]
1957 [(set_attr "type" "arith")])
1959 ;; If the constant is 255, then emit an extu.b instruction instead of an
1960 ;; and, since that will give better code.
1962 (define_expand "andsi3"
1963 [(set (match_operand:SI 0 "arith_reg_operand" "")
1964 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1965 (match_operand:SI 2 "logical_operand" "")))]
1969 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1971 emit_insn (gen_zero_extendqisi2 (operands[0],
1972 gen_lowpart (QImode, operands[1])));
1977 (define_insn_and_split "anddi3"
1978 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1979 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1980 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1987 && ! logical_operand (operands[2], DImode)"
1991 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1992 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1994 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1997 [(set_attr "type" "arith_media")])
1999 (define_insn "andcdi3"
2000 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2001 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2002 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2005 [(set_attr "type" "arith_media")])
2007 (define_insn "iorsi3"
2008 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2009 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2010 (match_operand:SI 2 "logical_operand" "r,K08")))]
2013 [(set_attr "type" "arith")])
2015 (define_insn "iordi3"
2016 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2017 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2018 (match_operand:DI 2 "logical_operand" "r,I10")))]
2023 [(set_attr "type" "arith_media")])
2025 (define_insn "xorsi3"
2026 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2027 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2028 (match_operand:SI 2 "logical_operand" "K08,r")))]
2031 [(set_attr "type" "arith")])
2033 (define_insn "xordi3"
2034 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2035 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2036 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2041 [(set_attr "type" "arith_media")])
2043 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2044 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2046 [(set (match_operand:DI 0 "arith_reg_operand" "")
2047 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2048 [(match_operand 1 "any_register_operand" "")
2049 (match_operand 2 "any_register_operand" "")])))]
2051 [(set (match_dup 5) (match_dup 4))
2052 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2055 enum machine_mode inmode = GET_MODE (operands[1]);
2058 if (GET_CODE (operands[0]) == SUBREG)
2060 offset = SUBREG_BYTE (operands[0]);
2061 operands[0] = SUBREG_REG (operands[0]);
2063 if (GET_CODE (operands[0]) != REG)
2065 if (! TARGET_LITTLE_ENDIAN)
2066 offset += 8 - GET_MODE_SIZE (inmode);
2067 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2070 ;; -------------------------------------------------------------------------
2071 ;; Shifts and rotates
2072 ;; -------------------------------------------------------------------------
2074 (define_expand "rotldi3"
2075 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2076 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2077 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2079 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2081 (define_insn "rotldi3_mextr"
2082 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2083 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2084 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2088 static char templ[16];
2090 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2091 8 - (int) (INTVAL (operands[2]) >> 3));
2094 [(set_attr "type" "arith_media")])
2096 (define_expand "rotrdi3"
2097 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2098 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2099 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2101 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2103 (define_insn "rotrdi3_mextr"
2104 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2105 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2106 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2110 static char templ[16];
2112 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2115 [(set_attr "type" "arith_media")])
2117 (define_insn "rotlsi3_1"
2118 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2119 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2122 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2125 [(set_attr "type" "arith")])
2127 (define_insn "rotlsi3_31"
2128 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2129 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2131 (clobber (reg:SI T_REG))]
2134 [(set_attr "type" "arith")])
2136 (define_insn "rotlsi3_16"
2137 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2138 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2142 [(set_attr "type" "arith")])
2144 (define_expand "rotlsi3"
2145 [(set (match_operand:SI 0 "arith_reg_operand" "")
2146 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2147 (match_operand:SI 2 "immediate_operand" "")))]
2151 static const char rot_tab[] = {
2152 000, 000, 000, 000, 000, 000, 010, 001,
2153 001, 001, 011, 013, 003, 003, 003, 003,
2154 003, 003, 003, 003, 003, 013, 012, 002,
2155 002, 002, 010, 000, 000, 000, 000, 000,
2160 if (GET_CODE (operands[2]) != CONST_INT)
2162 count = INTVAL (operands[2]);
2163 choice = rot_tab[count];
2164 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2170 emit_move_insn (operands[0], operands[1]);
2171 count -= (count & 16) * 2;
2174 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2181 parts[0] = gen_reg_rtx (SImode);
2182 parts[1] = gen_reg_rtx (SImode);
2183 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2184 parts[choice-1] = operands[1];
2185 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2186 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2187 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2188 count = (count & ~16) - 8;
2192 for (; count > 0; count--)
2193 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2194 for (; count < 0; count++)
2195 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2200 (define_insn "*rotlhi3_8"
2201 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2202 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2206 [(set_attr "type" "arith")])
2208 (define_expand "rotlhi3"
2209 [(set (match_operand:HI 0 "arith_reg_operand" "")
2210 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2211 (match_operand:HI 2 "immediate_operand" "")))]
2215 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2222 ;; This pattern is used by init_expmed for computing the costs of shift
2225 (define_insn_and_split "ashlsi3_std"
2226 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2227 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2228 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2229 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2231 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2232 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2240 && GET_CODE (operands[2]) == CONST_INT
2241 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2242 [(set (match_dup 3) (match_dup 2))
2244 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2245 (clobber (match_dup 4))])]
2246 "operands[4] = gen_rtx_SCRATCH (SImode);"
2247 [(set_attr "length" "*,*,*,4")
2248 (set_attr "type" "dyn_shift,arith,arith,arith")])
2250 (define_insn "ashlhi3_k"
2251 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2252 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2253 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2254 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2258 [(set_attr "type" "arith")])
2260 (define_insn "ashlsi3_n"
2261 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2262 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2263 (match_operand:SI 2 "const_int_operand" "n")))
2264 (clobber (reg:SI T_REG))]
2265 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2267 [(set (attr "length")
2268 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2270 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2272 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2274 (const_string "8")))
2275 (set_attr "type" "arith")])
2278 [(set (match_operand:SI 0 "arith_reg_operand" "")
2279 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2280 (match_operand:SI 2 "const_int_operand" "")))
2281 (clobber (reg:SI T_REG))]
2282 "TARGET_SH1 && reload_completed"
2283 [(use (reg:SI R0_REG))]
2286 gen_shifty_op (ASHIFT, operands);
2290 (define_insn "ashlsi3_media"
2291 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2292 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2293 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2298 [(set_attr "type" "arith_media")])
2300 (define_expand "ashlsi3"
2301 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2302 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2303 (match_operand:SI 2 "nonmemory_operand" "")))
2304 (clobber (reg:SI T_REG))])]
2310 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2313 if (GET_CODE (operands[2]) == CONST_INT
2314 && sh_dynamicalize_shift_p (operands[2]))
2315 operands[2] = force_reg (SImode, operands[2]);
2318 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2321 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2325 (define_insn "ashlhi3"
2326 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2327 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2328 (match_operand:HI 2 "const_int_operand" "n")))
2329 (clobber (reg:SI T_REG))]
2332 [(set (attr "length")
2333 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2335 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2337 (const_string "6")))
2338 (set_attr "type" "arith")])
2341 [(set (match_operand:HI 0 "arith_reg_operand" "")
2342 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2343 (match_operand:HI 2 "const_int_operand" "")))
2344 (clobber (reg:SI T_REG))]
2345 "TARGET_SH1 && reload_completed"
2346 [(use (reg:SI R0_REG))]
2349 gen_shifty_hi_op (ASHIFT, operands);
2354 ; arithmetic shift right
2357 (define_insn "ashrsi3_k"
2358 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2359 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2360 (match_operand:SI 2 "const_int_operand" "M")))
2361 (clobber (reg:SI T_REG))]
2362 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2364 [(set_attr "type" "arith")])
2366 ;; We can't do HImode right shifts correctly unless we start out with an
2367 ;; explicit zero / sign extension; doing that would result in worse overall
2368 ;; code, so just let the machine independent code widen the mode.
2369 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2372 ;; ??? This should be a define expand.
2374 (define_insn "ashrsi2_16"
2375 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2376 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2380 [(set_attr "length" "4")])
2383 [(set (match_operand:SI 0 "arith_reg_operand" "")
2384 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2387 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2388 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2389 "operands[2] = gen_lowpart (HImode, operands[0]);")
2391 ;; ??? This should be a define expand.
2393 (define_insn "ashrsi2_31"
2394 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2395 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2397 (clobber (reg:SI T_REG))]
2400 [(set_attr "length" "4")])
2403 [(set (match_operand:SI 0 "arith_reg_operand" "")
2404 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2406 (clobber (reg:SI T_REG))]
2411 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2412 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2416 (define_insn "ashlsi_c"
2417 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2418 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2420 (lt:SI (match_dup 1) (const_int 0)))]
2423 [(set_attr "type" "arith")])
2425 (define_insn "ashrsi3_d"
2426 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2427 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2428 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2431 [(set_attr "type" "dyn_shift")])
2433 (define_insn "ashrsi3_n"
2434 [(set (reg:SI R4_REG)
2435 (ashiftrt:SI (reg:SI R4_REG)
2436 (match_operand:SI 0 "const_int_operand" "i")))
2437 (clobber (reg:SI T_REG))
2438 (clobber (reg:SI PR_REG))
2439 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2442 [(set_attr "type" "sfunc")
2443 (set_attr "needs_delay_slot" "yes")])
2445 (define_insn "ashrsi3_media"
2446 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2447 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2448 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2453 [(set_attr "type" "arith_media")])
2455 (define_expand "ashrsi3"
2456 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2457 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2458 (match_operand:SI 2 "nonmemory_operand" "")))
2459 (clobber (reg:SI T_REG))])]
2465 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2468 if (expand_ashiftrt (operands))
2474 ;; logical shift right
2476 (define_insn "lshrsi3_d"
2477 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2479 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2482 [(set_attr "type" "dyn_shift")])
2484 ;; Only the single bit shift clobbers the T bit.
2486 (define_insn "lshrsi3_m"
2487 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2488 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2489 (match_operand:SI 2 "const_int_operand" "M")))
2490 (clobber (reg:SI T_REG))]
2491 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2493 [(set_attr "type" "arith")])
2495 (define_insn "lshrsi3_k"
2496 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2497 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2498 (match_operand:SI 2 "const_int_operand" "P27")))]
2499 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2500 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2502 [(set_attr "type" "arith")])
2504 (define_insn "lshrsi3_n"
2505 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2506 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2507 (match_operand:SI 2 "const_int_operand" "n")))
2508 (clobber (reg:SI T_REG))]
2509 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2511 [(set (attr "length")
2512 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2514 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2516 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2518 (const_string "8")))
2519 (set_attr "type" "arith")])
2522 [(set (match_operand:SI 0 "arith_reg_operand" "")
2523 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2524 (match_operand:SI 2 "const_int_operand" "")))
2525 (clobber (reg:SI T_REG))]
2526 "TARGET_SH1 && reload_completed"
2527 [(use (reg:SI R0_REG))]
2530 gen_shifty_op (LSHIFTRT, operands);
2534 (define_insn "lshrsi3_media"
2535 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2536 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2537 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2542 [(set_attr "type" "arith_media")])
2544 (define_expand "lshrsi3"
2545 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2546 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2547 (match_operand:SI 2 "nonmemory_operand" "")))
2548 (clobber (reg:SI T_REG))])]
2554 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2557 if (GET_CODE (operands[2]) == CONST_INT
2558 && sh_dynamicalize_shift_p (operands[2]))
2559 operands[2] = force_reg (SImode, operands[2]);
2560 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2562 rtx count = copy_to_mode_reg (SImode, operands[2]);
2563 emit_insn (gen_negsi2 (count, count));
2564 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2567 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2571 ;; ??? This should be a define expand.
2573 (define_insn "ashldi3_k"
2574 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2575 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2577 (clobber (reg:SI T_REG))]
2579 "shll %R0\;rotcl %S0"
2580 [(set_attr "length" "4")
2581 (set_attr "type" "arith")])
2583 (define_insn "ashldi3_media"
2584 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2585 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2586 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2591 [(set_attr "type" "arith_media")])
2593 (define_expand "ashldi3"
2594 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2595 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2596 (match_operand:DI 2 "immediate_operand" "")))
2597 (clobber (reg:SI T_REG))])]
2603 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2606 if (GET_CODE (operands[2]) != CONST_INT
2607 || INTVAL (operands[2]) != 1)
2611 ;; ??? This should be a define expand.
2613 (define_insn "lshrdi3_k"
2614 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2615 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2617 (clobber (reg:SI T_REG))]
2619 "shlr %S0\;rotcr %R0"
2620 [(set_attr "length" "4")
2621 (set_attr "type" "arith")])
2623 (define_insn "lshrdi3_media"
2624 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2625 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2626 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2631 [(set_attr "type" "arith_media")])
2633 (define_expand "lshrdi3"
2634 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2635 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2636 (match_operand:DI 2 "immediate_operand" "")))
2637 (clobber (reg:SI T_REG))])]
2643 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2646 if (GET_CODE (operands[2]) != CONST_INT
2647 || INTVAL (operands[2]) != 1)
2651 ;; ??? This should be a define expand.
2653 (define_insn "ashrdi3_k"
2654 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2655 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2657 (clobber (reg:SI T_REG))]
2659 "shar %S0\;rotcr %R0"
2660 [(set_attr "length" "4")
2661 (set_attr "type" "arith")])
2663 (define_insn "ashrdi3_media"
2664 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2665 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2666 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2671 [(set_attr "type" "arith_media")])
2673 (define_expand "ashrdi3"
2674 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2675 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2676 (match_operand:DI 2 "immediate_operand" "")))
2677 (clobber (reg:SI T_REG))])]
2683 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2686 if (GET_CODE (operands[2]) != CONST_INT
2687 || INTVAL (operands[2]) != 1)
2691 ;; combined left/right shift
2694 [(set (match_operand:SI 0 "register_operand" "")
2695 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2696 (match_operand:SI 2 "const_int_operand" ""))
2697 (match_operand:SI 3 "const_int_operand" "")))]
2698 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2699 [(use (reg:SI R0_REG))]
2700 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2704 [(set (match_operand:SI 0 "register_operand" "")
2705 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2706 (match_operand:SI 2 "const_int_operand" ""))
2707 (match_operand:SI 3 "const_int_operand" "")))
2708 (clobber (reg:SI T_REG))]
2709 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2710 [(use (reg:SI R0_REG))]
2711 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2715 [(set (match_operand:SI 0 "register_operand" "=r")
2716 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2717 (match_operand:SI 2 "const_int_operand" "n"))
2718 (match_operand:SI 3 "const_int_operand" "n")))
2719 (clobber (reg:SI T_REG))]
2720 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2722 [(set (attr "length")
2723 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2727 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2729 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2731 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2736 (const_string "16")]
2737 (const_string "18")))
2738 (set_attr "type" "arith")])
2741 [(set (match_operand:SI 0 "register_operand" "=z")
2742 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2743 (match_operand:SI 2 "const_int_operand" "n"))
2744 (match_operand:SI 3 "const_int_operand" "n")))
2745 (clobber (reg:SI T_REG))]
2746 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2748 [(set (attr "length")
2749 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2751 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2753 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2755 (const_string "10")))
2756 (set_attr "type" "arith")])
2758 ;; shift left / and combination with a scratch register: The combine pass
2759 ;; does not accept the individual instructions, even though they are
2760 ;; cheap. But it needs a precise description so that it is usable after
2762 (define_insn "and_shl_scratch"
2763 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2767 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2768 (match_operand:SI 2 "const_int_operand" "N,n"))
2769 (match_operand:SI 3 "" "0,r"))
2770 (match_operand:SI 4 "const_int_operand" "n,n"))
2771 (match_operand:SI 5 "const_int_operand" "n,n")))
2772 (clobber (reg:SI T_REG))]
2775 [(set (attr "length")
2776 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2778 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2780 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2782 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2783 (const_string "10")]
2784 (const_string "12")))
2785 (set_attr "type" "arith")])
2788 [(set (match_operand:SI 0 "register_operand" "")
2792 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2793 (match_operand:SI 2 "const_int_operand" ""))
2794 (match_operand:SI 3 "register_operand" ""))
2795 (match_operand:SI 4 "const_int_operand" ""))
2796 (match_operand:SI 5 "const_int_operand" "")))
2797 (clobber (reg:SI T_REG))]
2799 [(use (reg:SI R0_REG))]
2802 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2804 if (INTVAL (operands[2]))
2806 gen_shifty_op (LSHIFTRT, operands);
2808 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2809 operands[2] = operands[4];
2810 gen_shifty_op (ASHIFT, operands);
2811 if (INTVAL (operands[5]))
2813 operands[2] = operands[5];
2814 gen_shifty_op (LSHIFTRT, operands);
2819 ;; signed left/right shift combination.
2821 [(set (match_operand:SI 0 "register_operand" "")
2823 (ashift:SI (match_operand:SI 1 "register_operand" "")
2824 (match_operand:SI 2 "const_int_operand" ""))
2825 (match_operand:SI 3 "const_int_operand" "")
2827 (clobber (reg:SI T_REG))]
2829 [(use (reg:SI R0_REG))]
2830 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2833 (define_insn "shl_sext_ext"
2834 [(set (match_operand:SI 0 "register_operand" "=r")
2836 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2837 (match_operand:SI 2 "const_int_operand" "n"))
2838 (match_operand:SI 3 "const_int_operand" "n")
2840 (clobber (reg:SI T_REG))]
2841 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2843 [(set (attr "length")
2844 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2846 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2854 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2859 (const_string "16")]
2860 (const_string "18")))
2861 (set_attr "type" "arith")])
2863 (define_insn "shl_sext_sub"
2864 [(set (match_operand:SI 0 "register_operand" "=z")
2866 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2867 (match_operand:SI 2 "const_int_operand" "n"))
2868 (match_operand:SI 3 "const_int_operand" "n")
2870 (clobber (reg:SI T_REG))]
2871 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2873 [(set (attr "length")
2874 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2876 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2878 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2880 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2881 (const_string "12")]
2882 (const_string "14")))
2883 (set_attr "type" "arith")])
2885 ;; These patterns are found in expansions of DImode shifts by 16, and
2886 ;; allow the xtrct instruction to be generated from C source.
2888 (define_insn "xtrct_left"
2889 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2890 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2892 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2896 [(set_attr "type" "arith")])
2898 (define_insn "xtrct_right"
2899 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2900 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2902 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2906 [(set_attr "type" "arith")])
2908 ;; -------------------------------------------------------------------------
2910 ;; -------------------------------------------------------------------------
2913 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2914 (neg:SI (plus:SI (reg:SI T_REG)
2915 (match_operand:SI 1 "arith_reg_operand" "r"))))
2917 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2921 [(set_attr "type" "arith")])
2923 (define_insn "*negdi_media"
2924 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2925 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2928 [(set_attr "type" "arith_media")])
2930 (define_expand "negdi2"
2931 [(set (match_operand:DI 0 "arith_reg_operand" "")
2932 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2938 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2939 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2941 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2942 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2944 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2945 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2947 emit_insn (gen_clrt ());
2948 emit_insn (gen_negc (low_dst, low_src));
2949 emit_insn (gen_negc (high_dst, high_src));
2954 (define_insn "negsi2"
2955 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2956 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2959 [(set_attr "type" "arith")])
2961 (define_insn "one_cmplsi2"
2962 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2963 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2966 [(set_attr "type" "arith")])
2968 (define_expand "one_cmpldi2"
2969 [(set (match_operand:DI 0 "arith_reg_operand" "")
2970 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2972 "TARGET_SHMEDIA" "")
2974 ;; -------------------------------------------------------------------------
2975 ;; Zero extension instructions
2976 ;; -------------------------------------------------------------------------
2978 (define_insn "zero_extendsidi2"
2979 [(set (match_operand:DI 0 "register_operand" "=r")
2980 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2982 "addz.l %1, r63, %0"
2983 [(set_attr "type" "arith_media")])
2985 (define_insn "zero_extendhidi2"
2986 [(set (match_operand:DI 0 "register_operand" "=r,r")
2987 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2992 [(set_attr "type" "*,load_media")])
2995 [(set (match_operand:DI 0 "register_operand" "")
2996 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2997 "TARGET_SHMEDIA && reload_completed"
2998 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2999 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3002 if (GET_CODE (operands[1]) == TRUNCATE)
3003 operands[1] = XEXP (operands[1], 0);
3006 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3007 ;; reload the entire truncate expression.
3008 (define_insn_and_split "*loaddi_trunc"
3009 [(set (match_operand 0 "int_gpr_dest" "=r")
3010 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3011 "TARGET_SHMEDIA && reload_completed"
3013 "TARGET_SHMEDIA && reload_completed"
3014 [(set (match_dup 0) (match_dup 1))]
3015 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3017 (define_insn "zero_extendqidi2"
3018 [(set (match_operand:DI 0 "register_operand" "=r,r")
3019 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3024 [(set_attr "type" "arith_media,load_media")])
3026 (define_expand "zero_extendhisi2"
3027 [(set (match_operand:SI 0 "arith_reg_operand" "")
3028 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3032 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3033 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3036 (define_insn "*zero_extendhisi2_compact"
3037 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3038 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3041 [(set_attr "type" "arith")])
3043 (define_insn "*zero_extendhisi2_media"
3044 [(set (match_operand:SI 0 "register_operand" "=r,r")
3045 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3050 [(set_attr "type" "arith_media,load_media")])
3053 [(set (match_operand:SI 0 "register_operand" "")
3054 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3055 "TARGET_SHMEDIA && reload_completed"
3056 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3057 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3060 if (GET_CODE (operands[1]) == TRUNCATE)
3061 operands[1] = XEXP (operands[1], 0);
3064 (define_expand "zero_extendqisi2"
3065 [(set (match_operand:SI 0 "arith_reg_operand" "")
3066 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3070 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3071 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3074 (define_insn "*zero_extendqisi2_compact"
3075 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3076 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3079 [(set_attr "type" "arith")])
3081 (define_insn "*zero_extendqisi2_media"
3082 [(set (match_operand:SI 0 "register_operand" "=r,r")
3083 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3088 [(set_attr "type" "arith_media,load_media")])
3090 (define_insn "zero_extendqihi2"
3091 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3092 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3095 [(set_attr "type" "arith")])
3097 ;; -------------------------------------------------------------------------
3098 ;; Sign extension instructions
3099 ;; -------------------------------------------------------------------------
3101 ;; ??? This should be a define expand.
3102 ;; ??? Or perhaps it should be dropped?
3104 ;; convert_move generates good code for SH[1-4].
3105 (define_insn "extendsidi2"
3106 [(set (match_operand:DI 0 "register_operand" "=r,r")
3107 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3112 [(set_attr "type" "arith_media,load_media")])
3114 (define_insn "extendhidi2"
3115 [(set (match_operand:DI 0 "register_operand" "=r,r")
3116 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3121 [(set_attr "type" "*,load_media")])
3124 [(set (match_operand:DI 0 "register_operand" "")
3125 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3126 "TARGET_SHMEDIA && reload_completed"
3127 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3128 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3131 if (GET_CODE (operands[1]) == TRUNCATE)
3132 operands[1] = XEXP (operands[1], 0);
3135 (define_insn "extendqidi2"
3136 [(set (match_operand:DI 0 "register_operand" "=r,r")
3137 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3142 [(set_attr "type" "*,load_media")])
3145 [(set (match_operand:DI 0 "register_operand" "")
3146 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3147 "TARGET_SHMEDIA && reload_completed"
3148 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3149 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3152 if (GET_CODE (operands[1]) == TRUNCATE)
3153 operands[1] = XEXP (operands[1], 0);
3156 (define_expand "extendhisi2"
3157 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3162 (define_insn "*extendhisi2_compact"
3163 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3164 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3169 [(set_attr "type" "arith,load")])
3171 (define_insn "*extendhisi2_media"
3172 [(set (match_operand:SI 0 "register_operand" "=r,r")
3173 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3178 [(set_attr "type" "arith_media,load_media")])
3181 [(set (match_operand:SI 0 "register_operand" "")
3182 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3183 "TARGET_SHMEDIA && reload_completed"
3184 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3185 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3188 if (GET_CODE (operands[1]) == TRUNCATE)
3189 operands[1] = XEXP (operands[1], 0);
3192 (define_expand "extendqisi2"
3193 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3198 (define_insn "*extendqisi2_compact"
3199 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3200 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3205 [(set_attr "type" "arith,load")])
3207 (define_insn "*extendqisi2_media"
3208 [(set (match_operand:SI 0 "register_operand" "=r,r")
3209 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3214 [(set_attr "type" "arith_media,load_media")])
3217 [(set (match_operand:SI 0 "register_operand" "")
3218 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3219 "TARGET_SHMEDIA && reload_completed"
3220 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3221 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3224 if (GET_CODE (operands[1]) == TRUNCATE)
3225 operands[1] = XEXP (operands[1], 0);
3228 (define_insn "extendqihi2"
3229 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3230 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3235 [(set_attr "type" "arith,load")])
3237 /* It would seem useful to combine the truncXi patterns into the movXi
3238 patterns, but unary operators are ignored when matching constraints,
3239 so we need separate patterns. */
3240 (define_insn "truncdisi2"
3241 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3242 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3251 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3254 (define_insn "truncdihi2"
3255 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3256 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3259 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3261 [(set_attr "type" "arith_media,store_media")
3262 (set_attr "length" "8,4")])
3264 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3265 ; Because we use zero extension, we can't provide signed QImode compares
3266 ; using a simple compare or conditional banch insn.
3267 (define_insn "truncdiqi2"
3268 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3269 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3274 [(set_attr "type" "arith_media,store")])
3276 ;; -------------------------------------------------------------------------
3277 ;; Move instructions
3278 ;; -------------------------------------------------------------------------
3280 ;; define push and pop so it is easy for sh.c
3281 ;; We can't use push and pop on SHcompact because the stack must always
3282 ;; be 8-byte aligned.
3284 (define_expand "push"
3285 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3286 (match_operand:SI 0 "register_operand" "r,l,x"))]
3287 "TARGET_SH1 && ! TARGET_SH5"
3290 (define_expand "pop"
3291 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3292 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3293 "TARGET_SH1 && ! TARGET_SH5"
3296 (define_expand "push_e"
3297 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3298 (match_operand:SF 0 "" ""))
3299 (use (reg:PSI FPSCR_REG))
3300 (clobber (scratch:SI))])]
3301 "TARGET_SH1 && ! TARGET_SH5"
3304 (define_insn "push_fpul"
3305 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3306 "TARGET_SH2E && ! TARGET_SH5"
3308 [(set_attr "type" "store")
3309 (set_attr "late_fp_use" "yes")
3310 (set_attr "hit_stack" "yes")])
3312 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3314 (define_expand "push_4"
3315 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3316 (match_operand:DF 0 "" ""))
3317 (use (reg:PSI FPSCR_REG))
3318 (clobber (scratch:SI))])]
3319 "TARGET_SH1 && ! TARGET_SH5"
3322 (define_expand "pop_e"
3323 [(parallel [(set (match_operand:SF 0 "" "")
3324 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3325 (use (reg:PSI FPSCR_REG))
3326 (clobber (scratch:SI))])]
3327 "TARGET_SH1 && ! TARGET_SH5"
3330 (define_insn "pop_fpul"
3331 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3332 "TARGET_SH2E && ! TARGET_SH5"
3334 [(set_attr "type" "load")
3335 (set_attr "hit_stack" "yes")])
3337 (define_expand "pop_4"
3338 [(parallel [(set (match_operand:DF 0 "" "")
3339 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3340 (use (reg:PSI FPSCR_REG))
3341 (clobber (scratch:SI))])]
3342 "TARGET_SH1 && ! TARGET_SH5"
3345 (define_expand "push_fpscr"
3350 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3351 gen_rtx (PRE_DEC, Pmode,
3352 stack_pointer_rtx)),
3354 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3358 (define_expand "pop_fpscr"
3363 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3364 gen_rtx (MEM, PSImode,
3365 gen_rtx (POST_INC, Pmode,
3366 stack_pointer_rtx))));
3367 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3371 ;; These two patterns can happen as the result of optimization, when
3372 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3373 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3376 [(set (reg:SI T_REG) (const_int 0))]
3381 [(set (reg:SI T_REG) (const_int 1))]
3385 ;; t/r must come after r/r, lest reload will try to reload stuff like
3386 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3387 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3388 (define_insn "movsi_i"
3389 [(set (match_operand:SI 0 "general_movdst_operand"
3390 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3391 (match_operand:SI 1 "general_movsrc_operand"
3392 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3395 && (register_operand (operands[0], SImode)
3396 || register_operand (operands[1], SImode))"
3413 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3414 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3416 ;; t/r must come after r/r, lest reload will try to reload stuff like
3417 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3418 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3419 ;; will require a reload.
3420 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3421 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3422 (define_insn "movsi_ie"
3423 [(set (match_operand:SI 0 "general_movdst_operand"
3424 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3425 (match_operand:SI 1 "general_movsrc_operand"
3426 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3428 && (register_operand (operands[0], SImode)
3429 || register_operand (operands[1], SImode))"
3453 ! move optimized away"
3454 [(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")
3455 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3456 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3458 (define_insn "movsi_i_lowpart"
3459 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3460 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3462 && (register_operand (operands[0], SImode)
3463 || register_operand (operands[1], SImode))"
3473 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3475 (define_insn_and_split "load_ra"
3476 [(set (match_operand:SI 0 "general_movdst_operand" "")
3477 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3480 "&& ! rtx_equal_function_value_matters"
3481 [(set (match_dup 0) (match_dup 1))]
3484 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3485 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3488 (define_insn "*movsi_media"
3489 [(set (match_operand:SI 0 "general_movdst_operand"
3490 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3491 (match_operand:SI 1 "general_movsrc_operand"
3492 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3494 && (register_operand (operands[0], SImode)
3495 || sh_register_operand (operands[1], SImode))"
3510 [(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")
3511 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3513 (define_insn "*movsi_media_nofpu"
3514 [(set (match_operand:SI 0 "general_movdst_operand"
3515 "=r,r,r,r,m,*b,r,b")
3516 (match_operand:SI 1 "general_movsrc_operand"
3517 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3519 && (register_operand (operands[0], SImode)
3520 || sh_register_operand (operands[1], SImode))"
3530 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3531 (set_attr "length" "4,4,8,4,4,4,4,12")])
3534 [(set (match_operand:SI 0 "arith_reg_operand" "")
3535 (match_operand:SI 1 "immediate_operand" ""))]
3536 "TARGET_SHMEDIA && reload_completed
3537 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3538 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3541 operands[2] = shallow_copy_rtx (operands[1]);
3542 PUT_MODE (operands[2], DImode);
3546 [(set (match_operand:SI 0 "register_operand" "")
3547 (match_operand:SI 1 "immediate_operand" ""))]
3548 "TARGET_SHMEDIA && reload_completed
3549 && ((GET_CODE (operands[1]) == CONST_INT
3550 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3551 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3552 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3554 (define_expand "movsi"
3555 [(set (match_operand:SI 0 "general_movdst_operand" "")
3556 (match_operand:SI 1 "general_movsrc_operand" ""))]
3558 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3560 (define_expand "ic_invalidate_line"
3561 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3562 (match_dup 1)] UNSPEC_ICACHE)
3563 (clobber (scratch:SI))])]
3564 "TARGET_HARD_SH4 || TARGET_SH5"
3569 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3572 else if (TARGET_SHCOMPACT)
3574 operands[1] = function_symbol (\"__ic_invalidate\");
3575 operands[1] = force_reg (Pmode, operands[1]);
3576 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3579 operands[0] = force_reg (Pmode, operands[0]);
3580 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3584 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3585 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3586 ;; the requirement *1*00 for associative address writes. The alignment of
3587 ;; %0 implies that its least significant bit is cleared,
3588 ;; thus we clear the V bit of a matching entry if there is one.
3589 (define_insn "ic_invalidate_line_i"
3590 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3591 (match_operand:SI 1 "register_operand" "r")]
3593 (clobber (match_scratch:SI 2 "=&r"))]
3595 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3596 [(set_attr "length" "8")
3597 (set_attr "type" "cwb")])
3599 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3600 ;; an add in the code that calculates the address.
3601 (define_insn "ic_invalidate_line_media"
3602 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3605 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3606 [(set_attr "length" "16")
3607 (set_attr "type" "invalidate_line_media")])
3609 (define_insn "ic_invalidate_line_compact"
3610 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3611 (match_operand:SI 1 "register_operand" "r")]
3613 (clobber (reg:SI PR_REG))]
3616 [(set_attr "type" "sfunc")
3617 (set_attr "needs_delay_slot" "yes")])
3619 (define_expand "initialize_trampoline"
3620 [(match_operand:SI 0 "" "")
3621 (match_operand:SI 1 "" "")
3622 (match_operand:SI 2 "" "")]
3628 tramp = force_reg (Pmode, operands[0]);
3629 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3630 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3631 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3633 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3637 (define_insn "initialize_trampoline_compact"
3638 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3639 (match_operand:SI 1 "register_operand" "r")
3640 (reg:SI R2_REG) (reg:SI R3_REG)]
3643 (clobber (reg:SI PR_REG))]
3646 [(set_attr "type" "sfunc")
3647 (set_attr "needs_delay_slot" "yes")])
3649 (define_insn "movqi_i"
3650 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3651 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3653 && (arith_reg_operand (operands[0], QImode)
3654 || arith_reg_operand (operands[1], QImode))"
3662 [(set_attr "type" "move,load,store,move,move,move")])
3664 (define_insn "*movqi_media"
3665 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3666 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3668 && (arith_reg_operand (operands[0], QImode)
3669 || arith_reg_or_0_operand (operands[1], QImode))"
3675 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3677 (define_expand "movqi"
3678 [(set (match_operand:QI 0 "general_operand" "")
3679 (match_operand:QI 1 "general_operand" ""))]
3681 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3683 (define_expand "reload_inqi"
3684 [(set (match_operand:SI 2 "" "=&r")
3685 (match_operand:QI 1 "inqhi_operand" ""))
3686 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3687 (truncate:QI (match_dup 3)))]
3691 rtx inner = XEXP (operands[1], 0);
3692 int regno = REGNO (inner);
3694 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3695 operands[1] = gen_rtx_REG (SImode, regno);
3696 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3699 /* When storing r0, we have to avoid reg+reg addressing. */
3700 (define_insn "movhi_i"
3701 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3702 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3704 && (arith_reg_operand (operands[0], HImode)
3705 || arith_reg_operand (operands[1], HImode))
3706 && (GET_CODE (operands[0]) != MEM
3707 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3708 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3709 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3719 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3721 (define_insn "*movhi_media"
3722 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3723 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3725 && (arith_reg_operand (operands[0], HImode)
3726 || arith_reg_or_0_operand (operands[1], HImode))"
3733 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3736 [(set (match_operand:HI 0 "register_operand" "")
3737 (match_operand:HI 1 "immediate_operand" ""))]
3738 "TARGET_SHMEDIA && reload_completed
3739 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3740 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3742 (define_expand "movhi"
3743 [(set (match_operand:HI 0 "general_movdst_operand" "")
3744 (match_operand:HI 1 "general_movsrc_operand" ""))]
3746 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3748 (define_expand "reload_inhi"
3749 [(set (match_operand:SI 2 "" "=&r")
3750 (match_operand:HI 1 "inqhi_operand" ""))
3751 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3752 (truncate:HI (match_dup 3)))]
3756 rtx inner = XEXP (operands[1], 0);
3757 int regno = REGNO (inner);
3759 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3760 operands[1] = gen_rtx_REG (SImode, regno);
3761 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3764 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3765 ;; compiled with -m2 -ml -O3 -funroll-loops
3766 (define_insn "*movdi_i"
3767 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3768 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3770 && (arith_reg_operand (operands[0], DImode)
3771 || arith_reg_operand (operands[1], DImode))"
3772 "* return output_movedouble (insn, operands, DImode);"
3773 [(set_attr "length" "4")
3774 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3776 ;; If the output is a register and the input is memory or a register, we have
3777 ;; to be careful and see which word needs to be loaded first.
3780 [(set (match_operand:DI 0 "general_movdst_operand" "")
3781 (match_operand:DI 1 "general_movsrc_operand" ""))]
3782 "TARGET_SH1 && reload_completed"
3783 [(set (match_dup 2) (match_dup 3))
3784 (set (match_dup 4) (match_dup 5))]
3789 if ((GET_CODE (operands[0]) == MEM
3790 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3791 || (GET_CODE (operands[1]) == MEM
3792 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3795 if (GET_CODE (operands[0]) == REG)
3796 regno = REGNO (operands[0]);
3797 else if (GET_CODE (operands[0]) == SUBREG)
3798 regno = subreg_regno (operands[0]);
3799 else if (GET_CODE (operands[0]) == MEM)
3805 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3807 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3808 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3809 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3810 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3814 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3815 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3816 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3817 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3820 if (operands[2] == 0 || operands[3] == 0
3821 || operands[4] == 0 || operands[5] == 0)
3825 (define_insn "*movdi_media"
3826 [(set (match_operand:DI 0 "general_movdst_operand"
3827 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3828 (match_operand:DI 1 "general_movsrc_operand"
3829 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3831 && (register_operand (operands[0], DImode)
3832 || sh_register_operand (operands[1], DImode))"
3847 [(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")
3848 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3850 (define_insn "*movdi_media_nofpu"
3851 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3852 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3854 && (register_operand (operands[0], DImode)
3855 || sh_register_operand (operands[1], DImode))"
3865 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3866 (set_attr "length" "4,4,16,4,4,4,4,*")])
3869 [(set (match_operand:DI 0 "arith_reg_operand" "")
3870 (match_operand:DI 1 "immediate_operand" ""))]
3871 "TARGET_SHMEDIA && reload_completed
3872 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3873 [(set (match_dup 0) (match_dup 1))]
3878 if (TARGET_SHMEDIA64)
3879 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3881 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3883 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3889 (define_expand "movdi_const"
3890 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3891 (const:DI (sign_extend:DI
3894 (match_operand:DI 1 "immediate_operand" "s")
3897 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3905 (const_int 32)))))))))
3907 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3915 (const_int 16)))))))))
3917 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3923 (match_dup 1))))))))]
3924 "TARGET_SHMEDIA64 && reload_completed
3925 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3928 sh_mark_label (operands[1], 4);
3931 (define_expand "movdi_const_32bit"
3932 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3933 (const:DI (sign_extend:DI
3936 (match_operand:DI 1 "immediate_operand" "s")
3939 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3945 (match_dup 1))))))))]
3946 "TARGET_SHMEDIA32 && reload_completed
3947 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3950 sh_mark_label (operands[1], 2);
3953 (define_expand "movdi_const_16bit"
3954 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3955 (const:DI (sign_extend:DI
3957 (match_operand:DI 1 "immediate_operand" "s")))))]
3958 "TARGET_SHMEDIA && flag_pic && reload_completed
3959 && GET_CODE (operands[1]) == SYMBOL_REF"
3963 [(set (match_operand:DI 0 "arith_reg_operand" "")
3964 (match_operand:DI 1 "immediate_operand" ""))]
3965 "TARGET_SHMEDIA && reload_completed
3966 && GET_CODE (operands[1]) == CONST_INT
3967 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3968 [(set (match_dup 0) (match_dup 2))
3972 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3973 unsigned HOST_WIDE_INT low = val;
3974 unsigned HOST_WIDE_INT high = val;
3975 unsigned HOST_WIDE_INT sign;
3976 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3978 /* Sign-extend the 16 least-significant bits. */
3983 /* Arithmetic shift right the word by 16 bits. */
3986 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3991 /* If we can't generate the constant with a two-insn movi / shori
3992 sequence, try some other strategies. */
3993 if (! CONST_OK_FOR_I16 (high))
3995 /* Try constant load / left shift. We know VAL != 0. */
3996 val2 = val ^ (val-1);
3999 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4001 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4002 || (! CONST_OK_FOR_I16 (high >> 16)
4003 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4005 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4006 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4007 GEN_INT (trailing_zeroes));
4011 /* Try constant load / right shift. */
4012 val2 = (val >> 15) + 1;
4013 if (val2 == (val2 & -val2))
4015 int shift = 49 - exact_log2 (val2);
4017 val2 = trunc_int_for_mode (val << shift, DImode);
4018 if (CONST_OK_FOR_I16 (val2))
4020 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4026 val2 = val & 0xffff;
4027 if ((val >> 16 & 0xffff) == val2
4028 && (val >> 32 & 0xffff) == val2
4029 && (val >> 48 & 0xffff) == val2)
4031 val2 = (HOST_WIDE_INT) val >> 48;
4032 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4033 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4036 /* Try movi / mshflo.l */
4037 val2 = (HOST_WIDE_INT) val >> 32;
4038 if (val2 == trunc_int_for_mode (val, SImode))
4040 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4044 /* Try movi / mshflo.l w/ r63. */
4045 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4046 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4054 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4057 operands[2] = GEN_INT (val2);
4061 [(set (match_operand:DI 0 "arith_reg_operand" "")
4062 (match_operand:DI 1 "immediate_operand" ""))]
4063 "TARGET_SHMEDIA && reload_completed
4064 && GET_CODE (operands[1]) == CONST_DOUBLE"
4065 [(set (match_dup 0) (match_dup 2))
4067 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4068 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4071 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4072 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4073 unsigned HOST_WIDE_INT val = low;
4074 unsigned HOST_WIDE_INT sign;
4076 /* Sign-extend the 16 least-significant bits. */
4080 operands[1] = GEN_INT (val);
4082 /* Arithmetic shift right the double-word by 16 bits. */
4084 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4087 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4091 /* This will only be true if high is a sign-extension of low, i.e.,
4092 it must be either 0 or (unsigned)-1, and be zero iff the
4093 most-significant bit of low is set. */
4094 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4095 operands[2] = GEN_INT (low);
4097 operands[2] = immed_double_const (low, high, DImode);
4100 (define_insn "shori_media"
4101 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4102 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4106 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4111 [(set_attr "type" "arith_media,*")])
4113 (define_expand "movdi"
4114 [(set (match_operand:DI 0 "general_movdst_operand" "")
4115 (match_operand:DI 1 "general_movsrc_operand" ""))]
4117 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4119 (define_insn "movdf_media"
4120 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4121 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4123 && (register_operand (operands[0], DFmode)
4124 || sh_register_operand (operands[1], DFmode))"
4135 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4137 (define_insn "movdf_media_nofpu"
4138 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4139 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4141 && (register_operand (operands[0], DFmode)
4142 || sh_register_operand (operands[1], DFmode))"
4148 [(set_attr "type" "arith_media,*,load_media,store_media")])
4151 [(set (match_operand:DF 0 "arith_reg_operand" "")
4152 (match_operand:DF 1 "immediate_operand" ""))]
4153 "TARGET_SHMEDIA && reload_completed"
4154 [(set (match_dup 3) (match_dup 2))]
4157 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4159 REAL_VALUE_TYPE value;
4161 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4162 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4164 if (HOST_BITS_PER_WIDE_INT >= 64)
4165 operands[2] = immed_double_const ((unsigned long) values[endian]
4166 | ((HOST_WIDE_INT) values[1 - endian]
4168 else if (HOST_BITS_PER_WIDE_INT == 32)
4169 operands[2] = immed_double_const (values[endian], values[1 - endian],
4174 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4177 ;; ??? This should be a define expand.
4179 (define_insn "movdf_k"
4180 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4181 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4183 && (! TARGET_SH4 || reload_completed
4184 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4185 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4186 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4187 && (arith_reg_operand (operands[0], DFmode)
4188 || arith_reg_operand (operands[1], DFmode))"
4189 "* return output_movedouble (insn, operands, DFmode);"
4190 [(set_attr "length" "4")
4191 (set_attr "type" "move,pcload,load,store")])
4193 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4194 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4195 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4196 ;; the d/m/c/X alternative, which is split later into single-precision
4197 ;; instructions. And when not optimizing, no splits are done before fixing
4198 ;; up pcloads, so we need usable length information for that.
4199 (define_insn "movdf_i4"
4200 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4201 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4202 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4203 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4205 && (arith_reg_operand (operands[0], DFmode)
4206 || arith_reg_operand (operands[1], DFmode))"
4218 [(set_attr_alternative "length"
4219 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4221 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4222 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4223 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4225 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4226 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4227 ;; increment or decrement r15 explicitly.
4229 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4230 (const_int 10) (const_int 8))
4232 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233 (const_int 10) (const_int 8))])
4234 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4235 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4236 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4237 (const_string "double")
4238 (const_string "none")))])
4240 ;; Moving DFmode between fp/general registers through memory
4241 ;; (the top of the stack) is faster than moving through fpul even for
4242 ;; little endian. Because the type of an instruction is important for its
4243 ;; scheduling, it is beneficial to split these operations, rather than
4244 ;; emitting them in one single chunk, even if this will expose a stack
4245 ;; use that will prevent scheduling of other stack accesses beyond this
4248 [(set (match_operand:DF 0 "register_operand" "")
4249 (match_operand:DF 1 "register_operand" ""))
4250 (use (match_operand:PSI 2 "fpscr_operand" ""))
4251 (clobber (match_scratch:SI 3 "=X"))]
4252 "TARGET_SH4 && reload_completed
4253 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4259 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4261 emit_move_insn (stack_pointer_rtx,
4262 plus_constant (stack_pointer_rtx, -8));
4263 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4266 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4267 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4268 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4269 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4270 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4273 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4274 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4275 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4278 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4282 ;; local-alloc sometimes allocates scratch registers even when not required,
4283 ;; so we must be prepared to handle these.
4285 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4287 [(set (match_operand:DF 0 "general_movdst_operand" "")
4288 (match_operand:DF 1 "general_movsrc_operand" ""))
4289 (use (match_operand:PSI 2 "fpscr_operand" ""))
4290 (clobber (match_scratch:SI 3 ""))]
4293 && true_regnum (operands[0]) < 16
4294 && true_regnum (operands[1]) < 16"
4295 [(set (match_dup 0) (match_dup 1))]
4298 /* If this was a reg <-> mem operation with base + index reg addressing,
4299 we have to handle this in a special way. */
4300 rtx mem = operands[0];
4302 if (! memory_operand (mem, DFmode))
4307 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4308 mem = SUBREG_REG (mem);
4309 if (GET_CODE (mem) == MEM)
4311 rtx addr = XEXP (mem, 0);
4312 if (GET_CODE (addr) == PLUS
4313 && GET_CODE (XEXP (addr, 0)) == REG
4314 && GET_CODE (XEXP (addr, 1)) == REG)
4317 rtx reg0 = gen_rtx (REG, Pmode, 0);
4318 rtx regop = operands[store_p], word0 ,word1;
4320 if (GET_CODE (regop) == SUBREG)
4321 alter_subreg (®op);
4322 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4326 mem = copy_rtx (mem);
4327 PUT_MODE (mem, SImode);
4328 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4329 alter_subreg (&word0);
4330 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4331 alter_subreg (&word1);
4332 if (store_p || ! refers_to_regno_p (REGNO (word0),
4333 REGNO (word0) + 1, addr, 0))
4336 ? gen_movsi_ie (mem, word0)
4337 : gen_movsi_ie (word0, mem));
4338 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4339 mem = copy_rtx (mem);
4341 ? gen_movsi_ie (mem, word1)
4342 : gen_movsi_ie (word1, mem));
4343 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4347 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4348 emit_insn (gen_movsi_ie (word1, mem));
4349 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350 mem = copy_rtx (mem);
4351 emit_insn (gen_movsi_ie (word0, mem));
4358 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4360 [(set (match_operand:DF 0 "register_operand" "")
4361 (match_operand:DF 1 "memory_operand" ""))
4362 (use (match_operand:PSI 2 "fpscr_operand" ""))
4363 (clobber (reg:SI R0_REG))]
4364 "TARGET_SH4 && reload_completed"
4365 [(parallel [(set (match_dup 0) (match_dup 1))
4367 (clobber (scratch:SI))])]
4370 (define_expand "reload_indf"
4371 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4372 (match_operand:DF 1 "immediate_operand" "FQ"))
4373 (use (reg:PSI FPSCR_REG))
4374 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4378 (define_expand "reload_outdf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4380 (match_operand:DF 1 "register_operand" "af,r"))
4381 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4385 ;; Simplify no-op moves.
4387 [(set (match_operand:SF 0 "register_operand" "")
4388 (match_operand:SF 1 "register_operand" ""))
4389 (use (match_operand:PSI 2 "fpscr_operand" ""))
4390 (clobber (match_scratch:SI 3 "X"))]
4391 "TARGET_SH2E && reload_completed
4392 && true_regnum (operands[0]) == true_regnum (operands[1])"
4393 [(set (match_dup 0) (match_dup 0))]
4396 ;; fmovd substitute post-reload splits
4398 [(set (match_operand:DF 0 "register_operand" "")
4399 (match_operand:DF 1 "register_operand" ""))
4400 (use (match_operand:PSI 2 "fpscr_operand" ""))
4401 (clobber (match_scratch:SI 3 "X"))]
4402 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4403 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4404 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4408 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4409 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4410 gen_rtx (REG, SFmode, src), operands[2]));
4411 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4412 gen_rtx (REG, SFmode, src + 1), operands[2]));
4417 [(set (match_operand:DF 0 "register_operand" "")
4418 (mem:DF (match_operand:SI 1 "register_operand" "")))
4419 (use (match_operand:PSI 2 "fpscr_operand" ""))
4420 (clobber (match_scratch:SI 3 ""))]
4421 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4422 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4423 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4427 int regno = true_regnum (operands[0]);
4429 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4431 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4432 regno + !! TARGET_LITTLE_ENDIAN),
4433 mem2, operands[2]));
4434 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4435 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4436 regno + ! TARGET_LITTLE_ENDIAN),
4437 gen_rtx (MEM, SFmode, operands[1]),
4443 [(set (match_operand:DF 0 "register_operand" "")
4444 (match_operand:DF 1 "memory_operand" ""))
4445 (use (match_operand:PSI 2 "fpscr_operand" ""))
4446 (clobber (match_scratch:SI 3 ""))]
4447 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4448 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4452 int regno = true_regnum (operands[0]);
4453 rtx addr, insn, adjust = NULL_RTX;
4454 rtx mem2 = copy_rtx (operands[1]);
4455 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4456 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4458 PUT_MODE (mem2, SFmode);
4459 operands[1] = copy_rtx (mem2);
4460 addr = XEXP (mem2, 0);
4461 if (GET_CODE (addr) != POST_INC)
4463 /* If we have to modify the stack pointer, the value that we have
4464 read with post-increment might be modified by an interrupt,
4465 so write it back. */
4466 if (REGNO (addr) == STACK_POINTER_REGNUM)
4467 adjust = gen_push_e (reg0);
4469 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4470 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4472 addr = XEXP (addr, 0);
4473 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4474 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4475 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4479 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4484 [(set (match_operand:DF 0 "memory_operand" "")
4485 (match_operand:DF 1 "register_operand" ""))
4486 (use (match_operand:PSI 2 "fpscr_operand" ""))
4487 (clobber (match_scratch:SI 3 ""))]
4488 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4489 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4493 int regno = true_regnum (operands[1]);
4494 rtx insn, addr, adjust = NULL_RTX;
4496 operands[0] = copy_rtx (operands[0]);
4497 PUT_MODE (operands[0], SFmode);
4498 insn = emit_insn (gen_movsf_ie (operands[0],
4499 gen_rtx (REG, SFmode,
4500 regno + ! TARGET_LITTLE_ENDIAN),
4502 operands[0] = copy_rtx (operands[0]);
4503 addr = XEXP (operands[0], 0);
4504 if (GET_CODE (addr) != PRE_DEC)
4506 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4507 emit_insn_before (adjust, insn);
4508 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4510 addr = XEXP (addr, 0);
4512 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4513 insn = emit_insn (gen_movsf_ie (operands[0],
4514 gen_rtx (REG, SFmode,
4515 regno + !! TARGET_LITTLE_ENDIAN),
4517 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4521 ;; If the output is a register and the input is memory or a register, we have
4522 ;; to be careful and see which word needs to be loaded first.
4525 [(set (match_operand:DF 0 "general_movdst_operand" "")
4526 (match_operand:DF 1 "general_movsrc_operand" ""))]
4527 "TARGET_SH1 && reload_completed"
4528 [(set (match_dup 2) (match_dup 3))
4529 (set (match_dup 4) (match_dup 5))]
4534 if ((GET_CODE (operands[0]) == MEM
4535 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4536 || (GET_CODE (operands[1]) == MEM
4537 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4540 if (GET_CODE (operands[0]) == REG)
4541 regno = REGNO (operands[0]);
4542 else if (GET_CODE (operands[0]) == SUBREG)
4543 regno = subreg_regno (operands[0]);
4544 else if (GET_CODE (operands[0]) == MEM)
4550 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4552 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4553 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4554 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4555 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4559 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4560 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4561 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4562 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4565 if (operands[2] == 0 || operands[3] == 0
4566 || operands[4] == 0 || operands[5] == 0)
4570 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4571 ;; used only once, let combine add in the index again.
4574 [(set (match_operand:SI 0 "register_operand" "")
4575 (match_operand:SI 1 "" ""))
4576 (clobber (match_operand 2 "register_operand" ""))]
4577 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4578 [(use (reg:SI R0_REG))]
4581 rtx addr, reg, const_int;
4583 if (GET_CODE (operands[1]) != MEM)
4585 addr = XEXP (operands[1], 0);
4586 if (GET_CODE (addr) != PLUS)
4588 reg = XEXP (addr, 0);
4589 const_int = XEXP (addr, 1);
4590 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4591 && GET_CODE (const_int) == CONST_INT))
4593 emit_move_insn (operands[2], const_int);
4594 emit_move_insn (operands[0],
4595 change_address (operands[1], VOIDmode,
4596 gen_rtx_PLUS (SImode, reg, operands[2])));
4601 [(set (match_operand:SI 1 "" "")
4602 (match_operand:SI 0 "register_operand" ""))
4603 (clobber (match_operand 2 "register_operand" ""))]
4604 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4605 [(use (reg:SI R0_REG))]
4608 rtx addr, reg, const_int;
4610 if (GET_CODE (operands[1]) != MEM)
4612 addr = XEXP (operands[1], 0);
4613 if (GET_CODE (addr) != PLUS)
4615 reg = XEXP (addr, 0);
4616 const_int = XEXP (addr, 1);
4617 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4618 && GET_CODE (const_int) == CONST_INT))
4620 emit_move_insn (operands[2], const_int);
4621 emit_move_insn (change_address (operands[1], VOIDmode,
4622 gen_rtx_PLUS (SImode, reg, operands[2])),
4627 (define_expand "movdf"
4628 [(set (match_operand:DF 0 "general_movdst_operand" "")
4629 (match_operand:DF 1 "general_movsrc_operand" ""))]
4633 if (prepare_move_operands (operands, DFmode)) DONE;
4636 if (TARGET_SHMEDIA_FPU)
4637 emit_insn (gen_movdf_media (operands[0], operands[1]));
4639 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4644 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4649 ;;This is incompatible with the way gcc uses subregs.
4650 ;;(define_insn "movv2sf_i"
4651 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4652 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4653 ;; "TARGET_SHMEDIA_FPU
4654 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4655 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4659 ;; fst%M0.p %m0, %1"
4660 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4662 (define_insn_and_split "movv2sf_i"
4663 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4664 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4665 "TARGET_SHMEDIA_FPU"
4667 "TARGET_SHMEDIA_FPU && reload_completed"
4668 [(set (match_dup 0) (match_dup 1))]
4671 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4672 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4675 (define_expand "movv2sf"
4676 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4677 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4678 "TARGET_SHMEDIA_FPU"
4681 if (prepare_move_operands (operands, V2SFmode))
4685 (define_expand "addv2sf3"
4686 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4688 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4689 "TARGET_SHMEDIA_FPU"
4692 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4696 (define_expand "subv2sf3"
4697 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4698 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4699 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4700 "TARGET_SHMEDIA_FPU"
4703 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4707 (define_expand "mulv2sf3"
4708 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4709 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4710 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4711 "TARGET_SHMEDIA_FPU"
4714 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4718 (define_expand "divv2sf3"
4719 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SHMEDIA_FPU"
4725 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4729 (define_insn_and_split "*movv4sf_i"
4730 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4731 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4732 "TARGET_SHMEDIA_FPU"
4734 "&& reload_completed"
4740 for (i = 0; i < 4/2; i++)
4744 if (GET_CODE (operands[0]) == MEM)
4745 x = gen_rtx_MEM (V2SFmode,
4746 plus_constant (XEXP (operands[0], 0),
4747 i * GET_MODE_SIZE (V2SFmode)));
4749 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4751 if (GET_CODE (operands[1]) == MEM)
4752 y = gen_rtx_MEM (V2SFmode,
4753 plus_constant (XEXP (operands[1], 0),
4754 i * GET_MODE_SIZE (V2SFmode)));
4756 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4758 emit_insn (gen_movv2sf_i (x, y));
4763 [(set_attr "length" "8")])
4765 (define_expand "movv4sf"
4766 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4767 (match_operand:V4SF 1 "general_operand" ""))]
4768 "TARGET_SHMEDIA_FPU"
4771 if (prepare_move_operands (operands, V4SFmode))
4775 (define_insn_and_split "*movv16sf_i"
4776 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4777 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4778 "TARGET_SHMEDIA_FPU"
4780 "&& reload_completed"
4786 for (i = 0; i < 16/2; i++)
4790 if (GET_CODE (operands[0]) == MEM)
4791 x = gen_rtx_MEM (V2SFmode,
4792 plus_constant (XEXP (operands[0], 0),
4793 i * GET_MODE_SIZE (V2SFmode)));
4796 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4800 if (GET_CODE (operands[1]) == MEM)
4801 y = gen_rtx_MEM (V2SFmode,
4802 plus_constant (XEXP (operands[1], 0),
4803 i * GET_MODE_SIZE (V2SFmode)));
4806 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4810 emit_insn (gen_movv2sf_i (x, y));
4815 [(set_attr "length" "32")])
4817 (define_expand "movv16sf"
4818 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4819 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4820 "TARGET_SHMEDIA_FPU"
4823 if (prepare_move_operands (operands, V16SFmode))
4827 (define_insn "movsf_media"
4828 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4829 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4831 && (register_operand (operands[0], SFmode)
4832 || sh_register_operand (operands[1], SFmode))"
4843 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4845 (define_insn "movsf_media_nofpu"
4846 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4847 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4849 && (register_operand (operands[0], SFmode)
4850 || sh_register_operand (operands[1], SFmode))"
4856 [(set_attr "type" "arith_media,*,load_media,store_media")])
4859 [(set (match_operand:SF 0 "arith_reg_operand" "")
4860 (match_operand:SF 1 "immediate_operand" ""))]
4861 "TARGET_SHMEDIA && reload_completed
4862 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4863 [(set (match_dup 3) (match_dup 2))]
4867 REAL_VALUE_TYPE value;
4869 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4870 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4871 operands[2] = GEN_INT (values);
4873 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4876 (define_insn "movsf_i"
4877 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4878 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4881 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4882 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4883 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4884 && (arith_reg_operand (operands[0], SFmode)
4885 || arith_reg_operand (operands[1], SFmode))"
4894 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4896 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4897 ;; update_flow_info would not know where to put REG_EQUAL notes
4898 ;; when the destination changes mode.
4899 (define_insn "movsf_ie"
4900 [(set (match_operand:SF 0 "general_movdst_operand"
4901 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4902 (match_operand:SF 1 "general_movsrc_operand"
4903 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4904 (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"))
4905 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4908 && (arith_reg_operand (operands[0], SFmode)
4909 || arith_reg_operand (operands[1], SFmode)
4910 || arith_reg_operand (operands[3], SImode)
4911 || (fpul_operand (operands[0], SFmode)
4912 && memory_operand (operands[1], SFmode)
4913 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4914 || (fpul_operand (operands[1], SFmode)
4915 && memory_operand (operands[0], SFmode)
4916 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4936 ! move optimized away"
4937 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4938 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4939 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4940 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4941 (const_string "single")
4942 (const_string "none")))])
4945 [(set (match_operand:SF 0 "register_operand" "")
4946 (match_operand:SF 1 "register_operand" ""))
4947 (use (match_operand:PSI 2 "fpscr_operand" ""))
4948 (clobber (reg:SI FPUL_REG))]
4950 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4952 (clobber (scratch:SI))])
4953 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4955 (clobber (scratch:SI))])]
4958 (define_expand "movsf"
4959 [(set (match_operand:SF 0 "general_movdst_operand" "")
4960 (match_operand:SF 1 "general_movsrc_operand" ""))]
4964 if (prepare_move_operands (operands, SFmode))
4968 if (TARGET_SHMEDIA_FPU)
4969 emit_insn (gen_movsf_media (operands[0], operands[1]));
4971 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4976 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4981 (define_insn "mov_nop"
4982 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4985 [(set_attr "length" "0")
4986 (set_attr "type" "nil")])
4988 (define_expand "reload_insf"
4989 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4990 (match_operand:SF 1 "immediate_operand" "FQ"))
4991 (use (reg:PSI FPSCR_REG))
4992 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4996 (define_expand "reload_insi"
4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4999 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5003 (define_insn "*movsi_y"
5004 [(set (match_operand:SI 0 "register_operand" "=y,y")
5005 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5006 (clobber (match_scratch:SI 2 "=&z,r"))]
5008 && (reload_in_progress || reload_completed)"
5010 [(set_attr "length" "4")
5011 (set_attr "type" "pcload,move")])
5014 [(set (match_operand:SI 0 "register_operand" "")
5015 (match_operand:SI 1 "immediate_operand" ""))
5016 (clobber (match_operand:SI 2 "register_operand" ""))]
5018 [(set (match_dup 2) (match_dup 1))
5019 (set (match_dup 0) (match_dup 2))]
5023 [(set (match_operand:SI 0 "register_operand" "")
5024 (match_operand:SI 1 "memory_operand" ""))
5025 (clobber (reg:SI R0_REG))]
5027 [(set (match_dup 0) (match_dup 1))]
5030 ;; ------------------------------------------------------------------------
5031 ;; Define the real conditional branch instructions.
5032 ;; ------------------------------------------------------------------------
5034 (define_insn "branch_true"
5035 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5036 (label_ref (match_operand 0 "" ""))
5039 "* return output_branch (1, insn, operands);"
5040 [(set_attr "type" "cbranch")])
5042 (define_insn "branch_false"
5043 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5044 (label_ref (match_operand 0 "" ""))
5047 "* return output_branch (0, insn, operands);"
5048 [(set_attr "type" "cbranch")])
5050 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5051 ;; which destination is too far away.
5052 ;; The const_int_operand is distinct for each branch target; it avoids
5053 ;; unwanted matches with redundant_insn.
5054 (define_insn "block_branch_redirect"
5055 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5058 [(set_attr "length" "0")])
5060 ;; This one has the additional purpose to record a possible scratch register
5061 ;; for the following branch.
5062 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5063 ;; because the insn then might be deemed dead and deleted. And we can't
5064 ;; make the use in the jump insn explicit because that would disable
5065 ;; delay slot scheduling from the target.
5066 (define_insn "indirect_jump_scratch"
5067 [(set (match_operand:SI 0 "register_operand" "=r")
5068 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5069 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5072 [(set_attr "length" "0")])
5074 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5075 ;; being pulled into the delay slot of a condbranch that has been made to
5076 ;; jump around the unconditional jump because it was out of range.
5077 (define_insn "stuff_delay_slot"
5079 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5080 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5083 [(set_attr "length" "0")
5084 (set_attr "cond_delay_slot" "yes")])
5086 ;; Conditional branch insns
5088 (define_expand "beq_media"
5090 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5091 (match_operand:DI 2 "arith_operand" "r,I06"))
5092 (label_ref:DI (match_operand 0 "" ""))
5097 (define_insn "*beq_media_i"
5099 (if_then_else (match_operator 3 "equality_comparison_operator"
5100 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5101 (match_operand:DI 2 "arith_operand" "r,I06")])
5102 (match_operand:DI 0 "target_operand" "b,b")
5108 [(set_attr "type" "cbranch_media")])
5110 (define_expand "bne_media"
5112 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5113 (match_operand:DI 2 "arith_operand" "r,I06"))
5114 (label_ref:DI (match_operand 0 "" ""))
5119 (define_expand "bgt_media"
5121 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5122 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5123 (label_ref:DI (match_operand 0 "" ""))
5128 (define_expand "bge_media"
5130 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5131 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5132 (label_ref:DI (match_operand 0 "" ""))
5137 (define_expand "bgtu_media"
5139 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5140 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5141 (label_ref:DI (match_operand 0 "" ""))
5146 (define_expand "bgeu_media"
5148 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5149 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5150 (label_ref:DI (match_operand 0 "" ""))
5155 (define_insn "*bgt_media_i"
5157 (if_then_else (match_operator 3 "greater_comparison_operator"
5158 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5159 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5160 (match_operand:DI 0 "target_operand" "b")
5163 "b%o3%' %N1, %N2, %0"
5164 [(set_attr "type" "cbranch_media")])
5166 ;; These are only needed to make invert_jump() happy.
5167 (define_insn "*blt_media_i"
5169 (if_then_else (match_operator 3 "less_comparison_operator"
5170 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5171 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5172 (match_operand:DI 0 "target_operand" "b")
5175 "b%o3%' %N2, %N1, %0"
5176 [(set_attr "type" "cbranch_media")])
5178 (define_expand "beq"
5180 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5181 (label_ref (match_operand 0 "" ""))
5188 if (GET_MODE (sh_compare_op0) != DImode)
5190 rtx tmp = gen_reg_rtx (DImode);
5192 emit_insn (gen_seq (tmp));
5193 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5197 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5198 emit_jump_insn (gen_beq_media (operands[0],
5199 sh_compare_op0, sh_compare_op1));
5203 from_compare (operands, EQ);
5206 (define_expand "bne"
5208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5209 (label_ref (match_operand 0 "" ""))
5216 if (GET_MODE (sh_compare_op0) != DImode)
5218 rtx tmp = gen_reg_rtx (DImode);
5220 emit_insn (gen_seq (tmp));
5221 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5225 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5226 emit_jump_insn (gen_bne_media (operands[0],
5227 sh_compare_op0, sh_compare_op1));
5231 from_compare (operands, EQ);
5234 (define_expand "bgt"
5236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5237 (label_ref (match_operand 0 "" ""))
5244 if (GET_MODE (sh_compare_op0) != DImode)
5246 rtx tmp = gen_reg_rtx (DImode);
5248 emit_insn (gen_sgt (tmp));
5249 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5253 if (sh_compare_op0 != const0_rtx)
5254 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5255 if (sh_compare_op1 != const0_rtx)
5256 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5257 emit_jump_insn (gen_bgt_media (operands[0],
5258 sh_compare_op0, sh_compare_op1));
5262 from_compare (operands, GT);
5265 (define_expand "blt"
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5275 if (GET_MODE (sh_compare_op0) != DImode)
5277 rtx tmp = gen_reg_rtx (DImode);
5279 emit_insn (gen_slt (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288 emit_jump_insn (gen_bgt_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5293 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5295 rtx tmp = sh_compare_op0;
5296 sh_compare_op0 = sh_compare_op1;
5297 sh_compare_op1 = tmp;
5298 emit_insn (gen_bgt (operands[0]));
5301 from_compare (operands, GE);
5304 (define_expand "ble"
5306 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5307 (label_ref (match_operand 0 "" ""))
5314 if (GET_MODE (sh_compare_op0) != DImode)
5316 rtx tmp = gen_reg_rtx (DImode);
5318 emit_insn (gen_sle (tmp));
5319 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5323 if (sh_compare_op0 != const0_rtx)
5324 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5325 if (sh_compare_op1 != const0_rtx)
5326 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5327 emit_jump_insn (gen_bge_media (operands[0],
5328 sh_compare_op1, sh_compare_op0));
5334 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5336 rtx tmp = sh_compare_op0;
5337 sh_compare_op0 = sh_compare_op1;
5338 sh_compare_op1 = tmp;
5339 emit_insn (gen_bge (operands[0]));
5342 from_compare (operands, GT);
5345 (define_expand "bge"
5347 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5348 (label_ref (match_operand 0 "" ""))
5355 if (GET_MODE (sh_compare_op0) != DImode)
5357 rtx tmp = gen_reg_rtx (DImode);
5359 emit_insn (gen_sge (tmp));
5360 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5364 if (sh_compare_op0 != const0_rtx)
5365 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5366 if (sh_compare_op1 != const0_rtx)
5367 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5368 emit_jump_insn (gen_bge_media (operands[0],
5369 sh_compare_op0, sh_compare_op1));
5375 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5377 rtx tmp = sh_compare_op0;
5378 sh_compare_op0 = sh_compare_op1;
5379 sh_compare_op1 = tmp;
5380 emit_insn (gen_ble (operands[0]));
5383 from_compare (operands, GE);
5386 (define_expand "bgtu"
5388 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5389 (label_ref (match_operand 0 "" ""))
5396 if (sh_compare_op0 != const0_rtx)
5397 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5398 if (sh_compare_op1 != const0_rtx)
5399 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5400 emit_jump_insn (gen_bgtu_media (operands[0],
5401 sh_compare_op0, sh_compare_op1));
5405 from_compare (operands, GTU);
5408 (define_expand "bltu"
5410 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5411 (label_ref (match_operand 0 "" ""))
5418 if (sh_compare_op0 != const0_rtx)
5419 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5420 if (sh_compare_op1 != const0_rtx)
5421 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5422 emit_jump_insn (gen_bgtu_media (operands[0],
5423 sh_compare_op1, sh_compare_op0));
5427 from_compare (operands, GEU);
5430 (define_expand "bgeu"
5432 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5433 (label_ref (match_operand 0 "" ""))
5440 if (sh_compare_op0 != const0_rtx)
5441 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5442 if (sh_compare_op1 != const0_rtx)
5443 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5444 emit_jump_insn (gen_bgeu_media (operands[0],
5445 sh_compare_op0, sh_compare_op1));
5449 from_compare (operands, GEU);
5452 (define_expand "bleu"
5454 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5455 (label_ref (match_operand 0 "" ""))
5462 if (sh_compare_op0 != const0_rtx)
5463 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5464 if (sh_compare_op1 != const0_rtx)
5465 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5466 emit_jump_insn (gen_bgeu_media (operands[0],
5467 sh_compare_op1, sh_compare_op0));
5471 from_compare (operands, GTU);
5474 (define_expand "bunordered"
5475 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5477 (if_then_else (ne (match_dup 1) (const_int 0))
5478 (label_ref:DI (match_operand 0 "" ""))
5483 operands[1] = gen_reg_rtx (DImode);
5484 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5485 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5488 ;; ------------------------------------------------------------------------
5489 ;; Jump and linkage insns
5490 ;; ------------------------------------------------------------------------
5492 (define_insn "jump_compact"
5494 (label_ref (match_operand 0 "" "")))]
5498 /* The length is 16 if the delay slot is unfilled. */
5499 if (get_attr_length(insn) > 4)
5500 return output_far_jump(insn, operands[0]);
5502 return \"bra %l0%#\";
5504 [(set_attr "type" "jump")
5505 (set_attr "needs_delay_slot" "yes")])
5507 ;; ??? It would be much saner to explicitly use the scratch register
5508 ;; in the jump insn, and have indirect_jump_scratch only set it,
5509 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5510 ;; from the target then, as it uses simplejump_p.
5511 ;;(define_insn "jump_compact_far"
5513 ;; (label_ref (match_operand 0 "" "")))
5514 ;; (use (match_operand 1 "register_operand" "r")]
5516 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5517 ;; [(set_attr "type" "jump")
5518 ;; (set_attr "needs_delay_slot" "yes")])
5520 (define_insn "jump_media"
5522 (match_operand:DI 0 "target_operand" "b"))]
5525 [(set_attr "type" "jump_media")])
5527 (define_expand "jump"
5529 (label_ref (match_operand 0 "" "")))]
5534 emit_jump_insn (gen_jump_compact (operands[0]));
5535 else if (TARGET_SHMEDIA)
5537 if (reload_in_progress || reload_completed)
5539 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5545 (define_insn "force_mode_for_call"
5546 [(use (reg:PSI FPSCR_REG))]
5549 [(set_attr "length" "0")
5550 (set (attr "fp_mode")
5551 (if_then_else (eq_attr "fpu_single" "yes")
5552 (const_string "single") (const_string "double")))])
5554 (define_insn "calli"
5555 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5556 (match_operand 1 "" ""))
5557 (use (reg:PSI FPSCR_REG))
5558 (clobber (reg:SI PR_REG))]
5561 [(set_attr "type" "call")
5562 (set (attr "fp_mode")
5563 (if_then_else (eq_attr "fpu_single" "yes")
5564 (const_string "single") (const_string "double")))
5565 (set_attr "needs_delay_slot" "yes")])
5567 ;; This is a pc-rel call, using bsrf, for use with PIC.
5569 (define_insn "calli_pcrel"
5570 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5571 (match_operand 1 "" ""))
5572 (use (reg:PSI FPSCR_REG))
5573 (use (reg:SI PIC_REG))
5574 (use (match_operand 2 "" ""))
5575 (clobber (reg:SI PR_REG))]
5578 [(set_attr "type" "call")
5579 (set (attr "fp_mode")
5580 (if_then_else (eq_attr "fpu_single" "yes")
5581 (const_string "single") (const_string "double")))
5582 (set_attr "needs_delay_slot" "yes")])
5584 (define_insn_and_split "call_pcrel"
5585 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5586 (match_operand 1 "" ""))
5587 (use (reg:PSI FPSCR_REG))
5588 (use (reg:SI PIC_REG))
5589 (clobber (reg:SI PR_REG))
5590 (clobber (match_scratch:SI 2 "=r"))]
5597 rtx lab = PATTERN (gen_call_site ());
5599 if (SYMBOL_REF_LOCAL_P (operands[0]))
5600 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5602 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5603 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5606 [(set_attr "type" "call")
5607 (set (attr "fp_mode")
5608 (if_then_else (eq_attr "fpu_single" "yes")
5609 (const_string "single") (const_string "double")))
5610 (set_attr "needs_delay_slot" "yes")])
5612 (define_insn "call_compact"
5613 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5614 (match_operand 1 "" ""))
5615 (match_operand 2 "immediate_operand" "n")
5616 (use (reg:SI R0_REG))
5617 (use (reg:SI R1_REG))
5618 (use (reg:PSI FPSCR_REG))
5619 (clobber (reg:SI PR_REG))]
5620 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
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")])
5628 (define_insn "call_compact_rettramp"
5629 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5630 (match_operand 1 "" ""))
5631 (match_operand 2 "immediate_operand" "n")
5632 (use (reg:SI R0_REG))
5633 (use (reg:SI R1_REG))
5634 (use (reg:PSI FPSCR_REG))
5635 (clobber (reg:SI R10_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_media"
5646 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5647 (match_operand 1 "" ""))
5648 (clobber (reg:DI PR_MEDIA_REG))]
5651 [(set_attr "type" "jump_media")])
5653 (define_insn "call_valuei"
5654 [(set (match_operand 0 "" "=rf")
5655 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5656 (match_operand 2 "" "")))
5657 (use (reg:PSI FPSCR_REG))
5658 (clobber (reg:SI PR_REG))]
5661 [(set_attr "type" "call")
5662 (set (attr "fp_mode")
5663 (if_then_else (eq_attr "fpu_single" "yes")
5664 (const_string "single") (const_string "double")))
5665 (set_attr "needs_delay_slot" "yes")])
5667 (define_insn "call_valuei_pcrel"
5668 [(set (match_operand 0 "" "=rf")
5669 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5670 (match_operand 2 "" "")))
5671 (use (reg:PSI FPSCR_REG))
5672 (use (reg:SI PIC_REG))
5673 (use (match_operand 3 "" ""))
5674 (clobber (reg:SI PR_REG))]
5677 [(set_attr "type" "call")
5678 (set (attr "fp_mode")
5679 (if_then_else (eq_attr "fpu_single" "yes")
5680 (const_string "single") (const_string "double")))
5681 (set_attr "needs_delay_slot" "yes")])
5683 (define_insn_and_split "call_value_pcrel"
5684 [(set (match_operand 0 "" "=rf")
5685 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5686 (match_operand 2 "" "")))
5687 (use (reg:PSI FPSCR_REG))
5688 (use (reg:SI PIC_REG))
5689 (clobber (reg:SI PR_REG))
5690 (clobber (match_scratch:SI 3 "=r"))]
5697 rtx lab = PATTERN (gen_call_site ());
5699 if (SYMBOL_REF_LOCAL_P (operands[1]))
5700 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5702 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5703 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5707 [(set_attr "type" "call")
5708 (set (attr "fp_mode")
5709 (if_then_else (eq_attr "fpu_single" "yes")
5710 (const_string "single") (const_string "double")))
5711 (set_attr "needs_delay_slot" "yes")])
5713 (define_insn "call_value_compact"
5714 [(set (match_operand 0 "" "=rf")
5715 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5716 (match_operand 2 "" "")))
5717 (match_operand 3 "immediate_operand" "n")
5718 (use (reg:SI R0_REG))
5719 (use (reg:SI R1_REG))
5720 (use (reg:PSI FPSCR_REG))
5721 (clobber (reg:SI PR_REG))]
5722 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5724 [(set_attr "type" "call")
5725 (set (attr "fp_mode")
5726 (if_then_else (eq_attr "fpu_single" "yes")
5727 (const_string "single") (const_string "double")))
5728 (set_attr "needs_delay_slot" "yes")])
5730 (define_insn "call_value_compact_rettramp"
5731 [(set (match_operand 0 "" "=rf")
5732 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5733 (match_operand 2 "" "")))
5734 (match_operand 3 "immediate_operand" "n")
5735 (use (reg:SI R0_REG))
5736 (use (reg:SI R1_REG))
5737 (use (reg:PSI FPSCR_REG))
5738 (clobber (reg:SI R10_REG))
5739 (clobber (reg:SI PR_REG))]
5740 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5742 [(set_attr "type" "call")
5743 (set (attr "fp_mode")
5744 (if_then_else (eq_attr "fpu_single" "yes")
5745 (const_string "single") (const_string "double")))
5746 (set_attr "needs_delay_slot" "yes")])
5748 (define_insn "call_value_media"
5749 [(set (match_operand 0 "" "=rf")
5750 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5751 (match_operand 2 "" "")))
5752 (clobber (reg:DI PR_MEDIA_REG))]
5755 [(set_attr "type" "jump_media")])
5757 (define_expand "call"
5758 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5759 (match_operand 1 "" ""))
5760 (match_operand 2 "" "")
5761 (use (reg:PSI FPSCR_REG))
5762 (clobber (reg:SI PR_REG))])]
5768 operands[0] = XEXP (operands[0], 0);
5769 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5771 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5773 rtx reg = gen_reg_rtx (Pmode);
5775 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5780 operands[0] = gen_sym2PIC (operands[0]);
5781 PUT_MODE (operands[0], Pmode);
5784 if (GET_MODE (operands[0]) == SImode)
5786 if (GET_CODE (operands[0]) == REG)
5787 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5788 else if (GET_CODE (operands[0]) == SUBREG)
5790 operands[0] = SUBREG_REG (operands[0]);
5791 if (GET_MODE (operands[0]) != DImode)
5792 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5796 operands[0] = shallow_copy_rtx (operands[0]);
5797 PUT_MODE (operands[0], DImode);
5800 if (! target_reg_operand (operands[0], DImode))
5801 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5802 emit_call_insn (gen_call_media (operands[0], operands[1]));
5805 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5807 rtx cookie_rtx = operands[2];
5808 long cookie = INTVAL (cookie_rtx);
5809 rtx func = XEXP (operands[0], 0);
5814 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5816 rtx reg = gen_reg_rtx (Pmode);
5818 emit_insn (gen_symGOTPLT2reg (reg, func));
5822 func = legitimize_pic_address (func, Pmode, 0);
5825 r0 = gen_rtx_REG (SImode, R0_REG);
5826 r1 = gen_rtx_REG (SImode, R1_REG);
5828 /* Since such a call function may use all call-clobbered
5829 registers, we force a mode switch earlier, so that we don't
5830 run out of registers when adjusting fpscr for the call. */
5831 emit_insn (gen_force_mode_for_call ());
5833 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5836 rtx reg = gen_reg_rtx (Pmode);
5838 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5841 operands[0] = force_reg (SImode, operands[0]);
5843 emit_move_insn (r0, func);
5844 emit_move_insn (r1, cookie_rtx);
5846 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5847 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5850 emit_call_insn (gen_call_compact (operands[0], operands[1],
5855 else if (TARGET_SHCOMPACT && flag_pic
5856 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5857 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5859 rtx reg = gen_reg_rtx (Pmode);
5861 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5862 XEXP (operands[0], 0) = reg;
5864 if (flag_pic && TARGET_SH2
5865 && GET_CODE (operands[0]) == MEM
5866 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5868 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5873 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5874 operands[1] = operands[2];
5877 emit_call_insn (gen_calli (operands[0], operands[1]));
5881 (define_insn "call_pop_compact"
5882 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5883 (match_operand 1 "" ""))
5884 (match_operand 2 "immediate_operand" "n")
5885 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5886 (match_operand 3 "immediate_operand" "n")))
5887 (use (reg:SI R0_REG))
5888 (use (reg:SI R1_REG))
5889 (use (reg:PSI FPSCR_REG))
5890 (clobber (reg:SI PR_REG))]
5891 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5893 [(set_attr "type" "call")
5894 (set (attr "fp_mode")
5895 (if_then_else (eq_attr "fpu_single" "yes")
5896 (const_string "single") (const_string "double")))
5897 (set_attr "needs_delay_slot" "yes")])
5899 (define_insn "call_pop_compact_rettramp"
5900 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5901 (match_operand 1 "" ""))
5902 (match_operand 2 "immediate_operand" "n")
5903 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5904 (match_operand 3 "immediate_operand" "n")))
5905 (use (reg:SI R0_REG))
5906 (use (reg:SI R1_REG))
5907 (use (reg:PSI FPSCR_REG))
5908 (clobber (reg:SI R10_REG))
5909 (clobber (reg:SI PR_REG))]
5910 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5912 [(set_attr "type" "call")
5913 (set (attr "fp_mode")
5914 (if_then_else (eq_attr "fpu_single" "yes")
5915 (const_string "single") (const_string "double")))
5916 (set_attr "needs_delay_slot" "yes")])
5918 (define_expand "call_pop"
5919 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5920 (match_operand 1 "" ""))
5921 (match_operand 2 "" "")
5922 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5923 (match_operand 3 "" "")))])]
5927 if (operands[2] && INTVAL (operands[2]))
5929 rtx cookie_rtx = operands[2];
5930 long cookie = INTVAL (cookie_rtx);
5931 rtx func = XEXP (operands[0], 0);
5936 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5938 rtx reg = gen_reg_rtx (Pmode);
5940 emit_insn (gen_symGOTPLT2reg (reg, func));
5944 func = legitimize_pic_address (func, Pmode, 0);
5947 r0 = gen_rtx_REG (SImode, R0_REG);
5948 r1 = gen_rtx_REG (SImode, R1_REG);
5950 /* Since such a call function may use all call-clobbered
5951 registers, we force a mode switch earlier, so that we don't
5952 run out of registers when adjusting fpscr for the call. */
5953 emit_insn (gen_force_mode_for_call ());
5955 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5958 rtx reg = gen_reg_rtx (Pmode);
5960 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5963 operands[0] = force_reg (SImode, operands[0]);
5965 emit_move_insn (r0, func);
5966 emit_move_insn (r1, cookie_rtx);
5968 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5969 emit_call_insn (gen_call_pop_compact_rettramp
5970 (operands[0], operands[1], operands[2], operands[3]));
5972 emit_call_insn (gen_call_pop_compact
5973 (operands[0], operands[1], operands[2], operands[3]));
5981 (define_expand "call_value"
5982 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5983 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5984 (match_operand 2 "" "")))
5985 (match_operand 3 "" "")
5986 (use (reg:PSI FPSCR_REG))
5987 (clobber (reg:SI PR_REG))])]
5993 operands[1] = XEXP (operands[1], 0);
5994 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5996 if (! SYMBOL_REF_LOCAL_P (operands[1]))
5998 rtx reg = gen_reg_rtx (Pmode);
6000 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6005 operands[1] = gen_sym2PIC (operands[1]);
6006 PUT_MODE (operands[1], Pmode);
6009 if (GET_MODE (operands[1]) == SImode)
6011 if (GET_CODE (operands[1]) == REG)
6012 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6013 else if (GET_CODE (operands[1]) == SUBREG)
6015 operands[1] = SUBREG_REG (operands[1]);
6016 if (GET_MODE (operands[1]) != DImode)
6017 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6021 operands[1] = shallow_copy_rtx (operands[1]);
6022 PUT_MODE (operands[1], DImode);
6025 if (! target_reg_operand (operands[1], DImode))
6026 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6027 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6031 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6033 rtx cookie_rtx = operands[3];
6034 long cookie = INTVAL (cookie_rtx);
6035 rtx func = XEXP (operands[1], 0);
6040 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6042 rtx reg = gen_reg_rtx (Pmode);
6044 emit_insn (gen_symGOTPLT2reg (reg, func));
6048 func = legitimize_pic_address (func, Pmode, 0);
6051 r0 = gen_rtx_REG (SImode, R0_REG);
6052 r1 = gen_rtx_REG (SImode, R1_REG);
6054 /* Since such a call function may use all call-clobbered
6055 registers, we force a mode switch earlier, so that we don't
6056 run out of registers when adjusting fpscr for the call. */
6057 emit_insn (gen_force_mode_for_call ());
6059 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6062 rtx reg = gen_reg_rtx (Pmode);
6064 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6067 operands[1] = force_reg (SImode, operands[1]);
6069 emit_move_insn (r0, func);
6070 emit_move_insn (r1, cookie_rtx);
6072 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6073 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6078 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6079 operands[2], operands[3]));
6083 else if (TARGET_SHCOMPACT && flag_pic
6084 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6085 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6087 rtx reg = gen_reg_rtx (Pmode);
6089 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6090 XEXP (operands[1], 0) = reg;
6092 if (flag_pic && TARGET_SH2
6093 && GET_CODE (operands[1]) == MEM
6094 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6096 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6101 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6103 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6107 (define_insn "sibcalli"
6108 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6109 (match_operand 1 "" ""))
6110 (use (reg:PSI FPSCR_REG))
6114 [(set_attr "needs_delay_slot" "yes")
6115 (set (attr "fp_mode")
6116 (if_then_else (eq_attr "fpu_single" "yes")
6117 (const_string "single") (const_string "double")))
6118 (set_attr "type" "jump_ind")])
6120 (define_insn "sibcalli_pcrel"
6121 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6122 (match_operand 1 "" ""))
6123 (use (match_operand 2 "" ""))
6124 (use (reg:PSI FPSCR_REG))
6128 [(set_attr "needs_delay_slot" "yes")
6129 (set (attr "fp_mode")
6130 (if_then_else (eq_attr "fpu_single" "yes")
6131 (const_string "single") (const_string "double")))
6132 (set_attr "type" "jump_ind")])
6134 (define_insn_and_split "sibcall_pcrel"
6135 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6136 (match_operand 1 "" ""))
6137 (use (reg:PSI FPSCR_REG))
6138 (clobber (match_scratch:SI 2 "=k"))
6146 rtx lab = PATTERN (gen_call_site ());
6149 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6150 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6152 SIBLING_CALL_P (call_insn) = 1;
6155 [(set_attr "needs_delay_slot" "yes")
6156 (set (attr "fp_mode")
6157 (if_then_else (eq_attr "fpu_single" "yes")
6158 (const_string "single") (const_string "double")))
6159 (set_attr "type" "jump_ind")])
6161 (define_insn "sibcall_compact"
6162 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6163 (match_operand 1 "" ""))
6165 (use (match_operand:SI 2 "register_operand" "z,x"))
6166 (use (reg:SI R1_REG))
6167 (use (reg:PSI FPSCR_REG))
6168 ;; We want to make sure the `x' above will only match MACH_REG
6169 ;; because sibcall_epilogue may clobber MACL_REG.
6170 (clobber (reg:SI MACL_REG))]
6174 jmp @%0\\n sts %2, r0"
6175 [(set_attr "needs_delay_slot" "yes,no")
6176 (set_attr "length" "2,4")
6177 (set (attr "fp_mode") (const_string "single"))
6178 (set_attr "type" "jump_ind")])
6180 (define_insn "sibcall_media"
6181 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6182 (match_operand 1 "" ""))
6183 (use (reg:SI PR_MEDIA_REG))
6187 [(set_attr "type" "jump_media")])
6189 (define_expand "sibcall"
6191 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6192 (match_operand 1 "" ""))
6193 (match_operand 2 "" "")
6194 (use (reg:PSI FPSCR_REG))
6201 operands[0] = XEXP (operands[0], 0);
6202 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6204 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6206 rtx reg = gen_reg_rtx (Pmode);
6208 /* We must not use GOTPLT for sibcalls, because PIC_REG
6209 must be restored before the PLT code gets to run. */
6210 emit_insn (gen_symGOT2reg (reg, operands[0]));
6215 operands[0] = gen_sym2PIC (operands[0]);
6216 PUT_MODE (operands[0], Pmode);
6219 if (GET_MODE (operands[0]) == SImode)
6221 if (GET_CODE (operands[0]) == REG)
6222 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6223 else if (GET_CODE (operands[0]) == SUBREG)
6225 operands[0] = SUBREG_REG (operands[0]);
6226 if (GET_MODE (operands[0]) != DImode)
6227 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6231 operands[0] = shallow_copy_rtx (operands[0]);
6232 PUT_MODE (operands[0], DImode);
6235 if (! target_reg_operand (operands[0], DImode))
6236 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6237 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6240 else if (TARGET_SHCOMPACT && operands[2]
6241 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6243 rtx cookie_rtx = operands[2];
6244 long cookie = INTVAL (cookie_rtx);
6245 rtx func = XEXP (operands[0], 0);
6250 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6252 rtx reg = gen_reg_rtx (Pmode);
6254 emit_insn (gen_symGOT2reg (reg, func));
6258 func = legitimize_pic_address (func, Pmode, 0);
6261 /* FIXME: if we could tell whether all argument registers are
6262 already taken, we could decide whether to force the use of
6263 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6264 simple way to tell. We could use the CALL_COOKIE, but we
6265 can't currently tell a register used for regular argument
6266 passing from one that is unused. If we leave it up to reload
6267 to decide which register to use, it seems to always choose
6268 R0_REG, which leaves no available registers in SIBCALL_REGS
6269 to hold the address of the trampoline. */
6270 mach = gen_rtx_REG (SImode, MACH_REG);
6271 r1 = gen_rtx_REG (SImode, R1_REG);
6273 /* Since such a call function may use all call-clobbered
6274 registers, we force a mode switch earlier, so that we don't
6275 run out of registers when adjusting fpscr for the call. */
6276 emit_insn (gen_force_mode_for_call ());
6278 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6281 rtx reg = gen_reg_rtx (Pmode);
6283 emit_insn (gen_symGOT2reg (reg, operands[0]));
6286 operands[0] = force_reg (SImode, operands[0]);
6288 /* We don't need a return trampoline, since the callee will
6289 return directly to the upper caller. */
6290 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6292 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6293 cookie_rtx = GEN_INT (cookie);
6296 emit_move_insn (mach, func);
6297 emit_move_insn (r1, cookie_rtx);
6299 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6302 else if (TARGET_SHCOMPACT && flag_pic
6303 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6304 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6306 rtx reg = gen_reg_rtx (Pmode);
6308 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6309 XEXP (operands[0], 0) = reg;
6311 if (flag_pic && TARGET_SH2
6312 && GET_CODE (operands[0]) == MEM
6313 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6314 /* The PLT needs the PIC register, but the epilogue would have
6315 to restore it, so we can only use PC-relative PIC calls for
6316 static functions. */
6317 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6319 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6323 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6325 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6329 (define_expand "sibcall_value"
6330 [(set (match_operand 0 "" "")
6331 (call (match_operand 1 "" "")
6332 (match_operand 2 "" "")))
6333 (match_operand 3 "" "")]
6337 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6341 (define_insn "call_value_pop_compact"
6342 [(set (match_operand 0 "" "=rf")
6343 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6344 (match_operand 2 "" "")))
6345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6346 (match_operand 4 "immediate_operand" "n")))
6347 (match_operand 3 "immediate_operand" "n")
6348 (use (reg:SI R0_REG))
6349 (use (reg:SI R1_REG))
6350 (use (reg:PSI FPSCR_REG))
6351 (clobber (reg:SI PR_REG))]
6352 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6354 [(set_attr "type" "call")
6355 (set (attr "fp_mode")
6356 (if_then_else (eq_attr "fpu_single" "yes")
6357 (const_string "single") (const_string "double")))
6358 (set_attr "needs_delay_slot" "yes")])
6360 (define_insn "call_value_pop_compact_rettramp"
6361 [(set (match_operand 0 "" "=rf")
6362 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6363 (match_operand 2 "" "")))
6364 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6365 (match_operand 4 "immediate_operand" "n")))
6366 (match_operand 3 "immediate_operand" "n")
6367 (use (reg:SI R0_REG))
6368 (use (reg:SI R1_REG))
6369 (use (reg:PSI FPSCR_REG))
6370 (clobber (reg:SI R10_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_expand "call_value_pop"
6381 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6382 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6383 (match_operand 2 "" "")))
6384 (match_operand 3 "" "")
6385 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6386 (match_operand 4 "" "")))])]
6390 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6392 rtx cookie_rtx = operands[3];
6393 long cookie = INTVAL (cookie_rtx);
6394 rtx func = XEXP (operands[1], 0);
6399 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6401 rtx reg = gen_reg_rtx (Pmode);
6403 emit_insn (gen_symGOTPLT2reg (reg, func));
6407 func = legitimize_pic_address (func, Pmode, 0);
6410 r0 = gen_rtx_REG (SImode, R0_REG);
6411 r1 = gen_rtx_REG (SImode, R1_REG);
6413 /* Since such a call function may use all call-clobbered
6414 registers, we force a mode switch earlier, so that we don't
6415 run out of registers when adjusting fpscr for the call. */
6416 emit_insn (gen_force_mode_for_call ());
6418 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6421 rtx reg = gen_reg_rtx (Pmode);
6423 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6426 operands[1] = force_reg (SImode, operands[1]);
6428 emit_move_insn (r0, func);
6429 emit_move_insn (r1, cookie_rtx);
6431 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6432 emit_call_insn (gen_call_value_pop_compact_rettramp
6433 (operands[0], operands[1], operands[2],
6434 operands[3], operands[4]));
6436 emit_call_insn (gen_call_value_pop_compact
6437 (operands[0], operands[1], operands[2],
6438 operands[3], operands[4]));
6446 (define_expand "sibcall_epilogue"
6451 sh_expand_epilogue ();
6452 if (TARGET_SHCOMPACT)
6456 /* If epilogue clobbers r0, preserve it in macl. */
6457 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6458 if ((set = single_set (insn))
6459 && GET_CODE (SET_DEST (set)) == REG
6460 && REGNO (SET_DEST (set)) == R0_REG)
6462 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6463 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6466 /* We can't tell at this point whether the sibcall is a
6467 sibcall_compact and, if it is, whether it uses r0 or
6468 mach as operand 2, so let the instructions that
6469 preserve r0 be optimized away if r0 turns out to be
6471 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6472 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6474 i = emit_move_insn (r0, tmp);
6475 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6483 (define_insn "indirect_jump_compact"
6485 (match_operand:SI 0 "arith_reg_operand" "r"))]
6488 [(set_attr "needs_delay_slot" "yes")
6489 (set_attr "type" "jump_ind")])
6491 (define_expand "indirect_jump"
6493 (match_operand 0 "register_operand" ""))]
6497 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6498 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6501 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6502 ;; which can be present in structured code from indirect jumps which can not
6503 ;; be present in structured code. This allows -fprofile-arcs to work.
6505 ;; For SH1 processors.
6506 (define_insn "casesi_jump_1"
6508 (match_operand:SI 0 "register_operand" "r"))
6509 (use (label_ref (match_operand 1 "" "")))]
6512 [(set_attr "needs_delay_slot" "yes")
6513 (set_attr "type" "jump_ind")])
6515 ;; For all later processors.
6516 (define_insn "casesi_jump_2"
6517 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6518 (label_ref (match_operand 1 "" ""))))
6519 (use (label_ref (match_operand 2 "" "")))]
6521 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6523 [(set_attr "needs_delay_slot" "yes")
6524 (set_attr "type" "jump_ind")])
6526 (define_insn "casesi_jump_media"
6527 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6528 (use (label_ref (match_operand 1 "" "")))]
6531 [(set_attr "type" "jump_media")])
6533 ;; Call subroutine returning any type.
6534 ;; ??? This probably doesn't work.
6536 (define_expand "untyped_call"
6537 [(parallel [(call (match_operand 0 "" "")
6539 (match_operand 1 "" "")
6540 (match_operand 2 "" "")])]
6541 "TARGET_SH2E || TARGET_SHMEDIA"
6546 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6548 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6550 rtx set = XVECEXP (operands[2], 0, i);
6551 emit_move_insn (SET_DEST (set), SET_SRC (set));
6554 /* The optimizer does not know that the call sets the function value
6555 registers we stored in the result block. We avoid problems by
6556 claiming that all hard registers are used and clobbered at this
6558 emit_insn (gen_blockage ());
6563 ;; ------------------------------------------------------------------------
6565 ;; ------------------------------------------------------------------------
6568 [(set (reg:SI T_REG)
6569 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6570 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6573 [(set_attr "type" "arith")])
6580 ;; Load address of a label. This is only generated by the casesi expand,
6581 ;; and by machine_dependent_reorg (fixing up fp moves).
6582 ;; This must use unspec, because this only works for labels that are
6586 [(set (reg:SI R0_REG)
6587 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6590 [(set_attr "in_delay_slot" "no")
6591 (set_attr "type" "arith")])
6593 ;; machine_dependent_reorg will make this a `mova'.
6594 (define_insn "mova_const"
6595 [(set (reg:SI R0_REG)
6596 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6599 [(set_attr "in_delay_slot" "no")
6600 (set_attr "type" "arith")])
6602 (define_expand "GOTaddr2picreg"
6603 [(set (reg:SI R0_REG)
6604 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6606 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6607 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6610 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6611 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6614 operands[1] = gen_datalabel_ref (operands[1]);
6618 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6619 rtx dipic = operands[0];
6620 rtx lab = PATTERN (gen_call_site ());
6623 equiv = operands[1];
6624 operands[1] = gen_rtx_MINUS (DImode,
6628 gen_rtx_MINUS (DImode,
6629 gen_rtx_CONST (DImode,
6632 operands[1] = gen_sym2PIC (operands[1]);
6633 PUT_MODE (operands[1], DImode);
6635 if (GET_MODE (dipic) != DImode)
6636 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6638 if (TARGET_SHMEDIA64)
6639 emit_insn (gen_movdi_const (dipic, operands[1]));
6641 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6643 emit_insn (gen_ptrel (tr, dipic, lab));
6645 if (GET_MODE (operands[0]) != GET_MODE (tr))
6646 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6648 insn = emit_move_insn (operands[0], tr);
6650 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6659 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6660 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6661 UNSPEC_DATALABEL)))]
6662 "TARGET_SHMEDIA && flag_pic
6663 && EXTRA_CONSTRAINT_Csy (operands[1])"
6664 "ptb/u datalabel %1, %0"
6665 [(set_attr "type" "pt_media")
6666 (set_attr "length" "*")])
6668 (define_insn "ptrel"
6669 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6670 (plus:DI (match_operand:DI 1 "register_operand" "r")
6672 (match_operand:DI 2 "" "")]
6674 "%O2: ptrel/u %1, %0"
6675 [(set_attr "type" "ptabs_media")])
6677 (define_expand "builtin_setjmp_receiver"
6678 [(match_operand 0 "" "")]
6682 emit_insn (gen_GOTaddr2picreg ());
6686 (define_expand "call_site"
6687 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6691 static HOST_WIDE_INT i = 0;
6692 operands[0] = GEN_INT (i);
6696 (define_expand "sym_label2reg"
6697 [(set (match_operand:SI 0 "" "")
6700 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6703 (match_operand:SI 2 "" "")
6707 (define_expand "symGOT_load"
6708 [(set (match_dup 2) (match_operand 1 "" ""))
6709 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6710 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6716 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6717 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6721 rtx reg = operands[2];
6723 if (GET_MODE (reg) != DImode)
6724 reg = gen_rtx_SUBREG (DImode, reg, 0);
6727 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6729 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6732 emit_move_insn (operands[2], operands[1]);
6734 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6736 gen_rtx_REG (Pmode, PIC_REG)));
6738 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6740 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6747 (define_expand "sym2GOT"
6748 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6752 (define_expand "symGOT2reg"
6753 [(match_operand 0 "" "") (match_operand 1 "" "")]
6759 gotsym = gen_sym2GOT (operands[1]);
6760 PUT_MODE (gotsym, Pmode);
6761 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6763 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6768 (define_expand "sym2GOTPLT"
6769 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6773 (define_expand "symGOTPLT2reg"
6774 [(match_operand 0 "" "") (match_operand 1 "" "")]
6778 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6782 (define_expand "sym2GOTOFF"
6783 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6787 (define_expand "symGOTOFF2reg"
6788 [(match_operand 0 "" "") (match_operand 1 "" "")]
6792 rtx gotoffsym, insn;
6793 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6795 gotoffsym = gen_sym2GOTOFF (operands[1]);
6796 PUT_MODE (gotoffsym, Pmode);
6797 emit_move_insn (t, gotoffsym);
6798 insn = emit_move_insn (operands[0],
6799 gen_rtx_PLUS (Pmode, t,
6800 gen_rtx_REG (Pmode, PIC_REG)));
6802 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6808 (define_expand "symPLT_label2reg"
6809 [(set (match_operand:SI 0 "" "")
6812 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6816 (match_operand:SI 2 "" "")
6818 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6819 ;; Even though the PIC register is not really used by the call
6820 ;; sequence in which this is expanded, the PLT code assumes the PIC
6821 ;; register is set, so we must not skip its initialization. Since
6822 ;; we only use this expand as part of calling sequences, and never
6823 ;; to take the address of a function, this is the best point to
6824 ;; insert the (use). Using the PLT to take the address of a
6825 ;; function would be wrong, not only because the PLT entry could
6826 ;; then be called from a function that doesn't initialize the PIC
6827 ;; register to the proper GOT, but also because pointers to the
6828 ;; same function might not compare equal, should they be set by
6829 ;; different shared libraries.
6830 (use (reg:SI PIC_REG))]
6834 (define_expand "sym2PIC"
6835 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6839 ;; TLS code generation.
6840 ;; ??? this should be a define_insn_and_split
6841 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6842 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6845 (define_insn "tls_global_dynamic"
6846 [(set (match_operand:SI 0 "register_operand" "=&z")
6847 (unspec:SI [(match_operand:SI 1 "" "")]
6849 (use (reg:PSI FPSCR_REG))
6850 (use (reg:SI PIC_REG))
6851 (clobber (reg:SI PR_REG))
6852 (clobber (scratch:SI))]
6858 \\tmova\\t2f,r0\\n\\
6859 \\tmov.l\\t2f,r1\\n\\
6862 \\tadd\\tr12,r4\\n\\
6866 1:\\t.long\\t%a1@TLSGD\\n\\
6867 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6870 [(set_attr "type" "tls_load")
6871 (set_attr "length" "26")])
6873 (define_insn "tls_local_dynamic"
6874 [(set (match_operand:SI 0 "register_operand" "=&z")
6875 (unspec:SI [(match_operand:SI 1 "" "")]
6877 (use (reg:PSI FPSCR_REG))
6878 (use (reg:SI PIC_REG))
6879 (clobber (reg:SI PR_REG))
6880 (clobber (scratch:SI))]
6886 \\tmova\\t2f,r0\\n\\
6887 \\tmov.l\\t2f,r1\\n\\
6890 \\tadd\\tr12,r4\\n\\
6894 1:\\t.long\\t%a1@TLSLDM\\n\\
6895 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6898 [(set_attr "type" "tls_load")
6899 (set_attr "length" "26")])
6901 (define_expand "sym2DTPOFF"
6902 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6906 (define_expand "symDTPOFF2reg"
6907 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6911 rtx dtpoffsym, insn;
6912 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6914 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6915 PUT_MODE (dtpoffsym, Pmode);
6916 emit_move_insn (t, dtpoffsym);
6917 insn = emit_move_insn (operands[0],
6918 gen_rtx_PLUS (Pmode, t, operands[2]));
6922 (define_expand "sym2GOTTPOFF"
6923 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6927 (define_insn "tls_initial_exec"
6928 [(set (match_operand:SI 0 "register_operand" "=&r")
6929 (unspec:SI [(match_operand:SI 1 "" "")]
6931 (use (reg:SI GBR_REG))
6932 (use (reg:SI PIC_REG))
6933 (clobber (reg:SI R0_REG))]
6939 \\tstc\\tgbr,%0\\n\\
6940 \\tmov.l\\t@(r0,r12),r0\\n\\
6944 1:\\t.long\\t%a1\\n\\
6947 [(set_attr "type" "tls_load")
6948 (set_attr "length" "16")])
6950 (define_expand "sym2TPOFF"
6951 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6955 (define_expand "symTPOFF2reg"
6956 [(match_operand 0 "" "") (match_operand 1 "" "")]
6962 tpoffsym = gen_sym2TPOFF (operands[1]);
6963 PUT_MODE (tpoffsym, Pmode);
6964 insn = emit_move_insn (operands[0], tpoffsym);
6968 (define_insn "load_gbr"
6969 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6970 (use (reg:SI GBR_REG))]
6973 [(set_attr "type" "tls_load")])
6975 ;; case instruction for switch statements.
6977 ;; Operand 0 is index
6978 ;; operand 1 is the minimum bound
6979 ;; operand 2 is the maximum bound - minimum bound + 1
6980 ;; operand 3 is CODE_LABEL for the table;
6981 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6983 (define_expand "casesi"
6984 [(match_operand:SI 0 "arith_reg_operand" "")
6985 (match_operand:SI 1 "arith_reg_operand" "")
6986 (match_operand:SI 2 "arith_reg_operand" "")
6987 (match_operand 3 "" "") (match_operand 4 "" "")]
6991 rtx reg = gen_reg_rtx (SImode);
6992 rtx reg2 = gen_reg_rtx (SImode);
6995 rtx reg = gen_reg_rtx (DImode);
6996 rtx reg2 = gen_reg_rtx (DImode);
6997 rtx reg3 = gen_reg_rtx (DImode);
6998 rtx reg4 = gen_reg_rtx (DImode);
6999 rtx reg5 = gen_reg_rtx (DImode);
7001 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7002 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7003 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7005 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7006 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7007 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7008 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7009 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7010 (DImode, operands[3])));
7011 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7012 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7013 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7017 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7018 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7019 /* If optimizing, casesi_worker depends on the mode of the instruction
7020 before label it 'uses' - operands[3]. */
7021 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7023 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7025 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7027 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7028 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7029 operands[3], but to lab. We will fix this up in
7030 machine_dependent_reorg. */
7035 (define_expand "casesi_0"
7036 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7037 (set (match_dup 4) (minus:SI (match_dup 4)
7038 (match_operand:SI 1 "arith_operand" "")))
7040 (gtu:SI (match_dup 4)
7041 (match_operand:SI 2 "arith_reg_operand" "")))
7043 (if_then_else (ne (reg:SI T_REG)
7045 (label_ref (match_operand 3 "" ""))
7050 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7051 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7052 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7054 (define_insn "casesi_worker_0"
7055 [(set (match_operand:SI 0 "register_operand" "=r,r")
7056 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7057 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7058 (clobber (match_scratch:SI 3 "=X,1"))
7059 (clobber (match_scratch:SI 4 "=&z,z"))]
7064 [(set (match_operand:SI 0 "register_operand" "")
7065 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7066 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7067 (clobber (match_scratch:SI 3 ""))
7068 (clobber (match_scratch:SI 4 ""))]
7069 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7070 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7071 (parallel [(set (match_dup 0)
7072 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7073 (label_ref (match_dup 2))] UNSPEC_CASESI))
7074 (clobber (match_dup 3))])
7075 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7076 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7079 [(set (match_operand:SI 0 "register_operand" "")
7080 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7081 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7082 (clobber (match_scratch:SI 3 ""))
7083 (clobber (match_scratch:SI 4 ""))]
7084 "TARGET_SH2 && reload_completed"
7085 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7086 (parallel [(set (match_dup 0)
7087 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7088 (label_ref (match_dup 2))] UNSPEC_CASESI))
7089 (clobber (match_dup 3))])]
7090 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7092 (define_insn "*casesi_worker"
7093 [(set (match_operand:SI 0 "register_operand" "=r,r")
7094 (unspec:SI [(reg:SI R0_REG)
7095 (match_operand:SI 1 "register_operand" "0,r")
7096 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7097 (clobber (match_scratch:SI 3 "=X,1"))]
7101 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7103 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7106 switch (GET_MODE (diff_vec))
7109 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7111 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7113 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7114 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7115 return \"mov.b @(r0,%1),%0\";
7120 [(set_attr "length" "4")])
7122 (define_insn "casesi_shift_media"
7123 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7124 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7125 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7130 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7132 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7135 switch (GET_MODE (diff_vec))
7138 return \"shlli %1, 2, %0\";
7140 return \"shlli %1, 1, %0\";
7142 if (rtx_equal_p (operands[0], operands[1]))
7144 return \"add %1, r63, %0\";
7149 [(set_attr "type" "arith_media")])
7151 (define_insn "casesi_load_media"
7152 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7153 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7154 (match_operand 2 "arith_reg_operand" "r")
7155 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7159 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7161 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7164 switch (GET_MODE (diff_vec))
7167 return \"ldx.l %1, %2, %0\";
7170 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7171 return \"ldx.uw %1, %2, %0\";
7173 return \"ldx.w %1, %2, %0\";
7175 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7176 return \"ldx.ub %1, %2, %0\";
7177 return \"ldx.b %1, %2, %0\";
7182 [(set_attr "type" "load_media")])
7184 (define_expand "return"
7186 "reload_completed && ! sh_need_epilogue ()"
7191 emit_jump_insn (gen_return_media ());
7195 if (TARGET_SHCOMPACT
7196 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7198 emit_jump_insn (gen_shcompact_return_tramp ());
7203 (define_insn "*return_i"
7205 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7206 && (current_function_args_info.call_cookie
7207 & CALL_COOKIE_RET_TRAMP (1)))
7208 && reload_completed"
7210 [(set_attr "type" "return")
7211 (set_attr "needs_delay_slot" "yes")])
7213 (define_expand "shcompact_return_tramp"
7216 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7219 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7220 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7223 emit_insn (gen_symGOTPLT2reg (reg, sym));
7225 emit_move_insn (reg, sym);
7227 emit_jump_insn (gen_shcompact_return_tramp_i ());
7231 (define_insn "shcompact_return_tramp_i"
7232 [(parallel [(return) (use (reg:SI R0_REG))])]
7234 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7236 [(set_attr "type" "jump_ind")
7237 (set_attr "needs_delay_slot" "yes")])
7239 (define_insn "return_media_i"
7240 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7241 "TARGET_SHMEDIA && reload_completed"
7243 [(set_attr "type" "jump_media")])
7245 (define_insn "return_media_rte"
7247 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7249 [(set_attr "type" "jump_media")])
7251 (define_expand "return_media"
7253 "TARGET_SHMEDIA && reload_completed"
7256 int tr_regno = sh_media_register_for_return ();
7259 if (current_function_interrupt)
7261 emit_jump_insn (gen_return_media_rte ());
7266 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7268 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7271 tr = gen_rtx_REG (DImode, tr_regno);
7272 emit_move_insn (tr, r18);
7275 tr = gen_rtx_REG (DImode, tr_regno);
7277 emit_jump_insn (gen_return_media_i (tr));
7281 (define_insn "shcompact_preserve_incoming_args"
7282 [(set (match_operand:SI 0 "register_operand" "+r")
7283 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7286 [(set_attr "length" "0")])
7288 (define_insn "shcompact_incoming_args"
7289 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7290 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7291 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7292 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7293 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7294 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7295 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7296 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7297 (set (mem:BLK (reg:SI MACL_REG))
7298 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7299 (use (reg:SI R0_REG))
7300 (clobber (reg:SI R0_REG))
7301 (clobber (reg:SI MACL_REG))
7302 (clobber (reg:SI MACH_REG))
7303 (clobber (reg:SI PR_REG))]
7306 [(set_attr "needs_delay_slot" "yes")])
7308 (define_insn "shmedia_save_restore_regs_compact"
7309 [(set (reg:SI SP_REG)
7310 (plus:SI (reg:SI SP_REG)
7311 (match_operand:SI 0 "immediate_operand" "i")))
7312 (use (reg:SI R0_REG))
7313 (clobber (reg:SI PR_REG))]
7315 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7316 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7318 [(set_attr "needs_delay_slot" "yes")])
7320 (define_expand "prologue"
7323 "sh_expand_prologue (); DONE;")
7325 (define_expand "epilogue"
7330 sh_expand_epilogue ();
7331 emit_jump_insn (gen_return ());
7335 (define_expand "eh_return"
7336 [(use (match_operand 0 "register_operand" ""))]
7339 rtx tmp, ra = operands[0];
7341 if (TARGET_SHMEDIA64)
7342 emit_insn (gen_eh_set_ra_di (ra));
7344 emit_insn (gen_eh_set_ra_si (ra));
7349 ;; Clobber the return address on the stack. We can't expand this
7350 ;; until we know where it will be put in the stack frame.
7352 (define_insn "eh_set_ra_si"
7353 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7354 (clobber (match_scratch:SI 1 "=&r"))]
7355 "! TARGET_SHMEDIA64"
7358 (define_insn "eh_set_ra_di"
7359 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7360 (clobber (match_scratch:DI 1 "=&r"))]
7365 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7366 (clobber (match_scratch 1 ""))]
7371 sh_set_return_address (operands[0], operands[1]);
7375 (define_insn "blockage"
7376 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7379 [(set_attr "length" "0")])
7381 ;; ------------------------------------------------------------------------
7383 ;; ------------------------------------------------------------------------
7386 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7387 (eq:SI (reg:SI T_REG) (const_int 1)))]
7390 [(set_attr "type" "arith")])
7392 (define_expand "seq"
7393 [(set (match_operand:SI 0 "arith_reg_operand" "")
7400 if (GET_MODE (operands[0]) != DImode)
7401 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7402 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7403 if (sh_compare_op1 != const0_rtx)
7404 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7405 ? GET_MODE (sh_compare_op0)
7406 : GET_MODE (sh_compare_op1),
7409 switch (GET_MODE (sh_compare_op0))
7412 emit_insn (gen_cmpeqdi_media (operands[0],
7413 sh_compare_op0, sh_compare_op1));
7417 if (! TARGET_SHMEDIA_FPU)
7419 emit_insn (gen_cmpeqsf_media (operands[0],
7420 sh_compare_op0, sh_compare_op1));
7424 if (! TARGET_SHMEDIA_FPU)
7426 emit_insn (gen_cmpeqdf_media (operands[0],
7427 sh_compare_op0, sh_compare_op1));
7435 operands[1] = prepare_scc_operands (EQ);
7438 (define_expand "slt"
7439 [(set (match_operand:SI 0 "arith_reg_operand" "")
7446 if (GET_MODE (operands[0]) != DImode)
7447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7448 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7449 if (sh_compare_op1 != const0_rtx)
7450 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7451 ? GET_MODE (sh_compare_op0)
7452 : GET_MODE (sh_compare_op1),
7455 switch (GET_MODE (sh_compare_op0))
7458 emit_insn (gen_cmpgtdi_media (operands[0],
7459 sh_compare_op1, sh_compare_op0));
7463 if (! TARGET_SHMEDIA_FPU)
7465 emit_insn (gen_cmpgtsf_media (operands[0],
7466 sh_compare_op1, sh_compare_op0));
7470 if (! TARGET_SHMEDIA_FPU)
7472 emit_insn (gen_cmpgtdf_media (operands[0],
7473 sh_compare_op1, sh_compare_op0));
7481 operands[1] = prepare_scc_operands (LT);
7484 (define_expand "sle"
7485 [(match_operand:SI 0 "arith_reg_operand" "")]
7489 rtx tmp = sh_compare_op0;
7493 if (GET_MODE (operands[0]) != DImode)
7494 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7495 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7496 if (sh_compare_op1 != const0_rtx)
7497 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7498 ? GET_MODE (sh_compare_op0)
7499 : GET_MODE (sh_compare_op1),
7502 switch (GET_MODE (sh_compare_op0))
7506 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7508 emit_insn (gen_cmpgtdi_media (tmp,
7509 sh_compare_op0, sh_compare_op1));
7510 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7515 if (! TARGET_SHMEDIA_FPU)
7517 emit_insn (gen_cmpgesf_media (operands[0],
7518 sh_compare_op1, sh_compare_op0));
7522 if (! TARGET_SHMEDIA_FPU)
7524 emit_insn (gen_cmpgedf_media (operands[0],
7525 sh_compare_op1, sh_compare_op0));
7534 sh_compare_op0 = sh_compare_op1;
7535 sh_compare_op1 = tmp;
7536 emit_insn (gen_sge (operands[0]));
7540 (define_expand "sgt"
7541 [(set (match_operand:SI 0 "arith_reg_operand" "")
7548 if (GET_MODE (operands[0]) != DImode)
7549 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7551 if (sh_compare_op1 != const0_rtx)
7552 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7553 ? GET_MODE (sh_compare_op0)
7554 : GET_MODE (sh_compare_op1),
7557 switch (GET_MODE (sh_compare_op0))
7560 emit_insn (gen_cmpgtdi_media (operands[0],
7561 sh_compare_op0, sh_compare_op1));
7565 if (! TARGET_SHMEDIA_FPU)
7567 emit_insn (gen_cmpgtsf_media (operands[0],
7568 sh_compare_op0, sh_compare_op1));
7572 if (! TARGET_SHMEDIA_FPU)
7574 emit_insn (gen_cmpgtdf_media (operands[0],
7575 sh_compare_op0, sh_compare_op1));
7583 operands[1] = prepare_scc_operands (GT);
7586 (define_expand "sge"
7587 [(set (match_operand:SI 0 "arith_reg_operand" "")
7594 if (GET_MODE (operands[0]) != DImode)
7595 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7596 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7597 if (sh_compare_op1 != const0_rtx)
7598 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7599 ? GET_MODE (sh_compare_op0)
7600 : GET_MODE (sh_compare_op1),
7603 switch (GET_MODE (sh_compare_op0))
7607 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7609 emit_insn (gen_cmpgtdi_media (tmp,
7610 sh_compare_op1, sh_compare_op0));
7611 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7616 if (! TARGET_SHMEDIA_FPU)
7618 emit_insn (gen_cmpgesf_media (operands[0],
7619 sh_compare_op0, sh_compare_op1));
7623 if (! TARGET_SHMEDIA_FPU)
7625 emit_insn (gen_cmpgedf_media (operands[0],
7626 sh_compare_op0, sh_compare_op1));
7635 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7639 rtx lab = gen_label_rtx ();
7640 prepare_scc_operands (EQ);
7641 emit_jump_insn (gen_branch_true (lab));
7642 prepare_scc_operands (GT);
7644 emit_insn (gen_movt (operands[0]));
7647 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7650 operands[1] = prepare_scc_operands (GE);
7653 (define_expand "sgtu"
7654 [(set (match_operand:SI 0 "arith_reg_operand" "")
7661 if (GET_MODE (operands[0]) != DImode)
7662 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7663 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7664 if (sh_compare_op1 != const0_rtx)
7665 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7666 ? GET_MODE (sh_compare_op0)
7667 : GET_MODE (sh_compare_op1),
7670 emit_insn (gen_cmpgtudi_media (operands[0],
7671 sh_compare_op0, sh_compare_op1));
7674 operands[1] = prepare_scc_operands (GTU);
7677 (define_expand "sltu"
7678 [(set (match_operand:SI 0 "arith_reg_operand" "")
7685 if (GET_MODE (operands[0]) != DImode)
7686 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7687 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7688 if (sh_compare_op1 != const0_rtx)
7689 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7690 ? GET_MODE (sh_compare_op0)
7691 : GET_MODE (sh_compare_op1),
7694 emit_insn (gen_cmpgtudi_media (operands[0],
7695 sh_compare_op1, sh_compare_op0));
7698 operands[1] = prepare_scc_operands (LTU);
7701 (define_expand "sleu"
7702 [(set (match_operand:SI 0 "arith_reg_operand" "")
7711 if (GET_MODE (operands[0]) != DImode)
7712 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7713 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7714 if (sh_compare_op1 != const0_rtx)
7715 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7716 ? GET_MODE (sh_compare_op0)
7717 : GET_MODE (sh_compare_op1),
7720 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7722 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7723 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7727 operands[1] = prepare_scc_operands (LEU);
7730 (define_expand "sgeu"
7731 [(set (match_operand:SI 0 "arith_reg_operand" "")
7740 if (GET_MODE (operands[0]) != DImode)
7741 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7742 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7743 if (sh_compare_op1 != const0_rtx)
7744 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7745 ? GET_MODE (sh_compare_op0)
7746 : GET_MODE (sh_compare_op1),
7749 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7751 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7752 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7757 operands[1] = prepare_scc_operands (GEU);
7760 ;; sne moves the complement of the T reg to DEST like this:
7764 ;; This is better than xoring compare result with 1 because it does
7765 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7768 (define_expand "sne"
7769 [(set (match_dup 2) (const_int -1))
7770 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7771 (neg:SI (plus:SI (match_dup 1)
7774 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7783 if (GET_MODE (operands[0]) != DImode)
7784 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7786 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7789 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7790 if (sh_compare_op1 != const0_rtx)
7791 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7792 ? GET_MODE (sh_compare_op0)
7793 : GET_MODE (sh_compare_op1),
7796 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7798 emit_insn (gen_seq (tmp));
7799 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7804 operands[1] = prepare_scc_operands (EQ);
7805 operands[2] = gen_reg_rtx (SImode);
7808 (define_expand "sunordered"
7809 [(set (match_operand:DI 0 "arith_reg_operand" "")
7810 (unordered:DI (match_dup 1) (match_dup 2)))]
7811 "TARGET_SHMEDIA_FPU"
7814 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7815 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7818 ;; Use the same trick for FP sle / sge
7819 (define_expand "movnegt"
7820 [(set (match_dup 2) (const_int -1))
7821 (parallel [(set (match_operand 0 "" "")
7822 (neg:SI (plus:SI (match_dup 1)
7825 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7828 "operands[2] = gen_reg_rtx (SImode);")
7830 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7831 ;; This prevents a regression that occurred when we switched from xor to
7835 [(set (match_operand:SI 0 "arith_reg_operand" "")
7836 (plus:SI (reg:SI T_REG)
7839 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7840 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7843 ;; -------------------------------------------------------------------------
7844 ;; Instructions to cope with inline literal tables
7845 ;; -------------------------------------------------------------------------
7847 ; 2 byte integer in line
7849 (define_insn "consttable_2"
7850 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7851 (match_operand 1 "" "")]
7856 if (operands[1] != const0_rtx)
7857 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7860 [(set_attr "length" "2")
7861 (set_attr "in_delay_slot" "no")])
7863 ; 4 byte integer in line
7865 (define_insn "consttable_4"
7866 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7867 (match_operand 1 "" "")]
7872 if (operands[1] != const0_rtx)
7873 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7876 [(set_attr "length" "4")
7877 (set_attr "in_delay_slot" "no")])
7879 ; 8 byte integer in line
7881 (define_insn "consttable_8"
7882 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7883 (match_operand 1 "" "")]
7888 if (operands[1] != const0_rtx)
7889 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7892 [(set_attr "length" "8")
7893 (set_attr "in_delay_slot" "no")])
7895 ; 4 byte floating point
7897 (define_insn "consttable_sf"
7898 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7899 (match_operand 1 "" "")]
7904 if (operands[1] != const0_rtx)
7907 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7908 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7912 [(set_attr "length" "4")
7913 (set_attr "in_delay_slot" "no")])
7915 ; 8 byte floating point
7917 (define_insn "consttable_df"
7918 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7919 (match_operand 1 "" "")]
7924 if (operands[1] != const0_rtx)
7927 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7928 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7932 [(set_attr "length" "8")
7933 (set_attr "in_delay_slot" "no")])
7935 ;; Alignment is needed for some constant tables; it may also be added for
7936 ;; Instructions at the start of loops, or after unconditional branches.
7937 ;; ??? We would get more accurate lengths if we did instruction
7938 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7939 ;; here is too conservative.
7941 ; align to a two byte boundary
7943 (define_expand "align_2"
7944 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7948 ; align to a four byte boundary
7949 ;; align_4 and align_log are instructions for the starts of loops, or
7950 ;; after unconditional branches, which may take up extra room.
7952 (define_expand "align_4"
7953 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7957 ; align to a cache line boundary
7959 (define_insn "align_log"
7960 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7963 [(set_attr "length" "0")
7964 (set_attr "in_delay_slot" "no")])
7966 ; emitted at the end of the literal table, used to emit the
7967 ; 32bit branch labels if needed.
7969 (define_insn "consttable_end"
7970 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7972 "* return output_jump_label_table ();"
7973 [(set_attr "in_delay_slot" "no")])
7975 ; emitted at the end of the window in the literal table.
7977 (define_insn "consttable_window_end"
7978 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7981 [(set_attr "length" "0")
7982 (set_attr "in_delay_slot" "no")])
7984 ;; -------------------------------------------------------------------------
7986 ;; -------------------------------------------------------------------------
7988 ;; String/block move insn.
7990 (define_expand "movstrsi"
7991 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7992 (mem:BLK (match_operand:BLK 1 "" "")))
7993 (use (match_operand:SI 2 "nonmemory_operand" ""))
7994 (use (match_operand:SI 3 "immediate_operand" ""))
7995 (clobber (reg:SI PR_REG))
7996 (clobber (reg:SI R4_REG))
7997 (clobber (reg:SI R5_REG))
7998 (clobber (reg:SI R0_REG))])]
7999 "TARGET_SH1 && ! TARGET_SH5"
8002 if(expand_block_move (operands))
8007 (define_insn "block_move_real"
8008 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8009 (mem:BLK (reg:SI R5_REG)))
8010 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8011 (clobber (reg:SI PR_REG))
8012 (clobber (reg:SI R0_REG))])]
8013 "TARGET_SH1 && ! TARGET_HARD_SH4"
8015 [(set_attr "type" "sfunc")
8016 (set_attr "needs_delay_slot" "yes")])
8018 (define_insn "block_lump_real"
8019 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8020 (mem:BLK (reg:SI R5_REG)))
8021 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8022 (use (reg:SI R6_REG))
8023 (clobber (reg:SI PR_REG))
8024 (clobber (reg:SI T_REG))
8025 (clobber (reg:SI R4_REG))
8026 (clobber (reg:SI R5_REG))
8027 (clobber (reg:SI R6_REG))
8028 (clobber (reg:SI R0_REG))])]
8029 "TARGET_SH1 && ! TARGET_HARD_SH4"
8031 [(set_attr "type" "sfunc")
8032 (set_attr "needs_delay_slot" "yes")])
8034 (define_insn "block_move_real_i4"
8035 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8036 (mem:BLK (reg:SI R5_REG)))
8037 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8038 (clobber (reg:SI PR_REG))
8039 (clobber (reg:SI R0_REG))
8040 (clobber (reg:SI R1_REG))
8041 (clobber (reg:SI R2_REG))])]
8044 [(set_attr "type" "sfunc")
8045 (set_attr "needs_delay_slot" "yes")])
8047 (define_insn "block_lump_real_i4"
8048 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8049 (mem:BLK (reg:SI R5_REG)))
8050 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8051 (use (reg:SI R6_REG))
8052 (clobber (reg:SI PR_REG))
8053 (clobber (reg:SI T_REG))
8054 (clobber (reg:SI R4_REG))
8055 (clobber (reg:SI R5_REG))
8056 (clobber (reg:SI R6_REG))
8057 (clobber (reg:SI R0_REG))
8058 (clobber (reg:SI R1_REG))
8059 (clobber (reg:SI R2_REG))
8060 (clobber (reg:SI R3_REG))])]
8063 [(set_attr "type" "sfunc")
8064 (set_attr "needs_delay_slot" "yes")])
8066 ;; -------------------------------------------------------------------------
8067 ;; Floating point instructions.
8068 ;; -------------------------------------------------------------------------
8070 ;; ??? All patterns should have a type attribute.
8072 (define_expand "fpu_switch0"
8073 [(set (match_operand:SI 0 "" "") (match_dup 2))
8074 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8078 operands[1] = get_fpscr_rtx ();
8079 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8081 operands[2] = legitimize_pic_address (operands[2], SImode,
8082 no_new_pseudos ? operands[0] : 0);
8085 (define_expand "fpu_switch1"
8086 [(set (match_operand:SI 0 "" "") (match_dup 2))
8087 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8088 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8092 operands[1] = get_fpscr_rtx ();
8093 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8095 operands[2] = legitimize_pic_address (operands[2], SImode,
8096 no_new_pseudos ? operands[0] : 0);
8097 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8100 (define_expand "movpsi"
8101 [(set (match_operand:PSI 0 "register_operand" "")
8102 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8106 ;; The c / m alternative is a fake to guide reload to load directly into
8107 ;; fpscr, since reload doesn't know how to use post-increment.
8108 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8109 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8110 ;; predicate after reload.
8111 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8112 ;; like a mac -> gpr move.
8113 (define_insn "fpu_switch"
8114 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8115 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8117 && (! reload_completed
8118 || true_regnum (operands[0]) != FPSCR_REG
8119 || GET_CODE (operands[1]) != MEM
8120 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8122 ! precision stays the same
8131 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8132 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8135 [(set (reg:PSI FPSCR_REG)
8136 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8137 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8138 [(set (match_dup 0) (match_dup 0))]
8141 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8142 gen_rtx (MEM, PSImode,
8143 gen_rtx (POST_INC, Pmode,
8145 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8149 [(set (reg:PSI FPSCR_REG)
8150 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8152 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8155 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156 gen_rtx (MEM, PSImode,
8157 gen_rtx (POST_INC, Pmode,
8159 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8162 ;; ??? This uses the fp unit, but has no type indicating that.
8163 ;; If we did that, this would either give a bogus latency or introduce
8164 ;; a bogus FIFO constraint.
8165 ;; Since this insn is currently only used for prologues/epilogues,
8166 ;; it is probably best to claim no function unit, which matches the
8168 (define_insn "toggle_sz"
8169 [(set (reg:PSI FPSCR_REG)
8170 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8174 (define_expand "addsf3"
8175 [(set (match_operand:SF 0 "arith_reg_operand" "")
8176 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8177 (match_operand:SF 2 "arith_reg_operand" "")))]
8178 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8183 expand_sf_binop (&gen_addsf3_i, operands);
8188 (define_insn "*addsf3_media"
8189 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8190 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8191 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8192 "TARGET_SHMEDIA_FPU"
8194 [(set_attr "type" "fparith_media")])
8196 (define_insn_and_split "unary_sf_op"
8197 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8202 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8203 (match_operator:SF 2 "unary_float_operator"
8204 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8205 (parallel [(match_operand 4
8206 "const_int_operand" "n")]))]))
8207 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8208 "TARGET_SHMEDIA_FPU"
8210 "TARGET_SHMEDIA_FPU && reload_completed"
8211 [(set (match_dup 5) (match_dup 6))]
8214 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8215 rtx op1 = gen_rtx_REG (SFmode,
8216 (true_regnum (operands[1])
8217 + (INTVAL (operands[4]) ^ endian)));
8219 operands[7] = gen_rtx_REG (SFmode,
8220 (true_regnum (operands[0])
8221 + (INTVAL (operands[3]) ^ endian)));
8222 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8224 [(set_attr "type" "fparith_media")])
8226 (define_insn_and_split "binary_sf_op"
8227 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8232 (parallel [(match_operand 7 "const_int_operand" "n")]))
8233 (match_operator:SF 3 "binary_float_operator"
8234 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8235 (parallel [(match_operand 5
8236 "const_int_operand" "n")]))
8237 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8238 (parallel [(match_operand 6
8239 "const_int_operand" "n")]))]))
8240 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8241 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8243 "&& reload_completed"
8244 [(set (match_dup 8) (match_dup 9))]
8247 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8248 rtx op1 = gen_rtx_REG (SFmode,
8249 (true_regnum (operands[1])
8250 + (INTVAL (operands[5]) ^ endian)));
8251 rtx op2 = gen_rtx_REG (SFmode,
8252 (true_regnum (operands[2])
8253 + (INTVAL (operands[6]) ^ endian)));
8255 operands[8] = gen_rtx_REG (SFmode,
8256 (true_regnum (operands[0])
8257 + (INTVAL (operands[4]) ^ endian)));
8258 operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8260 [(set_attr "type" "fparith_media")])
8262 (define_insn "addsf3_i"
8263 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8264 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8265 (match_operand:SF 2 "arith_reg_operand" "f")))
8266 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8269 [(set_attr "type" "fp")
8270 (set_attr "fp_mode" "single")])
8272 (define_expand "subsf3"
8273 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8274 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8275 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8276 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8281 expand_sf_binop (&gen_subsf3_i, operands);
8286 (define_insn "*subsf3_media"
8287 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8288 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8289 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8290 "TARGET_SHMEDIA_FPU"
8292 [(set_attr "type" "fparith_media")])
8294 (define_insn "subsf3_i"
8295 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8296 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8297 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8298 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8301 [(set_attr "type" "fp")
8302 (set_attr "fp_mode" "single")])
8304 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8305 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8306 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8307 ;; SH3E, we use a separate insn for SH3E mulsf3.
8309 (define_expand "mulsf3"
8310 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8311 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8312 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8313 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8317 expand_sf_binop (&gen_mulsf3_i4, operands);
8318 else if (TARGET_SH2E)
8319 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8320 if (! TARGET_SHMEDIA)
8324 (define_insn "*mulsf3_media"
8325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8326 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8327 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8328 "TARGET_SHMEDIA_FPU"
8330 [(set_attr "type" "fparith_media")])
8332 (define_insn "mulsf3_i4"
8333 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8334 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8335 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8336 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8339 [(set_attr "type" "fp")
8340 (set_attr "fp_mode" "single")])
8342 (define_insn "mulsf3_ie"
8343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8344 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8345 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8346 "TARGET_SH2E && ! TARGET_SH4"
8348 [(set_attr "type" "fp")])
8350 (define_insn "*mac_media"
8351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8352 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8353 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8354 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8355 "TARGET_SHMEDIA_FPU"
8357 [(set_attr "type" "fparith_media")])
8359 (define_insn "*macsf3"
8360 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8361 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8362 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8363 (match_operand:SF 3 "arith_reg_operand" "0")))
8364 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8365 "TARGET_SH2E && ! TARGET_SH4"
8367 [(set_attr "type" "fp")
8368 (set_attr "fp_mode" "single")])
8370 (define_expand "divsf3"
8371 [(set (match_operand:SF 0 "arith_reg_operand" "")
8372 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8373 (match_operand:SF 2 "arith_reg_operand" "")))]
8374 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8379 expand_sf_binop (&gen_divsf3_i, operands);
8384 (define_insn "*divsf3_media"
8385 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8386 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8387 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8388 "TARGET_SHMEDIA_FPU"
8390 [(set_attr "type" "fdiv_media")])
8392 (define_insn "divsf3_i"
8393 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8394 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8395 (match_operand:SF 2 "arith_reg_operand" "f")))
8396 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8399 [(set_attr "type" "fdiv")
8400 (set_attr "fp_mode" "single")])
8402 (define_insn "floatdisf2"
8403 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8404 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
8407 [(set_attr "type" "fpconv_media")])
8409 (define_expand "floatsisf2"
8410 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8411 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8412 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8417 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8422 (define_insn "*floatsisf2_media"
8423 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8424 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8425 "TARGET_SHMEDIA_FPU"
8427 [(set_attr "type" "fpconv_media")])
8429 (define_insn "floatsisf2_i4"
8430 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8431 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8432 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8435 [(set_attr "type" "fp")
8436 (set_attr "fp_mode" "single")])
8438 (define_insn "*floatsisf2_ie"
8439 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8440 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8441 "TARGET_SH2E && ! TARGET_SH4"
8443 [(set_attr "type" "fp")])
8445 (define_insn "fix_truncsfdi2"
8446 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8447 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8448 "TARGET_SHMEDIA_FPU"
8450 [(set_attr "type" "fpconv_media")])
8452 (define_expand "fix_truncsfsi2"
8453 [(set (match_operand:SI 0 "fpul_operand" "=y")
8454 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8455 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8460 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8465 (define_insn "*fix_truncsfsi2_media"
8466 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8467 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8468 "TARGET_SHMEDIA_FPU"
8470 [(set_attr "type" "fpconv_media")])
8472 (define_insn "fix_truncsfsi2_i4"
8473 [(set (match_operand:SI 0 "fpul_operand" "=y")
8474 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8475 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8478 [(set_attr "type" "ftrc_s")
8479 (set_attr "fp_mode" "single")])
8481 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8482 ;; fix_truncsfsi2_i4.
8483 ;; (define_insn "fix_truncsfsi2_i4_2"
8484 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8485 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8486 ;; (use (reg:PSI FPSCR_REG))
8487 ;; (clobber (reg:SI FPUL_REG))]
8490 ;; [(set_attr "length" "4")
8491 ;; (set_attr "fp_mode" "single")])
8494 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8495 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8496 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8497 ;; (clobber (reg:SI FPUL_REG))]
8499 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8500 ;; (use (match_dup 2))])
8501 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8503 (define_insn "*fixsfsi"
8504 [(set (match_operand:SI 0 "fpul_operand" "=y")
8505 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8506 "TARGET_SH2E && ! TARGET_SH4"
8508 [(set_attr "type" "fp")])
8510 (define_insn "cmpgtsf_t"
8511 [(set (reg:SI T_REG)
8512 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8513 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8514 "TARGET_SH2E && ! TARGET_SH4"
8516 [(set_attr "type" "fp")
8517 (set_attr "fp_mode" "single")])
8519 (define_insn "cmpeqsf_t"
8520 [(set (reg:SI T_REG)
8521 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8522 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8523 "TARGET_SH2E && ! TARGET_SH4"
8525 [(set_attr "type" "fp")
8526 (set_attr "fp_mode" "single")])
8528 (define_insn "ieee_ccmpeqsf_t"
8529 [(set (reg:SI T_REG)
8530 (ior:SI (reg:SI T_REG)
8531 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8532 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8533 "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8534 "* return output_ieee_ccmpeq (insn, operands);"
8535 [(set_attr "length" "4")])
8538 (define_insn "cmpgtsf_t_i4"
8539 [(set (reg:SI T_REG)
8540 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8541 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8542 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8545 [(set_attr "type" "fp")
8546 (set_attr "fp_mode" "single")])
8548 (define_insn "cmpeqsf_t_i4"
8549 [(set (reg:SI T_REG)
8550 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8551 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8552 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8555 [(set_attr "type" "fp")
8556 (set_attr "fp_mode" "single")])
8558 (define_insn "*ieee_ccmpeqsf_t_4"
8559 [(set (reg:SI T_REG)
8560 (ior:SI (reg:SI T_REG)
8561 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8562 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8563 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8564 "TARGET_IEEE && TARGET_SH4"
8565 "* return output_ieee_ccmpeq (insn, operands);"
8566 [(set_attr "length" "4")
8567 (set_attr "fp_mode" "single")])
8569 (define_insn "cmpeqsf_media"
8570 [(set (match_operand:DI 0 "register_operand" "=r")
8571 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8572 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8573 "TARGET_SHMEDIA_FPU"
8574 "fcmpeq.s %1, %2, %0"
8575 [(set_attr "type" "fcmp_media")])
8577 (define_insn "cmpgtsf_media"
8578 [(set (match_operand:DI 0 "register_operand" "=r")
8579 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8580 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8581 "TARGET_SHMEDIA_FPU"
8582 "fcmpgt.s %1, %2, %0"
8583 [(set_attr "type" "fcmp_media")])
8585 (define_insn "cmpgesf_media"
8586 [(set (match_operand:DI 0 "register_operand" "=r")
8587 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8588 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8589 "TARGET_SHMEDIA_FPU"
8590 "fcmpge.s %1, %2, %0"
8591 [(set_attr "type" "fcmp_media")])
8593 (define_insn "cmpunsf_media"
8594 [(set (match_operand:DI 0 "register_operand" "=r")
8595 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8596 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8597 "TARGET_SHMEDIA_FPU"
8598 "fcmpun.s %1, %2, %0"
8599 [(set_attr "type" "fcmp_media")])
8601 (define_expand "cmpsf"
8602 [(set (reg:SI T_REG)
8603 (compare (match_operand:SF 0 "arith_operand" "")
8604 (match_operand:SF 1 "arith_operand" "")))]
8605 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8608 sh_compare_op0 = operands[0];
8609 sh_compare_op1 = operands[1];
8613 (define_expand "negsf2"
8614 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8615 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8616 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8621 expand_sf_unop (&gen_negsf2_i, operands);
8626 (define_insn "*negsf2_media"
8627 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8628 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8629 "TARGET_SHMEDIA_FPU"
8631 [(set_attr "type" "fmove_media")])
8633 (define_insn "negsf2_i"
8634 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8635 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8636 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8639 [(set_attr "type" "fmove")
8640 (set_attr "fp_mode" "single")])
8642 (define_expand "sqrtsf2"
8643 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8644 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8645 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8650 expand_sf_unop (&gen_sqrtsf2_i, operands);
8655 (define_insn "*sqrtsf2_media"
8656 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8657 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8658 "TARGET_SHMEDIA_FPU"
8660 [(set_attr "type" "fdiv_media")])
8662 (define_insn "sqrtsf2_i"
8663 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8664 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8665 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8668 [(set_attr "type" "fdiv")
8669 (set_attr "fp_mode" "single")])
8671 (define_expand "abssf2"
8672 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8673 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8674 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8679 expand_sf_unop (&gen_abssf2_i, operands);
8684 (define_insn "*abssf2_media"
8685 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8686 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8687 "TARGET_SHMEDIA_FPU"
8689 [(set_attr "type" "fmove_media")])
8691 (define_insn "abssf2_i"
8692 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8693 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8694 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8697 [(set_attr "type" "fmove")
8698 (set_attr "fp_mode" "single")])
8700 (define_expand "adddf3"
8701 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8702 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8703 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8704 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8709 expand_df_binop (&gen_adddf3_i, operands);
8714 (define_insn "*adddf3_media"
8715 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8716 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8717 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8718 "TARGET_SHMEDIA_FPU"
8720 [(set_attr "type" "dfparith_media")])
8722 (define_insn "adddf3_i"
8723 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8724 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8725 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8726 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8729 [(set_attr "type" "dfp_arith")
8730 (set_attr "fp_mode" "double")])
8732 (define_expand "subdf3"
8733 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8734 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8735 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8736 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8741 expand_df_binop (&gen_subdf3_i, operands);
8746 (define_insn "*subdf3_media"
8747 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8748 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8749 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8750 "TARGET_SHMEDIA_FPU"
8752 [(set_attr "type" "dfparith_media")])
8754 (define_insn "subdf3_i"
8755 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8756 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8757 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8758 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8761 [(set_attr "type" "dfp_arith")
8762 (set_attr "fp_mode" "double")])
8764 (define_expand "muldf3"
8765 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8766 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8767 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8768 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8773 expand_df_binop (&gen_muldf3_i, operands);
8778 (define_insn "*muldf3_media"
8779 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8780 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8781 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8782 "TARGET_SHMEDIA_FPU"
8784 [(set_attr "type" "dfmul_media")])
8786 (define_insn "muldf3_i"
8787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8788 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8789 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8790 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8793 [(set_attr "type" "dfp_arith")
8794 (set_attr "fp_mode" "double")])
8796 (define_expand "divdf3"
8797 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8798 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8799 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8800 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8805 expand_df_binop (&gen_divdf3_i, operands);
8810 (define_insn "*divdf3_media"
8811 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8812 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8813 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8814 "TARGET_SHMEDIA_FPU"
8816 [(set_attr "type" "dfdiv_media")])
8818 (define_insn "divdf3_i"
8819 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8820 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8821 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8822 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8825 [(set_attr "type" "dfdiv")
8826 (set_attr "fp_mode" "double")])
8828 (define_insn "floatdidf2"
8829 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8830 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8831 "TARGET_SHMEDIA_FPU"
8833 [(set_attr "type" "dfpconv_media")])
8835 (define_expand "floatsidf2"
8836 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8837 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8838 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8843 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8849 (define_insn "*floatsidf2_media"
8850 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8851 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8852 "TARGET_SHMEDIA_FPU"
8854 [(set_attr "type" "dfpconv_media")])
8856 (define_insn "floatsidf2_i"
8857 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8858 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8859 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8862 [(set_attr "type" "dfp_conv")
8863 (set_attr "fp_mode" "double")])
8865 (define_insn "fix_truncdfdi2"
8866 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8867 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8868 "TARGET_SHMEDIA_FPU"
8870 [(set_attr "type" "dfpconv_media")])
8872 (define_expand "fix_truncdfsi2"
8873 [(set (match_operand:SI 0 "fpul_operand" "")
8874 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8875 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8880 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8886 (define_insn "*fix_truncdfsi2_media"
8887 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8888 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8889 "TARGET_SHMEDIA_FPU"
8891 [(set_attr "type" "dfpconv_media")])
8893 (define_insn "fix_truncdfsi2_i"
8894 [(set (match_operand:SI 0 "fpul_operand" "=y")
8895 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8896 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8899 [(set_attr "type" "dfp_conv")
8900 (set_attr "dfp_comp" "no")
8901 (set_attr "fp_mode" "double")])
8903 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8904 ;; fix_truncdfsi2_i.
8905 ;; (define_insn "fix_truncdfsi2_i4"
8906 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8907 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8908 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8909 ;; (clobber (reg:SI FPUL_REG))]
8912 ;; [(set_attr "length" "4")
8913 ;; (set_attr "fp_mode" "double")])
8916 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8917 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8918 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8919 ;; (clobber (reg:SI FPUL_REG))]
8921 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8922 ;; (use (match_dup 2))])
8923 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8925 (define_insn "cmpgtdf_t"
8926 [(set (reg:SI T_REG)
8927 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8928 (match_operand:DF 1 "arith_reg_operand" "f")))
8929 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8932 [(set_attr "type" "dfp_cmp")
8933 (set_attr "fp_mode" "double")])
8935 (define_insn "cmpeqdf_t"
8936 [(set (reg:SI T_REG)
8937 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8938 (match_operand:DF 1 "arith_reg_operand" "f")))
8939 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8942 [(set_attr "type" "dfp_cmp")
8943 (set_attr "fp_mode" "double")])
8945 (define_insn "*ieee_ccmpeqdf_t"
8946 [(set (reg:SI T_REG)
8947 (ior:SI (reg:SI T_REG)
8948 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8949 (match_operand:DF 1 "arith_reg_operand" "f"))))
8950 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8951 "TARGET_IEEE && TARGET_SH4"
8952 "* return output_ieee_ccmpeq (insn, operands);"
8953 [(set_attr "length" "4")
8954 (set_attr "fp_mode" "double")])
8956 (define_insn "cmpeqdf_media"
8957 [(set (match_operand:DI 0 "register_operand" "=r")
8958 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8959 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8960 "TARGET_SHMEDIA_FPU"
8962 [(set_attr "type" "fcmp_media")])
8964 (define_insn "cmpgtdf_media"
8965 [(set (match_operand:DI 0 "register_operand" "=r")
8966 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8967 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8968 "TARGET_SHMEDIA_FPU"
8970 [(set_attr "type" "fcmp_media")])
8972 (define_insn "cmpgedf_media"
8973 [(set (match_operand:DI 0 "register_operand" "=r")
8974 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8975 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8976 "TARGET_SHMEDIA_FPU"
8978 [(set_attr "type" "fcmp_media")])
8980 (define_insn "cmpundf_media"
8981 [(set (match_operand:DI 0 "register_operand" "=r")
8982 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8983 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8984 "TARGET_SHMEDIA_FPU"
8986 [(set_attr "type" "fcmp_media")])
8988 (define_expand "cmpdf"
8989 [(set (reg:SI T_REG)
8990 (compare (match_operand:DF 0 "arith_operand" "")
8991 (match_operand:DF 1 "arith_operand" "")))]
8992 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8995 sh_compare_op0 = operands[0];
8996 sh_compare_op1 = operands[1];
9000 (define_expand "negdf2"
9001 [(set (match_operand:DF 0 "arith_reg_operand" "")
9002 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9003 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9008 expand_df_unop (&gen_negdf2_i, operands);
9013 (define_insn "*negdf2_media"
9014 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9015 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9016 "TARGET_SHMEDIA_FPU"
9018 [(set_attr "type" "fmove_media")])
9020 (define_insn "negdf2_i"
9021 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9022 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9023 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9026 [(set_attr "type" "fmove")
9027 (set_attr "fp_mode" "double")])
9029 (define_expand "sqrtdf2"
9030 [(set (match_operand:DF 0 "arith_reg_operand" "")
9031 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9032 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9037 expand_df_unop (&gen_sqrtdf2_i, operands);
9042 (define_insn "*sqrtdf2_media"
9043 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9044 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9045 "TARGET_SHMEDIA_FPU"
9047 [(set_attr "type" "dfdiv_media")])
9049 (define_insn "sqrtdf2_i"
9050 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9051 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9052 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9055 [(set_attr "type" "dfdiv")
9056 (set_attr "fp_mode" "double")])
9058 (define_expand "absdf2"
9059 [(set (match_operand:DF 0 "arith_reg_operand" "")
9060 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9061 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9066 expand_df_unop (&gen_absdf2_i, operands);
9071 (define_insn "*absdf2_media"
9072 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9073 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9074 "TARGET_SHMEDIA_FPU"
9076 [(set_attr "type" "fmove_media")])
9078 (define_insn "absdf2_i"
9079 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9080 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9081 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9084 [(set_attr "type" "fmove")
9085 (set_attr "fp_mode" "double")])
9087 (define_expand "extendsfdf2"
9088 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9089 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9090 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9095 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9101 (define_insn "*extendsfdf2_media"
9102 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9103 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9104 "TARGET_SHMEDIA_FPU"
9106 [(set_attr "type" "dfpconv_media")])
9108 (define_insn "extendsfdf2_i4"
9109 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9110 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9111 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9114 [(set_attr "type" "fp")
9115 (set_attr "fp_mode" "double")])
9117 (define_expand "truncdfsf2"
9118 [(set (match_operand:SF 0 "fpul_operand" "")
9119 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9120 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9125 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9131 (define_insn "*truncdfsf2_media"
9132 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9133 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9134 "TARGET_SHMEDIA_FPU"
9136 [(set_attr "type" "dfpconv_media")])
9138 (define_insn "truncdfsf2_i4"
9139 [(set (match_operand:SF 0 "fpul_operand" "=y")
9140 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9141 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9144 [(set_attr "type" "fp")
9145 (set_attr "fp_mode" "double")])
9147 ;; Bit field extract patterns. These give better code for packed bitfields,
9148 ;; because they allow auto-increment addresses to be generated.
9150 (define_expand "insv"
9151 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9152 (match_operand:SI 1 "immediate_operand" "")
9153 (match_operand:SI 2 "immediate_operand" ""))
9154 (match_operand:SI 3 "general_operand" ""))]
9155 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9158 rtx addr_target, orig_address, shift_reg, qi_val;
9159 HOST_WIDE_INT bitsize, size, v;
9160 rtx x = operands[3];
9162 /* ??? expmed doesn't care for non-register predicates. */
9163 if (! memory_operand (operands[0], VOIDmode)
9164 || ! immediate_operand (operands[1], VOIDmode)
9165 || ! immediate_operand (operands[2], VOIDmode)
9166 || ! general_operand (x, VOIDmode))
9168 /* If this isn't a 16 / 24 / 32 bit field, or if
9169 it doesn't start on a byte boundary, then fail. */
9170 bitsize = INTVAL (operands[1]);
9171 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9172 || (INTVAL (operands[2]) % 8) != 0)
9176 orig_address = XEXP (operands[0], 0);
9177 shift_reg = gen_reg_rtx (SImode);
9178 if (GET_CODE (x) == CONST_INT)
9181 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9185 emit_insn (gen_movsi (shift_reg, operands[3]));
9186 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9188 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9190 operands[0] = replace_equiv_address (operands[0], addr_target);
9191 emit_insn (gen_movqi (operands[0], qi_val));
9195 if (GET_CODE (x) == CONST_INT)
9197 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9200 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9201 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9203 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9204 emit_insn (gen_movqi (operands[0], qi_val));
9210 ;; -------------------------------------------------------------------------
9212 ;; -------------------------------------------------------------------------
9214 ;; This matches cases where a stack pointer increment at the start of the
9215 ;; epilogue combines with a stack slot read loading the return value.
9218 [(set (match_operand:SI 0 "arith_reg_operand" "")
9219 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9220 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9221 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9224 ;; See the comment on the dt combiner pattern above.
9227 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9228 (plus:SI (match_dup 0)
9231 (eq:SI (match_dup 0)
9236 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9237 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9238 ;; reload when the constant is too large for a reg+offset address.
9240 ;; ??? We would get much better code if this was done in reload. This would
9241 ;; require modifying find_reloads_address to recognize that if the constant
9242 ;; is out-of-range for an immediate add, then we get better code by reloading
9243 ;; the constant into a register than by reloading the sum into a register,
9244 ;; since the former is one instruction shorter if the address does not need
9245 ;; to be offsettable. Unfortunately this does not work, because there is
9246 ;; only one register, r0, that can be used as an index register. This register
9247 ;; is also the function return value register. So, if we try to force reload
9248 ;; to use double-reg addresses, then we end up with some instructions that
9249 ;; need to use r0 twice. The only way to fix this is to change the calling
9250 ;; convention so that r0 is not used to return values.
9253 [(set (match_operand:SI 0 "register_operand" "=r")
9254 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9255 (set (mem:SI (match_dup 0))
9256 (match_operand:SI 2 "general_movsrc_operand" ""))]
9257 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9258 "mov.l %2,@(%0,%1)")
9261 [(set (match_operand:SI 0 "register_operand" "=r")
9262 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9263 (set (match_operand:SI 2 "general_movdst_operand" "")
9264 (mem:SI (match_dup 0)))]
9265 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9266 "mov.l @(%0,%1),%2")
9269 [(set (match_operand:SI 0 "register_operand" "=r")
9270 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9271 (set (mem:HI (match_dup 0))
9272 (match_operand:HI 2 "general_movsrc_operand" ""))]
9273 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9274 "mov.w %2,@(%0,%1)")
9277 [(set (match_operand:SI 0 "register_operand" "=r")
9278 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9279 (set (match_operand:HI 2 "general_movdst_operand" "")
9280 (mem:HI (match_dup 0)))]
9281 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9282 "mov.w @(%0,%1),%2")
9285 [(set (match_operand:SI 0 "register_operand" "=r")
9286 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9287 (set (mem:QI (match_dup 0))
9288 (match_operand:QI 2 "general_movsrc_operand" ""))]
9289 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9290 "mov.b %2,@(%0,%1)")
9293 [(set (match_operand:SI 0 "register_operand" "=r")
9294 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9295 (set (match_operand:QI 2 "general_movdst_operand" "")
9296 (mem:QI (match_dup 0)))]
9297 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9298 "mov.b @(%0,%1),%2")
9301 [(set (match_operand:SI 0 "register_operand" "=r")
9302 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9303 (set (mem:SF (match_dup 0))
9304 (match_operand:SF 2 "general_movsrc_operand" ""))]
9305 "TARGET_SH1 && REGNO (operands[0]) == 0
9306 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9307 || (GET_CODE (operands[2]) == SUBREG
9308 && REGNO (SUBREG_REG (operands[2])) < 16))
9309 && reg_unused_after (operands[0], insn)"
9310 "mov.l %2,@(%0,%1)")
9313 [(set (match_operand:SI 0 "register_operand" "=r")
9314 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9315 (set (match_operand:SF 2 "general_movdst_operand" "")
9317 (mem:SF (match_dup 0)))]
9318 "TARGET_SH1 && REGNO (operands[0]) == 0
9319 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9320 || (GET_CODE (operands[2]) == SUBREG
9321 && REGNO (SUBREG_REG (operands[2])) < 16))
9322 && reg_unused_after (operands[0], insn)"
9323 "mov.l @(%0,%1),%2")
9326 [(set (match_operand:SI 0 "register_operand" "=r")
9327 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9328 (set (mem:SF (match_dup 0))
9329 (match_operand:SF 2 "general_movsrc_operand" ""))]
9330 "TARGET_SH2E && REGNO (operands[0]) == 0
9331 && ((GET_CODE (operands[2]) == REG
9332 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9333 || (GET_CODE (operands[2]) == SUBREG
9334 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9335 && reg_unused_after (operands[0], insn)"
9336 "fmov{.s|} %2,@(%0,%1)")
9339 [(set (match_operand:SI 0 "register_operand" "=r")
9340 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9341 (set (match_operand:SF 2 "general_movdst_operand" "")
9343 (mem:SF (match_dup 0)))]
9344 "TARGET_SH2E && REGNO (operands[0]) == 0
9345 && ((GET_CODE (operands[2]) == REG
9346 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9347 || (GET_CODE (operands[2]) == SUBREG
9348 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9349 && reg_unused_after (operands[0], insn)"
9350 "fmov{.s|} @(%0,%1),%2")
9352 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9353 (define_insn "sp_switch_1"
9360 xoperands[0] = sp_switch;
9361 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9362 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9363 return \"mov r0,r15\";
9365 [(set_attr "length" "10")])
9367 ;; Switch back to the original stack for interrupt functions with the
9368 ;; sp_switch attribute. */
9369 (define_insn "sp_switch_2"
9372 "mov.l @r15+,r15\;mov.l @r15+,r0"
9373 [(set_attr "length" "4")])
9375 ;; Integer vector moves
9377 (define_expand "movv8qi"
9378 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9379 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9381 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9383 (define_insn "movv8qi_i"
9384 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9385 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9387 && (register_operand (operands[0], V8QImode)
9388 || sh_register_operand (operands[1], V8QImode))"
9395 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9396 (set_attr "length" "4,4,16,4,4")])
9399 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9400 (subreg:V8QI (const_int 0) 0))]
9403 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9404 (const_int 0) (const_int 0) (const_int 0)
9405 (const_int 0) (const_int 0)]))])
9408 [(set (match_operand 0 "arith_reg_dest" "")
9409 (match_operand 1 "sh_rep_vec" ""))]
9410 "TARGET_SHMEDIA && reload_completed
9411 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9412 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9413 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9414 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9415 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9416 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9417 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9418 [(set (match_dup 0) (match_dup 1))
9422 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9423 rtx elt1 = XVECEXP (operands[1], 0, 1);
9426 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9430 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9431 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9433 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9434 operands[1] = XVECEXP (operands[1], 0, 0);
9437 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9438 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9439 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9440 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9443 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9445 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9451 [(set (match_operand 0 "arith_reg_dest" "")
9452 (match_operand 1 "sh_const_vec" ""))]
9453 "TARGET_SHMEDIA && reload_completed
9454 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9455 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9456 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9457 [(set (match_dup 0) (match_dup 1))]
9460 rtx v = operands[1];
9461 enum machine_mode new_mode
9462 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9464 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9466 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9469 (define_expand "movv2hi"
9470 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9471 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9473 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9475 (define_insn "movv2hi_i"
9476 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9477 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9479 && (register_operand (operands[0], V2HImode)
9480 || sh_register_operand (operands[1], V2HImode))"
9487 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9488 (set_attr "length" "4,4,16,4,4")])
9490 (define_expand "movv4hi"
9491 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9492 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9494 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9496 (define_insn "movv4hi_i"
9497 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9498 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9500 && (register_operand (operands[0], V4HImode)
9501 || sh_register_operand (operands[1], V4HImode))"
9508 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9509 (set_attr "length" "4,4,16,4,4")])
9511 (define_expand "movv2si"
9512 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9513 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9515 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9517 (define_insn "movv2si_i"
9518 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9519 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9521 && (register_operand (operands[0], V2SImode)
9522 || sh_register_operand (operands[1], V2SImode))"
9529 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9530 (set_attr "length" "4,4,16,4,4")])
9532 ;; Multimedia Intrinsics
9534 (define_insn "absv2si2"
9535 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9536 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9539 [(set_attr "type" "mcmp_media")])
9541 (define_insn "absv4hi2"
9542 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9543 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9546 [(set_attr "type" "mcmp_media")])
9548 (define_insn "addv2si3"
9549 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9550 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9551 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9554 [(set_attr "type" "arith_media")])
9556 (define_insn "addv4hi3"
9557 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9558 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9559 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9562 [(set_attr "type" "arith_media")])
9564 (define_insn "ssaddv2si3"
9565 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9566 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9567 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9569 "madds.l %1, %2, %0"
9570 [(set_attr "type" "mcmp_media")])
9572 (define_insn "usaddv8qi3"
9573 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9574 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9575 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9577 "madds.ub %1, %2, %0"
9578 [(set_attr "type" "mcmp_media")])
9580 (define_insn "ssaddv4hi3"
9581 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9582 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9583 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9585 "madds.w %1, %2, %0"
9586 [(set_attr "type" "mcmp_media")])
9588 (define_insn "negcmpeqv8qi"
9589 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9590 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9591 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9593 "mcmpeq.b %N1, %N2, %0"
9594 [(set_attr "type" "mcmp_media")])
9596 (define_insn "negcmpeqv2si"
9597 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9598 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9599 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9601 "mcmpeq.l %N1, %N2, %0"
9602 [(set_attr "type" "mcmp_media")])
9604 (define_insn "negcmpeqv4hi"
9605 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9606 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9607 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9609 "mcmpeq.w %N1, %N2, %0"
9610 [(set_attr "type" "mcmp_media")])
9612 (define_insn "negcmpgtuv8qi"
9613 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9614 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9615 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9617 "mcmpgt.ub %N1, %N2, %0"
9618 [(set_attr "type" "mcmp_media")])
9620 (define_insn "negcmpgtv2si"
9621 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9622 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9623 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9625 "mcmpgt.l %N1, %N2, %0"
9626 [(set_attr "type" "mcmp_media")])
9628 (define_insn "negcmpgtv4hi"
9629 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9630 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9631 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9633 "mcmpgt.w %N1, %N2, %0"
9634 [(set_attr "type" "mcmp_media")])
9637 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9638 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9639 (match_operand:DI 2 "arith_reg_operand" "r"))
9640 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9641 (not:DI (match_dup 2)))))]
9644 [(set_attr "type" "arith_media")])
9646 (define_insn "mcnvs_lw"
9647 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9649 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9650 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9652 "mcnvs.lw %N1, %N2, %0"
9653 [(set_attr "type" "mcmp_media")])
9655 (define_insn "mcnvs_wb"
9656 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9658 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9659 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9661 "mcnvs.wb %N1, %N2, %0"
9662 [(set_attr "type" "mcmp_media")])
9664 (define_insn "mcnvs_wub"
9665 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9667 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9668 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9670 "mcnvs.wub %N1, %N2, %0"
9671 [(set_attr "type" "mcmp_media")])
9673 (define_insn "mextr_rl"
9674 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9675 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9676 (match_operand:HI 3 "mextr_bit_offset" "i"))
9677 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9678 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9679 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9682 static char templ[16];
9684 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9685 (int) INTVAL (operands[3]) >> 3);
9688 [(set_attr "type" "arith_media")])
9690 (define_insn "*mextr_lr"
9691 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9692 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9693 (match_operand:HI 3 "mextr_bit_offset" "i"))
9694 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9695 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9696 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9699 static char templ[16];
9701 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9702 (int) INTVAL (operands[4]) >> 3);
9705 [(set_attr "type" "arith_media")])
9707 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9708 ; vector then varies depending on endianness.
9709 (define_expand "mextr1"
9710 [(match_operand:DI 0 "arith_reg_dest" "")
9711 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9712 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9716 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9717 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9721 (define_expand "mextr2"
9722 [(match_operand:DI 0 "arith_reg_dest" "")
9723 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9724 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9728 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9729 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9733 (define_expand "mextr3"
9734 [(match_operand:DI 0 "arith_reg_dest" "")
9735 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9736 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9740 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9741 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9745 (define_expand "mextr4"
9746 [(match_operand:DI 0 "arith_reg_dest" "")
9747 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9748 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9752 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9753 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9757 (define_expand "mextr5"
9758 [(match_operand:DI 0 "arith_reg_dest" "")
9759 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9760 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9764 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9765 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9769 (define_expand "mextr6"
9770 [(match_operand:DI 0 "arith_reg_dest" "")
9771 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9772 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9776 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9777 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9781 (define_expand "mextr7"
9782 [(match_operand:DI 0 "arith_reg_dest" "")
9783 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9784 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9788 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9789 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9793 (define_expand "mmacfx_wl"
9794 [(match_operand:V2SI 0 "arith_reg_dest" "")
9795 (match_operand:V2HI 1 "extend_reg_operand" "")
9796 (match_operand:V2HI 2 "extend_reg_operand" "")
9797 (match_operand:V2SI 3 "arith_reg_operand" "")]
9801 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9802 operands[1], operands[2]));
9806 (define_insn "mmacfx_wl_i"
9807 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9809 (match_operand:V2SI 1 "arith_reg_operand" "0")
9814 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9815 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9818 "mmacfx.wl %2, %3, %0"
9819 [(set_attr "type" "mac_media")])
9821 (define_expand "mmacnfx_wl"
9822 [(match_operand:V2SI 0 "arith_reg_dest" "")
9823 (match_operand:V2HI 1 "extend_reg_operand" "")
9824 (match_operand:V2HI 2 "extend_reg_operand" "")
9825 (match_operand:V2SI 3 "arith_reg_operand" "")]
9829 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9830 operands[1], operands[2]));
9834 (define_insn "mmacnfx_wl_i"
9835 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9837 (match_operand:V2SI 1 "arith_reg_operand" "0")
9842 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9843 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9846 "mmacnfx.wl %2, %3, %0"
9847 [(set_attr "type" "mac_media")])
9849 (define_insn "mulv2si3"
9850 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9851 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9852 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9855 [(set_attr "type" "d2mpy_media")])
9857 (define_insn "mulv4hi3"
9858 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9859 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9860 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9863 [(set_attr "type" "dmpy_media")])
9865 (define_insn "mmulfx_l"
9866 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9870 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9871 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9874 "mmulfx.l %1, %2, %0"
9875 [(set_attr "type" "d2mpy_media")])
9877 (define_insn "mmulfx_w"
9878 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9882 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9883 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9886 "mmulfx.w %1, %2, %0"
9887 [(set_attr "type" "dmpy_media")])
9889 (define_insn "mmulfxrp_w"
9890 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9895 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9896 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9900 "mmulfxrp.w %1, %2, %0"
9901 [(set_attr "type" "dmpy_media")])
9903 (define_expand "mmulhi_wl"
9904 [(match_operand:V2SI 0 "arith_reg_dest" "")
9905 (match_operand:V4HI 1 "arith_reg_operand" "")
9906 (match_operand:V4HI 2 "arith_reg_operand" "")]
9910 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9911 (operands[0], operands[1], operands[2]));
9915 (define_expand "mmullo_wl"
9916 [(match_operand:V2SI 0 "arith_reg_dest" "")
9917 (match_operand:V4HI 1 "arith_reg_operand" "")
9918 (match_operand:V4HI 2 "arith_reg_operand" "")]
9922 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9923 (operands[0], operands[1], operands[2]));
9927 (define_insn "mmul23_wl"
9928 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9931 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9932 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9933 (parallel [(const_int 2) (const_int 3)])))]
9935 "* return (TARGET_LITTLE_ENDIAN
9936 ? \"mmulhi.wl %1, %2, %0\"
9937 : \"mmullo.wl %1, %2, %0\");"
9938 [(set_attr "type" "dmpy_media")])
9940 (define_insn "mmul01_wl"
9941 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9944 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9945 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9946 (parallel [(const_int 0) (const_int 1)])))]
9948 "* return (TARGET_LITTLE_ENDIAN
9949 ? \"mmullo.wl %1, %2, %0\"
9950 : \"mmulhi.wl %1, %2, %0\");"
9951 [(set_attr "type" "dmpy_media")])
9953 (define_expand "mmulsum_wq"
9954 [(match_operand:DI 0 "arith_reg_dest" "")
9955 (match_operand:V4HI 1 "arith_reg_operand" "")
9956 (match_operand:V4HI 2 "arith_reg_operand" "")
9957 (match_operand:DI 3 "arith_reg_operand" "")]
9961 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9962 operands[1], operands[2]));
9966 (define_insn "mmulsum_wq_i"
9967 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9968 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9973 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9974 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9975 (parallel [(const_int 0)]))
9976 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9977 (sign_extend:V4DI (match_dup 3)))
9978 (parallel [(const_int 1)])))
9980 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9981 (sign_extend:V4DI (match_dup 3)))
9982 (parallel [(const_int 2)]))
9983 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9984 (sign_extend:V4DI (match_dup 3)))
9985 (parallel [(const_int 3)]))))))]
9987 "mmulsum.wq %2, %3, %0"
9988 [(set_attr "type" "mac_media")])
9990 (define_expand "mperm_w"
9991 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9992 (match_operand:V4HI 1 "arith_reg_operand" "r")
9993 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
9997 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9998 (operands[0], operands[1], operands[2]));
10002 ; This use of vec_select isn't exactly correct according to rtl.texi
10003 ; (because not constant), but it seems a straightforward extension.
10004 (define_insn "mperm_w_little"
10005 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10007 (match_operand:V4HI 1 "arith_reg_operand" "r")
10009 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10010 (const_int 2) (const_int 0))
10011 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10012 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10013 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10014 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10015 "mperm.w %1, %N2, %0"
10016 [(set_attr "type" "arith_media")])
10018 (define_insn "mperm_w_big"
10019 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10021 (match_operand:V4HI 1 "arith_reg_operand" "r")
10023 [(zero_extract:QI (not:QI (match_operand:QI 2
10024 "extend_reg_or_0_operand" "rZ"))
10025 (const_int 2) (const_int 0))
10026 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10027 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10028 (zero_extract:QI (not:QI (match_dup 2))
10029 (const_int 2) (const_int 6))])))]
10030 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10031 "mperm.w %1, %N2, %0"
10032 [(set_attr "type" "arith_media")])
10034 (define_insn "mperm_w0"
10035 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10037 "trunc_hi_operand" "r"))))]
10039 "mperm.w %1, r63, %0"
10040 [(set_attr "type" "arith_media")])
10042 (define_expand "msad_ubq"
10043 [(match_operand:DI 0 "arith_reg_dest" "")
10044 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10045 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10046 (match_operand:DI 3 "arith_reg_operand" "")]
10050 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10051 operands[1], operands[2]));
10055 (define_insn "msad_ubq_i"
10056 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10061 (match_operand:DI 1 "arith_reg_operand" "0")
10062 (abs:DI (vec_select:DI
10065 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10067 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10068 (parallel [(const_int 0)]))))
10069 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10070 (zero_extend:V8DI (match_dup 3)))
10071 (parallel [(const_int 1)]))))
10073 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10074 (zero_extend:V8DI (match_dup 3)))
10075 (parallel [(const_int 2)])))
10076 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10077 (zero_extend:V8DI (match_dup 3)))
10078 (parallel [(const_int 3)])))))
10081 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10082 (zero_extend:V8DI (match_dup 3)))
10083 (parallel [(const_int 4)])))
10084 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10085 (zero_extend:V8DI (match_dup 3)))
10086 (parallel [(const_int 5)]))))
10088 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10089 (zero_extend:V8DI (match_dup 3)))
10090 (parallel [(const_int 6)])))
10091 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10092 (zero_extend:V8DI (match_dup 3)))
10093 (parallel [(const_int 7)])))))))]
10095 "msad.ubq %N2, %N3, %0"
10096 [(set_attr "type" "mac_media")])
10098 (define_insn "mshalds_l"
10099 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10102 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10103 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10104 (const_int 31)))))]
10106 "mshalds.l %1, %2, %0"
10107 [(set_attr "type" "mcmp_media")])
10109 (define_insn "mshalds_w"
10110 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10113 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10114 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10115 (const_int 15)))))]
10117 "mshalds.w %1, %2, %0"
10118 [(set_attr "type" "mcmp_media")])
10120 (define_insn "ashrv2si3"
10121 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10122 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10123 (match_operand:DI 2 "arith_reg_operand" "r")))]
10125 "mshard.l %1, %2, %0"
10126 [(set_attr "type" "arith_media")])
10128 (define_insn "ashrv4hi3"
10129 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10130 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10131 (match_operand:DI 2 "arith_reg_operand" "r")))]
10133 "mshard.w %1, %2, %0"
10134 [(set_attr "type" "arith_media")])
10136 (define_insn "mshards_q"
10137 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10139 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10140 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10142 "mshards.q %1, %N2, %0"
10143 [(set_attr "type" "mcmp_media")])
10145 (define_expand "mshfhi_b"
10146 [(match_operand:V8QI 0 "arith_reg_dest" "")
10147 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10148 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10152 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10153 (operands[0], operands[1], operands[2]));
10157 (define_expand "mshflo_b"
10158 [(match_operand:V8QI 0 "arith_reg_dest" "")
10159 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10160 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10164 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10165 (operands[0], operands[1], operands[2]));
10169 (define_insn "mshf4_b"
10171 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10173 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10174 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10175 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10176 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10178 "* return (TARGET_LITTLE_ENDIAN
10179 ? \"mshfhi.b %N1, %N2, %0\"
10180 : \"mshflo.b %N1, %N2, %0\");"
10181 [(set_attr "type" "arith_media")])
10183 (define_insn "mshf0_b"
10185 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10187 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10188 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10189 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10190 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10192 "* return (TARGET_LITTLE_ENDIAN
10193 ? \"mshflo.b %N1, %N2, %0\"
10194 : \"mshfhi.b %N1, %N2, %0\");"
10195 [(set_attr "type" "arith_media")])
10197 (define_expand "mshfhi_l"
10198 [(match_operand:V2SI 0 "arith_reg_dest" "")
10199 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10200 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10204 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10205 (operands[0], operands[1], operands[2]));
10209 (define_expand "mshflo_l"
10210 [(match_operand:V2SI 0 "arith_reg_dest" "")
10211 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10212 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10216 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10217 (operands[0], operands[1], operands[2]));
10221 (define_insn "mshf4_l"
10222 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10224 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10225 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10226 (parallel [(const_int 1) (const_int 3)])))]
10228 "* return (TARGET_LITTLE_ENDIAN
10229 ? \"mshfhi.l %N1, %N2, %0\"
10230 : \"mshflo.l %N1, %N2, %0\");"
10231 [(set_attr "type" "arith_media")])
10233 (define_insn "mshf0_l"
10234 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10236 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10237 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10238 (parallel [(const_int 0) (const_int 2)])))]
10240 "* return (TARGET_LITTLE_ENDIAN
10241 ? \"mshflo.l %N1, %N2, %0\"
10242 : \"mshfhi.l %N1, %N2, %0\");"
10243 [(set_attr "type" "arith_media")])
10245 (define_expand "mshfhi_w"
10246 [(match_operand:V4HI 0 "arith_reg_dest" "")
10247 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10248 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10252 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10253 (operands[0], operands[1], operands[2]));
10257 (define_expand "mshflo_w"
10258 [(match_operand:V4HI 0 "arith_reg_dest" "")
10259 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10260 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10264 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10265 (operands[0], operands[1], operands[2]));
10269 (define_insn "mshf4_w"
10270 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10272 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10273 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10274 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10276 "* return (TARGET_LITTLE_ENDIAN
10277 ? \"mshfhi.w %N1, %N2, %0\"
10278 : \"mshflo.w %N1, %N2, %0\");"
10279 [(set_attr "type" "arith_media")])
10281 (define_insn "mshf0_w"
10282 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10284 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10285 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10286 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10288 "* return (TARGET_LITTLE_ENDIAN
10289 ? \"mshflo.w %N1, %N2, %0\"
10290 : \"mshfhi.w %N1, %N2, %0\");"
10291 [(set_attr "type" "arith_media")])
10293 (define_insn "mshflo_w_x"
10294 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10296 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10297 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10298 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10300 "mshflo.w %N1, %N2, %0"
10301 [(set_attr "type" "arith_media")])
10303 /* These are useful to expand ANDs and as combiner patterns. */
10304 (define_insn_and_split "mshfhi_l_di"
10305 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10306 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10308 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10309 (const_int -4294967296))))]
10312 mshfhi.l %N1, %N2, %0
10314 "TARGET_SHMEDIA && reload_completed
10315 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10316 [(set (match_dup 3) (match_dup 4))
10317 (set (match_dup 5) (match_dup 6))]
10320 operands[3] = gen_lowpart (SImode, operands[0]);
10321 operands[4] = gen_highpart (SImode, operands[1]);
10322 operands[5] = gen_highpart (SImode, operands[0]);
10323 operands[6] = gen_highpart (SImode, operands[2]);
10325 [(set_attr "type" "arith_media")])
10327 (define_insn "*mshfhi_l_di_rev"
10328 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10329 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10330 (const_int -4294967296))
10331 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10334 "mshfhi.l %N2, %N1, %0"
10335 [(set_attr "type" "arith_media")])
10338 [(set (match_operand:DI 0 "arith_reg_dest" "")
10339 (ior:DI (zero_extend:DI (match_operand:SI 1
10340 "extend_reg_or_0_operand" ""))
10341 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10342 (const_int -4294967296))))
10343 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10348 emit_insn (gen_ashldi3_media (operands[3],
10349 simplify_gen_subreg (DImode, operands[1],
10352 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10356 (define_insn "mshflo_l_di"
10357 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10358 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10359 (const_int 4294967295))
10360 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10364 "mshflo.l %N1, %N2, %0"
10365 [(set_attr "type" "arith_media")])
10367 (define_insn "*mshflo_l_di_rev"
10368 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10369 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10371 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10372 (const_int 4294967295))))]
10375 "mshflo.l %N2, %N1, %0"
10376 [(set_attr "type" "arith_media")])
10378 ;; Combiner pattern for trampoline initialization.
10379 (define_insn_and_split "*double_shori"
10380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10381 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10383 (match_operand:DI 2 "const_int_operand" "n")))]
10385 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10387 "rtx_equal_p (operands[0], operands[1])"
10391 HOST_WIDE_INT v = INTVAL (operands[2]);
10393 emit_insn (gen_shori_media (operands[0], operands[0],
10394 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10395 emit_insn (gen_shori_media (operands[0], operands[0],
10396 gen_int_mode (v, HImode)));
10401 (define_insn "*mshflo_l_di_x"
10402 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10403 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10405 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10409 "mshflo.l %N1, %N2, %0"
10410 [(set_attr "type" "arith_media")])
10412 (define_insn_and_split "concat_v2sf"
10413 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10414 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10415 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10416 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10420 mshflo.l %N1, %N2, %0
10423 "TARGET_SHMEDIA && reload_completed
10424 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10425 [(set (match_dup 3) (match_dup 1))
10426 (set (match_dup 4) (match_dup 2))]
10429 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10430 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10432 [(set_attr "type" "arith_media")])
10434 (define_insn "*mshflo_l_di_x_rev"
10435 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10436 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10438 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10441 "mshflo.l %N2, %N1, %0"
10442 [(set_attr "type" "arith_media")])
10444 (define_insn "ashlv2si3"
10445 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10446 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10447 (match_operand:DI 2 "arith_reg_operand" "r")))]
10449 "mshlld.l %1, %2, %0"
10450 [(set_attr "type" "arith_media")])
10452 (define_insn "ashlv4hi3"
10453 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10454 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10455 (match_operand:DI 2 "arith_reg_operand" "r")))]
10457 "mshlld.w %1, %2, %0"
10458 [(set_attr "type" "arith_media")])
10460 (define_insn "lshrv2si3"
10461 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10462 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10463 (match_operand:DI 2 "arith_reg_operand" "r")))]
10465 "mshlrd.l %1, %2, %0"
10466 [(set_attr "type" "arith_media")])
10468 (define_insn "lshrv4hi3"
10469 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10471 (match_operand:DI 2 "arith_reg_operand" "r")))]
10473 "mshlrd.w %1, %2, %0"
10474 [(set_attr "type" "arith_media")])
10476 (define_insn "subv2si3"
10477 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10478 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10479 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10481 "msub.l %N1, %2, %0"
10482 [(set_attr "type" "arith_media")])
10484 (define_insn "subv4hi3"
10485 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10486 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10487 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10489 "msub.w %N1, %2, %0"
10490 [(set_attr "type" "arith_media")])
10492 (define_insn "sssubv2si3"
10493 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10494 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10497 "msubs.l %N1, %2, %0"
10498 [(set_attr "type" "mcmp_media")])
10500 (define_insn "ussubv8qi3"
10501 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10502 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10503 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10505 "msubs.ub %1, %2, %0"
10506 [(set_attr "type" "mcmp_media")])
10508 (define_insn "sssubv4hi3"
10509 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10510 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10511 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10513 "msubs.w %N1, %2, %0"
10514 [(set_attr "type" "mcmp_media")])
10516 ;; Floating Point Intrinsics
10518 (define_insn "fcosa_s"
10519 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10520 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10524 [(set_attr "type" "atrans_media")])
10526 (define_insn "fsina_s"
10527 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10528 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10532 [(set_attr "type" "atrans_media")])
10534 (define_insn "fipr"
10535 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10537 "fp_arith_reg_operand" "f")
10538 (match_operand:V4SF 2
10539 "fp_arith_reg_operand" "f"))
10540 (parallel [(const_int 0)]))
10541 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10542 (parallel [(const_int 1)])))
10543 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10544 (parallel [(const_int 2)]))
10545 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10546 (parallel [(const_int 3)])))))]
10549 [(set_attr "type" "fparith_media")])
10551 (define_insn "fsrra_s"
10552 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10553 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10557 [(set_attr "type" "atrans_media")])
10559 (define_insn "ftrv"
10560 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10564 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10565 (parallel [(const_int 0) (const_int 5)
10566 (const_int 10) (const_int 15)]))
10567 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10569 (vec_select:V4SF (match_dup 1)
10570 (parallel [(const_int 4) (const_int 9)
10571 (const_int 14) (const_int 3)]))
10572 (vec_select:V4SF (match_dup 2)
10573 (parallel [(const_int 1) (const_int 2)
10574 (const_int 3) (const_int 0)]))))
10577 (vec_select:V4SF (match_dup 1)
10578 (parallel [(const_int 8) (const_int 13)
10579 (const_int 2) (const_int 7)]))
10580 (vec_select:V4SF (match_dup 2)
10581 (parallel [(const_int 2) (const_int 3)
10582 (const_int 0) (const_int 1)])))
10584 (vec_select:V4SF (match_dup 1)
10585 (parallel [(const_int 12) (const_int 1)
10586 (const_int 6) (const_int 11)]))
10587 (vec_select:V4SF (match_dup 2)
10588 (parallel [(const_int 3) (const_int 0)
10589 (const_int 1) (const_int 2)]))))))]
10592 [(set_attr "type" "fparith_media")])
10595 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10596 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10600 [(set_attr "type" "arith_media")])
10602 (define_insn "nsbsi"
10603 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10605 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10609 [(set_attr "type" "arith_media")])
10611 (define_insn "nsbdi"
10612 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10614 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10618 [(set_attr "type" "arith_media")])
10620 (define_expand "ffsdi2"
10621 [(set (match_operand:DI 0 "arith_reg_dest" "")
10622 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10626 rtx scratch = gen_reg_rtx (DImode);
10629 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10630 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10631 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10632 emit_insn (gen_nsbdi (scratch, scratch));
10633 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10634 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10635 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10637 = gen_rtx_EXPR_LIST (REG_EQUAL,
10638 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10642 (define_expand "ffssi2"
10643 [(set (match_operand:SI 0 "arith_reg_dest" "")
10644 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10648 rtx scratch = gen_reg_rtx (SImode);
10649 rtx discratch = gen_reg_rtx (DImode);
10652 emit_insn (gen_adddi3 (discratch,
10653 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10655 emit_insn (gen_andcdi3 (discratch,
10656 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10658 emit_insn (gen_nsbsi (scratch, discratch));
10659 last = emit_insn (gen_subsi3 (operands[0],
10660 force_reg (SImode, GEN_INT (63)), scratch));
10662 = gen_rtx_EXPR_LIST (REG_EQUAL,
10663 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10667 (define_insn "byterev"
10668 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10669 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10670 (parallel [(const_int 7) (const_int 6) (const_int 5)
10671 (const_int 4) (const_int 3) (const_int 2)
10672 (const_int 1) (const_int 0)])))]
10675 [(set_attr "type" "arith_media")])
10677 ;; The following description models the
10678 ;; SH4 pipeline using the DFA based scheduler.
10679 ;; The DFA based description is better way to model
10680 ;; a superscalar pipeline as compared to function unit
10681 ;; reservation model.
10682 ;; 1. The function unit based model is oriented to describe at most one
10683 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10684 ;; pipeline units by same insn. This can be done using DFA based description.
10685 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10686 ;; 3. Writing all unit reservations for an instruction class is more natural description
10687 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10688 ;; old function unit based model.
10689 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10692 ;; Two automata are defined to reduce number of states
10693 ;; which a single large automaton will have.(Factoring)
10695 (define_automaton "inst_pipeline,fpu_pipe")
10697 ;; This unit is basically the decode unit of the processor.
10698 ;; Since SH4 is a dual issue machine,it is as if there are two
10699 ;; units so that any insn can be processed by either one
10700 ;; of the decoding unit.
10702 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10705 ;; The fixed point arithmetic calculator(?? EX Unit).
10707 (define_cpu_unit "int" "inst_pipeline")
10709 ;; f1_1 and f1_2 are floating point units.Actually there is
10710 ;; a f1 unit which can overlap with other f1 unit but
10711 ;; not another F1 unit.It is as though there were two
10714 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10716 ;; The floating point units (except FS - F2 always precedes it.)
10718 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10720 ;; This is basically the MA unit of SH4
10721 ;; used in LOAD/STORE pipeline.
10723 (define_cpu_unit "memory" "inst_pipeline")
10725 ;; However, there are LS group insns that don't use it, even ones that
10726 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10727 (define_cpu_unit "load_store" "inst_pipeline")
10729 ;; The address calculator used for branch instructions.
10730 ;; This will be reserved after "issue" of branch instructions
10731 ;; and this is to make sure that no two branch instructions
10732 ;; can be issued in parallel.
10734 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10736 ;; ----------------------------------------------------
10737 ;; This reservation is to simplify the dual issue description.
10739 (define_reservation "issue" "pipe_01|pipe_02")
10741 ;; This is to express the locking of D stage.
10742 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10744 (define_reservation "d_lock" "pipe_01+pipe_02")
10746 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10747 (define_reservation "F01" "F0+F1")
10749 ;; This is to simplify description where F1,F2,FS
10750 ;; are used simultaneously.
10752 (define_reservation "fpu" "F1+F2")
10754 ;; This is to highlight the fact that f1
10755 ;; cannot overlap with F1.
10757 (exclusion_set "f1_1,f1_2" "F1")
10759 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10761 ;; Although reg moves have a latency of zero
10762 ;; we need to highlight that they use D stage
10767 (define_insn_reservation "reg_mov" 0
10768 (and (eq_attr "pipe_model" "sh4")
10769 (eq_attr "type" "move"))
10774 (define_insn_reservation "freg_mov" 0
10775 (and (eq_attr "pipe_model" "sh4")
10776 (eq_attr "type" "fmove"))
10777 "issue+load_store")
10779 ;; We don't model all pipeline stages; we model the issue ('D') stage
10780 ;; inasmuch as we allow only two instructions to issue simultaneously,
10781 ;; and CO instructions prevent any simultaneous issue of another instruction.
10782 ;; (This uses pipe_01 and pipe_02).
10783 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10784 ;; Double issue of EX / BR insns is prevented by using the int unit /
10785 ;; pcr_addrcalc unit in the EX stage.
10786 ;; Double issue of BR / LS instructions is prevented by using the
10787 ;; pcr_addrcalc / load_store unit in the issue cycle.
10788 ;; Double issue of FE instructions is prevented by using F0 in the first
10789 ;; pipeline stage after the first D stage.
10790 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10791 ;; (except in the cases outlined above), nor to describe the FS stage after
10794 ;; Other MT group instructions(1 step operations)
10799 (define_insn_reservation "mt" 1
10800 (and (eq_attr "pipe_model" "sh4")
10801 (eq_attr "type" "mt_group"))
10804 ;; Fixed Point Arithmetic Instructions(1 step operations)
10809 (define_insn_reservation "sh4_simple_arith" 1
10810 (and (eq_attr "pipe_model" "sh4")
10811 (eq_attr "insn_class" "ex_group"))
10814 ;; Load and store instructions have no alignment peculiarities for the SH4,
10815 ;; but they use the load-store unit, which they share with the fmove type
10816 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10817 ;; Loads have a latency of two.
10818 ;; However, call insns can only paired with a preceding insn, and have
10819 ;; a delay slot, so that we want two more insns to be scheduled between the
10820 ;; load of the function address and the call. This is equivalent to a
10821 ;; latency of three.
10822 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10823 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10824 ;; We only do this for SImode loads of general registers, to make the work
10825 ;; for ADJUST_COST easier.
10827 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10832 (define_insn_reservation "sh4_load" 2
10833 (and (eq_attr "pipe_model" "sh4")
10834 (eq_attr "type" "load,pcload"))
10835 "issue+load_store,nothing,memory")
10837 ;; calls / sfuncs need an extra instruction for their delay slot.
10838 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10839 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10840 ;; count of a dynamic shift.
10841 (define_insn_reservation "sh4_load_si" 3
10842 (and (eq_attr "pipe_model" "sh4")
10843 (eq_attr "type" "load_si,pcload_si"))
10844 "issue+load_store,nothing,memory")
10846 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10848 ;; The load latency is upped to three higher if the dependent insn does
10849 ;; double precision computation. We want the 'default' latency to reflect
10850 ;; that increased latency because otherwise the insn priorities won't
10851 ;; allow proper scheduling.
10852 (define_insn_reservation "sh4_fload" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "fload,pcfload"))
10855 "issue+load_store,nothing,memory")
10857 ;; (define_bypass 2 "sh4_fload" "!")
10859 (define_insn_reservation "sh4_store" 1
10860 (and (eq_attr "pipe_model" "sh4")
10861 (eq_attr "type" "store"))
10862 "issue+load_store,nothing,memory")
10864 ;; Load Store instructions.
10869 (define_insn_reservation "sh4_gp_fpul" 1
10870 (and (eq_attr "pipe_model" "sh4")
10871 (eq_attr "type" "gp_fpul"))
10872 "issue+load_store")
10874 ;; Load Store instructions.
10879 (define_insn_reservation "sh4_fpul_gp" 3
10880 (and (eq_attr "pipe_model" "sh4")
10881 (eq_attr "type" "fpul_gp"))
10882 "issue+load_store")
10884 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10886 ;; Latency when taken: 2 (or 1)
10888 ;; The latency is 1 when displacement is 0.
10889 ;; We can't really do much with the latency, even if we could express it,
10890 ;; but the pairing restrictions are useful to take into account.
10891 ;; ??? If the branch is likely, we might want to fill the delay slot;
10892 ;; if the branch is likely, but not very likely, should we pretend to use
10893 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10895 (define_insn_reservation "sh4_branch" 1
10896 (and (eq_attr "pipe_model" "sh4")
10897 (eq_attr "type" "cbranch,jump"))
10898 "issue+pcr_addrcalc")
10900 ;; Branch Far (JMP,RTS,BRAF)
10904 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10905 ;; can't be distinguished from bra for the "jump" pattern.
10907 (define_insn_reservation "sh4_return" 3
10908 (and (eq_attr "pipe_model" "sh4")
10909 (eq_attr "type" "return,jump_ind"))
10916 ;; this instruction can be executed in any of the pipelines
10917 ;; and blocks the pipeline for next 4 stages.
10919 (define_insn_reservation "sh4_return_from_exp" 5
10920 (and (eq_attr "pipe_model" "sh4")
10921 (eq_attr "type" "rte"))
10929 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10930 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10931 (define_insn_reservation "ocbwb" 6
10932 (and (eq_attr "pipe_model" "sh4")
10933 (eq_attr "type" "cwb"))
10934 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10940 ;; The SX stage is blocked for last 2 cycles.
10941 ;; OTOH, the only time that has an effect for insns generated by the compiler
10942 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10943 ;; or when we are doing a function call - and we don't do inter-function
10944 ;; scheduling. For the function call case, it's really best that we end with
10945 ;; something that models an rts.
10947 (define_insn_reservation "sh4_lds_to_pr" 3
10948 (and (eq_attr "pipe_model" "sh4")
10949 (eq_attr "type" "prset") )
10952 ;; calls introduce a longisch delay that is likely to flush the pipelines
10953 ;; of the caller's instructions. Ordinary functions tend to end with a
10954 ;; load to restore a register (in the delay slot of rts), while sfuncs
10955 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10956 ;; since there are no instructions that contend for memory access early.
10957 ;; We could, of course, provide exact scheduling information for specific
10958 ;; sfuncs, if that should prove useful.
10960 (define_insn_reservation "sh4_call" 16
10961 (and (eq_attr "pipe_model" "sh4")
10962 (eq_attr "type" "call,sfunc"))
10969 ;; The SX unit is blocked for last 2 cycles.
10971 (define_insn_reservation "ldsmem_to_pr" 3
10972 (and (eq_attr "pipe_model" "sh4")
10973 (eq_attr "type" "pload"))
10980 ;; The SX unit in second and third cycles.
10982 (define_insn_reservation "sts_from_pr" 2
10983 (and (eq_attr "pipe_model" "sh4")
10984 (eq_attr "type" "prget"))
10992 (define_insn_reservation "sh4_prstore_mem" 2
10993 (and (eq_attr "pipe_model" "sh4")
10994 (eq_attr "type" "pstore"))
10995 "d_lock*2,nothing,memory")
11001 ;; F1 is blocked for last three cycles.
11003 (define_insn_reservation "fpscr_load" 4
11004 (and (eq_attr "pipe_model" "sh4")
11005 (eq_attr "type" "gp_fpscr"))
11006 "d_lock,nothing,F1*3")
11011 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11013 ;; F1 is blocked for last three cycles.
11015 (define_insn_reservation "fpscr_load_mem" 4
11016 (and (eq_attr "pipe_model" "sh4")
11017 (eq_attr "type" "mem_fpscr"))
11018 "d_lock,nothing,(F1+memory),F1*2")
11021 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11026 (define_insn_reservation "multi" 4
11027 (and (eq_attr "pipe_model" "sh4")
11028 (eq_attr "type" "smpy,dmpy"))
11029 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11031 ;; Fixed STS from MACL / MACH
11036 (define_insn_reservation "sh4_mac_gp" 3
11037 (and (eq_attr "pipe_model" "sh4")
11038 (eq_attr "type" "mac_gp"))
11042 ;; Single precision floating point computation FCMP/EQ,
11043 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11048 (define_insn_reservation "fp_arith" 3
11049 (and (eq_attr "pipe_model" "sh4")
11050 (eq_attr "type" "fp"))
11053 (define_insn_reservation "fp_arith_ftrc" 3
11054 (and (eq_attr "pipe_model" "sh4")
11055 (eq_attr "type" "ftrc_s"))
11058 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11060 ;; Single Precision FDIV/SQRT
11062 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
11064 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11066 (define_insn_reservation "fp_div" 12
11067 (and (eq_attr "pipe_model" "sh4")
11068 (eq_attr "type" "fdiv"))
11069 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11071 ;; Double Precision floating point computation
11072 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11074 ;; Latency: (3,4)/5
11077 (define_insn_reservation "dp_float" 4
11078 (and (eq_attr "pipe_model" "sh4")
11079 (eq_attr "type" "dfp_conv"))
11080 "issue,F01,F1+F2,F2")
11082 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11084 ;; Latency: (7,8)/9
11087 (define_insn_reservation "fp_double_arith" 8
11088 (and (eq_attr "pipe_model" "sh4")
11089 (eq_attr "type" "dfp_arith"))
11090 "issue,F01,F1+F2,fpu*4,F2")
11092 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11097 (define_insn_reservation "fp_double_cmp" 3
11098 (and (eq_attr "pipe_model" "sh4")
11099 (eq_attr "type" "dfp_cmp"))
11100 "d_lock,(d_lock+F01),F1+F2,F2")
11102 ;; Double precision FDIV/SQRT
11104 ;; Latency: (24,25)/26
11107 (define_insn_reservation "dp_div" 25
11108 (and (eq_attr "pipe_model" "sh4")
11109 (eq_attr "type" "dfdiv"))
11110 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11113 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
11114 ;; case, we'd get a d_lock instead of issue at the end.
11115 (define_insn_reservation "arith3" 3
11116 (and (eq_attr "pipe_model" "sh4")
11117 (eq_attr "type" "arith3"))
11118 "issue,d_lock+pcr_addrcalc,issue")
11120 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11121 (define_insn_reservation "arith3b" 2
11122 (and (eq_attr "pipe_model" "sh4")
11123 (eq_attr "type" "arith3"))
11124 "issue,d_lock+pcr_addrcalc")