1 ;;- Machine description for Hitachi / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;; Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING. If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences. Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported. There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported. Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR. This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
50 ;; Special formats used for outputting SH instructions:
52 ;; %. -- print a .s if insn needs delay slot
53 ;; %@ -- print rte/rts if is/isn't an interrupt function
54 ;; %# -- output a nop if there is nothing to put in the delay slot
55 ;; %O -- print a constant without the #
56 ;; %R -- print the lsw reg of a double
57 ;; %S -- print the msw reg of a double
58 ;; %T -- print next word of a double REG or MEM
60 ;; Special predicates:
62 ;; arith_operand -- operand is valid source for arithmetic op
63 ;; arith_reg_operand -- operand is valid register for arithmetic op
64 ;; general_movdst_operand -- operand is valid move destination
65 ;; general_movsrc_operand -- operand is valid move source
66 ;; logical_operand -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
70 ;; -------------------------------------------------------------------------
118 ;; These are used with unspec.
119 (UNSPEC_COMPACT_ARGS 0)
132 (UNSPEC_INIT_TRAMP 13)
139 ;; These are used with unspec_volatile.
145 (UNSPECV_WINDOW_END 10)
146 (UNSPECV_CONST_END 11)
149 ;; -------------------------------------------------------------------------
151 ;; -------------------------------------------------------------------------
156 "sh1,sh2,sh3,sh3e,sh4,sh5"
157 (const (symbol_ref "sh_cpu_attr")))
159 (define_attr "endian" "big,little"
160 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
161 (const_string "little") (const_string "big"))))
163 ;; Indicate if the default fpu mode is single precision.
164 (define_attr "fpu_single" "yes,no"
165 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
166 (const_string "yes") (const_string "no"))))
168 (define_attr "fmovd" "yes,no"
169 (const (if_then_else (symbol_ref "TARGET_FMOVD")
170 (const_string "yes") (const_string "no"))))
172 (define_attr "pipe_model" "sh1,sh4,sh5media"
174 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
175 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
176 (const_string "sh1"))))
178 ;; cbranch conditional branch instructions
179 ;; jump unconditional jumps
180 ;; arith ordinary arithmetic
181 ;; arith3 a compound insn that behaves similarly to a sequence of
182 ;; three insns of type arith
183 ;; arith3b like above, but might end with a redirected branch
185 ;; load_si Likewise, SImode variant for general register.
186 ;; fload Likewise, but load to fp register.
188 ;; move general purpose register to register
189 ;; mt_group other sh4 mt instructions
190 ;; fmove register to register, floating point
191 ;; smpy word precision integer multiply
192 ;; dmpy longword or doublelongword precision integer multiply
194 ;; pload load of pr reg, which can't be put into delay slot of rts
195 ;; prset copy register to pr reg, ditto
196 ;; pstore store of pr reg, which can't be put into delay slot of jsr
197 ;; prget copy pr to register, ditto
198 ;; pcload pc relative load of constant value
199 ;; pcfload Likewise, but load to fp register.
200 ;; pcload_si Likewise, SImode variant for general register.
201 ;; rte return from exception
202 ;; sfunc special function call with known used registers
203 ;; call function call
205 ;; fdiv floating point divide (or square root)
206 ;; gp_fpul move from general purpose register to fpul
207 ;; fpul_gp move from fpul to general purpose register
208 ;; mac_gp move from mac[lh] to general purpose register
209 ;; dfp_arith, dfp_cmp,dfp_conv
210 ;; ftrc_s fix_truncsfsi2_i4
211 ;; dfdiv double precision floating point divide (or square root)
212 ;; cwb ic_invalidate_line_i
213 ;; arith_media SHmedia arithmetic, logical, and shift instructions
214 ;; cbranch_media SHmedia conditional branch instructions
215 ;; cmp_media SHmedia compare instructions
216 ;; dfdiv_media SHmedia double precision divide and square root
217 ;; dfmul_media SHmedia double precision multiply instruction
218 ;; dfparith_media SHmedia double precision floating point arithmetic
219 ;; dfpconv_media SHmedia double precision floating point conversions
220 ;; dmpy_media SHmedia longword multiply
221 ;; fcmp_media SHmedia floating point compare instructions
222 ;; fdiv_media SHmedia single precision divide and square root
223 ;; fload_media SHmedia floating point register load instructions
224 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
225 ;; fparith_media SHmedia single precision floating point arithmetic
226 ;; fpconv_media SHmedia single precision floating point conversions
227 ;; fstore_media SHmedia floating point register store instructions
228 ;; gettr_media SHmedia gettr instruction
229 ;; invalidate_line_media SHmedia invaldiate_line sequence
230 ;; jump_media SHmedia unconditional branch instructions
231 ;; load_media SHmedia general register load instructions
232 ;; pt_media SHmedia pt instruction (expanded by assembler)
233 ;; ptabs_media SHmedia ptabs instruction
234 ;; store_media SHmedia general register store instructions
235 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
236 ;; mac_media SHmedia mac-style fixed point operations
237 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
238 ;; atrans SHmedia approximate transcendential functions
239 ;; ustore_media SHmedia unaligned stores
240 ;; nil no-op move, will be deleted.
243 "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,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"
244 (const_string "other"))
246 ;; We define a new attribute namely "insn_class".We use
247 ;; this for the DFA based pipeline description.
249 ;; mt_group SH4 "mt" group instructions.
251 ;; ex_group SH4 "ex" group instructions.
253 ;; ls_group SH4 "ls" group instructions.
256 (define_attr "insn_class"
257 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
258 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
259 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
260 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
261 (eq_attr "type" "cbranch,jump") (const_string "br_group")
262 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
263 (const_string "fe_group")
264 (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")]
265 (const_string "none")))
266 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
267 ;; so these do not belong in an insn group, although they are modeled
268 ;; with their own define_insn_reservations.
270 ;; Indicate what precision must be selected in fpscr for this insn, if any.
272 (define_attr "fp_mode" "single,double,none" (const_string "none"))
274 ; If a conditional branch destination is within -252..258 bytes away
275 ; from the instruction it can be 2 bytes long. Something in the
276 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
277 ; branches are initially assumed to be 16 bytes long.
278 ; In machine_dependent_reorg, we split all branches that are longer than
281 ;; The maximum range used for SImode constant pool entries is 1018. A final
282 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
283 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
284 ;; instruction around the pool table, 2 bytes of alignment before the table,
285 ;; and 30 bytes of alignment after the table. That gives a maximum total
286 ;; pool size of 1058 bytes.
287 ;; Worst case code/pool content size ratio is 1:2 (using asms).
288 ;; Thus, in the worst case, there is one instruction in front of a maximum
289 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
290 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
291 ;; If we have a forward branch, the initial table will be put after the
292 ;; unconditional branch.
294 ;; ??? We could do much better by keeping track of the actual pcloads within
295 ;; the branch range and in the pcload range in front of the branch range.
297 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
299 (define_attr "short_cbranch_p" "no,yes"
300 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
302 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
304 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
306 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
308 ] (const_string "no")))
310 (define_attr "med_branch_p" "no,yes"
311 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
314 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
316 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
319 ] (const_string "no")))
321 (define_attr "med_cbranch_p" "no,yes"
322 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
325 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
327 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
330 ] (const_string "no")))
332 (define_attr "braf_branch_p" "no,yes"
333 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
335 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
338 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
340 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
343 ] (const_string "no")))
345 (define_attr "braf_cbranch_p" "no,yes"
346 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
348 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
351 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
356 ] (const_string "no")))
358 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
359 ; For wider ranges, we need a combination of a code and a data part.
360 ; If we can get a scratch register for a long range jump, the code
361 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
362 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
363 ; long; otherwise, it must be 6 bytes long.
365 ; All other instructions are two bytes long by default.
367 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
368 ;; but getattrtab doesn't understand this.
369 (define_attr "length" ""
370 (cond [(eq_attr "type" "cbranch")
371 (cond [(eq_attr "short_cbranch_p" "yes")
373 (eq_attr "med_cbranch_p" "yes")
375 (eq_attr "braf_cbranch_p" "yes")
377 ;; ??? using pc is not computed transitively.
378 (ne (match_dup 0) (match_dup 0))
380 (ne (symbol_ref ("flag_pic")) (const_int 0))
383 (eq_attr "type" "jump")
384 (cond [(eq_attr "med_branch_p" "yes")
386 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
388 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
389 (symbol_ref "code_for_indirect_jump_scratch")))
390 (if_then_else (eq_attr "braf_branch_p" "yes")
393 (eq_attr "braf_branch_p" "yes")
395 ;; ??? using pc is not computed transitively.
396 (ne (match_dup 0) (match_dup 0))
398 (ne (symbol_ref ("flag_pic")) (const_int 0))
401 (eq_attr "type" "pt_media")
402 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
403 (const_int 20) (const_int 12))
404 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
408 ;; (define_function_unit {name} {num-units} {n-users} {test}
409 ;; {ready-delay} {issue-delay} [{conflict-list}])
411 ;; Load and store instructions save a cycle if they are aligned on a
412 ;; four byte boundary. Using a function unit for stores encourages
413 ;; gcc to separate load and store instructions by one instruction,
414 ;; which makes it more likely that the linker will be able to word
415 ;; align them when relaxing.
417 ;; Loads have a latency of two.
418 ;; However, call insns can have a delay slot, so that we want one more
419 ;; insn to be scheduled between the load of the function address and the call.
420 ;; This is equivalent to a latency of three.
421 ;; We cannot use a conflict list for this, because we need to distinguish
422 ;; between the actual call address and the function arguments.
423 ;; ADJUST_COST can only properly handle reductions of the cost, so we
424 ;; use a latency of three here.
425 ;; We only do this for SImode loads of general registers, to make the work
426 ;; for ADJUST_COST easier.
427 (define_function_unit "memory" 1 0
428 (and (eq_attr "pipe_model" "sh1")
429 (eq_attr "type" "load_si,pcload_si"))
431 (define_function_unit "memory" 1 0
432 (and (eq_attr "pipe_model" "sh1")
433 (eq_attr "type" "load,pcload,pload,store,pstore"))
436 (define_function_unit "int" 1 0
437 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
439 (define_function_unit "int" 1 0
440 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
442 (define_function_unit "int" 1 0
443 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
445 ;; ??? These are approximations.
446 (define_function_unit "mpy" 1 0
447 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
448 (define_function_unit "mpy" 1 0
449 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
451 (define_function_unit "fp" 1 0
452 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
453 (define_function_unit "fp" 1 0
454 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
457 ;; SH-5 SHmedia scheduling
458 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
459 ;; single-issue machine. It has four pipelines, the branch unit (br),
460 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
461 ;; the floating point unit (fpu).
462 ;; Here model the instructions with a latency greater than one cycle.
464 ;; Every instruction on SH-5 occupies the issue resource for at least one
466 (define_function_unit "sh5issue" 1 0
467 (and (eq_attr "pipe_model" "sh5media")
468 (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)
470 ;; Specify the various types of instruction which have latency > 1
471 (define_function_unit "sh5issue" 1 0
472 (and (eq_attr "pipe_model" "sh5media")
473 (eq_attr "type" "mcmp_media")) 2 1)
475 (define_function_unit "sh5issue" 1 0
476 (and (eq_attr "pipe_model" "sh5media")
477 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
478 ;; but see sh_adjust_cost for mac_media exception.
480 (define_function_unit "sh5issue" 1 0
481 (and (eq_attr "pipe_model" "sh5media")
482 (eq_attr "type" "fload_media,fmove_media")) 4 1)
484 (define_function_unit "sh5issue" 1 0
485 (and (eq_attr "pipe_model" "sh5media")
486 (eq_attr "type" "d2mpy_media")) 4 2)
488 (define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
492 (define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
496 (define_function_unit "sh5issue" 1 0
497 (and (eq_attr "pipe_model" "sh5media")
498 (eq_attr "type" "invalidate_line_media")) 7 7)
500 (define_function_unit "sh5issue" 1 0
501 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
503 (define_function_unit "sh5issue" 1 0
504 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
506 ;; Floating-point divide and square-root occupy an additional resource,
507 ;; which is not internally pipelined. However, other instructions
508 ;; can continue to issue.
509 (define_function_unit "sh5fds" 1 0
510 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
512 (define_function_unit "sh5fds" 1 0
513 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
515 ; Definitions for filling branch delay slots.
517 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
519 ;; ??? This should be (nil) instead of (const_int 0)
520 (define_attr "hit_stack" "yes,no"
521 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
524 (const_string "yes")))
526 (define_attr "interrupt_function" "no,yes"
527 (const (symbol_ref "current_function_interrupt")))
529 (define_attr "in_delay_slot" "yes,no"
530 (cond [(eq_attr "type" "cbranch") (const_string "no")
531 (eq_attr "type" "pcload,pcload_si") (const_string "no")
532 (eq_attr "needs_delay_slot" "yes") (const_string "no")
533 (eq_attr "length" "2") (const_string "yes")
534 ] (const_string "no")))
536 (define_attr "cond_delay_slot" "yes,no"
537 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
538 ] (const_string "no")))
540 (define_attr "is_sfunc" ""
541 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
543 (define_attr "is_mac_media" ""
544 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
546 (define_attr "branch_zero" "yes,no"
547 (cond [(eq_attr "type" "!cbranch") (const_string "no")
548 (ne (symbol_ref "(next_active_insn (insn)\
549 == (prev_active_insn\
550 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
551 && get_attr_length (next_active_insn (insn)) == 2")
553 (const_string "yes")]
554 (const_string "no")))
556 ;; SH4 Double-precision computation with double-precision result -
557 ;; the two halves are ready at different times.
558 (define_attr "dfp_comp" "yes,no"
559 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
560 (const_string "no")))
562 ;; Insns for which the latency of a preceding fp insn is decreased by one.
563 (define_attr "late_fp_use" "yes,no" (const_string "no"))
564 ;; And feeding insns for which this relevant.
565 (define_attr "any_fp_comp" "yes,no"
566 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
567 (const_string "yes")]
568 (const_string "no")))
570 (define_attr "any_int_load" "yes,no"
571 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
572 (const_string "yes")]
573 (const_string "no")))
576 (eq_attr "needs_delay_slot" "yes")
577 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
579 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
580 ;; and thus we can't put a pop instruction in its delay slot.
581 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
582 ;; instruction can go in the delay slot.
584 ;; Since a normal return (rts) implicitly uses the PR register,
585 ;; we can't allow PR register loads in an rts delay slot.
588 (eq_attr "type" "return")
589 [(and (eq_attr "in_delay_slot" "yes")
590 (ior (and (eq_attr "interrupt_function" "no")
591 (eq_attr "type" "!pload,prset"))
592 (and (eq_attr "interrupt_function" "yes")
594 (ne (symbol_ref "TARGET_SH3") (const_int 0))
595 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
597 ;; Since a call implicitly uses the PR register, we can't allow
598 ;; a PR register store in a jsr delay slot.
601 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
602 [(and (eq_attr "in_delay_slot" "yes")
603 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
605 ;; Say that we have annulled true branches, since this gives smaller and
606 ;; faster code when branches are predicted as not taken.
609 (and (eq_attr "type" "cbranch")
610 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
611 [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
613 ;; -------------------------------------------------------------------------
614 ;; SImode signed integer comparisons
615 ;; -------------------------------------------------------------------------
619 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
620 (match_operand:SI 1 "arith_operand" "L,r"))
624 [(set_attr "type" "mt_group")])
626 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
627 ;; That would still allow reload to create cmpi instructions, but would
628 ;; perhaps allow forcing the constant into a register when that is better.
629 ;; Probably should use r0 for mem/imm compares, but force constant into a
630 ;; register for pseudo/imm compares.
632 (define_insn "cmpeqsi_t"
634 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
635 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
641 [(set_attr "type" "mt_group")])
643 (define_insn "cmpgtsi_t"
645 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
646 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
651 [(set_attr "type" "mt_group")])
653 (define_insn "cmpgesi_t"
655 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
656 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
661 [(set_attr "type" "mt_group")])
663 ;; -------------------------------------------------------------------------
664 ;; SImode unsigned integer comparisons
665 ;; -------------------------------------------------------------------------
667 (define_insn "cmpgeusi_t"
669 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
670 (match_operand:SI 1 "arith_reg_operand" "r")))]
673 [(set_attr "type" "mt_group")])
675 (define_insn "cmpgtusi_t"
677 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
678 (match_operand:SI 1 "arith_reg_operand" "r")))]
681 [(set_attr "type" "mt_group")])
683 ;; We save the compare operands in the cmpxx patterns and use them when
684 ;; we generate the branch.
686 (define_expand "cmpsi"
688 (compare (match_operand:SI 0 "arith_operand" "")
689 (match_operand:SI 1 "arith_operand" "")))]
693 sh_compare_op0 = operands[0];
694 sh_compare_op1 = operands[1];
698 ;; -------------------------------------------------------------------------
699 ;; DImode signed integer comparisons
700 ;; -------------------------------------------------------------------------
702 ;; ??? Could get better scheduling by splitting the initial test from the
703 ;; rest of the insn after reload. However, the gain would hardly justify
704 ;; the sh.md size increase necessary to do that.
708 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
709 (match_operand:DI 1 "arith_operand" "r"))
712 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
714 [(set_attr "length" "6")
715 (set_attr "type" "arith3b")])
717 (define_insn "cmpeqdi_t"
719 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
720 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
723 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
724 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
725 [(set_attr "length" "6")
726 (set_attr "type" "arith3b")])
730 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
731 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
732 ;; If we applied this split when not optimizing, it would only be
733 ;; applied during the machine-dependent reorg, when no new basic blocks
735 "TARGET_SH1 && reload_completed && optimize"
736 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
737 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
738 (label_ref (match_dup 6))
740 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
745 = gen_rtx_REG (SImode,
746 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
748 = (operands[1] == const0_rtx
750 : gen_rtx_REG (SImode,
751 true_regnum (operands[1])
752 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
753 operands[4] = gen_lowpart (SImode, operands[0]);
754 operands[5] = gen_lowpart (SImode, operands[1]);
755 operands[6] = gen_label_rtx ();
758 (define_insn "cmpgtdi_t"
760 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
761 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
764 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
765 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
766 [(set_attr "length" "8")
767 (set_attr "type" "arith3")])
769 (define_insn "cmpgedi_t"
771 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
772 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
775 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
777 [(set_attr "length" "8,2")
778 (set_attr "type" "arith3,mt_group")])
780 ;; -------------------------------------------------------------------------
781 ;; DImode unsigned integer comparisons
782 ;; -------------------------------------------------------------------------
784 (define_insn "cmpgeudi_t"
786 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
787 (match_operand:DI 1 "arith_reg_operand" "r")))]
789 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
790 [(set_attr "length" "8")
791 (set_attr "type" "arith3")])
793 (define_insn "cmpgtudi_t"
795 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
796 (match_operand:DI 1 "arith_reg_operand" "r")))]
798 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
799 [(set_attr "length" "8")
800 (set_attr "type" "arith3")])
802 (define_insn "cmpeqdi_media"
803 [(set (match_operand:DI 0 "register_operand" "=r")
804 (eq:DI (match_operand:DI 1 "register_operand" "%r")
805 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
808 [(set_attr "type" "cmp_media")])
810 (define_insn "cmpgtdi_media"
811 [(set (match_operand:DI 0 "register_operand" "=r")
812 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
813 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
816 [(set_attr "type" "cmp_media")])
818 (define_insn "cmpgtudi_media"
819 [(set (match_operand:DI 0 "register_operand" "=r")
820 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
821 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
823 "cmpgtu %N1, %N2, %0"
824 [(set_attr "type" "cmp_media")])
826 ;; We save the compare operands in the cmpxx patterns and use them when
827 ;; we generate the branch.
829 (define_expand "cmpdi"
831 (compare (match_operand:DI 0 "arith_operand" "")
832 (match_operand:DI 1 "arith_operand" "")))]
833 "TARGET_SH2 || TARGET_SHMEDIA"
836 sh_compare_op0 = operands[0];
837 sh_compare_op1 = operands[1];
840 ;; -------------------------------------------------------------------------
841 ;; Conditional move instructions
842 ;; -------------------------------------------------------------------------
844 ;; The insn names may seem reversed, but note that cmveq performs the move
845 ;; if op1 == 0, and cmvne does it if op1 != 0.
847 (define_insn "movdicc_false"
848 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
849 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
851 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
852 (match_operand:DI 3 "arith_reg_operand" "0")))]
855 [(set_attr "type" "arith_media")])
857 (define_insn "movdicc_true"
858 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
859 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
861 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
862 (match_operand:DI 3 "arith_reg_operand" "0")))]
865 [(set_attr "type" "arith_media")])
867 (define_expand "movdicc"
868 [(set (match_operand:DI 0 "register_operand" "")
869 (if_then_else:DI (match_operand 1 "comparison_operator" "")
870 (match_operand:DI 2 "register_operand" "")
871 (match_operand:DI 3 "register_operand" "")))]
875 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
876 && GET_MODE (sh_compare_op0) == DImode
877 && sh_compare_op1 == const0_rtx)
878 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
879 sh_compare_op0, sh_compare_op1);
887 tmp = gen_reg_rtx (DImode);
889 switch (GET_CODE (operands[1]))
892 emit_insn (gen_seq (tmp));
893 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
897 emit_insn (gen_seq (tmp));
898 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
902 emit_insn (gen_sgt (tmp));
903 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
907 emit_insn (gen_slt (tmp));
908 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
912 emit_insn (gen_slt (tmp));
913 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
917 emit_insn (gen_sgt (tmp));
918 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
922 emit_insn (gen_sgtu (tmp));
923 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
927 emit_insn (gen_sltu (tmp));
928 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
932 emit_insn (gen_sltu (tmp));
933 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
937 emit_insn (gen_sgtu (tmp));
938 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
942 emit_insn (gen_sunordered (tmp));
943 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
947 emit_insn (gen_sunordered (tmp));
948 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
965 ;; -------------------------------------------------------------------------
966 ;; Addition instructions
967 ;; -------------------------------------------------------------------------
969 (define_expand "adddi3"
970 [(set (match_operand:DI 0 "arith_reg_operand" "")
971 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
972 (match_operand:DI 2 "arith_operand" "")))]
978 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
980 operands[2] = force_reg (DImode, operands[2]);
981 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
986 (define_insn "*adddi3_media"
987 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
988 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
989 (match_operand:DI 2 "arith_operand" "r,P")))]
994 [(set_attr "type" "arith_media")])
996 (define_insn "adddi3z_media"
997 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
999 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1000 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1002 "addz.l %1, %N2, %0"
1003 [(set_attr "type" "arith_media")])
1005 (define_insn "adddi3_compact"
1006 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1007 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1008 (match_operand:DI 2 "arith_reg_operand" "r")))
1009 (clobber (reg:SI T_REG))]
1012 [(set_attr "length" "6")])
1015 [(set (match_operand:DI 0 "arith_reg_operand" "")
1016 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1017 (match_operand:DI 2 "arith_reg_operand" "")))
1018 (clobber (reg:SI T_REG))]
1019 "TARGET_SH1 && reload_completed"
1023 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1024 high0 = gen_rtx_REG (SImode,
1025 true_regnum (operands[0])
1026 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1027 high2 = gen_rtx_REG (SImode,
1028 true_regnum (operands[2])
1029 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1030 emit_insn (gen_clrt ());
1031 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1032 emit_insn (gen_addc1 (high0, high0, high2));
1037 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1038 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1039 (match_operand:SI 2 "arith_reg_operand" "r"))
1042 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1045 [(set_attr "type" "arith")])
1047 (define_insn "addc1"
1048 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1049 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1050 (match_operand:SI 2 "arith_reg_operand" "r"))
1052 (clobber (reg:SI T_REG))]
1055 [(set_attr "type" "arith")])
1057 (define_expand "addsi3"
1058 [(set (match_operand:SI 0 "arith_reg_operand" "")
1059 (plus:SI (match_operand:SI 1 "arith_operand" "")
1060 (match_operand:SI 2 "arith_operand" "")))]
1065 operands[1] = force_reg (SImode, operands[1]);
1068 (define_insn "addsi3_media"
1069 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1070 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1071 (match_operand:SI 2 "arith_operand" "r,P")))]
1076 [(set_attr "type" "arith_media")])
1078 (define_insn "*addsi3_compact"
1079 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1080 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1081 (match_operand:SI 2 "arith_operand" "rI")))]
1084 [(set_attr "type" "arith")])
1086 ;; -------------------------------------------------------------------------
1087 ;; Subtraction instructions
1088 ;; -------------------------------------------------------------------------
1090 (define_expand "subdi3"
1091 [(set (match_operand:DI 0 "arith_reg_operand" "")
1092 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1093 (match_operand:DI 2 "arith_reg_operand" "")))]
1099 operands[1] = force_reg (DImode, operands[1]);
1100 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1105 (define_insn "*subdi3_media"
1106 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1107 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1108 (match_operand:DI 2 "arith_reg_operand" "r")))]
1111 [(set_attr "type" "arith_media")])
1113 (define_insn "subdi3_compact"
1114 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1115 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1116 (match_operand:DI 2 "arith_reg_operand" "r")))
1117 (clobber (reg:SI T_REG))]
1120 [(set_attr "length" "6")])
1123 [(set (match_operand:DI 0 "arith_reg_operand" "")
1124 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1125 (match_operand:DI 2 "arith_reg_operand" "")))
1126 (clobber (reg:SI T_REG))]
1127 "TARGET_SH1 && reload_completed"
1131 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1132 high0 = gen_rtx_REG (SImode,
1133 true_regnum (operands[0])
1134 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1135 high2 = gen_rtx_REG (SImode,
1136 true_regnum (operands[2])
1137 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1138 emit_insn (gen_clrt ());
1139 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1140 emit_insn (gen_subc1 (high0, high0, high2));
1145 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1146 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1147 (match_operand:SI 2 "arith_reg_operand" "r"))
1150 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1153 [(set_attr "type" "arith")])
1155 (define_insn "subc1"
1156 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1157 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1158 (match_operand:SI 2 "arith_reg_operand" "r"))
1160 (clobber (reg:SI T_REG))]
1163 [(set_attr "type" "arith")])
1165 (define_insn "*subsi3_internal"
1166 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1167 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1168 (match_operand:SI 2 "arith_reg_operand" "r")))]
1171 [(set_attr "type" "arith")])
1173 (define_insn "*subsi3_media"
1174 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1175 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1176 (match_operand:SI 2 "extend_reg_operand" "r")))]
1179 [(set_attr "type" "arith_media")])
1181 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1182 ;; will sometimes save one instruction. Otherwise we might get
1183 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1186 (define_expand "subsi3"
1187 [(set (match_operand:SI 0 "arith_reg_operand" "")
1188 (minus:SI (match_operand:SI 1 "arith_operand" "")
1189 (match_operand:SI 2 "arith_reg_operand" "")))]
1193 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1195 emit_insn (gen_negsi2 (operands[0], operands[2]));
1196 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1201 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1203 if (operands[1] != const0_rtx)
1204 operands[1] = force_reg (SImode, operands[1]);
1208 ;; -------------------------------------------------------------------------
1209 ;; Division instructions
1210 ;; -------------------------------------------------------------------------
1212 ;; We take advantage of the library routines which don't clobber as many
1213 ;; registers as a normal function call would.
1215 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1216 ;; also has an effect on the register that holds the address of the sfunc.
1217 ;; To make this work, we have an extra dummy insn that shows the use
1218 ;; of this register for reorg.
1220 (define_insn "use_sfunc_addr"
1221 [(set (reg:SI PR_REG)
1222 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1225 [(set_attr "length" "0")])
1227 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1228 ;; hard register 0. If we used hard register 0, then the next instruction
1229 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1230 ;; gets allocated to a stack slot that needs its address reloaded, then
1231 ;; there is nothing to prevent reload from using r0 to reload the address.
1232 ;; This reload would clobber the value in r0 we are trying to store.
1233 ;; If we let reload allocate r0, then this problem can never happen.
1235 (define_insn "udivsi3_i1"
1236 [(set (match_operand:SI 0 "register_operand" "=z")
1237 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1238 (clobber (reg:SI T_REG))
1239 (clobber (reg:SI PR_REG))
1240 (clobber (reg:SI R4_REG))
1241 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1242 "TARGET_SH1 && ! TARGET_SH4"
1244 [(set_attr "type" "sfunc")
1245 (set_attr "needs_delay_slot" "yes")])
1247 ; Since shmedia-nofpu code could be linked against shcompact code, and
1248 ; the udivsi3 libcall has the same name, we must consider all registers
1249 ; clobbered that are in the union of the registers clobbered by the
1250 ; shmedia and the shcompact implementation. Note, if the shcompact
1251 ; implemenation actually used shcompact code, we'd need to clobber
1252 ; also r23 and fr23.
1253 (define_insn "udivsi3_i1_media"
1254 [(set (match_operand:SI 0 "register_operand" "=z")
1255 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1256 (clobber (reg:SI T_MEDIA_REG))
1257 (clobber (reg:SI PR_MEDIA_REG))
1258 (clobber (reg:SI R20_REG))
1259 (clobber (reg:SI R21_REG))
1260 (clobber (reg:SI R22_REG))
1261 (clobber (reg:DI TR0_REG))
1262 (clobber (reg:DI TR1_REG))
1263 (clobber (reg:DI TR2_REG))
1264 (use (match_operand:DI 1 "target_operand" "b"))]
1265 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1267 [(set_attr "type" "sfunc")
1268 (set_attr "needs_delay_slot" "yes")])
1270 (define_expand "udivsi3_i4_media"
1272 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1274 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1275 (set (match_dup 5) (float:DF (match_dup 3)))
1276 (set (match_dup 6) (float:DF (match_dup 4)))
1277 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1278 (set (match_dup 8) (fix:DI (match_dup 7)))
1279 (set (match_operand:SI 0 "register_operand" "")
1280 (truncate:SI (match_dup 8)))]
1281 "TARGET_SHMEDIA_FPU"
1284 operands[3] = gen_reg_rtx (DImode);
1285 operands[4] = gen_reg_rtx (DImode);
1286 operands[5] = gen_reg_rtx (DFmode);
1287 operands[6] = gen_reg_rtx (DFmode);
1288 operands[7] = gen_reg_rtx (DFmode);
1289 operands[8] = gen_reg_rtx (DImode);
1292 (define_insn "udivsi3_i4"
1293 [(set (match_operand:SI 0 "register_operand" "=y")
1294 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1295 (clobber (reg:SI T_REG))
1296 (clobber (reg:SI PR_REG))
1297 (clobber (reg:DF DR0_REG))
1298 (clobber (reg:DF DR2_REG))
1299 (clobber (reg:DF DR4_REG))
1300 (clobber (reg:SI R0_REG))
1301 (clobber (reg:SI R1_REG))
1302 (clobber (reg:SI R4_REG))
1303 (clobber (reg:SI R5_REG))
1304 (use (reg:PSI FPSCR_REG))
1305 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1306 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1308 [(set_attr "type" "sfunc")
1309 (set_attr "fp_mode" "double")
1310 (set_attr "needs_delay_slot" "yes")])
1312 (define_insn "udivsi3_i4_single"
1313 [(set (match_operand:SI 0 "register_operand" "=y")
1314 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315 (clobber (reg:SI T_REG))
1316 (clobber (reg:SI PR_REG))
1317 (clobber (reg:DF DR0_REG))
1318 (clobber (reg:DF DR2_REG))
1319 (clobber (reg:DF DR4_REG))
1320 (clobber (reg:SI R0_REG))
1321 (clobber (reg:SI R1_REG))
1322 (clobber (reg:SI R4_REG))
1323 (clobber (reg:SI R5_REG))
1324 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1325 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1327 [(set_attr "type" "sfunc")
1328 (set_attr "needs_delay_slot" "yes")])
1330 (define_expand "udivsi3"
1331 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1332 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1333 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1334 (parallel [(set (match_operand:SI 0 "register_operand" "")
1335 (udiv:SI (reg:SI R4_REG)
1337 (clobber (reg:SI T_REG))
1338 (clobber (reg:SI PR_REG))
1339 (clobber (reg:SI R4_REG))
1340 (use (match_dup 3))])]
1346 operands[3] = gen_reg_rtx (Pmode);
1347 /* Emit the move of the address to a pseudo outside of the libcall. */
1348 if (TARGET_HARD_SH4 && TARGET_SH3E)
1350 emit_move_insn (operands[3],
1351 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1352 if (TARGET_FPU_SINGLE)
1353 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1355 last = gen_udivsi3_i4 (operands[0], operands[3]);
1357 else if (TARGET_SHMEDIA_FPU)
1359 operands[1] = force_reg (SImode, operands[1]);
1360 operands[2] = force_reg (SImode, operands[2]);
1361 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1364 else if (TARGET_SH5)
1366 emit_move_insn (operands[3],
1367 gen_rtx_SYMBOL_REF (Pmode,
1373 last = gen_udivsi3_i1_media (operands[0],
1376 : gen_rtx_SUBREG (DImode, operands[3],
1378 else if (TARGET_FPU_ANY)
1379 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1381 last = gen_udivsi3_i1 (operands[0], operands[3]);
1385 emit_move_insn (operands[3],
1386 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1387 last = gen_udivsi3_i1 (operands[0], operands[3]);
1389 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1390 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1391 last = emit_insn (last);
1392 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1393 invariant code motion can move it. */
1394 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1395 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1399 (define_insn "divsi3_i1"
1400 [(set (match_operand:SI 0 "register_operand" "=z")
1401 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1402 (clobber (reg:SI T_REG))
1403 (clobber (reg:SI PR_REG))
1404 (clobber (reg:SI R1_REG))
1405 (clobber (reg:SI R2_REG))
1406 (clobber (reg:SI R3_REG))
1407 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1408 "TARGET_SH1 && ! TARGET_SH4"
1410 [(set_attr "type" "sfunc")
1411 (set_attr "needs_delay_slot" "yes")])
1413 ; Since shmedia-nofpu code could be linked against shcompact code, and
1414 ; the sdivsi3 libcall has the same name, we must consider all registers
1415 ; clobbered that are in the union of the registers clobbered by the
1416 ; shmedia and the shcompact implementation. Note, if the shcompact
1417 ; implemenation actually used shcompact code, we'd need to clobber
1418 ; also r22, r23 and fr23.
1419 (define_insn "divsi3_i1_media"
1420 [(set (match_operand:SI 0 "register_operand" "=z")
1421 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1422 (clobber (reg:SI T_MEDIA_REG))
1423 (clobber (reg:SI PR_MEDIA_REG))
1424 (clobber (reg:SI R1_REG))
1425 (clobber (reg:SI R2_REG))
1426 (clobber (reg:SI R3_REG))
1427 (clobber (reg:SI R20_REG))
1428 (clobber (reg:SI R21_REG))
1429 (clobber (reg:DI TR0_REG))
1430 (clobber (reg:DI TR1_REG))
1431 (clobber (reg:DI TR2_REG))
1432 (use (match_operand:DI 1 "target_operand" "b"))]
1433 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1435 [(set_attr "type" "sfunc")])
1437 (define_expand "divsi3_i4_media"
1438 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1439 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1440 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1441 (set (match_operand:SI 0 "register_operand" "=r")
1442 (fix:SI (match_dup 5)))]
1443 "TARGET_SHMEDIA_FPU"
1446 operands[3] = gen_reg_rtx (DFmode);
1447 operands[4] = gen_reg_rtx (DFmode);
1448 operands[5] = gen_reg_rtx (DFmode);
1451 (define_insn "divsi3_i4"
1452 [(set (match_operand:SI 0 "register_operand" "=y")
1453 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1454 (clobber (reg:SI PR_REG))
1455 (clobber (reg:DF DR0_REG))
1456 (clobber (reg:DF DR2_REG))
1457 (use (reg:PSI FPSCR_REG))
1458 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1459 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1461 [(set_attr "type" "sfunc")
1462 (set_attr "fp_mode" "double")
1463 (set_attr "needs_delay_slot" "yes")])
1465 (define_insn "divsi3_i4_single"
1466 [(set (match_operand:SI 0 "register_operand" "=y")
1467 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1468 (clobber (reg:SI PR_REG))
1469 (clobber (reg:DF DR0_REG))
1470 (clobber (reg:DF DR2_REG))
1471 (clobber (reg:SI R2_REG))
1472 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1473 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1475 [(set_attr "type" "sfunc")
1476 (set_attr "needs_delay_slot" "yes")])
1478 (define_expand "divsi3"
1479 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1480 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1481 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1482 (parallel [(set (match_operand:SI 0 "register_operand" "")
1483 (div:SI (reg:SI R4_REG)
1485 (clobber (reg:SI T_REG))
1486 (clobber (reg:SI PR_REG))
1487 (clobber (reg:SI R1_REG))
1488 (clobber (reg:SI R2_REG))
1489 (clobber (reg:SI R3_REG))
1490 (use (match_dup 3))])]
1496 operands[3] = gen_reg_rtx (Pmode);
1497 /* Emit the move of the address to a pseudo outside of the libcall. */
1498 if (TARGET_HARD_SH4 && TARGET_SH3E)
1500 emit_move_insn (operands[3],
1501 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1502 if (TARGET_FPU_SINGLE)
1503 last = gen_divsi3_i4_single (operands[0], operands[3]);
1505 last = gen_divsi3_i4 (operands[0], operands[3]);
1507 else if (TARGET_SHMEDIA_FPU)
1509 operands[1] = force_reg (SImode, operands[1]);
1510 operands[2] = force_reg (SImode, operands[2]);
1511 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1514 else if (TARGET_SH5)
1516 emit_move_insn (operands[3],
1517 gen_rtx_SYMBOL_REF (Pmode,
1523 last = gen_divsi3_i1_media (operands[0],
1526 : gen_rtx_SUBREG (DImode, operands[3],
1528 else if (TARGET_FPU_ANY)
1529 last = gen_divsi3_i4_single (operands[0], operands[3]);
1531 last = gen_divsi3_i1 (operands[0], operands[3]);
1535 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1536 last = gen_divsi3_i1 (operands[0], operands[3]);
1538 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1539 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1540 last = emit_insn (last);
1541 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1542 invariant code motion can move it. */
1543 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1544 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1548 ;; -------------------------------------------------------------------------
1549 ;; Multiplication instructions
1550 ;; -------------------------------------------------------------------------
1552 (define_insn "umulhisi3_i"
1553 [(set (reg:SI MACL_REG)
1554 (mult:SI (zero_extend:SI
1555 (match_operand:HI 0 "arith_reg_operand" "r"))
1557 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1560 [(set_attr "type" "smpy")])
1562 (define_insn "mulhisi3_i"
1563 [(set (reg:SI MACL_REG)
1564 (mult:SI (sign_extend:SI
1565 (match_operand:HI 0 "arith_reg_operand" "r"))
1567 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1570 [(set_attr "type" "smpy")])
1572 (define_expand "mulhisi3"
1573 [(set (reg:SI MACL_REG)
1574 (mult:SI (sign_extend:SI
1575 (match_operand:HI 1 "arith_reg_operand" ""))
1577 (match_operand:HI 2 "arith_reg_operand" ""))))
1578 (set (match_operand:SI 0 "arith_reg_operand" "")
1585 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1586 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1587 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1588 invariant code motion can move it. */
1589 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1590 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1591 /* expand_binop can't find a suitable code in umul_widen_optab to
1592 make a REG_EQUAL note from, so make one here.
1593 See also smulsi3_highpart.
1594 ??? Alternatively, we could put this at the calling site of expand_binop,
1595 i.e. expand_expr. */
1597 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1602 (define_expand "umulhisi3"
1603 [(set (reg:SI MACL_REG)
1604 (mult:SI (zero_extend:SI
1605 (match_operand:HI 1 "arith_reg_operand" ""))
1607 (match_operand:HI 2 "arith_reg_operand" ""))))
1608 (set (match_operand:SI 0 "arith_reg_operand" "")
1615 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1616 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1617 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1618 invariant code motion can move it. */
1619 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1620 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1621 /* expand_binop can't find a suitable code in umul_widen_optab to
1622 make a REG_EQUAL note from, so make one here.
1623 See also smulsi3_highpart.
1624 ??? Alternatively, we could put this at the calling site of expand_binop,
1625 i.e. expand_expr. */
1627 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1632 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1633 ;; a call to a routine which clobbers known registers.
1636 [(set (match_operand:SI 1 "register_operand" "=z")
1637 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1638 (clobber (reg:SI MACL_REG))
1639 (clobber (reg:SI T_REG))
1640 (clobber (reg:SI PR_REG))
1641 (clobber (reg:SI R3_REG))
1642 (clobber (reg:SI R2_REG))
1643 (clobber (reg:SI R1_REG))
1644 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1647 [(set_attr "type" "sfunc")
1648 (set_attr "needs_delay_slot" "yes")])
1650 (define_expand "mulsi3_call"
1651 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1652 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1653 (parallel[(set (match_operand:SI 0 "register_operand" "")
1654 (mult:SI (reg:SI R4_REG)
1656 (clobber (reg:SI MACL_REG))
1657 (clobber (reg:SI T_REG))
1658 (clobber (reg:SI PR_REG))
1659 (clobber (reg:SI R3_REG))
1660 (clobber (reg:SI R2_REG))
1661 (clobber (reg:SI R1_REG))
1662 (use (match_operand:SI 3 "register_operand" ""))])]
1666 (define_insn "mul_l"
1667 [(set (reg:SI MACL_REG)
1668 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1669 (match_operand:SI 1 "arith_reg_operand" "r")))]
1672 [(set_attr "type" "dmpy")])
1674 (define_expand "mulsi3"
1675 [(set (reg:SI MACL_REG)
1676 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1677 (match_operand:SI 2 "arith_reg_operand" "")))
1678 (set (match_operand:SI 0 "arith_reg_operand" "")
1687 /* The address must be set outside the libcall,
1688 since it goes into a pseudo. */
1689 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1690 rtx addr = force_reg (SImode, sym);
1691 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1694 last = emit_insn (insns);
1698 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1700 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1701 /* consec_sets_giv can only recognize the first insn that sets a
1702 giv as the giv insn. So we must tag this also with a REG_EQUAL
1704 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1706 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1707 invariant code motion can move it. */
1708 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1709 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1713 (define_insn "mulsidi3_i"
1714 [(set (reg:SI MACH_REG)
1718 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1719 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1721 (set (reg:SI MACL_REG)
1722 (mult:SI (match_dup 0)
1726 [(set_attr "type" "dmpy")])
1728 (define_expand "mulsidi3"
1729 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1730 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1731 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1732 "TARGET_SH2 || TARGET_SHMEDIA"
1737 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1743 (define_insn "mulsidi3_media"
1744 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1745 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1746 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1749 [(set_attr "type" "dmpy_media")])
1751 (define_insn "mulsidi3_compact"
1752 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1754 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1755 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1756 (clobber (reg:SI MACH_REG))
1757 (clobber (reg:SI MACL_REG))]
1762 [(set (match_operand:DI 0 "arith_reg_operand" "")
1764 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1765 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1766 (clobber (reg:SI MACH_REG))
1767 (clobber (reg:SI MACL_REG))]
1772 rtx low_dst = gen_lowpart (SImode, operands[0]);
1773 rtx high_dst = gen_highpart (SImode, operands[0]);
1775 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1777 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1778 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1779 /* We need something to tag the possible REG_EQUAL notes on to. */
1780 emit_move_insn (operands[0], operands[0]);
1784 (define_insn "umulsidi3_i"
1785 [(set (reg:SI MACH_REG)
1789 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1790 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1792 (set (reg:SI MACL_REG)
1793 (mult:SI (match_dup 0)
1797 [(set_attr "type" "dmpy")])
1799 (define_expand "umulsidi3"
1800 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1801 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1802 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1803 "TARGET_SH2 || TARGET_SHMEDIA"
1808 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1814 (define_insn "umulsidi3_media"
1815 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1816 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1817 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1820 [(set_attr "type" "dmpy_media")])
1822 (define_insn "umulsidi3_compact"
1823 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1825 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1826 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1827 (clobber (reg:SI MACH_REG))
1828 (clobber (reg:SI MACL_REG))]
1833 [(set (match_operand:DI 0 "arith_reg_operand" "")
1834 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1835 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1836 (clobber (reg:SI MACH_REG))
1837 (clobber (reg:SI MACL_REG))]
1842 rtx low_dst = gen_lowpart (SImode, operands[0]);
1843 rtx high_dst = gen_highpart (SImode, operands[0]);
1845 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1847 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1848 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1849 /* We need something to tag the possible REG_EQUAL notes on to. */
1850 emit_move_insn (operands[0], operands[0]);
1854 (define_insn "smulsi3_highpart_i"
1855 [(set (reg:SI MACH_REG)
1859 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1860 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1862 (clobber (reg:SI MACL_REG))]
1865 [(set_attr "type" "dmpy")])
1867 (define_expand "smulsi3_highpart"
1869 [(set (reg:SI MACH_REG)
1873 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1874 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1876 (clobber (reg:SI MACL_REG))])
1877 (set (match_operand:SI 0 "arith_reg_operand" "")
1884 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1885 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1886 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1887 invariant code motion can move it. */
1888 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1889 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1890 /* expand_binop can't find a suitable code in mul_highpart_optab to
1891 make a REG_EQUAL note from, so make one here.
1892 See also {,u}mulhisi.
1893 ??? Alternatively, we could put this at the calling site of expand_binop,
1894 i.e. expand_mult_highpart. */
1896 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1901 (define_insn "umulsi3_highpart_i"
1902 [(set (reg:SI MACH_REG)
1906 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1907 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1909 (clobber (reg:SI MACL_REG))]
1912 [(set_attr "type" "dmpy")])
1914 (define_expand "umulsi3_highpart"
1916 [(set (reg:SI MACH_REG)
1920 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1921 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1923 (clobber (reg:SI MACL_REG))])
1924 (set (match_operand:SI 0 "arith_reg_operand" "")
1931 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1932 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1933 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1934 invariant code motion can move it. */
1935 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1936 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1940 ;; -------------------------------------------------------------------------
1941 ;; Logical operations
1942 ;; -------------------------------------------------------------------------
1944 (define_insn "*andsi3_compact"
1945 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1946 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1947 (match_operand:SI 2 "logical_operand" "r,L")))]
1950 [(set_attr "type" "arith")])
1952 ;; If the constant is 255, then emit an extu.b instruction instead of an
1953 ;; and, since that will give better code.
1955 (define_expand "andsi3"
1956 [(set (match_operand:SI 0 "arith_reg_operand" "")
1957 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1958 (match_operand:SI 2 "logical_operand" "")))]
1962 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1964 emit_insn (gen_zero_extendqisi2 (operands[0],
1965 gen_lowpart (QImode, operands[1])));
1970 (define_insn_and_split "anddi3"
1971 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1972 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1973 (match_operand:DI 2 "and_operand" "r,P,n")))]
1980 && ! logical_operand (operands[2], DImode)"
1984 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1985 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1987 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1990 [(set_attr "type" "arith_media")])
1992 (define_insn "andcdi3"
1993 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1994 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1995 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1998 [(set_attr "type" "arith_media")])
2000 (define_insn "iorsi3"
2001 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2002 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2003 (match_operand:SI 2 "logical_operand" "r,L")))]
2006 [(set_attr "type" "arith")])
2008 (define_insn "iordi3"
2009 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2010 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2011 (match_operand:DI 2 "logical_operand" "r,P")))]
2016 [(set_attr "type" "arith_media")])
2018 (define_insn "xorsi3"
2019 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2020 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2021 (match_operand:SI 2 "logical_operand" "L,r")))]
2024 [(set_attr "type" "arith")])
2026 (define_insn "xordi3"
2027 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2028 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2029 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2034 [(set_attr "type" "arith_media")])
2036 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2037 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2039 [(set (match_operand:DI 0 "arith_reg_operand" "")
2040 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2041 [(match_operand 1 "any_register_operand" "")
2042 (match_operand 2 "any_register_operand" "")])))]
2044 [(set (match_dup 5) (match_dup 4))
2045 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2048 enum machine_mode inmode = GET_MODE (operands[1]);
2049 int regno, offset = 0;
2051 if (GET_CODE (operands[0]) == SUBREG)
2053 offset = SUBREG_BYTE (operands[0]);
2054 operands[0] = SUBREG_REG (operands[0]);
2056 if (GET_CODE (operands[0]) != REG)
2058 if (! TARGET_LITTLE_ENDIAN)
2059 offset += 8 - GET_MODE_SIZE (inmode);
2060 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2063 ;; -------------------------------------------------------------------------
2064 ;; Shifts and rotates
2065 ;; -------------------------------------------------------------------------
2067 (define_expand "rotldi3"
2068 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2069 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2070 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2072 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2074 (define_insn "rotldi3_mextr"
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")))]
2081 static char templ[16];
2083 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2084 8 - (int) (INTVAL (operands[2]) >> 3));
2087 [(set_attr "type" "arith_media")])
2089 (define_expand "rotrdi3"
2090 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2091 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2092 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2094 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2096 (define_insn "rotrdi3_mextr"
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")))]
2103 static char templ[16];
2105 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2108 [(set_attr "type" "arith_media")])
2110 (define_insn "rotlsi3_1"
2111 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2112 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2115 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2118 [(set_attr "type" "arith")])
2120 (define_insn "rotlsi3_31"
2121 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2122 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2124 (clobber (reg:SI T_REG))]
2127 [(set_attr "type" "arith")])
2129 (define_insn "rotlsi3_16"
2130 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2131 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2135 [(set_attr "type" "arith")])
2137 (define_expand "rotlsi3"
2138 [(set (match_operand:SI 0 "arith_reg_operand" "")
2139 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2140 (match_operand:SI 2 "immediate_operand" "")))]
2144 static const char rot_tab[] = {
2145 000, 000, 000, 000, 000, 000, 010, 001,
2146 001, 001, 011, 013, 003, 003, 003, 003,
2147 003, 003, 003, 003, 003, 013, 012, 002,
2148 002, 002, 010, 000, 000, 000, 000, 000,
2153 if (GET_CODE (operands[2]) != CONST_INT)
2155 count = INTVAL (operands[2]);
2156 choice = rot_tab[count];
2157 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2163 emit_move_insn (operands[0], operands[1]);
2164 count -= (count & 16) * 2;
2167 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2174 parts[0] = gen_reg_rtx (SImode);
2175 parts[1] = gen_reg_rtx (SImode);
2176 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2177 parts[choice-1] = operands[1];
2178 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2179 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2180 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2181 count = (count & ~16) - 8;
2185 for (; count > 0; count--)
2186 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2187 for (; count < 0; count++)
2188 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2193 (define_insn "*rotlhi3_8"
2194 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2195 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2199 [(set_attr "type" "arith")])
2201 (define_expand "rotlhi3"
2202 [(set (match_operand:HI 0 "arith_reg_operand" "")
2203 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2204 (match_operand:HI 2 "immediate_operand" "")))]
2208 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2215 ;; This pattern is used by init_expmed for computing the costs of shift
2218 (define_insn_and_split "ashlsi3_std"
2219 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2220 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2221 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2222 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2224 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2225 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2233 && GET_CODE (operands[2]) == CONST_INT
2234 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2235 [(set (match_dup 3) (match_dup 2))
2237 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2238 (clobber (match_dup 4))])]
2239 "operands[4] = gen_rtx_SCRATCH (SImode);"
2240 [(set_attr "length" "*,*,*,4")
2241 (set_attr "type" "dyn_shift,arith,arith,arith")])
2243 (define_insn "ashlhi3_k"
2244 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2245 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2246 (match_operand:HI 2 "const_int_operand" "M,K")))]
2247 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2251 [(set_attr "type" "arith")])
2253 (define_insn "ashlsi3_n"
2254 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2255 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2256 (match_operand:SI 2 "const_int_operand" "n")))
2257 (clobber (reg:SI T_REG))]
2258 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2260 [(set (attr "length")
2261 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2263 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2265 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2267 (const_string "8")))
2268 (set_attr "type" "arith")])
2271 [(set (match_operand:SI 0 "arith_reg_operand" "")
2272 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2273 (match_operand:SI 2 "const_int_operand" "")))
2274 (clobber (reg:SI T_REG))]
2275 "TARGET_SH1 && reload_completed"
2276 [(use (reg:SI R0_REG))]
2279 gen_shifty_op (ASHIFT, operands);
2283 (define_insn "ashlsi3_media"
2284 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2285 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2286 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2291 [(set_attr "type" "arith_media")])
2293 (define_expand "ashlsi3"
2294 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2295 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2296 (match_operand:SI 2 "nonmemory_operand" "")))
2297 (clobber (reg:SI T_REG))])]
2303 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2306 if (GET_CODE (operands[2]) == CONST_INT
2307 && sh_dynamicalize_shift_p (operands[2]))
2308 operands[2] = force_reg (SImode, operands[2]);
2311 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2314 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2318 (define_insn "ashlhi3"
2319 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2320 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2321 (match_operand:HI 2 "const_int_operand" "n")))
2322 (clobber (reg:SI T_REG))]
2325 [(set (attr "length")
2326 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2328 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2330 (const_string "6")))
2331 (set_attr "type" "arith")])
2334 [(set (match_operand:HI 0 "arith_reg_operand" "")
2335 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2336 (match_operand:HI 2 "const_int_operand" "")))
2337 (clobber (reg:SI T_REG))]
2338 "TARGET_SH1 && reload_completed"
2339 [(use (reg:SI R0_REG))]
2342 gen_shifty_hi_op (ASHIFT, operands);
2347 ; arithmetic shift right
2350 (define_insn "ashrsi3_k"
2351 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2352 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2353 (match_operand:SI 2 "const_int_operand" "M")))
2354 (clobber (reg:SI T_REG))]
2355 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2357 [(set_attr "type" "arith")])
2359 ;; We can't do HImode right shifts correctly unless we start out with an
2360 ;; explicit zero / sign extension; doing that would result in worse overall
2361 ;; code, so just let the machine independent code widen the mode.
2362 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2365 ;; ??? This should be a define expand.
2367 (define_insn "ashrsi2_16"
2368 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2369 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2373 [(set_attr "length" "4")])
2376 [(set (match_operand:SI 0 "arith_reg_operand" "")
2377 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2380 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2381 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2382 "operands[2] = gen_lowpart (HImode, operands[0]);")
2384 ;; ??? This should be a define expand.
2386 (define_insn "ashrsi2_31"
2387 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2388 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2390 (clobber (reg:SI T_REG))]
2393 [(set_attr "length" "4")])
2396 [(set (match_operand:SI 0 "arith_reg_operand" "")
2397 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2399 (clobber (reg:SI T_REG))]
2404 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2405 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2409 (define_insn "ashlsi_c"
2410 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2411 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2413 (lt:SI (match_dup 1) (const_int 0)))]
2416 [(set_attr "type" "arith")])
2418 (define_insn "ashrsi3_d"
2419 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2420 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2421 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2424 [(set_attr "type" "dyn_shift")])
2426 (define_insn "ashrsi3_n"
2427 [(set (reg:SI R4_REG)
2428 (ashiftrt:SI (reg:SI R4_REG)
2429 (match_operand:SI 0 "const_int_operand" "i")))
2430 (clobber (reg:SI T_REG))
2431 (clobber (reg:SI PR_REG))
2432 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2435 [(set_attr "type" "sfunc")
2436 (set_attr "needs_delay_slot" "yes")])
2438 (define_insn "ashrsi3_media"
2439 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2440 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2441 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2446 [(set_attr "type" "arith_media")])
2448 (define_expand "ashrsi3"
2449 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2450 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2451 (match_operand:SI 2 "nonmemory_operand" "")))
2452 (clobber (reg:SI T_REG))])]
2458 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2461 if (expand_ashiftrt (operands))
2467 ;; logical shift right
2469 (define_insn "lshrsi3_d"
2470 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2471 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2472 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2475 [(set_attr "type" "dyn_shift")])
2477 ;; Only the single bit shift clobbers the T bit.
2479 (define_insn "lshrsi3_m"
2480 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2481 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2482 (match_operand:SI 2 "const_int_operand" "M")))
2483 (clobber (reg:SI T_REG))]
2484 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2486 [(set_attr "type" "arith")])
2488 (define_insn "lshrsi3_k"
2489 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2490 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2491 (match_operand:SI 2 "const_int_operand" "K")))]
2492 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2493 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2495 [(set_attr "type" "arith")])
2497 (define_insn "lshrsi3_n"
2498 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2499 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2500 (match_operand:SI 2 "const_int_operand" "n")))
2501 (clobber (reg:SI T_REG))]
2502 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2504 [(set (attr "length")
2505 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2507 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2509 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2511 (const_string "8")))
2512 (set_attr "type" "arith")])
2515 [(set (match_operand:SI 0 "arith_reg_operand" "")
2516 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2517 (match_operand:SI 2 "const_int_operand" "")))
2518 (clobber (reg:SI T_REG))]
2519 "TARGET_SH1 && reload_completed"
2520 [(use (reg:SI R0_REG))]
2523 gen_shifty_op (LSHIFTRT, operands);
2527 (define_insn "lshrsi3_media"
2528 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2529 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2530 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2535 [(set_attr "type" "arith_media")])
2537 (define_expand "lshrsi3"
2538 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2539 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2540 (match_operand:SI 2 "nonmemory_operand" "")))
2541 (clobber (reg:SI T_REG))])]
2547 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2550 if (GET_CODE (operands[2]) == CONST_INT
2551 && sh_dynamicalize_shift_p (operands[2]))
2552 operands[2] = force_reg (SImode, operands[2]);
2553 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2555 rtx count = copy_to_mode_reg (SImode, operands[2]);
2556 emit_insn (gen_negsi2 (count, count));
2557 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2560 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2564 ;; ??? This should be a define expand.
2566 (define_insn "ashldi3_k"
2567 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2568 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2570 (clobber (reg:SI T_REG))]
2572 "shll %R0\;rotcl %S0"
2573 [(set_attr "length" "4")
2574 (set_attr "type" "arith")])
2576 (define_insn "ashldi3_media"
2577 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2578 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2579 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2584 [(set_attr "type" "arith_media")])
2586 (define_expand "ashldi3"
2587 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2588 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2589 (match_operand:DI 2 "immediate_operand" "")))
2590 (clobber (reg:SI T_REG))])]
2596 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2599 if (GET_CODE (operands[2]) != CONST_INT
2600 || INTVAL (operands[2]) != 1)
2604 ;; ??? This should be a define expand.
2606 (define_insn "lshrdi3_k"
2607 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2608 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2610 (clobber (reg:SI T_REG))]
2612 "shlr %S0\;rotcr %R0"
2613 [(set_attr "length" "4")
2614 (set_attr "type" "arith")])
2616 (define_insn "lshrdi3_media"
2617 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2618 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2619 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2624 [(set_attr "type" "arith_media")])
2626 (define_expand "lshrdi3"
2627 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2628 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2629 (match_operand:DI 2 "immediate_operand" "")))
2630 (clobber (reg:SI T_REG))])]
2636 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2639 if (GET_CODE (operands[2]) != CONST_INT
2640 || INTVAL (operands[2]) != 1)
2644 ;; ??? This should be a define expand.
2646 (define_insn "ashrdi3_k"
2647 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2648 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2650 (clobber (reg:SI T_REG))]
2652 "shar %S0\;rotcr %R0"
2653 [(set_attr "length" "4")
2654 (set_attr "type" "arith")])
2656 (define_insn "ashrdi3_media"
2657 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2658 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2659 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2664 [(set_attr "type" "arith_media")])
2666 (define_expand "ashrdi3"
2667 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2668 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2669 (match_operand:DI 2 "immediate_operand" "")))
2670 (clobber (reg:SI T_REG))])]
2676 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2679 if (GET_CODE (operands[2]) != CONST_INT
2680 || INTVAL (operands[2]) != 1)
2684 ;; combined left/right shift
2687 [(set (match_operand:SI 0 "register_operand" "")
2688 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2689 (match_operand:SI 2 "const_int_operand" ""))
2690 (match_operand:SI 3 "const_int_operand" "")))]
2691 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2692 [(use (reg:SI R0_REG))]
2693 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2697 [(set (match_operand:SI 0 "register_operand" "")
2698 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2699 (match_operand:SI 2 "const_int_operand" ""))
2700 (match_operand:SI 3 "const_int_operand" "")))
2701 (clobber (reg:SI T_REG))]
2702 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2703 [(use (reg:SI R0_REG))]
2704 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2708 [(set (match_operand:SI 0 "register_operand" "=r")
2709 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2710 (match_operand:SI 2 "const_int_operand" "n"))
2711 (match_operand:SI 3 "const_int_operand" "n")))
2712 (clobber (reg:SI T_REG))]
2713 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2715 [(set (attr "length")
2716 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2718 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2720 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2722 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2724 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2726 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2728 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2729 (const_string "16")]
2730 (const_string "18")))
2731 (set_attr "type" "arith")])
2734 [(set (match_operand:SI 0 "register_operand" "=z")
2735 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2736 (match_operand:SI 2 "const_int_operand" "n"))
2737 (match_operand:SI 3 "const_int_operand" "n")))
2738 (clobber (reg:SI T_REG))]
2739 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2741 [(set (attr "length")
2742 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2744 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2746 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2748 (const_string "10")))
2749 (set_attr "type" "arith")])
2751 ;; shift left / and combination with a scratch register: The combine pass
2752 ;; does not accept the individual instructions, even though they are
2753 ;; cheap. But it needs a precise description so that it is usable after
2755 (define_insn "and_shl_scratch"
2756 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2760 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2761 (match_operand:SI 2 "const_int_operand" "N,n"))
2762 (match_operand:SI 3 "" "0,r"))
2763 (match_operand:SI 4 "const_int_operand" "n,n"))
2764 (match_operand:SI 5 "const_int_operand" "n,n")))
2765 (clobber (reg:SI T_REG))]
2768 [(set (attr "length")
2769 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2771 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2773 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2775 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2776 (const_string "10")]
2777 (const_string "12")))
2778 (set_attr "type" "arith")])
2781 [(set (match_operand:SI 0 "register_operand" "")
2785 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2786 (match_operand:SI 2 "const_int_operand" ""))
2787 (match_operand:SI 3 "register_operand" ""))
2788 (match_operand:SI 4 "const_int_operand" ""))
2789 (match_operand:SI 5 "const_int_operand" "")))
2790 (clobber (reg:SI T_REG))]
2792 [(use (reg:SI R0_REG))]
2795 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2797 if (INTVAL (operands[2]))
2799 gen_shifty_op (LSHIFTRT, operands);
2801 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2802 operands[2] = operands[4];
2803 gen_shifty_op (ASHIFT, operands);
2804 if (INTVAL (operands[5]))
2806 operands[2] = operands[5];
2807 gen_shifty_op (LSHIFTRT, operands);
2812 ;; signed left/right shift combination.
2814 [(set (match_operand:SI 0 "register_operand" "")
2816 (ashift:SI (match_operand:SI 1 "register_operand" "")
2817 (match_operand:SI 2 "const_int_operand" ""))
2818 (match_operand:SI 3 "const_int_operand" "")
2820 (clobber (reg:SI T_REG))]
2822 [(use (reg:SI R0_REG))]
2823 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2826 (define_insn "shl_sext_ext"
2827 [(set (match_operand:SI 0 "register_operand" "=r")
2829 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2830 (match_operand:SI 2 "const_int_operand" "n"))
2831 (match_operand:SI 3 "const_int_operand" "n")
2833 (clobber (reg:SI T_REG))]
2834 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2836 [(set (attr "length")
2837 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2839 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2841 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2843 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2845 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2847 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2849 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2851 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2852 (const_string "16")]
2853 (const_string "18")))
2854 (set_attr "type" "arith")])
2856 (define_insn "shl_sext_sub"
2857 [(set (match_operand:SI 0 "register_operand" "=z")
2859 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2860 (match_operand:SI 2 "const_int_operand" "n"))
2861 (match_operand:SI 3 "const_int_operand" "n")
2863 (clobber (reg:SI T_REG))]
2864 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2866 [(set (attr "length")
2867 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2869 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2871 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2873 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2874 (const_string "12")]
2875 (const_string "14")))
2876 (set_attr "type" "arith")])
2878 ;; These patterns are found in expansions of DImode shifts by 16, and
2879 ;; allow the xtrct instruction to be generated from C source.
2881 (define_insn "xtrct_left"
2882 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2883 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2885 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2889 [(set_attr "type" "arith")])
2891 (define_insn "xtrct_right"
2892 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2893 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2895 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2899 [(set_attr "type" "arith")])
2901 ;; -------------------------------------------------------------------------
2903 ;; -------------------------------------------------------------------------
2906 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2907 (neg:SI (plus:SI (reg:SI T_REG)
2908 (match_operand:SI 1 "arith_reg_operand" "r"))))
2910 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2914 [(set_attr "type" "arith")])
2916 (define_insn "*negdi_media"
2917 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2918 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2921 [(set_attr "type" "arith_media")])
2923 (define_expand "negdi2"
2924 [(set (match_operand:DI 0 "arith_reg_operand" "")
2925 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2931 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2932 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2934 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2935 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2937 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2938 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2940 emit_insn (gen_clrt ());
2941 emit_insn (gen_negc (low_dst, low_src));
2942 emit_insn (gen_negc (high_dst, high_src));
2947 (define_insn "negsi2"
2948 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2949 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2952 [(set_attr "type" "arith")])
2954 (define_insn "one_cmplsi2"
2955 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2956 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2959 [(set_attr "type" "arith")])
2961 (define_expand "one_cmpldi2"
2962 [(set (match_operand:DI 0 "arith_reg_operand" "")
2963 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2965 "TARGET_SHMEDIA" "")
2967 ;; -------------------------------------------------------------------------
2968 ;; Zero extension instructions
2969 ;; -------------------------------------------------------------------------
2971 (define_insn "zero_extendsidi2"
2972 [(set (match_operand:DI 0 "register_operand" "=r")
2973 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2975 "addz.l %1, r63, %0"
2976 [(set_attr "type" "arith_media")])
2978 (define_insn "zero_extendhidi2"
2979 [(set (match_operand:DI 0 "register_operand" "=r,r")
2980 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2985 [(set_attr "type" "*,load_media")])
2988 [(set (match_operand:DI 0 "register_operand" "")
2989 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2990 "TARGET_SHMEDIA && reload_completed"
2991 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2992 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2995 if (GET_CODE (operands[1]) == TRUNCATE)
2996 operands[1] = XEXP (operands[1], 0);
2999 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3000 ;; reload the entrire truncate expression.
3001 (define_insn_and_split "*loaddi_trunc"
3002 [(set (match_operand 0 "int_gpr_dest" "=r")
3003 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3004 "TARGET_SHMEDIA && reload_completed"
3006 "TARGET_SHMEDIA && reload_completed"
3007 [(set (match_dup 0) (match_dup 1))]
3008 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3010 (define_insn "zero_extendqidi2"
3011 [(set (match_operand:DI 0 "register_operand" "=r,r")
3012 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3017 [(set_attr "type" "arith_media,load_media")])
3019 (define_expand "zero_extendhisi2"
3020 [(set (match_operand:SI 0 "arith_reg_operand" "")
3021 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3025 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3026 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3029 (define_insn "*zero_extendhisi2_compact"
3030 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3031 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3034 [(set_attr "type" "arith")])
3036 (define_insn "*zero_extendhisi2_media"
3037 [(set (match_operand:SI 0 "register_operand" "=r,r")
3038 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3043 [(set_attr "type" "arith_media,load_media")])
3046 [(set (match_operand:SI 0 "register_operand" "")
3047 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3048 "TARGET_SHMEDIA && reload_completed"
3049 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3050 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3053 if (GET_CODE (operands[1]) == TRUNCATE)
3054 operands[1] = XEXP (operands[1], 0);
3057 (define_expand "zero_extendqisi2"
3058 [(set (match_operand:SI 0 "arith_reg_operand" "")
3059 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3063 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3064 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3067 (define_insn "*zero_extendqisi2_compact"
3068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3069 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3072 [(set_attr "type" "arith")])
3074 (define_insn "*zero_extendqisi2_media"
3075 [(set (match_operand:SI 0 "register_operand" "=r,r")
3076 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3081 [(set_attr "type" "arith_media,load_media")])
3083 (define_insn "zero_extendqihi2"
3084 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3085 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3088 [(set_attr "type" "arith")])
3090 ;; -------------------------------------------------------------------------
3091 ;; Sign extension instructions
3092 ;; -------------------------------------------------------------------------
3094 ;; ??? This should be a define expand.
3095 ;; ??? Or perhaps it should be dropped?
3097 ;; convert_move generates good code for SH[1-4].
3098 (define_insn "extendsidi2"
3099 [(set (match_operand:DI 0 "register_operand" "=r,r")
3100 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3105 [(set_attr "type" "arith_media,load_media")])
3107 (define_insn "extendhidi2"
3108 [(set (match_operand:DI 0 "register_operand" "=r,r")
3109 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3114 [(set_attr "type" "*,load_media")])
3117 [(set (match_operand:DI 0 "register_operand" "")
3118 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3119 "TARGET_SHMEDIA && reload_completed"
3120 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3121 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3124 if (GET_CODE (operands[1]) == TRUNCATE)
3125 operands[1] = XEXP (operands[1], 0);
3128 (define_insn "extendqidi2"
3129 [(set (match_operand:DI 0 "register_operand" "=r,r")
3130 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3135 [(set_attr "type" "*,load_media")])
3138 [(set (match_operand:DI 0 "register_operand" "")
3139 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3140 "TARGET_SHMEDIA && reload_completed"
3141 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3142 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3145 if (GET_CODE (operands[1]) == TRUNCATE)
3146 operands[1] = XEXP (operands[1], 0);
3149 (define_expand "extendhisi2"
3150 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3151 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3155 (define_insn "*extendhisi2_compact"
3156 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3157 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3162 [(set_attr "type" "arith,load")])
3164 (define_insn "*extendhisi2_media"
3165 [(set (match_operand:SI 0 "register_operand" "=r,r")
3166 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3171 [(set_attr "type" "arith_media,load_media")])
3174 [(set (match_operand:SI 0 "register_operand" "")
3175 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3176 "TARGET_SHMEDIA && reload_completed"
3177 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3178 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3181 if (GET_CODE (operands[1]) == TRUNCATE)
3182 operands[1] = XEXP (operands[1], 0);
3185 (define_expand "extendqisi2"
3186 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3187 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3191 (define_insn "*extendqisi2_compact"
3192 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3193 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3198 [(set_attr "type" "arith,load")])
3200 (define_insn "*extendqisi2_media"
3201 [(set (match_operand:SI 0 "register_operand" "=r,r")
3202 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3207 [(set_attr "type" "arith_media,load_media")])
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3212 "TARGET_SHMEDIA && reload_completed"
3213 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3214 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3217 if (GET_CODE (operands[1]) == TRUNCATE)
3218 operands[1] = XEXP (operands[1], 0);
3221 (define_insn "extendqihi2"
3222 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3223 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3228 [(set_attr "type" "arith,load")])
3230 /* It would seem useful to combine the truncXi patterns into the movXi
3231 patterns, but unary operators are ignored when matching constraints,
3232 so we need separate patterns. */
3233 (define_insn "truncdisi2"
3234 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3235 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3244 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3247 (define_insn "truncdihi2"
3248 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3249 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3252 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3254 [(set_attr "type" "arith_media,store_media")
3255 (set_attr "length" "8,4")])
3257 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3258 ; Because we use zero extension, we can't provide signed QImode compares
3259 ; using a simple compare or conditional banch insn.
3260 (define_insn "truncdiqi2"
3261 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3262 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3267 [(set_attr "type" "arith_media,store")])
3269 ;; -------------------------------------------------------------------------
3270 ;; Move instructions
3271 ;; -------------------------------------------------------------------------
3273 ;; define push and pop so it is easy for sh.c
3274 ;; We can't use push and pop on SHcompact because the stack must always
3275 ;; be 8-byte aligned.
3277 (define_expand "push"
3278 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3279 (match_operand:SI 0 "register_operand" "r,l,x"))]
3280 "TARGET_SH1 && ! TARGET_SH5"
3283 (define_expand "pop"
3284 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3285 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3286 "TARGET_SH1 && ! TARGET_SH5"
3289 (define_expand "push_e"
3290 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3291 (match_operand:SF 0 "" ""))
3292 (use (reg:PSI FPSCR_REG))
3293 (clobber (scratch:SI))])]
3294 "TARGET_SH1 && ! TARGET_SH5"
3297 (define_insn "push_fpul"
3298 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3299 "TARGET_SH3E && ! TARGET_SH5"
3301 [(set_attr "type" "store")
3302 (set_attr "late_fp_use" "yes")
3303 (set_attr "hit_stack" "yes")])
3305 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3307 (define_expand "push_4"
3308 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3309 (match_operand:DF 0 "" ""))
3310 (use (reg:PSI FPSCR_REG))
3311 (clobber (scratch:SI))])]
3312 "TARGET_SH1 && ! TARGET_SH5"
3315 (define_expand "pop_e"
3316 [(parallel [(set (match_operand:SF 0 "" "")
3317 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3318 (use (reg:PSI FPSCR_REG))
3319 (clobber (scratch:SI))])]
3320 "TARGET_SH1 && ! TARGET_SH5"
3323 (define_insn "pop_fpul"
3324 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3325 "TARGET_SH3E && ! TARGET_SH5"
3327 [(set_attr "type" "load")
3328 (set_attr "hit_stack" "yes")])
3330 (define_expand "pop_4"
3331 [(parallel [(set (match_operand:DF 0 "" "")
3332 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3333 (use (reg:PSI FPSCR_REG))
3334 (clobber (scratch:SI))])]
3335 "TARGET_SH1 && ! TARGET_SH5"
3338 (define_expand "push_fpscr"
3343 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3344 gen_rtx (PRE_DEC, Pmode,
3345 stack_pointer_rtx)),
3347 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3351 (define_expand "pop_fpscr"
3356 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3357 gen_rtx (MEM, PSImode,
3358 gen_rtx (POST_INC, Pmode,
3359 stack_pointer_rtx))));
3360 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3364 ;; These two patterns can happen as the result of optimization, when
3365 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3366 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3369 [(set (reg:SI T_REG) (const_int 0))]
3374 [(set (reg:SI T_REG) (const_int 1))]
3378 ;; t/r must come after r/r, lest reload will try to reload stuff like
3379 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3380 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3381 (define_insn "movsi_i"
3382 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3383 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3386 && (register_operand (operands[0], SImode)
3387 || register_operand (operands[1], SImode))"
3404 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3405 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3407 ;; t/r must come after r/r, lest reload will try to reload stuff like
3408 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3409 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3410 ;; will require a reload.
3411 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3412 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3413 (define_insn "movsi_ie"
3414 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3415 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3417 && (register_operand (operands[0], SImode)
3418 || register_operand (operands[1], SImode))"
3442 ! move optimized away"
3443 [(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")
3444 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3445 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3447 (define_insn "movsi_i_lowpart"
3448 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3449 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3451 && (register_operand (operands[0], SImode)
3452 || register_operand (operands[1], SImode))"
3462 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3464 (define_insn "*movsi_media"
3465 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3466 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3468 && (register_operand (operands[0], SImode)
3469 || register_operand (operands[1], SImode))"
3484 [(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")
3485 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3487 (define_insn "*movsi_media_nofpu"
3488 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3489 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3491 && (register_operand (operands[0], SImode)
3492 || register_operand (operands[1], SImode))"
3502 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3503 (set_attr "length" "4,4,8,4,4,4,4,12")])
3506 [(set (match_operand:SI 0 "arith_reg_operand" "")
3507 (match_operand:SI 1 "immediate_operand" ""))]
3508 "TARGET_SHMEDIA && reload_completed
3509 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3510 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3513 operands[2] = shallow_copy_rtx (operands[1]);
3514 PUT_MODE (operands[2], DImode);
3518 [(set (match_operand:SI 0 "register_operand" "")
3519 (match_operand:SI 1 "immediate_operand" ""))]
3520 "TARGET_SHMEDIA && reload_completed
3521 && ((GET_CODE (operands[1]) == CONST_INT
3522 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3523 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3524 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3526 (define_expand "movsi"
3527 [(set (match_operand:SI 0 "general_movdst_operand" "")
3528 (match_operand:SI 1 "general_movsrc_operand" ""))]
3530 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3532 (define_expand "ic_invalidate_line"
3533 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3534 (match_dup 1)] UNSPEC_ICACHE)
3535 (clobber (scratch:SI))])]
3536 "TARGET_HARD_SH4 || TARGET_SH5"
3541 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3544 else if (TARGET_SHCOMPACT)
3546 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3547 operands[1] = force_reg (Pmode, operands[1]);
3548 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3551 operands[0] = force_reg (Pmode, operands[0]);
3552 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3556 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3557 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3558 ;; the requirement *1*00 for associative address writes. The alignment of
3559 ;; %0 implies that its least significant bit is cleared,
3560 ;; thus we clear the V bit of a matching entry if there is one.
3561 (define_insn "ic_invalidate_line_i"
3562 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3563 (match_operand:SI 1 "register_operand" "r")]
3565 (clobber (match_scratch:SI 2 "=&r"))]
3567 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3568 [(set_attr "length" "8")
3569 (set_attr "type" "cwb")])
3571 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3572 ;; an add in the code that calculates the address.
3573 (define_insn "ic_invalidate_line_media"
3574 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3577 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3578 [(set_attr "length" "16")
3579 (set_attr "type" "invalidate_line_media")])
3581 (define_insn "ic_invalidate_line_compact"
3582 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3583 (match_operand:SI 1 "register_operand" "r")]
3585 (clobber (reg:SI PR_REG))]
3588 [(set_attr "type" "sfunc")
3589 (set_attr "needs_delay_slot" "yes")])
3591 (define_expand "initialize_trampoline"
3592 [(match_operand:SI 0 "" "")
3593 (match_operand:SI 1 "" "")
3594 (match_operand:SI 2 "" "")]
3600 tramp = force_reg (Pmode, operands[0]);
3601 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3602 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3603 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3605 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3609 (define_insn "initialize_trampoline_compact"
3610 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3611 (match_operand:SI 1 "register_operand" "r")
3612 (reg:SI R2_REG) (reg:SI R3_REG)]
3615 (clobber (reg:SI PR_REG))]
3618 [(set_attr "type" "sfunc")
3619 (set_attr "needs_delay_slot" "yes")])
3621 (define_insn "movqi_i"
3622 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3623 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3625 && (arith_reg_operand (operands[0], QImode)
3626 || arith_reg_operand (operands[1], QImode))"
3634 [(set_attr "type" "move,load,store,move,move,move")])
3636 (define_insn "*movqi_media"
3637 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3638 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3640 && (arith_reg_operand (operands[0], QImode)
3641 || arith_reg_operand (operands[1], QImode))"
3647 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3649 (define_expand "movqi"
3650 [(set (match_operand:QI 0 "general_operand" "")
3651 (match_operand:QI 1 "general_operand" ""))]
3653 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3655 (define_expand "reload_inqi"
3656 [(set (match_operand:SI 2 "" "=&r")
3657 (match_operand:QI 1 "inqhi_operand" ""))
3658 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3659 (truncate:HI (match_dup 3)))]
3663 rtx inner = XEXP (operands[1], 0);
3664 int regno = REGNO (inner);
3666 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3667 operands[1] = gen_rtx_REG (SImode, regno);
3668 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3671 (define_insn "movhi_i"
3672 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3673 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3675 && (arith_reg_operand (operands[0], HImode)
3676 || arith_reg_operand (operands[1], HImode))"
3686 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3688 (define_insn "*movhi_media"
3689 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3690 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3692 && (arith_reg_operand (operands[0], HImode)
3693 || arith_reg_operand (operands[1], HImode))"
3700 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3703 [(set (match_operand:HI 0 "register_operand" "")
3704 (match_operand:HI 1 "immediate_operand" ""))]
3705 "TARGET_SHMEDIA && reload_completed
3706 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3707 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3709 (define_expand "movhi"
3710 [(set (match_operand:HI 0 "general_movdst_operand" "")
3711 (match_operand:HI 1 "general_movsrc_operand" ""))]
3713 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3715 (define_expand "reload_inhi"
3716 [(set (match_operand:SI 2 "" "=&r")
3717 (match_operand:HI 1 "inqhi_operand" ""))
3718 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3719 (truncate:HI (match_dup 3)))]
3723 rtx inner = XEXP (operands[1], 0);
3724 int regno = REGNO (inner);
3726 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3727 operands[1] = gen_rtx_REG (SImode, regno);
3728 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3731 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3732 ;; compiled with -m2 -ml -O3 -funroll-loops
3733 (define_insn "*movdi_i"
3734 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3735 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3737 && (arith_reg_operand (operands[0], DImode)
3738 || arith_reg_operand (operands[1], DImode))"
3739 "* return output_movedouble (insn, operands, DImode);"
3740 [(set_attr "length" "4")
3741 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3743 ;; If the output is a register and the input is memory or a register, we have
3744 ;; to be careful and see which word needs to be loaded first.
3747 [(set (match_operand:DI 0 "general_movdst_operand" "")
3748 (match_operand:DI 1 "general_movsrc_operand" ""))]
3749 "TARGET_SH1 && reload_completed"
3750 [(set (match_dup 2) (match_dup 3))
3751 (set (match_dup 4) (match_dup 5))]
3756 if ((GET_CODE (operands[0]) == MEM
3757 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3758 || (GET_CODE (operands[1]) == MEM
3759 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3762 if (GET_CODE (operands[0]) == REG)
3763 regno = REGNO (operands[0]);
3764 else if (GET_CODE (operands[0]) == SUBREG)
3765 regno = subreg_regno (operands[0]);
3766 else if (GET_CODE (operands[0]) == MEM)
3772 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3774 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3775 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3776 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3777 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3781 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3782 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3783 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3784 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3787 if (operands[2] == 0 || operands[3] == 0
3788 || operands[4] == 0 || operands[5] == 0)
3792 (define_insn "*movdi_media"
3793 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3794 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3796 && (register_operand (operands[0], DImode)
3797 || register_operand (operands[1], DImode))"
3812 [(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")
3813 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3815 (define_insn "*movdi_media_nofpu"
3816 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3817 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3819 && (register_operand (operands[0], DImode)
3820 || register_operand (operands[1], DImode))"
3830 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3831 (set_attr "length" "4,4,16,4,4,4,4,*")])
3834 [(set (match_operand:DI 0 "arith_reg_operand" "")
3835 (match_operand:DI 1 "immediate_operand" ""))]
3836 "TARGET_SHMEDIA && reload_completed
3837 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3838 [(set (match_dup 0) (match_dup 1))]
3843 if (TARGET_SHMEDIA64)
3844 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3846 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3848 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3854 (define_expand "movdi_const"
3855 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3856 (const:DI (sign_extend:DI
3859 (match_operand:DI 1 "immediate_operand" "s")
3862 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3870 (const_int 32)))))))))
3872 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3880 (const_int 16)))))))))
3882 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3888 (match_dup 1))))))))]
3889 "TARGET_SHMEDIA64 && reload_completed
3890 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3893 sh_mark_label (operands[1], 4);
3896 (define_expand "movdi_const_32bit"
3897 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3898 (const:DI (sign_extend:DI
3901 (match_operand:DI 1 "immediate_operand" "s")
3904 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3910 (match_dup 1))))))))]
3911 "TARGET_SHMEDIA32 && reload_completed
3912 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3915 sh_mark_label (operands[1], 2);
3918 (define_expand "movdi_const_16bit"
3919 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3920 (const:DI (sign_extend:DI
3922 (match_operand:DI 1 "immediate_operand" "s")))))]
3923 "TARGET_SHMEDIA && flag_pic && reload_completed
3924 && GET_CODE (operands[1]) == SYMBOL_REF"
3928 [(set (match_operand:DI 0 "arith_reg_operand" "")
3929 (match_operand:DI 1 "immediate_operand" ""))]
3930 "TARGET_SHMEDIA && reload_completed
3931 && GET_CODE (operands[1]) == CONST_INT
3932 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3933 [(set (match_dup 0) (match_dup 2))
3937 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3938 unsigned HOST_WIDE_INT low = val;
3939 unsigned HOST_WIDE_INT high = val;
3940 unsigned HOST_WIDE_INT sign;
3941 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3943 /* Sign-extend the 16 least-significant bits. */
3948 /* Arithmetic shift right the word by 16 bits. */
3951 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3956 /* If we can't generate the constant with a two-insn movi / shori
3957 sequence, try some other strategies. */
3958 if (! CONST_OK_FOR_J (high))
3960 /* Try constant load / left shift. We know VAL != 0. */
3961 val2 = val ^ (val-1);
3964 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3966 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3967 || (! CONST_OK_FOR_J (high >> 16)
3968 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3970 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3971 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3972 GEN_INT (trailing_zeroes));
3976 /* Try constant load / right shift. */
3977 val2 = (val >> 15) + 1;
3978 if (val2 == (val2 & -val2))
3980 int shift = 49 - exact_log2 (val2);
3982 val2 = trunc_int_for_mode (val << shift, DImode);
3983 if (CONST_OK_FOR_J (val2))
3985 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3991 val2 = val & 0xffff;
3992 if ((val >> 16 & 0xffff) == val2
3993 && (val >> 32 & 0xffff) == val2
3994 && (val >> 48 & 0xffff) == val2)
3996 val2 = (HOST_WIDE_INT) val >> 48;
3997 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3998 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4001 /* Try movi / mshflo.l */
4002 val2 = (HOST_WIDE_INT) val >> 32;
4003 if (val2 == trunc_int_for_mode (val, SImode))
4005 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4009 /* Try movi / mshflo.l w/ r63. */
4010 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4011 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4013 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4019 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4022 operands[2] = GEN_INT (val2);
4026 [(set (match_operand:DI 0 "arith_reg_operand" "")
4027 (match_operand:DI 1 "immediate_operand" ""))]
4028 "TARGET_SHMEDIA && reload_completed
4029 && GET_CODE (operands[1]) == CONST_DOUBLE"
4030 [(set (match_dup 0) (match_dup 2))
4032 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4033 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4036 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4037 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4038 unsigned HOST_WIDE_INT val = low;
4039 unsigned HOST_WIDE_INT sign;
4041 /* Sign-extend the 16 least-significant bits. */
4045 operands[1] = GEN_INT (val);
4047 /* Arithmetic shift right the double-word by 16 bits. */
4049 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4052 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4056 /* This will only be true if high is a sign-extension of low, i.e.,
4057 it must be either 0 or (unsigned)-1, and be zero iff the
4058 most-significant bit of low is set. */
4059 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4060 operands[2] = GEN_INT (low);
4062 operands[2] = immed_double_const (low, high, DImode);
4065 (define_insn "shori_media"
4066 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4067 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4071 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4076 [(set_attr "type" "arith_media,*")])
4078 (define_expand "movdi"
4079 [(set (match_operand:DI 0 "general_movdst_operand" "")
4080 (match_operand:DI 1 "general_movsrc_operand" ""))]
4082 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4084 (define_insn "movdf_media"
4085 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4086 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4088 && (register_operand (operands[0], DFmode)
4089 || register_operand (operands[1], DFmode))"
4100 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4102 (define_insn "movdf_media_nofpu"
4103 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4104 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4106 && (register_operand (operands[0], DFmode)
4107 || register_operand (operands[1], DFmode))"
4113 [(set_attr "type" "arith_media,*,load_media,store_media")])
4116 [(set (match_operand:DF 0 "arith_reg_operand" "")
4117 (match_operand:DF 1 "immediate_operand" ""))]
4118 "TARGET_SHMEDIA && reload_completed"
4119 [(set (match_dup 3) (match_dup 2))]
4122 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4124 REAL_VALUE_TYPE value;
4126 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4127 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4129 if (HOST_BITS_PER_WIDE_INT >= 64)
4130 operands[2] = immed_double_const ((unsigned long) values[endian]
4131 | ((HOST_WIDE_INT) values[1 - endian]
4133 else if (HOST_BITS_PER_WIDE_INT == 32)
4134 operands[2] = immed_double_const (values[endian], values[1 - endian],
4139 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4142 ;; ??? This should be a define expand.
4144 (define_insn "movdf_k"
4145 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4146 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4148 && (! TARGET_SH4 || reload_completed
4149 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4150 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4151 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4152 && (arith_reg_operand (operands[0], DFmode)
4153 || arith_reg_operand (operands[1], DFmode))"
4154 "* return output_movedouble (insn, operands, DFmode);"
4155 [(set_attr "length" "4")
4156 (set_attr "type" "move,pcload,load,store")])
4158 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4159 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4160 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4161 ;; the d/m/c/X alternative, which is split later into single-precision
4162 ;; instructions. And when not optimizing, no splits are done before fixing
4163 ;; up pcloads, so we need usable length information for that.
4164 (define_insn "movdf_i4"
4165 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4166 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4167 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4168 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4170 && (arith_reg_operand (operands[0], DFmode)
4171 || arith_reg_operand (operands[1], DFmode))"
4183 [(set_attr_alternative "length"
4184 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4186 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4187 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4188 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4190 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4191 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4192 ;; increment or decrement r15 explicitly.
4194 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4195 (const_int 10) (const_int 8))
4197 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4198 (const_int 10) (const_int 8))])
4199 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4200 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4201 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4202 (const_string "double")
4203 (const_string "none")))])
4205 ;; Moving DFmode between fp/general registers through memory
4206 ;; (the top of the stack) is faster than moving through fpul even for
4207 ;; little endian. Because the type of an instruction is important for its
4208 ;; scheduling, it is beneficial to split these operations, rather than
4209 ;; emitting them in one single chunk, even if this will expose a stack
4210 ;; use that will prevent scheduling of other stack accesses beyond this
4213 [(set (match_operand:DF 0 "register_operand" "")
4214 (match_operand:DF 1 "register_operand" ""))
4215 (use (match_operand:PSI 2 "fpscr_operand" ""))
4216 (clobber (match_scratch:SI 3 "=X"))]
4217 "TARGET_SH4 && reload_completed
4218 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4224 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4226 emit_move_insn (stack_pointer_rtx,
4227 plus_constant (stack_pointer_rtx, -8));
4228 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4231 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4232 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4233 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4234 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4235 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4236 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4238 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4239 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4240 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4241 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4243 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4247 ;; local-alloc sometimes allocates scratch registers even when not required,
4248 ;; so we must be prepared to handle these.
4250 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4252 [(set (match_operand:DF 0 "general_movdst_operand" "")
4253 (match_operand:DF 1 "general_movsrc_operand" ""))
4254 (use (match_operand:PSI 2 "fpscr_operand" ""))
4255 (clobber (match_scratch:SI 3 ""))]
4258 && true_regnum (operands[0]) < 16
4259 && true_regnum (operands[1]) < 16"
4260 [(set (match_dup 0) (match_dup 1))]
4263 /* If this was a reg <-> mem operation with base + index reg addressing,
4264 we have to handle this in a special way. */
4265 rtx mem = operands[0];
4267 if (! memory_operand (mem, DFmode))
4272 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4273 mem = SUBREG_REG (mem);
4274 if (GET_CODE (mem) == MEM)
4276 rtx addr = XEXP (mem, 0);
4277 if (GET_CODE (addr) == PLUS
4278 && GET_CODE (XEXP (addr, 0)) == REG
4279 && GET_CODE (XEXP (addr, 1)) == REG)
4282 rtx reg0 = gen_rtx (REG, Pmode, 0);
4283 rtx regop = operands[store_p], word0 ,word1;
4285 if (GET_CODE (regop) == SUBREG)
4286 alter_subreg (®op);
4287 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4291 mem = copy_rtx (mem);
4292 PUT_MODE (mem, SImode);
4293 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4294 alter_subreg (&word0);
4295 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4296 alter_subreg (&word1);
4297 if (store_p || ! refers_to_regno_p (REGNO (word0),
4298 REGNO (word0) + 1, addr, 0))
4301 ? gen_movsi_ie (mem, word0)
4302 : gen_movsi_ie (word0, mem));
4303 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4304 mem = copy_rtx (mem);
4306 ? gen_movsi_ie (mem, word1)
4307 : gen_movsi_ie (word1, mem));
4308 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4312 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4313 emit_insn (gen_movsi_ie (word1, mem));
4314 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4315 mem = copy_rtx (mem);
4316 emit_insn (gen_movsi_ie (word0, mem));
4323 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4325 [(set (match_operand:DF 0 "register_operand" "")
4326 (match_operand:DF 1 "memory_operand" ""))
4327 (use (match_operand:PSI 2 "fpscr_operand" ""))
4328 (clobber (reg:SI R0_REG))]
4329 "TARGET_SH4 && reload_completed"
4330 [(parallel [(set (match_dup 0) (match_dup 1))
4332 (clobber (scratch:SI))])]
4335 (define_expand "reload_indf"
4336 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4337 (match_operand:DF 1 "immediate_operand" "FQ"))
4338 (use (reg:PSI FPSCR_REG))
4339 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4343 (define_expand "reload_outdf"
4344 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4345 (match_operand:DF 1 "register_operand" "af,r"))
4346 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4350 ;; Simplify no-op moves.
4352 [(set (match_operand:SF 0 "register_operand" "")
4353 (match_operand:SF 1 "register_operand" ""))
4354 (use (match_operand:PSI 2 "fpscr_operand" ""))
4355 (clobber (match_scratch:SI 3 "X"))]
4356 "TARGET_SH3E && reload_completed
4357 && true_regnum (operands[0]) == true_regnum (operands[1])"
4358 [(set (match_dup 0) (match_dup 0))]
4361 ;; fmovd substitute post-reload splits
4363 [(set (match_operand:DF 0 "register_operand" "")
4364 (match_operand:DF 1 "register_operand" ""))
4365 (use (match_operand:PSI 2 "fpscr_operand" ""))
4366 (clobber (match_scratch:SI 3 "X"))]
4367 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4368 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4369 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4373 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4374 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4375 gen_rtx (REG, SFmode, src), operands[2]));
4376 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4377 gen_rtx (REG, SFmode, src + 1), operands[2]));
4382 [(set (match_operand:DF 0 "register_operand" "")
4383 (mem:DF (match_operand:SI 1 "register_operand" "")))
4384 (use (match_operand:PSI 2 "fpscr_operand" ""))
4385 (clobber (match_scratch:SI 3 ""))]
4386 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4387 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4388 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4392 int regno = true_regnum (operands[0]);
4394 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4396 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4397 regno + !! TARGET_LITTLE_ENDIAN),
4398 mem2, operands[2]));
4399 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4400 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4401 regno + ! TARGET_LITTLE_ENDIAN),
4402 gen_rtx (MEM, SFmode, operands[1]),
4408 [(set (match_operand:DF 0 "register_operand" "")
4409 (match_operand:DF 1 "memory_operand" ""))
4410 (use (match_operand:PSI 2 "fpscr_operand" ""))
4411 (clobber (match_scratch:SI 3 ""))]
4412 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4413 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4417 int regno = true_regnum (operands[0]);
4418 rtx addr, insn, adjust = NULL_RTX;
4419 rtx mem2 = copy_rtx (operands[1]);
4420 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4421 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4423 PUT_MODE (mem2, SFmode);
4424 operands[1] = copy_rtx (mem2);
4425 addr = XEXP (mem2, 0);
4426 if (GET_CODE (addr) != POST_INC)
4428 /* If we have to modify the stack pointer, the value that we have
4429 read with post-increment might be modified by an interrupt,
4430 so write it back. */
4431 if (REGNO (addr) == STACK_POINTER_REGNUM)
4432 adjust = gen_push_e (reg0);
4434 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4435 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4437 addr = XEXP (addr, 0);
4438 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4439 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4440 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4444 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4449 [(set (match_operand:DF 0 "memory_operand" "")
4450 (match_operand:DF 1 "register_operand" ""))
4451 (use (match_operand:PSI 2 "fpscr_operand" ""))
4452 (clobber (match_scratch:SI 3 ""))]
4453 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4454 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4458 int regno = true_regnum (operands[1]);
4459 rtx insn, addr, adjust = NULL_RTX;
4461 operands[0] = copy_rtx (operands[0]);
4462 PUT_MODE (operands[0], SFmode);
4463 insn = emit_insn (gen_movsf_ie (operands[0],
4464 gen_rtx (REG, SFmode,
4465 regno + ! TARGET_LITTLE_ENDIAN),
4467 operands[0] = copy_rtx (operands[0]);
4468 addr = XEXP (operands[0], 0);
4469 if (GET_CODE (addr) != PRE_DEC)
4471 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4472 emit_insn_before (adjust, insn);
4473 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4475 addr = XEXP (addr, 0);
4477 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4478 insn = emit_insn (gen_movsf_ie (operands[0],
4479 gen_rtx (REG, SFmode,
4480 regno + !! TARGET_LITTLE_ENDIAN),
4482 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4486 ;; If the output is a register and the input is memory or a register, we have
4487 ;; to be careful and see which word needs to be loaded first.
4490 [(set (match_operand:DF 0 "general_movdst_operand" "")
4491 (match_operand:DF 1 "general_movsrc_operand" ""))]
4492 "TARGET_SH1 && reload_completed"
4493 [(set (match_dup 2) (match_dup 3))
4494 (set (match_dup 4) (match_dup 5))]
4499 if ((GET_CODE (operands[0]) == MEM
4500 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4501 || (GET_CODE (operands[1]) == MEM
4502 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4505 if (GET_CODE (operands[0]) == REG)
4506 regno = REGNO (operands[0]);
4507 else if (GET_CODE (operands[0]) == SUBREG)
4508 regno = subreg_regno (operands[0]);
4509 else if (GET_CODE (operands[0]) == MEM)
4515 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4517 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4518 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4519 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4520 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4524 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4525 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4526 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4527 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4530 if (operands[2] == 0 || operands[3] == 0
4531 || operands[4] == 0 || operands[5] == 0)
4535 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4536 ;; used only once, let combine add in the index again.
4539 [(set (match_operand:SI 0 "register_operand" "")
4540 (match_operand:SI 1 "" ""))
4541 (clobber (match_operand 2 "register_operand" ""))]
4542 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4543 [(use (reg:SI R0_REG))]
4546 rtx addr, reg, const_int;
4548 if (GET_CODE (operands[1]) != MEM)
4550 addr = XEXP (operands[1], 0);
4551 if (GET_CODE (addr) != PLUS)
4553 reg = XEXP (addr, 0);
4554 const_int = XEXP (addr, 1);
4555 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4556 && GET_CODE (const_int) == CONST_INT))
4558 emit_move_insn (operands[2], const_int);
4559 emit_move_insn (operands[0],
4560 change_address (operands[1], VOIDmode,
4561 gen_rtx_PLUS (SImode, reg, operands[2])));
4566 [(set (match_operand:SI 1 "" "")
4567 (match_operand:SI 0 "register_operand" ""))
4568 (clobber (match_operand 2 "register_operand" ""))]
4569 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4570 [(use (reg:SI R0_REG))]
4573 rtx addr, reg, const_int;
4575 if (GET_CODE (operands[1]) != MEM)
4577 addr = XEXP (operands[1], 0);
4578 if (GET_CODE (addr) != PLUS)
4580 reg = XEXP (addr, 0);
4581 const_int = XEXP (addr, 1);
4582 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4583 && GET_CODE (const_int) == CONST_INT))
4585 emit_move_insn (operands[2], const_int);
4586 emit_move_insn (change_address (operands[1], VOIDmode,
4587 gen_rtx_PLUS (SImode, reg, operands[2])),
4592 (define_expand "movdf"
4593 [(set (match_operand:DF 0 "general_movdst_operand" "")
4594 (match_operand:DF 1 "general_movsrc_operand" ""))]
4598 if (prepare_move_operands (operands, DFmode)) DONE;
4601 if (TARGET_SHMEDIA_FPU)
4602 emit_insn (gen_movdf_media (operands[0], operands[1]));
4604 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4609 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4614 ;;This is incompatible with the way gcc uses subregs.
4615 ;;(define_insn "movv2sf_i"
4616 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4617 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4618 ;; "TARGET_SHMEDIA_FPU
4619 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4620 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4624 ;; fst%M0.p %m0, %1"
4625 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4627 (define_insn_and_split "movv2sf_i"
4628 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4629 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4630 "TARGET_SHMEDIA_FPU"
4632 "TARGET_SHMEDIA_FPU && reload_completed"
4633 [(set (match_dup 0) (match_dup 1))]
4636 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4637 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4640 (define_expand "movv2sf"
4641 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4642 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4643 "TARGET_SHMEDIA_FPU"
4646 if (prepare_move_operands (operands, V2SFmode))
4650 (define_expand "addv2sf3"
4651 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4652 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4653 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4654 "TARGET_SHMEDIA_FPU"
4657 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4661 (define_expand "subv2sf3"
4662 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4663 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4664 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4665 "TARGET_SHMEDIA_FPU"
4668 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4672 (define_expand "mulv2sf3"
4673 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4674 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4675 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4676 "TARGET_SHMEDIA_FPU"
4679 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4683 (define_expand "divv2sf3"
4684 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4685 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4686 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4687 "TARGET_SHMEDIA_FPU"
4690 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4694 (define_insn_and_split "*movv4sf_i"
4695 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4696 (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4697 "TARGET_SHMEDIA_FPU"
4699 "&& reload_completed"
4705 for (i = 0; i < 4/2; i++)
4709 if (GET_CODE (operands[0]) == MEM)
4710 x = gen_rtx_MEM (V2SFmode,
4711 plus_constant (XEXP (operands[0], 0),
4712 i * GET_MODE_SIZE (V2SFmode)));
4714 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4716 if (GET_CODE (operands[1]) == MEM)
4717 y = gen_rtx_MEM (V2SFmode,
4718 plus_constant (XEXP (operands[1], 0),
4719 i * GET_MODE_SIZE (V2SFmode)));
4721 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4723 emit_insn (gen_movv2sf_i (x, y));
4728 [(set_attr "length" "8")])
4730 (define_expand "movv4sf"
4731 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4732 (match_operand:V4SF 1 "general_operand" ""))]
4733 "TARGET_SHMEDIA_FPU"
4736 if (prepare_move_operands (operands, V4SFmode))
4740 (define_insn_and_split "*movv16sf_i"
4741 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4742 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4743 "TARGET_SHMEDIA_FPU"
4745 "&& reload_completed"
4751 for (i = 0; i < 16/2; i++)
4755 if (GET_CODE (operands[0]) == MEM)
4756 x = gen_rtx_MEM (V2SFmode,
4757 plus_constant (XEXP (operands[0], 0),
4758 i * GET_MODE_SIZE (V2SFmode)));
4761 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4765 if (GET_CODE (operands[1]) == MEM)
4766 y = gen_rtx_MEM (V2SFmode,
4767 plus_constant (XEXP (operands[1], 0),
4768 i * GET_MODE_SIZE (V2SFmode)));
4771 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4775 emit_insn (gen_movv2sf_i (x, y));
4780 [(set_attr "length" "32")])
4782 (define_expand "movv16sf"
4783 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4784 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4785 "TARGET_SHMEDIA_FPU"
4788 if (prepare_move_operands (operands, V16SFmode))
4792 (define_insn "movsf_media"
4793 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4794 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4796 && (register_operand (operands[0], SFmode)
4797 || register_operand (operands[1], SFmode))"
4808 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4810 (define_insn "movsf_media_nofpu"
4811 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4812 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4814 && (register_operand (operands[0], SFmode)
4815 || register_operand (operands[1], SFmode))"
4821 [(set_attr "type" "arith_media,*,load_media,store_media")])
4824 [(set (match_operand:SF 0 "arith_reg_operand" "")
4825 (match_operand:SF 1 "immediate_operand" ""))]
4826 "TARGET_SHMEDIA && reload_completed
4827 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4828 [(set (match_dup 3) (match_dup 2))]
4832 REAL_VALUE_TYPE value;
4834 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4835 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4836 operands[2] = GEN_INT (values);
4838 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4841 (define_insn "movsf_i"
4842 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4843 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4846 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4847 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4848 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4849 && (arith_reg_operand (operands[0], SFmode)
4850 || arith_reg_operand (operands[1], SFmode))"
4859 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4861 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4862 ;; update_flow_info would not know where to put REG_EQUAL notes
4863 ;; when the destination changes mode.
4864 (define_insn "movsf_ie"
4865 [(set (match_operand:SF 0 "general_movdst_operand"
4866 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4867 (match_operand:SF 1 "general_movsrc_operand"
4868 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4869 (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"))
4870 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4873 && (arith_reg_operand (operands[0], SFmode)
4874 || arith_reg_operand (operands[1], SFmode)
4875 || arith_reg_operand (operands[3], SImode)
4876 || (fpul_operand (operands[0], SFmode)
4877 && memory_operand (operands[1], SFmode)
4878 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4879 || (fpul_operand (operands[1], SFmode)
4880 && memory_operand (operands[0], SFmode)
4881 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4901 ! move optimized away"
4902 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4903 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4904 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4905 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4906 (const_string "single")
4907 (const_string "none")))])
4910 [(set (match_operand:SF 0 "register_operand" "")
4911 (match_operand:SF 1 "register_operand" ""))
4912 (use (match_operand:PSI 2 "fpscr_operand" ""))
4913 (clobber (reg:SI FPUL_REG))]
4915 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4917 (clobber (scratch:SI))])
4918 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4920 (clobber (scratch:SI))])]
4923 (define_expand "movsf"
4924 [(set (match_operand:SF 0 "general_movdst_operand" "")
4925 (match_operand:SF 1 "general_movsrc_operand" ""))]
4929 if (prepare_move_operands (operands, SFmode))
4933 if (TARGET_SHMEDIA_FPU)
4934 emit_insn (gen_movsf_media (operands[0], operands[1]));
4936 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4941 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4946 (define_insn "mov_nop"
4947 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4950 [(set_attr "length" "0")
4951 (set_attr "type" "nil")])
4953 (define_expand "reload_insf"
4954 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4955 (match_operand:SF 1 "immediate_operand" "FQ"))
4956 (use (reg:PSI FPSCR_REG))
4957 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4961 (define_expand "reload_insi"
4962 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4963 (match_operand:SF 1 "immediate_operand" "FQ"))
4964 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4968 (define_insn "*movsi_y"
4969 [(set (match_operand:SI 0 "register_operand" "=y,y")
4970 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4971 (clobber (match_scratch:SI 2 "=&z,r"))]
4973 && (reload_in_progress || reload_completed)"
4975 [(set_attr "length" "4")
4976 (set_attr "type" "pcload,move")])
4979 [(set (match_operand:SI 0 "register_operand" "")
4980 (match_operand:SI 1 "immediate_operand" ""))
4981 (clobber (match_operand:SI 2 "register_operand" ""))]
4983 [(set (match_dup 2) (match_dup 1))
4984 (set (match_dup 0) (match_dup 2))]
4988 [(set (match_operand:SI 0 "register_operand" "")
4989 (match_operand:SI 1 "memory_operand" ""))
4990 (clobber (reg:SI R0_REG))]
4992 [(set (match_dup 0) (match_dup 1))]
4995 ;; ------------------------------------------------------------------------
4996 ;; Define the real conditional branch instructions.
4997 ;; ------------------------------------------------------------------------
4999 (define_insn "branch_true"
5000 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5001 (label_ref (match_operand 0 "" ""))
5004 "* return output_branch (1, insn, operands);"
5005 [(set_attr "type" "cbranch")])
5007 (define_insn "branch_false"
5008 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5009 (label_ref (match_operand 0 "" ""))
5012 "* return output_branch (0, insn, operands);"
5013 [(set_attr "type" "cbranch")])
5015 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5016 ;; which destination is too far away.
5017 ;; The const_int_operand is distinct for each branch target; it avoids
5018 ;; unwanted matches with redundant_insn.
5019 (define_insn "block_branch_redirect"
5020 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5023 [(set_attr "length" "0")])
5025 ;; This one has the additional purpose to record a possible scratch register
5026 ;; for the following branch.
5027 (define_insn "indirect_jump_scratch"
5028 [(set (match_operand:SI 0 "register_operand" "=r")
5029 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5032 [(set_attr "length" "0")])
5034 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5035 ;; being pulled into the delay slot of a condbranch that has been made to
5036 ;; jump around the unconditional jump because it was out of range.
5037 (define_insn "stuff_delay_slot"
5039 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5040 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5043 [(set_attr "length" "0")
5044 (set_attr "cond_delay_slot" "yes")])
5046 ;; Conditional branch insns
5048 (define_expand "beq_media"
5050 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5051 (match_operand:DI 2 "arith_operand" "r,O"))
5052 (label_ref:DI (match_operand 0 "" ""))
5057 (define_insn "*beq_media_i"
5059 (if_then_else (match_operator 3 "equality_comparison_operator"
5060 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5061 (match_operand:DI 2 "arith_operand" "r,O")])
5062 (match_operand:DI 0 "target_operand" "b,b")
5068 [(set_attr "type" "cbranch_media")])
5070 (define_expand "bne_media"
5072 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5073 (match_operand:DI 2 "arith_operand" "r,O"))
5074 (label_ref:DI (match_operand 0 "" ""))
5079 (define_expand "bgt_media"
5081 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5082 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5083 (label_ref:DI (match_operand 0 "" ""))
5088 (define_expand "bge_media"
5090 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5091 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5092 (label_ref:DI (match_operand 0 "" ""))
5097 (define_expand "bgtu_media"
5099 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5100 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5101 (label_ref:DI (match_operand 0 "" ""))
5106 (define_expand "bgeu_media"
5108 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5109 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5110 (label_ref:DI (match_operand 0 "" ""))
5115 (define_insn "*bgt_media_i"
5117 (if_then_else (match_operator 3 "greater_comparison_operator"
5118 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5119 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5120 (match_operand:DI 0 "target_operand" "b")
5123 "b%o3%' %N1, %N2, %0"
5124 [(set_attr "type" "cbranch_media")])
5126 ;; These are only needed to make invert_jump() happy.
5127 (define_insn "*blt_media_i"
5129 (if_then_else (match_operator 3 "less_comparison_operator"
5130 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5131 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5132 (match_operand:DI 0 "target_operand" "b")
5135 "b%o3%' %N2, %N1, %0"
5136 [(set_attr "type" "cbranch_media")])
5138 (define_expand "beq"
5140 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5141 (label_ref (match_operand 0 "" ""))
5148 if (GET_MODE (sh_compare_op0) != DImode)
5150 rtx tmp = gen_reg_rtx (DImode);
5152 emit_insn (gen_seq (tmp));
5153 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5157 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5158 emit_jump_insn (gen_beq_media (operands[0],
5159 sh_compare_op0, sh_compare_op1));
5163 from_compare (operands, EQ);
5166 (define_expand "bne"
5168 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5169 (label_ref (match_operand 0 "" ""))
5176 if (GET_MODE (sh_compare_op0) != DImode)
5178 rtx tmp = gen_reg_rtx (DImode);
5180 emit_insn (gen_seq (tmp));
5181 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5185 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5186 emit_jump_insn (gen_bne_media (operands[0],
5187 sh_compare_op0, sh_compare_op1));
5191 from_compare (operands, EQ);
5194 (define_expand "bgt"
5196 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5197 (label_ref (match_operand 0 "" ""))
5204 if (GET_MODE (sh_compare_op0) != DImode)
5206 rtx tmp = gen_reg_rtx (DImode);
5208 emit_insn (gen_sgt (tmp));
5209 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5213 if (sh_compare_op0 != const0_rtx)
5214 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5215 if (sh_compare_op1 != const0_rtx)
5216 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5217 emit_jump_insn (gen_bgt_media (operands[0],
5218 sh_compare_op0, sh_compare_op1));
5222 from_compare (operands, GT);
5225 (define_expand "blt"
5227 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5228 (label_ref (match_operand 0 "" ""))
5235 if (GET_MODE (sh_compare_op0) != DImode)
5237 rtx tmp = gen_reg_rtx (DImode);
5239 emit_insn (gen_slt (tmp));
5240 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5244 if (sh_compare_op0 != const0_rtx)
5245 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5246 if (sh_compare_op1 != const0_rtx)
5247 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5248 emit_jump_insn (gen_bgt_media (operands[0],
5249 sh_compare_op1, sh_compare_op0));
5253 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5255 rtx tmp = sh_compare_op0;
5256 sh_compare_op0 = sh_compare_op1;
5257 sh_compare_op1 = tmp;
5258 emit_insn (gen_bgt (operands[0]));
5261 from_compare (operands, GE);
5264 (define_expand "ble"
5266 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5267 (label_ref (match_operand 0 "" ""))
5274 if (GET_MODE (sh_compare_op0) != DImode)
5276 rtx tmp = gen_reg_rtx (DImode);
5278 emit_insn (gen_sle (tmp));
5279 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5283 if (sh_compare_op0 != const0_rtx)
5284 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5285 if (sh_compare_op1 != const0_rtx)
5286 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5287 emit_jump_insn (gen_bge_media (operands[0],
5288 sh_compare_op1, sh_compare_op0));
5294 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5296 rtx tmp = sh_compare_op0;
5297 sh_compare_op0 = sh_compare_op1;
5298 sh_compare_op1 = tmp;
5299 emit_insn (gen_bge (operands[0]));
5302 from_compare (operands, GT);
5305 (define_expand "bge"
5307 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5308 (label_ref (match_operand 0 "" ""))
5315 if (GET_MODE (sh_compare_op0) != DImode)
5317 rtx tmp = gen_reg_rtx (DImode);
5319 emit_insn (gen_sge (tmp));
5320 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5324 if (sh_compare_op0 != const0_rtx)
5325 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5326 if (sh_compare_op1 != const0_rtx)
5327 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5328 emit_jump_insn (gen_bge_media (operands[0],
5329 sh_compare_op0, sh_compare_op1));
5335 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5337 rtx tmp = sh_compare_op0;
5338 sh_compare_op0 = sh_compare_op1;
5339 sh_compare_op1 = tmp;
5340 emit_insn (gen_ble (operands[0]));
5343 from_compare (operands, GE);
5346 (define_expand "bgtu"
5348 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5349 (label_ref (match_operand 0 "" ""))
5356 if (sh_compare_op0 != const0_rtx)
5357 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5358 if (sh_compare_op1 != const0_rtx)
5359 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5360 emit_jump_insn (gen_bgtu_media (operands[0],
5361 sh_compare_op0, sh_compare_op1));
5365 from_compare (operands, GTU);
5368 (define_expand "bltu"
5370 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5371 (label_ref (match_operand 0 "" ""))
5378 if (sh_compare_op0 != const0_rtx)
5379 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5380 if (sh_compare_op1 != const0_rtx)
5381 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5382 emit_jump_insn (gen_bgtu_media (operands[0],
5383 sh_compare_op1, sh_compare_op0));
5387 from_compare (operands, GEU);
5390 (define_expand "bgeu"
5392 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5393 (label_ref (match_operand 0 "" ""))
5400 if (sh_compare_op0 != const0_rtx)
5401 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5402 if (sh_compare_op1 != const0_rtx)
5403 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5404 emit_jump_insn (gen_bgeu_media (operands[0],
5405 sh_compare_op0, sh_compare_op1));
5409 from_compare (operands, GEU);
5412 (define_expand "bleu"
5414 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5415 (label_ref (match_operand 0 "" ""))
5422 if (sh_compare_op0 != const0_rtx)
5423 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5424 if (sh_compare_op1 != const0_rtx)
5425 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5426 emit_jump_insn (gen_bgeu_media (operands[0],
5427 sh_compare_op1, sh_compare_op0));
5431 from_compare (operands, GTU);
5434 (define_expand "bunordered"
5435 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5437 (if_then_else (ne (match_dup 1) (const_int 0))
5438 (label_ref:DI (match_operand 0 "" ""))
5443 operands[1] = gen_reg_rtx (DImode);
5444 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5445 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5448 ;; ------------------------------------------------------------------------
5449 ;; Jump and linkage insns
5450 ;; ------------------------------------------------------------------------
5452 (define_insn "jump_compact"
5454 (label_ref (match_operand 0 "" "")))]
5458 /* The length is 16 if the delay slot is unfilled. */
5459 if (get_attr_length(insn) > 4)
5460 return output_far_jump(insn, operands[0]);
5462 return \"bra %l0%#\";
5464 [(set_attr "type" "jump")
5465 (set_attr "needs_delay_slot" "yes")])
5467 (define_insn "jump_media"
5469 (match_operand:DI 0 "target_operand" "b"))]
5472 [(set_attr "type" "jump_media")])
5474 (define_expand "jump"
5476 (label_ref (match_operand 0 "" "")))]
5481 emit_jump_insn (gen_jump_compact (operands[0]));
5482 else if (TARGET_SHMEDIA)
5484 if (reload_in_progress || reload_completed)
5486 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5492 (define_insn "force_mode_for_call"
5493 [(use (reg:PSI FPSCR_REG))]
5496 [(set_attr "length" "0")
5497 (set (attr "fp_mode")
5498 (if_then_else (eq_attr "fpu_single" "yes")
5499 (const_string "single") (const_string "double")))])
5501 (define_insn "calli"
5502 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5503 (match_operand 1 "" ""))
5504 (use (reg:PSI FPSCR_REG))
5505 (clobber (reg:SI PR_REG))]
5508 [(set_attr "type" "call")
5509 (set (attr "fp_mode")
5510 (if_then_else (eq_attr "fpu_single" "yes")
5511 (const_string "single") (const_string "double")))
5512 (set_attr "needs_delay_slot" "yes")])
5514 ;; This is a pc-rel call, using bsrf, for use with PIC.
5516 (define_insn "calli_pcrel"
5517 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5518 (match_operand 1 "" ""))
5519 (use (reg:PSI FPSCR_REG))
5520 (use (reg:SI PIC_REG))
5521 (use (match_operand 2 "" ""))
5522 (clobber (reg:SI PR_REG))]
5525 [(set_attr "type" "call")
5526 (set (attr "fp_mode")
5527 (if_then_else (eq_attr "fpu_single" "yes")
5528 (const_string "single") (const_string "double")))
5529 (set_attr "needs_delay_slot" "yes")])
5531 (define_insn_and_split "call_pcrel"
5532 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5533 (match_operand 1 "" ""))
5534 (use (reg:PSI FPSCR_REG))
5535 (use (reg:SI PIC_REG))
5536 (clobber (reg:SI PR_REG))
5537 (clobber (match_scratch:SI 2 "=r"))]
5544 rtx lab = PATTERN (gen_call_site ());
5546 if (SYMBOL_REF_FLAG (operands[0]))
5547 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5549 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5550 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5553 [(set_attr "type" "call")
5554 (set (attr "fp_mode")
5555 (if_then_else (eq_attr "fpu_single" "yes")
5556 (const_string "single") (const_string "double")))
5557 (set_attr "needs_delay_slot" "yes")])
5559 (define_insn "call_compact"
5560 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5561 (match_operand 1 "" ""))
5562 (match_operand 2 "immediate_operand" "n")
5563 (use (reg:SI R0_REG))
5564 (use (reg:SI R1_REG))
5565 (use (reg:PSI FPSCR_REG))
5566 (clobber (reg:SI PR_REG))]
5567 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5569 [(set_attr "type" "call")
5570 (set (attr "fp_mode")
5571 (if_then_else (eq_attr "fpu_single" "yes")
5572 (const_string "single") (const_string "double")))
5573 (set_attr "needs_delay_slot" "yes")])
5575 (define_insn "call_compact_rettramp"
5576 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5577 (match_operand 1 "" ""))
5578 (match_operand 2 "immediate_operand" "n")
5579 (use (reg:SI R0_REG))
5580 (use (reg:SI R1_REG))
5581 (use (reg:PSI FPSCR_REG))
5582 (clobber (reg:SI R10_REG))
5583 (clobber (reg:SI PR_REG))]
5584 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5586 [(set_attr "type" "call")
5587 (set (attr "fp_mode")
5588 (if_then_else (eq_attr "fpu_single" "yes")
5589 (const_string "single") (const_string "double")))
5590 (set_attr "needs_delay_slot" "yes")])
5592 (define_insn "call_media"
5593 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5594 (match_operand 1 "" ""))
5595 (clobber (reg:DI PR_MEDIA_REG))]
5598 [(set_attr "type" "jump_media")])
5600 (define_insn "call_valuei"
5601 [(set (match_operand 0 "" "=rf")
5602 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5603 (match_operand 2 "" "")))
5604 (use (reg:PSI FPSCR_REG))
5605 (clobber (reg:SI PR_REG))]
5608 [(set_attr "type" "call")
5609 (set (attr "fp_mode")
5610 (if_then_else (eq_attr "fpu_single" "yes")
5611 (const_string "single") (const_string "double")))
5612 (set_attr "needs_delay_slot" "yes")])
5614 (define_insn "call_valuei_pcrel"
5615 [(set (match_operand 0 "" "=rf")
5616 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5617 (match_operand 2 "" "")))
5618 (use (reg:PSI FPSCR_REG))
5619 (use (reg:SI PIC_REG))
5620 (use (match_operand 3 "" ""))
5621 (clobber (reg:SI PR_REG))]
5624 [(set_attr "type" "call")
5625 (set (attr "fp_mode")
5626 (if_then_else (eq_attr "fpu_single" "yes")
5627 (const_string "single") (const_string "double")))
5628 (set_attr "needs_delay_slot" "yes")])
5630 (define_insn_and_split "call_value_pcrel"
5631 [(set (match_operand 0 "" "=rf")
5632 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5633 (match_operand 2 "" "")))
5634 (use (reg:PSI FPSCR_REG))
5635 (use (reg:SI PIC_REG))
5636 (clobber (reg:SI PR_REG))
5637 (clobber (match_scratch:SI 3 "=r"))]
5644 rtx lab = PATTERN (gen_call_site ());
5646 if (SYMBOL_REF_FLAG (operands[1]))
5647 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5649 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5650 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5654 [(set_attr "type" "call")
5655 (set (attr "fp_mode")
5656 (if_then_else (eq_attr "fpu_single" "yes")
5657 (const_string "single") (const_string "double")))
5658 (set_attr "needs_delay_slot" "yes")])
5660 (define_insn "call_value_compact"
5661 [(set (match_operand 0 "" "=rf")
5662 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5663 (match_operand 2 "" "")))
5664 (match_operand 3 "immediate_operand" "n")
5665 (use (reg:SI R0_REG))
5666 (use (reg:SI R1_REG))
5667 (use (reg:PSI FPSCR_REG))
5668 (clobber (reg:SI PR_REG))]
5669 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5671 [(set_attr "type" "call")
5672 (set (attr "fp_mode")
5673 (if_then_else (eq_attr "fpu_single" "yes")
5674 (const_string "single") (const_string "double")))
5675 (set_attr "needs_delay_slot" "yes")])
5677 (define_insn "call_value_compact_rettramp"
5678 [(set (match_operand 0 "" "=rf")
5679 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5680 (match_operand 2 "" "")))
5681 (match_operand 3 "immediate_operand" "n")
5682 (use (reg:SI R0_REG))
5683 (use (reg:SI R1_REG))
5684 (use (reg:PSI FPSCR_REG))
5685 (clobber (reg:SI R10_REG))
5686 (clobber (reg:SI PR_REG))]
5687 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5689 [(set_attr "type" "call")
5690 (set (attr "fp_mode")
5691 (if_then_else (eq_attr "fpu_single" "yes")
5692 (const_string "single") (const_string "double")))
5693 (set_attr "needs_delay_slot" "yes")])
5695 (define_insn "call_value_media"
5696 [(set (match_operand 0 "" "=rf")
5697 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5698 (match_operand 2 "" "")))
5699 (clobber (reg:DI PR_MEDIA_REG))]
5702 [(set_attr "type" "jump_media")])
5704 (define_expand "call"
5705 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5706 (match_operand 1 "" ""))
5707 (match_operand 2 "" "")
5708 (use (reg:PSI FPSCR_REG))
5709 (clobber (reg:SI PR_REG))])]
5715 operands[0] = XEXP (operands[0], 0);
5716 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5718 if (! SYMBOL_REF_FLAG (operands[0]))
5720 rtx reg = gen_reg_rtx (Pmode);
5722 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5727 operands[0] = gen_sym2PIC (operands[0]);
5728 PUT_MODE (operands[0], Pmode);
5731 if (GET_MODE (operands[0]) == SImode)
5733 if (GET_CODE (operands[0]) == REG)
5734 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5735 else if (GET_CODE (operands[0]) == SUBREG)
5737 operands[0] = SUBREG_REG (operands[0]);
5738 if (GET_MODE (operands[0]) != DImode)
5739 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5743 operands[0] = shallow_copy_rtx (operands[0]);
5744 PUT_MODE (operands[0], DImode);
5747 if (! target_reg_operand (operands[0], DImode))
5748 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5749 emit_call_insn (gen_call_media (operands[0], operands[1]));
5752 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5754 rtx cookie_rtx = operands[2];
5755 long cookie = INTVAL (cookie_rtx);
5756 rtx func = XEXP (operands[0], 0);
5761 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5763 rtx reg = gen_reg_rtx (Pmode);
5765 emit_insn (gen_symGOTPLT2reg (reg, func));
5769 func = legitimize_pic_address (func, Pmode, 0);
5772 r0 = gen_rtx_REG (SImode, R0_REG);
5773 r1 = gen_rtx_REG (SImode, R1_REG);
5775 /* Since such a call function may use all call-clobbered
5776 registers, we force a mode switch earlier, so that we don't
5777 run out of registers when adjusting fpscr for the call. */
5778 emit_insn (gen_force_mode_for_call ());
5780 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5781 \"__GCC_shcompact_call_trampoline\");
5784 rtx reg = gen_reg_rtx (Pmode);
5786 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5789 operands[0] = force_reg (SImode, operands[0]);
5791 emit_move_insn (r0, func);
5792 emit_move_insn (r1, cookie_rtx);
5794 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5795 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5798 emit_call_insn (gen_call_compact (operands[0], operands[1],
5803 else if (TARGET_SHCOMPACT && flag_pic
5804 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5805 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5807 rtx reg = gen_reg_rtx (Pmode);
5809 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5810 XEXP (operands[0], 0) = reg;
5812 if (flag_pic && TARGET_SH2
5813 && GET_CODE (operands[0]) == MEM
5814 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5816 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5820 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5822 emit_call_insn (gen_calli (operands[0], operands[1]));
5826 (define_insn "call_pop_compact"
5827 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5828 (match_operand 1 "" ""))
5829 (match_operand 2 "immediate_operand" "n")
5830 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5831 (match_operand 3 "immediate_operand" "n")))
5832 (use (reg:SI R0_REG))
5833 (use (reg:SI R1_REG))
5834 (use (reg:PSI FPSCR_REG))
5835 (clobber (reg:SI PR_REG))]
5836 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5838 [(set_attr "type" "call")
5839 (set (attr "fp_mode")
5840 (if_then_else (eq_attr "fpu_single" "yes")
5841 (const_string "single") (const_string "double")))
5842 (set_attr "needs_delay_slot" "yes")])
5844 (define_insn "call_pop_compact_rettramp"
5845 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5846 (match_operand 1 "" ""))
5847 (match_operand 2 "immediate_operand" "n")
5848 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5849 (match_operand 3 "immediate_operand" "n")))
5850 (use (reg:SI R0_REG))
5851 (use (reg:SI R1_REG))
5852 (use (reg:PSI FPSCR_REG))
5853 (clobber (reg:SI R10_REG))
5854 (clobber (reg:SI PR_REG))]
5855 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5857 [(set_attr "type" "call")
5858 (set (attr "fp_mode")
5859 (if_then_else (eq_attr "fpu_single" "yes")
5860 (const_string "single") (const_string "double")))
5861 (set_attr "needs_delay_slot" "yes")])
5863 (define_expand "call_pop"
5864 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5865 (match_operand 1 "" ""))
5866 (match_operand 2 "" "")
5867 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5868 (match_operand 3 "" "")))])]
5872 if (operands[2] && INTVAL (operands[2]))
5874 rtx cookie_rtx = operands[2];
5875 long cookie = INTVAL (cookie_rtx);
5876 rtx func = XEXP (operands[0], 0);
5881 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5883 rtx reg = gen_reg_rtx (Pmode);
5885 emit_insn (gen_symGOTPLT2reg (reg, func));
5889 func = legitimize_pic_address (func, Pmode, 0);
5892 r0 = gen_rtx_REG (SImode, R0_REG);
5893 r1 = gen_rtx_REG (SImode, R1_REG);
5895 /* Since such a call function may use all call-clobbered
5896 registers, we force a mode switch earlier, so that we don't
5897 run out of registers when adjusting fpscr for the call. */
5898 emit_insn (gen_force_mode_for_call ());
5900 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5901 \"__GCC_shcompact_call_trampoline\");
5904 rtx reg = gen_reg_rtx (Pmode);
5906 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5909 operands[0] = force_reg (SImode, operands[0]);
5911 emit_move_insn (r0, func);
5912 emit_move_insn (r1, cookie_rtx);
5914 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5915 emit_call_insn (gen_call_pop_compact_rettramp
5916 (operands[0], operands[1], operands[2], operands[3]));
5918 emit_call_insn (gen_call_pop_compact
5919 (operands[0], operands[1], operands[2], operands[3]));
5927 (define_expand "call_value"
5928 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5929 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5930 (match_operand 2 "" "")))
5931 (match_operand 3 "" "")
5932 (use (reg:PSI FPSCR_REG))
5933 (clobber (reg:SI PR_REG))])]
5939 operands[1] = XEXP (operands[1], 0);
5940 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5942 if (! SYMBOL_REF_FLAG (operands[1]))
5944 rtx reg = gen_reg_rtx (Pmode);
5946 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5951 operands[1] = gen_sym2PIC (operands[1]);
5952 PUT_MODE (operands[1], Pmode);
5955 if (GET_MODE (operands[1]) == SImode)
5957 if (GET_CODE (operands[1]) == REG)
5958 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5959 else if (GET_CODE (operands[1]) == SUBREG)
5961 operands[1] = SUBREG_REG (operands[1]);
5962 if (GET_MODE (operands[1]) != DImode)
5963 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5967 operands[1] = shallow_copy_rtx (operands[1]);
5968 PUT_MODE (operands[1], DImode);
5971 if (! target_reg_operand (operands[1], DImode))
5972 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5973 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5977 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5979 rtx cookie_rtx = operands[3];
5980 long cookie = INTVAL (cookie_rtx);
5981 rtx func = XEXP (operands[1], 0);
5986 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5988 rtx reg = gen_reg_rtx (Pmode);
5990 emit_insn (gen_symGOTPLT2reg (reg, func));
5994 func = legitimize_pic_address (func, Pmode, 0);
5997 r0 = gen_rtx_REG (SImode, R0_REG);
5998 r1 = gen_rtx_REG (SImode, R1_REG);
6000 /* Since such a call function may use all call-clobbered
6001 registers, we force a mode switch earlier, so that we don't
6002 run out of registers when adjusting fpscr for the call. */
6003 emit_insn (gen_force_mode_for_call ());
6005 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6006 \"__GCC_shcompact_call_trampoline\");
6009 rtx reg = gen_reg_rtx (Pmode);
6011 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6014 operands[1] = force_reg (SImode, operands[1]);
6016 emit_move_insn (r0, func);
6017 emit_move_insn (r1, cookie_rtx);
6019 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6020 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6025 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6026 operands[2], operands[3]));
6030 else if (TARGET_SHCOMPACT && flag_pic
6031 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6032 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6034 rtx reg = gen_reg_rtx (Pmode);
6036 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6037 XEXP (operands[1], 0) = reg;
6039 if (flag_pic && TARGET_SH2
6040 && GET_CODE (operands[1]) == MEM
6041 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6043 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6048 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6050 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6054 (define_insn "sibcalli"
6055 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6056 (match_operand 1 "" ""))
6057 (use (reg:PSI FPSCR_REG))
6061 [(set_attr "needs_delay_slot" "yes")
6062 (set (attr "fp_mode")
6063 (if_then_else (eq_attr "fpu_single" "yes")
6064 (const_string "single") (const_string "double")))
6065 (set_attr "type" "jump_ind")])
6067 (define_insn "sibcalli_pcrel"
6068 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6069 (match_operand 1 "" ""))
6070 (use (match_operand 2 "" ""))
6071 (use (reg:PSI FPSCR_REG))
6075 [(set_attr "needs_delay_slot" "yes")
6076 (set (attr "fp_mode")
6077 (if_then_else (eq_attr "fpu_single" "yes")
6078 (const_string "single") (const_string "double")))
6079 (set_attr "type" "jump_ind")])
6081 (define_insn_and_split "sibcall_pcrel"
6082 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6083 (match_operand 1 "" ""))
6084 (use (reg:PSI FPSCR_REG))
6085 (clobber (match_scratch:SI 2 "=k"))
6093 rtx lab = PATTERN (gen_call_site ());
6096 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6097 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6099 SIBLING_CALL_P (call_insn) = 1;
6102 [(set_attr "needs_delay_slot" "yes")
6103 (set (attr "fp_mode")
6104 (if_then_else (eq_attr "fpu_single" "yes")
6105 (const_string "single") (const_string "double")))
6106 (set_attr "type" "jump_ind")])
6108 (define_insn "sibcall_compact"
6109 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6110 (match_operand 1 "" ""))
6112 (use (match_operand:SI 2 "register_operand" "z,x"))
6113 (use (reg:SI R1_REG))
6114 (use (reg:PSI FPSCR_REG))
6115 ;; We want to make sure the `x' above will only match MACH_REG
6116 ;; because sibcall_epilogue may clobber MACL_REG.
6117 (clobber (reg:SI MACL_REG))]
6121 jmp @%0\\n sts %2, r0"
6122 [(set_attr "needs_delay_slot" "yes,no")
6123 (set_attr "length" "2,4")
6124 (set (attr "fp_mode") (const_string "single"))
6125 (set_attr "type" "jump_ind")])
6127 (define_insn "sibcall_media"
6128 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6129 (match_operand 1 "" ""))
6133 [(set_attr "type" "jump_media")])
6135 (define_expand "sibcall"
6137 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6138 (match_operand 1 "" ""))
6139 (match_operand 2 "" "")
6140 (use (reg:PSI FPSCR_REG))
6147 operands[0] = XEXP (operands[0], 0);
6148 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6150 if (! SYMBOL_REF_FLAG (operands[0]))
6152 rtx reg = gen_reg_rtx (Pmode);
6154 /* We must not use GOTPLT for sibcalls, because PIC_REG
6155 must be restored before the PLT code gets to run. */
6156 emit_insn (gen_symGOT2reg (reg, operands[0]));
6161 operands[0] = gen_sym2PIC (operands[0]);
6162 PUT_MODE (operands[0], Pmode);
6165 if (GET_MODE (operands[0]) == SImode)
6167 if (GET_CODE (operands[0]) == REG)
6168 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6169 else if (GET_CODE (operands[0]) == SUBREG)
6171 operands[0] = SUBREG_REG (operands[0]);
6172 if (GET_MODE (operands[0]) != DImode)
6173 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6177 operands[0] = shallow_copy_rtx (operands[0]);
6178 PUT_MODE (operands[0], DImode);
6181 if (! target_reg_operand (operands[0], DImode))
6182 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6183 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6186 else if (TARGET_SHCOMPACT && operands[2]
6187 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6189 rtx cookie_rtx = operands[2];
6190 long cookie = INTVAL (cookie_rtx);
6191 rtx func = XEXP (operands[0], 0);
6196 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6198 rtx reg = gen_reg_rtx (Pmode);
6200 emit_insn (gen_symGOT2reg (reg, func));
6204 func = legitimize_pic_address (func, Pmode, 0);
6207 /* FIXME: if we could tell whether all argument registers are
6208 already taken, we could decide whether to force the use of
6209 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6210 simple way to tell. We could use the CALL_COOKIE, but we
6211 can't currently tell a register used for regular argument
6212 passing from one that is unused. If we leave it up to reload
6213 to decide which register to use, it seems to always choose
6214 R0_REG, which leaves no available registers in SIBCALL_REGS
6215 to hold the address of the trampoline. */
6216 mach = gen_rtx_REG (SImode, MACH_REG);
6217 r1 = gen_rtx_REG (SImode, R1_REG);
6219 /* Since such a call function may use all call-clobbered
6220 registers, we force a mode switch earlier, so that we don't
6221 run out of registers when adjusting fpscr for the call. */
6222 emit_insn (gen_force_mode_for_call ());
6224 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6225 \"__GCC_shcompact_call_trampoline\");
6228 rtx reg = gen_reg_rtx (Pmode);
6230 emit_insn (gen_symGOT2reg (reg, operands[0]));
6233 operands[0] = force_reg (SImode, operands[0]);
6235 /* We don't need a return trampoline, since the callee will
6236 return directly to the upper caller. */
6237 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6239 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6240 cookie_rtx = GEN_INT (cookie);
6243 emit_move_insn (mach, func);
6244 emit_move_insn (r1, cookie_rtx);
6246 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6249 else if (TARGET_SHCOMPACT && flag_pic
6250 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6251 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6253 rtx reg = gen_reg_rtx (Pmode);
6255 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6256 XEXP (operands[0], 0) = reg;
6258 if (flag_pic && TARGET_SH2
6259 && GET_CODE (operands[0]) == MEM
6260 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6261 /* The PLT needs the PIC register, but the epilogue would have
6262 to restore it, so we can only use PC-relative PIC calls for
6263 static functions. */
6264 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6266 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6270 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6272 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6276 (define_expand "sibcall_value"
6277 [(set (match_operand 0 "" "")
6278 (call (match_operand 1 "" "")
6279 (match_operand 2 "" "")))
6280 (match_operand 3 "" "")]
6284 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6288 (define_insn "call_value_pop_compact"
6289 [(set (match_operand 0 "" "=rf")
6290 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6291 (match_operand 2 "" "")))
6292 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6293 (match_operand 4 "immediate_operand" "n")))
6294 (match_operand 3 "immediate_operand" "n")
6295 (use (reg:SI R0_REG))
6296 (use (reg:SI R1_REG))
6297 (use (reg:PSI FPSCR_REG))
6298 (clobber (reg:SI PR_REG))]
6299 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6301 [(set_attr "type" "call")
6302 (set (attr "fp_mode")
6303 (if_then_else (eq_attr "fpu_single" "yes")
6304 (const_string "single") (const_string "double")))
6305 (set_attr "needs_delay_slot" "yes")])
6307 (define_insn "call_value_pop_compact_rettramp"
6308 [(set (match_operand 0 "" "=rf")
6309 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6310 (match_operand 2 "" "")))
6311 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6312 (match_operand 4 "immediate_operand" "n")))
6313 (match_operand 3 "immediate_operand" "n")
6314 (use (reg:SI R0_REG))
6315 (use (reg:SI R1_REG))
6316 (use (reg:PSI FPSCR_REG))
6317 (clobber (reg:SI R10_REG))
6318 (clobber (reg:SI PR_REG))]
6319 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6321 [(set_attr "type" "call")
6322 (set (attr "fp_mode")
6323 (if_then_else (eq_attr "fpu_single" "yes")
6324 (const_string "single") (const_string "double")))
6325 (set_attr "needs_delay_slot" "yes")])
6327 (define_expand "call_value_pop"
6328 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6329 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6330 (match_operand 2 "" "")))
6331 (match_operand 3 "" "")
6332 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6333 (match_operand 4 "" "")))])]
6337 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6339 rtx cookie_rtx = operands[3];
6340 long cookie = INTVAL (cookie_rtx);
6341 rtx func = XEXP (operands[1], 0);
6346 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6348 rtx reg = gen_reg_rtx (Pmode);
6350 emit_insn (gen_symGOTPLT2reg (reg, func));
6354 func = legitimize_pic_address (func, Pmode, 0);
6357 r0 = gen_rtx_REG (SImode, R0_REG);
6358 r1 = gen_rtx_REG (SImode, R1_REG);
6360 /* Since such a call function may use all call-clobbered
6361 registers, we force a mode switch earlier, so that we don't
6362 run out of registers when adjusting fpscr for the call. */
6363 emit_insn (gen_force_mode_for_call ());
6365 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6366 \"__GCC_shcompact_call_trampoline\");
6369 rtx reg = gen_reg_rtx (Pmode);
6371 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6374 operands[1] = force_reg (SImode, operands[1]);
6376 emit_move_insn (r0, func);
6377 emit_move_insn (r1, cookie_rtx);
6379 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6380 emit_call_insn (gen_call_value_pop_compact_rettramp
6381 (operands[0], operands[1], operands[2],
6382 operands[3], operands[4]));
6384 emit_call_insn (gen_call_value_pop_compact
6385 (operands[0], operands[1], operands[2],
6386 operands[3], operands[4]));
6394 (define_expand "sibcall_epilogue"
6399 sh_expand_epilogue ();
6400 if (TARGET_SHCOMPACT)
6404 /* If epilogue clobbers r0, preserve it in macl. */
6405 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6406 if ((set = single_set (insn))
6407 && GET_CODE (SET_DEST (set)) == REG
6408 && REGNO (SET_DEST (set)) == R0_REG)
6410 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6411 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6414 /* We can't tell at this point whether the sibcall is a
6415 sibcall_compact and, if it is, whether it uses r0 or
6416 mach as operand 2, so let the instructions that
6417 preserve r0 be optimized away if r0 turns out to be
6419 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6420 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6422 i = emit_move_insn (r0, tmp);
6423 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6431 (define_insn "indirect_jump_compact"
6433 (match_operand:SI 0 "arith_reg_operand" "r"))]
6436 [(set_attr "needs_delay_slot" "yes")
6437 (set_attr "type" "jump_ind")])
6439 (define_expand "indirect_jump"
6441 (match_operand 0 "register_operand" ""))]
6445 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6446 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6449 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6450 ;; which can be present in structured code from indirect jumps which can not
6451 ;; be present in structured code. This allows -fprofile-arcs to work.
6453 ;; For SH1 processors.
6454 (define_insn "casesi_jump_1"
6456 (match_operand:SI 0 "register_operand" "r"))
6457 (use (label_ref (match_operand 1 "" "")))]
6460 [(set_attr "needs_delay_slot" "yes")
6461 (set_attr "type" "jump_ind")])
6463 ;; For all later processors.
6464 (define_insn "casesi_jump_2"
6465 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6466 (label_ref (match_operand 1 "" ""))))
6467 (use (label_ref (match_operand 2 "" "")))]
6469 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6471 [(set_attr "needs_delay_slot" "yes")
6472 (set_attr "type" "jump_ind")])
6474 (define_insn "casesi_jump_media"
6475 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6476 (use (label_ref (match_operand 1 "" "")))]
6479 [(set_attr "type" "jump_media")])
6481 ;; Call subroutine returning any type.
6482 ;; ??? This probably doesn't work.
6484 (define_expand "untyped_call"
6485 [(parallel [(call (match_operand 0 "" "")
6487 (match_operand 1 "" "")
6488 (match_operand 2 "" "")])]
6489 "TARGET_SH3E || TARGET_SHMEDIA"
6494 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6496 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6498 rtx set = XVECEXP (operands[2], 0, i);
6499 emit_move_insn (SET_DEST (set), SET_SRC (set));
6502 /* The optimizer does not know that the call sets the function value
6503 registers we stored in the result block. We avoid problems by
6504 claiming that all hard registers are used and clobbered at this
6506 emit_insn (gen_blockage ());
6511 ;; ------------------------------------------------------------------------
6513 ;; ------------------------------------------------------------------------
6516 [(set (reg:SI T_REG)
6517 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6518 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6521 [(set_attr "type" "arith")])
6528 ;; Load address of a label. This is only generated by the casesi expand,
6529 ;; and by machine_dependent_reorg (fixing up fp moves).
6530 ;; This must use unspec, because this only works for labels that are
6534 [(set (reg:SI R0_REG)
6535 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6538 [(set_attr "in_delay_slot" "no")
6539 (set_attr "type" "arith")])
6541 ;; machine_dependent_reorg() will make this a `mova'.
6542 (define_insn "mova_const"
6543 [(set (reg:SI R0_REG)
6544 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6547 [(set_attr "in_delay_slot" "no")
6548 (set_attr "type" "arith")])
6550 (define_expand "GOTaddr2picreg"
6551 [(set (reg:SI R0_REG)
6552 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6554 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6555 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6558 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6559 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6562 operands[1] = gen_datalabel_ref (operands[1]);
6566 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6567 rtx dipic = operands[0];
6568 rtx lab = PATTERN (gen_call_site ());
6571 equiv = operands[1];
6572 operands[1] = gen_rtx_MINUS (DImode,
6576 gen_rtx_MINUS (DImode,
6577 gen_rtx_CONST (DImode,
6580 operands[1] = gen_sym2PIC (operands[1]);
6581 PUT_MODE (operands[1], DImode);
6583 if (GET_MODE (dipic) != DImode)
6584 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6586 if (TARGET_SHMEDIA64)
6587 emit_insn (gen_movdi_const (dipic, operands[1]));
6589 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6591 emit_insn (gen_ptrel (tr, dipic, lab));
6593 if (GET_MODE (operands[0]) != GET_MODE (tr))
6594 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6596 insn = emit_move_insn (operands[0], tr);
6598 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6606 ;; When generating PIC, we must match label_refs especially, because
6607 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6608 ;; them to do, because they can't be loaded directly into
6609 ;; non-branch-target registers.
6611 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6612 (match_operand:DI 1 "" "T"))]
6613 "TARGET_SHMEDIA && flag_pic
6614 && EXTRA_CONSTRAINT_T (operands[1])"
6616 [(set_attr "type" "pt_media")
6617 (set_attr "length" "*")])
6620 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6621 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6622 UNSPEC_DATALABEL)))]
6623 "TARGET_SHMEDIA && flag_pic
6624 && EXTRA_CONSTRAINT_T (operands[1])"
6625 "ptb/u datalabel %1, %0"
6626 [(set_attr "type" "pt_media")
6627 (set_attr "length" "*")])
6629 (define_insn "ptrel"
6630 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6631 (plus:DI (match_operand:DI 1 "register_operand" "r")
6633 (match_operand:DI 2 "" "")]
6635 "%O2: ptrel/u %1, %0"
6636 [(set_attr "type" "ptabs_media")])
6638 (define_expand "builtin_setjmp_receiver"
6639 [(match_operand 0 "" "")]
6643 emit_insn (gen_GOTaddr2picreg ());
6647 (define_expand "call_site"
6648 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6652 static HOST_WIDE_INT i = 0;
6653 operands[0] = GEN_INT (i);
6657 (define_expand "sym_label2reg"
6658 [(set (match_operand:SI 0 "" "")
6661 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6664 (match_operand:SI 2 "" "")
6668 (define_expand "symGOT_load"
6669 [(set (match_dup 2) (match_operand 1 "" ""))
6670 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6671 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6677 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6678 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6682 rtx reg = operands[2];
6684 if (GET_MODE (reg) != DImode)
6685 reg = gen_rtx_SUBREG (DImode, reg, 0);
6688 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6690 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6693 emit_move_insn (operands[2], operands[1]);
6695 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6697 gen_rtx_REG (Pmode, PIC_REG)));
6699 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6701 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6708 (define_expand "sym2GOT"
6709 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6713 (define_expand "symGOT2reg"
6714 [(match_operand 0 "" "") (match_operand 1 "" "")]
6720 gotsym = gen_sym2GOT (operands[1]);
6721 PUT_MODE (gotsym, Pmode);
6722 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6724 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6729 (define_expand "sym2GOTPLT"
6730 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6734 (define_expand "symGOTPLT2reg"
6735 [(match_operand 0 "" "") (match_operand 1 "" "")]
6739 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6743 (define_expand "sym2GOTOFF"
6744 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6748 (define_expand "symGOTOFF2reg"
6749 [(match_operand 0 "" "") (match_operand 1 "" "")]
6753 rtx gotoffsym, insn;
6754 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6756 gotoffsym = gen_sym2GOTOFF (operands[1]);
6757 PUT_MODE (gotoffsym, Pmode);
6758 emit_move_insn (t, gotoffsym);
6759 insn = emit_move_insn (operands[0],
6760 gen_rtx_PLUS (Pmode, t,
6761 gen_rtx_REG (Pmode, PIC_REG)));
6763 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6769 (define_expand "symPLT_label2reg"
6770 [(set (match_operand:SI 0 "" "")
6773 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6777 (match_operand:SI 2 "" "")
6779 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6780 ;; Even though the PIC register is not really used by the call
6781 ;; sequence in which this is expanded, the PLT code assumes the PIC
6782 ;; register is set, so we must not skip its initialization. Since
6783 ;; we only use this expand as part of calling sequences, and never
6784 ;; to take the address of a function, this is the best point to
6785 ;; insert the (use). Using the PLT to take the address of a
6786 ;; function would be wrong, not only because the PLT entry could
6787 ;; then be called from a function that doesn't initialize the PIC
6788 ;; register to the proper GOT, but also because pointers to the
6789 ;; same function might not compare equal, should they be set by
6790 ;; different shared libraries.
6791 (use (reg:SI PIC_REG))]
6795 (define_expand "sym2PIC"
6796 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6800 ;; case instruction for switch statements.
6802 ;; Operand 0 is index
6803 ;; operand 1 is the minimum bound
6804 ;; operand 2 is the maximum bound - minimum bound + 1
6805 ;; operand 3 is CODE_LABEL for the table;
6806 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6808 (define_expand "casesi"
6809 [(match_operand:SI 0 "arith_reg_operand" "")
6810 (match_operand:SI 1 "arith_reg_operand" "")
6811 (match_operand:SI 2 "arith_reg_operand" "")
6812 (match_operand 3 "" "") (match_operand 4 "" "")]
6816 rtx reg = gen_reg_rtx (SImode);
6817 rtx reg2 = gen_reg_rtx (SImode);
6820 rtx reg = gen_reg_rtx (DImode);
6821 rtx reg2 = gen_reg_rtx (DImode);
6822 rtx reg3 = gen_reg_rtx (DImode);
6823 rtx reg4 = gen_reg_rtx (DImode);
6824 rtx reg5 = gen_reg_rtx (DImode);
6826 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6827 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6828 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6830 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6831 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6832 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6833 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6834 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6835 (DImode, operands[3])));
6836 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6837 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6838 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6842 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6843 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6844 /* If optimizing, casesi_worker depends on the mode of the instruction
6845 before label it 'uses' - operands[3]. */
6846 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6848 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6850 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6852 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6853 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6854 operands[3], but to lab. We will fix this up in
6855 machine_dependent_reorg. */
6860 (define_expand "casesi_0"
6861 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6862 (set (match_dup 4) (minus:SI (match_dup 4)
6863 (match_operand:SI 1 "arith_operand" "")))
6865 (gtu:SI (match_dup 4)
6866 (match_operand:SI 2 "arith_reg_operand" "")))
6868 (if_then_else (ne (reg:SI T_REG)
6870 (label_ref (match_operand 3 "" ""))
6875 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6876 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6877 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6879 (define_insn "casesi_worker_0"
6880 [(set (match_operand:SI 0 "register_operand" "=r,r")
6881 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6882 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6883 (clobber (match_scratch:SI 3 "=X,1"))
6884 (clobber (match_scratch:SI 4 "=&z,z"))]
6889 [(set (match_operand:SI 0 "register_operand" "")
6890 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6891 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6892 (clobber (match_scratch:SI 3 ""))
6893 (clobber (match_scratch:SI 4 ""))]
6894 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6895 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6896 (parallel [(set (match_dup 0)
6897 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6898 (label_ref (match_dup 2))] UNSPEC_CASESI))
6899 (clobber (match_dup 3))])
6900 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6901 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6904 [(set (match_operand:SI 0 "register_operand" "")
6905 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6906 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6907 (clobber (match_scratch:SI 3 ""))
6908 (clobber (match_scratch:SI 4 ""))]
6909 "TARGET_SH2 && reload_completed"
6910 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6911 (parallel [(set (match_dup 0)
6912 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6913 (label_ref (match_dup 2))] UNSPEC_CASESI))
6914 (clobber (match_dup 3))])]
6915 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6917 (define_insn "*casesi_worker"
6918 [(set (match_operand:SI 0 "register_operand" "=r,r")
6919 (unspec:SI [(reg:SI R0_REG)
6920 (match_operand:SI 1 "register_operand" "0,r")
6921 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6922 (clobber (match_scratch:SI 3 "=X,1"))]
6926 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6928 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6931 switch (GET_MODE (diff_vec))
6934 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6936 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6938 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6939 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6940 return \"mov.b @(r0,%1),%0\";
6945 [(set_attr "length" "4")])
6947 (define_insn "casesi_shift_media"
6948 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6949 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6950 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6955 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6957 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6960 switch (GET_MODE (diff_vec))
6963 return \"shlli %1, 2, %0\";
6965 return \"shlli %1, 1, %0\";
6967 if (rtx_equal_p (operands[0], operands[1]))
6969 return \"add %1, r63, %0\";
6974 [(set_attr "type" "arith_media")])
6976 (define_insn "casesi_load_media"
6977 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6978 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6979 (match_operand 2 "arith_reg_operand" "r")
6980 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6984 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6986 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6989 switch (GET_MODE (diff_vec))
6992 return \"ldx.l %1, %2, %0\";
6995 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6996 return \"ldx.uw %1, %2, %0\";
6998 return \"ldx.w %1, %2, %0\";
7000 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7001 return \"ldx.ub %1, %2, %0\";
7002 return \"ldx.b %1, %2, %0\";
7007 [(set_attr "type" "load_media")])
7009 (define_expand "return"
7011 "reload_completed && ! sh_need_epilogue ()"
7016 emit_jump_insn (gen_return_media ());
7020 if (TARGET_SHCOMPACT
7021 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7023 emit_jump_insn (gen_shcompact_return_tramp ());
7028 (define_insn "*return_i"
7030 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7031 && (current_function_args_info.call_cookie
7032 & CALL_COOKIE_RET_TRAMP (1)))
7033 && reload_completed"
7035 [(set_attr "type" "return")
7036 (set_attr "needs_delay_slot" "yes")])
7038 (define_expand "shcompact_return_tramp"
7041 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7044 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7045 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7046 \"__GCC_shcompact_return_trampoline\");
7049 emit_insn (gen_symGOTPLT2reg (reg, sym));
7051 emit_move_insn (reg, sym);
7053 emit_jump_insn (gen_shcompact_return_tramp_i ());
7057 (define_insn "shcompact_return_tramp_i"
7058 [(parallel [(return) (use (reg:SI R0_REG))])]
7060 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7062 [(set_attr "type" "jump_ind")
7063 (set_attr "needs_delay_slot" "yes")])
7065 (define_insn "return_media_i"
7066 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7067 "TARGET_SHMEDIA && reload_completed"
7069 [(set_attr "type" "jump_media")])
7071 (define_expand "return_media"
7073 "TARGET_SHMEDIA && reload_completed"
7076 int tr_regno = sh_media_register_for_return ();
7081 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7084 tr = gen_rtx_REG (DImode, tr_regno);
7085 emit_move_insn (tr, r18);
7088 tr = gen_rtx_REG (DImode, tr_regno);
7090 emit_jump_insn (gen_return_media_i (tr));
7094 (define_insn "shcompact_preserve_incoming_args"
7095 [(set (match_operand:SI 0 "register_operand" "+r")
7096 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7099 [(set_attr "length" "0")])
7101 (define_insn "shcompact_incoming_args"
7102 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7103 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7104 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7105 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7106 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7107 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7108 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7109 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7110 (set (mem:BLK (reg:SI MACL_REG))
7111 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7112 (use (reg:SI R0_REG))
7113 (clobber (reg:SI R0_REG))
7114 (clobber (reg:SI MACL_REG))
7115 (clobber (reg:SI MACH_REG))
7116 (clobber (reg:SI PR_REG))]
7119 [(set_attr "needs_delay_slot" "yes")])
7121 (define_insn "shmedia_save_restore_regs_compact"
7122 [(set (reg:SI SP_REG)
7123 (plus:SI (reg:SI SP_REG)
7124 (match_operand:SI 0 "immediate_operand" "i")))
7125 (use (reg:SI R0_REG))
7126 (clobber (reg:SI PR_REG))]
7128 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7129 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7131 [(set_attr "needs_delay_slot" "yes")])
7133 (define_expand "prologue"
7136 "sh_expand_prologue (); DONE;")
7138 (define_expand "epilogue"
7143 sh_expand_epilogue ();
7144 emit_jump_insn (gen_return ());
7148 (define_insn "blockage"
7149 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7152 [(set_attr "length" "0")])
7154 ;; ------------------------------------------------------------------------
7156 ;; ------------------------------------------------------------------------
7159 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7160 (eq:SI (reg:SI T_REG) (const_int 1)))]
7163 [(set_attr "type" "arith")])
7165 (define_expand "seq"
7166 [(set (match_operand:SI 0 "arith_reg_operand" "")
7173 if (GET_MODE (operands[0]) != DImode)
7174 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7175 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7176 if (sh_compare_op1 != const0_rtx)
7177 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7178 ? GET_MODE (sh_compare_op0)
7179 : GET_MODE (sh_compare_op1),
7182 switch (GET_MODE (sh_compare_op0))
7185 emit_insn (gen_cmpeqdi_media (operands[0],
7186 sh_compare_op0, sh_compare_op1));
7190 if (! TARGET_SHMEDIA_FPU)
7192 emit_insn (gen_cmpeqsf_media (operands[0],
7193 sh_compare_op0, sh_compare_op1));
7197 if (! TARGET_SHMEDIA_FPU)
7199 emit_insn (gen_cmpeqdf_media (operands[0],
7200 sh_compare_op0, sh_compare_op1));
7208 operands[1] = prepare_scc_operands (EQ);
7211 (define_expand "slt"
7212 [(set (match_operand:SI 0 "arith_reg_operand" "")
7219 if (GET_MODE (operands[0]) != DImode)
7220 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7221 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7222 if (sh_compare_op1 != const0_rtx)
7223 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7224 ? GET_MODE (sh_compare_op0)
7225 : GET_MODE (sh_compare_op1),
7228 switch (GET_MODE (sh_compare_op0))
7231 emit_insn (gen_cmpgtdi_media (operands[0],
7232 sh_compare_op1, sh_compare_op0));
7236 if (! TARGET_SHMEDIA_FPU)
7238 emit_insn (gen_cmpgtsf_media (operands[0],
7239 sh_compare_op1, sh_compare_op0));
7243 if (! TARGET_SHMEDIA_FPU)
7245 emit_insn (gen_cmpgtdf_media (operands[0],
7246 sh_compare_op1, sh_compare_op0));
7254 operands[1] = prepare_scc_operands (LT);
7257 (define_expand "sle"
7258 [(match_operand:SI 0 "arith_reg_operand" "")]
7262 rtx tmp = sh_compare_op0;
7266 if (GET_MODE (operands[0]) != DImode)
7267 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7268 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7269 if (sh_compare_op1 != const0_rtx)
7270 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7271 ? GET_MODE (sh_compare_op0)
7272 : GET_MODE (sh_compare_op1),
7275 switch (GET_MODE (sh_compare_op0))
7279 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7281 emit_insn (gen_cmpgtdi_media (tmp,
7282 sh_compare_op0, sh_compare_op1));
7283 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7288 if (! TARGET_SHMEDIA_FPU)
7290 emit_insn (gen_cmpgesf_media (operands[0],
7291 sh_compare_op1, sh_compare_op0));
7295 if (! TARGET_SHMEDIA_FPU)
7297 emit_insn (gen_cmpgedf_media (operands[0],
7298 sh_compare_op1, sh_compare_op0));
7307 sh_compare_op0 = sh_compare_op1;
7308 sh_compare_op1 = tmp;
7309 emit_insn (gen_sge (operands[0]));
7313 (define_expand "sgt"
7314 [(set (match_operand:SI 0 "arith_reg_operand" "")
7321 if (GET_MODE (operands[0]) != DImode)
7322 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7323 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7324 if (sh_compare_op1 != const0_rtx)
7325 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7326 ? GET_MODE (sh_compare_op0)
7327 : GET_MODE (sh_compare_op1),
7330 switch (GET_MODE (sh_compare_op0))
7333 emit_insn (gen_cmpgtdi_media (operands[0],
7334 sh_compare_op0, sh_compare_op1));
7338 if (! TARGET_SHMEDIA_FPU)
7340 emit_insn (gen_cmpgtsf_media (operands[0],
7341 sh_compare_op0, sh_compare_op1));
7345 if (! TARGET_SHMEDIA_FPU)
7347 emit_insn (gen_cmpgtdf_media (operands[0],
7348 sh_compare_op0, sh_compare_op1));
7356 operands[1] = prepare_scc_operands (GT);
7359 (define_expand "sge"
7360 [(set (match_operand:SI 0 "arith_reg_operand" "")
7367 if (GET_MODE (operands[0]) != DImode)
7368 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7369 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7370 if (sh_compare_op1 != const0_rtx)
7371 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7372 ? GET_MODE (sh_compare_op0)
7373 : GET_MODE (sh_compare_op1),
7376 switch (GET_MODE (sh_compare_op0))
7380 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7382 emit_insn (gen_cmpgtdi_media (tmp,
7383 sh_compare_op1, sh_compare_op0));
7384 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7389 if (! TARGET_SHMEDIA_FPU)
7391 emit_insn (gen_cmpgesf_media (operands[0],
7392 sh_compare_op0, sh_compare_op1));
7396 if (! TARGET_SHMEDIA_FPU)
7398 emit_insn (gen_cmpgedf_media (operands[0],
7399 sh_compare_op0, sh_compare_op1));
7408 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7412 rtx lab = gen_label_rtx ();
7413 prepare_scc_operands (EQ);
7414 emit_jump_insn (gen_branch_true (lab));
7415 prepare_scc_operands (GT);
7417 emit_insn (gen_movt (operands[0]));
7420 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7423 operands[1] = prepare_scc_operands (GE);
7426 (define_expand "sgtu"
7427 [(set (match_operand:SI 0 "arith_reg_operand" "")
7434 if (GET_MODE (operands[0]) != DImode)
7435 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7436 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7437 if (sh_compare_op1 != const0_rtx)
7438 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7439 ? GET_MODE (sh_compare_op0)
7440 : GET_MODE (sh_compare_op1),
7443 emit_insn (gen_cmpgtudi_media (operands[0],
7444 sh_compare_op0, sh_compare_op1));
7447 operands[1] = prepare_scc_operands (GTU);
7450 (define_expand "sltu"
7451 [(set (match_operand:SI 0 "arith_reg_operand" "")
7458 if (GET_MODE (operands[0]) != DImode)
7459 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7460 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7461 if (sh_compare_op1 != const0_rtx)
7462 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7463 ? GET_MODE (sh_compare_op0)
7464 : GET_MODE (sh_compare_op1),
7467 emit_insn (gen_cmpgtudi_media (operands[0],
7468 sh_compare_op1, sh_compare_op0));
7471 operands[1] = prepare_scc_operands (LTU);
7474 (define_expand "sleu"
7475 [(set (match_operand:SI 0 "arith_reg_operand" "")
7484 if (GET_MODE (operands[0]) != DImode)
7485 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7486 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7487 if (sh_compare_op1 != const0_rtx)
7488 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7489 ? GET_MODE (sh_compare_op0)
7490 : GET_MODE (sh_compare_op1),
7493 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7495 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7496 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7500 operands[1] = prepare_scc_operands (LEU);
7503 (define_expand "sgeu"
7504 [(set (match_operand:SI 0 "arith_reg_operand" "")
7513 if (GET_MODE (operands[0]) != DImode)
7514 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7515 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7516 if (sh_compare_op1 != const0_rtx)
7517 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7518 ? GET_MODE (sh_compare_op0)
7519 : GET_MODE (sh_compare_op1),
7522 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7524 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7525 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7530 operands[1] = prepare_scc_operands (GEU);
7533 ;; sne moves the complement of the T reg to DEST like this:
7537 ;; This is better than xoring compare result with 1 because it does
7538 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7541 (define_expand "sne"
7542 [(set (match_dup 2) (const_int -1))
7543 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7544 (neg:SI (plus:SI (match_dup 1)
7547 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7556 if (GET_MODE (operands[0]) != DImode)
7557 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7559 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7562 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7563 if (sh_compare_op1 != const0_rtx)
7564 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7565 ? GET_MODE (sh_compare_op0)
7566 : GET_MODE (sh_compare_op1),
7569 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7571 emit_insn (gen_seq (tmp));
7572 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7577 operands[1] = prepare_scc_operands (EQ);
7578 operands[2] = gen_reg_rtx (SImode);
7581 (define_expand "sunordered"
7582 [(set (match_operand:DI 0 "arith_reg_operand" "")
7583 (unordered:DI (match_dup 1) (match_dup 2)))]
7584 "TARGET_SHMEDIA_FPU"
7587 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7588 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7591 ;; Use the same trick for FP sle / sge
7592 (define_expand "movnegt"
7593 [(set (match_dup 2) (const_int -1))
7594 (parallel [(set (match_operand 0 "" "")
7595 (neg:SI (plus:SI (match_dup 1)
7598 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7601 "operands[2] = gen_reg_rtx (SImode);")
7603 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7604 ;; This prevents a regression that occurred when we switched from xor to
7608 [(set (match_operand:SI 0 "arith_reg_operand" "")
7609 (plus:SI (reg:SI T_REG)
7612 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7613 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7616 ;; -------------------------------------------------------------------------
7617 ;; Instructions to cope with inline literal tables
7618 ;; -------------------------------------------------------------------------
7620 ; 2 byte integer in line
7622 (define_insn "consttable_2"
7623 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7624 (match_operand 1 "" "")]
7629 if (operands[1] != const0_rtx)
7630 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7633 [(set_attr "length" "2")
7634 (set_attr "in_delay_slot" "no")])
7636 ; 4 byte integer in line
7638 (define_insn "consttable_4"
7639 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7640 (match_operand 1 "" "")]
7645 if (operands[1] != const0_rtx)
7646 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7649 [(set_attr "length" "4")
7650 (set_attr "in_delay_slot" "no")])
7652 ; 8 byte integer in line
7654 (define_insn "consttable_8"
7655 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7656 (match_operand 1 "" "")]
7661 if (operands[1] != const0_rtx)
7662 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7665 [(set_attr "length" "8")
7666 (set_attr "in_delay_slot" "no")])
7668 ; 4 byte floating point
7670 (define_insn "consttable_sf"
7671 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7672 (match_operand 1 "" "")]
7677 if (operands[1] != const0_rtx)
7680 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7681 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7685 [(set_attr "length" "4")
7686 (set_attr "in_delay_slot" "no")])
7688 ; 8 byte floating point
7690 (define_insn "consttable_df"
7691 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7692 (match_operand 1 "" "")]
7697 if (operands[1] != const0_rtx)
7700 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7701 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7705 [(set_attr "length" "8")
7706 (set_attr "in_delay_slot" "no")])
7708 ;; Alignment is needed for some constant tables; it may also be added for
7709 ;; Instructions at the start of loops, or after unconditional branches.
7710 ;; ??? We would get more accurate lengths if we did instruction
7711 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7712 ;; here is too conservative.
7714 ; align to a two byte boundary
7716 (define_expand "align_2"
7717 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7721 ; align to a four byte boundary
7722 ;; align_4 and align_log are instructions for the starts of loops, or
7723 ;; after unconditional branches, which may take up extra room.
7725 (define_expand "align_4"
7726 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7730 ; align to a cache line boundary
7732 (define_insn "align_log"
7733 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7736 [(set_attr "length" "0")
7737 (set_attr "in_delay_slot" "no")])
7739 ; emitted at the end of the literal table, used to emit the
7740 ; 32bit branch labels if needed.
7742 (define_insn "consttable_end"
7743 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7745 "* return output_jump_label_table ();"
7746 [(set_attr "in_delay_slot" "no")])
7748 ; emitted at the end of the window in the literal table.
7750 (define_insn "consttable_window_end"
7751 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7754 [(set_attr "length" "0")
7755 (set_attr "in_delay_slot" "no")])
7757 ;; -------------------------------------------------------------------------
7759 ;; -------------------------------------------------------------------------
7761 ;; String/block move insn.
7763 (define_expand "movstrsi"
7764 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7765 (mem:BLK (match_operand:BLK 1 "" "")))
7766 (use (match_operand:SI 2 "nonmemory_operand" ""))
7767 (use (match_operand:SI 3 "immediate_operand" ""))
7768 (clobber (reg:SI PR_REG))
7769 (clobber (reg:SI R4_REG))
7770 (clobber (reg:SI R5_REG))
7771 (clobber (reg:SI R0_REG))])]
7772 "TARGET_SH1 && ! TARGET_SH5"
7775 if(expand_block_move (operands))
7780 (define_insn "block_move_real"
7781 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7782 (mem:BLK (reg:SI R5_REG)))
7783 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7784 (clobber (reg:SI PR_REG))
7785 (clobber (reg:SI R0_REG))])]
7786 "TARGET_SH1 && ! TARGET_HARD_SH4"
7788 [(set_attr "type" "sfunc")
7789 (set_attr "needs_delay_slot" "yes")])
7791 (define_insn "block_lump_real"
7792 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7793 (mem:BLK (reg:SI R5_REG)))
7794 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7795 (use (reg:SI R6_REG))
7796 (clobber (reg:SI PR_REG))
7797 (clobber (reg:SI T_REG))
7798 (clobber (reg:SI R4_REG))
7799 (clobber (reg:SI R5_REG))
7800 (clobber (reg:SI R6_REG))
7801 (clobber (reg:SI R0_REG))])]
7802 "TARGET_SH1 && ! TARGET_HARD_SH4"
7804 [(set_attr "type" "sfunc")
7805 (set_attr "needs_delay_slot" "yes")])
7807 (define_insn "block_move_real_i4"
7808 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7809 (mem:BLK (reg:SI R5_REG)))
7810 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7811 (clobber (reg:SI PR_REG))
7812 (clobber (reg:SI R0_REG))
7813 (clobber (reg:SI R1_REG))
7814 (clobber (reg:SI R2_REG))])]
7817 [(set_attr "type" "sfunc")
7818 (set_attr "needs_delay_slot" "yes")])
7820 (define_insn "block_lump_real_i4"
7821 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7822 (mem:BLK (reg:SI R5_REG)))
7823 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7824 (use (reg:SI R6_REG))
7825 (clobber (reg:SI PR_REG))
7826 (clobber (reg:SI T_REG))
7827 (clobber (reg:SI R4_REG))
7828 (clobber (reg:SI R5_REG))
7829 (clobber (reg:SI R6_REG))
7830 (clobber (reg:SI R0_REG))
7831 (clobber (reg:SI R1_REG))
7832 (clobber (reg:SI R2_REG))
7833 (clobber (reg:SI R3_REG))])]
7836 [(set_attr "type" "sfunc")
7837 (set_attr "needs_delay_slot" "yes")])
7839 ;; -------------------------------------------------------------------------
7840 ;; Floating point instructions.
7841 ;; -------------------------------------------------------------------------
7843 ;; ??? All patterns should have a type attribute.
7845 (define_expand "fpu_switch0"
7846 [(set (match_operand:SI 0 "" "") (match_dup 2))
7847 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7851 operands[1] = get_fpscr_rtx ();
7852 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7854 operands[2] = legitimize_pic_address (operands[2], SImode,
7855 no_new_pseudos ? operands[0] : 0);
7858 (define_expand "fpu_switch1"
7859 [(set (match_operand:SI 0 "" "") (match_dup 2))
7860 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7861 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7865 operands[1] = get_fpscr_rtx ();
7866 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7868 operands[2] = legitimize_pic_address (operands[2], SImode,
7869 no_new_pseudos ? operands[0] : 0);
7870 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7873 (define_expand "movpsi"
7874 [(set (match_operand:PSI 0 "register_operand" "")
7875 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7879 ;; The c / m alternative is a fake to guide reload to load directly into
7880 ;; fpscr, since reload doesn't know how to use post-increment.
7881 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7882 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7883 ;; predicate after reload.
7884 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7885 ;; like a mac -> gpr move.
7886 (define_insn "fpu_switch"
7887 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
7888 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
7890 && (! reload_completed
7891 || true_regnum (operands[0]) != FPSCR_REG
7892 || GET_CODE (operands[1]) != MEM
7893 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7895 ! precision stays the same
7904 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
7905 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
7908 [(set (reg:PSI FPSCR_REG)
7909 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7910 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7911 [(set (match_dup 0) (match_dup 0))]
7914 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7915 gen_rtx (MEM, PSImode,
7916 gen_rtx (POST_INC, Pmode,
7918 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7922 [(set (reg:PSI FPSCR_REG)
7923 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7925 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7928 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7929 gen_rtx (MEM, PSImode,
7930 gen_rtx (POST_INC, Pmode,
7932 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7935 ;; ??? This uses the fp unit, but has no type indicating that.
7936 ;; If we did that, this would either give a bogus latency or introduce
7937 ;; a bogus FIFO constraint.
7938 ;; Since this insn is currently only used for prologues/epilogues,
7939 ;; it is probably best to claim no function unit, which matches the
7941 (define_insn "toggle_sz"
7942 [(set (reg:PSI FPSCR_REG)
7943 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7947 (define_expand "addsf3"
7948 [(set (match_operand:SF 0 "arith_reg_operand" "")
7949 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7950 (match_operand:SF 2 "arith_reg_operand" "")))]
7951 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7956 expand_sf_binop (&gen_addsf3_i, operands);
7961 (define_insn "*addsf3_media"
7962 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7963 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7964 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7965 "TARGET_SHMEDIA_FPU"
7967 [(set_attr "type" "fparith_media")])
7969 (define_insn_and_split "unary_sf_op"
7970 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7975 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7976 (match_operator:SF 2 "unary_float_operator"
7977 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7978 (parallel [(match_operand 4
7979 "const_int_operand" "n")]))]))
7980 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7981 "TARGET_SHMEDIA_FPU"
7983 "TARGET_SHMEDIA_FPU && reload_completed"
7984 [(set (match_dup 5) (match_dup 6))]
7987 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7988 rtx op1 = gen_rtx_REG (SFmode,
7989 (true_regnum (operands[1])
7990 + (INTVAL (operands[4]) ^ endian)));
7992 operands[7] = gen_rtx_REG (SFmode,
7993 (true_regnum (operands[0])
7994 + (INTVAL (operands[3]) ^ endian)));
7995 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7997 [(set_attr "type" "fparith_media")])
7999 (define_insn_and_split "binary_sf_op"
8000 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8005 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8006 (match_operator:SF 3 "binary_float_operator"
8007 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8008 (parallel [(match_operand 5
8009 "const_int_operand" "n")]))
8010 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8011 (parallel [(match_operand 6
8012 "const_int_operand" "n")]))]))
8013 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8014 "TARGET_SHMEDIA_FPU"
8016 "TARGET_SHMEDIA_FPU && reload_completed"
8017 [(set (match_dup 7) (match_dup 8))]
8020 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8021 rtx op1 = gen_rtx_REG (SFmode,
8022 (true_regnum (operands[1])
8023 + (INTVAL (operands[5]) ^ endian)));
8024 rtx op2 = gen_rtx_REG (SFmode,
8025 (true_regnum (operands[2])
8026 + (INTVAL (operands[6]) ^ endian)));
8028 operands[7] = gen_rtx_REG (SFmode,
8029 (true_regnum (operands[0])
8030 + (INTVAL (operands[4]) ^ endian)));
8031 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8033 [(set_attr "type" "fparith_media")])
8035 (define_insn "addsf3_i"
8036 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8037 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8038 (match_operand:SF 2 "arith_reg_operand" "f")))
8039 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8042 [(set_attr "type" "fp")
8043 (set_attr "fp_mode" "single")])
8045 (define_expand "subsf3"
8046 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8047 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8048 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8049 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8054 expand_sf_binop (&gen_subsf3_i, operands);
8059 (define_insn "*subsf3_media"
8060 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8061 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8062 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8063 "TARGET_SHMEDIA_FPU"
8065 [(set_attr "type" "fparith_media")])
8067 (define_insn "subsf3_i"
8068 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8069 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8070 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8071 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8074 [(set_attr "type" "fp")
8075 (set_attr "fp_mode" "single")])
8077 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8078 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8079 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8080 ;; SH3E, we use a separate insn for SH3E mulsf3.
8082 (define_expand "mulsf3"
8083 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8084 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8085 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8086 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8090 expand_sf_binop (&gen_mulsf3_i4, operands);
8091 else if (TARGET_SH3E)
8092 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8093 if (! TARGET_SHMEDIA)
8097 (define_insn "*mulsf3_media"
8098 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8099 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8100 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8101 "TARGET_SHMEDIA_FPU"
8103 [(set_attr "type" "fparith_media")])
8105 (define_insn "mulsf3_i4"
8106 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8107 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8108 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8109 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8112 [(set_attr "type" "fp")
8113 (set_attr "fp_mode" "single")])
8115 (define_insn "mulsf3_ie"
8116 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8117 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8118 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8119 "TARGET_SH3E && ! TARGET_SH4"
8121 [(set_attr "type" "fp")])
8123 (define_insn "*mac_media"
8124 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8125 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8126 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8127 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8128 "TARGET_SHMEDIA_FPU"
8130 [(set_attr "type" "fparith_media")])
8132 (define_insn "*macsf3"
8133 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8134 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8135 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8136 (match_operand:SF 3 "arith_reg_operand" "0")))
8137 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8138 "TARGET_SH3E && ! TARGET_SH4"
8140 [(set_attr "type" "fp")
8141 (set_attr "fp_mode" "single")])
8143 (define_expand "divsf3"
8144 [(set (match_operand:SF 0 "arith_reg_operand" "")
8145 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8146 (match_operand:SF 2 "arith_reg_operand" "")))]
8147 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8152 expand_sf_binop (&gen_divsf3_i, operands);
8157 (define_insn "*divsf3_media"
8158 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8159 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8160 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8161 "TARGET_SHMEDIA_FPU"
8163 [(set_attr "type" "fdiv_media")])
8165 (define_insn "divsf3_i"
8166 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8167 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8168 (match_operand:SF 2 "arith_reg_operand" "f")))
8169 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8172 [(set_attr "type" "fdiv")
8173 (set_attr "fp_mode" "single")])
8175 (define_insn "floatdisf2"
8176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8178 "TARGET_SHMEDIA_FPU"
8180 [(set_attr "type" "fpconv_media")])
8182 (define_expand "floatsisf2"
8183 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8184 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8185 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8190 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8195 (define_insn "*floatsisf2_media"
8196 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8197 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8198 "TARGET_SHMEDIA_FPU"
8200 [(set_attr "type" "fpconv_media")])
8202 (define_insn "floatsisf2_i4"
8203 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8204 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8205 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8208 [(set_attr "type" "fp")
8209 (set_attr "fp_mode" "single")])
8211 (define_insn "*floatsisf2_ie"
8212 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8213 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8214 "TARGET_SH3E && ! TARGET_SH4"
8216 [(set_attr "type" "fp")])
8218 (define_insn "fix_truncsfdi2"
8219 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8220 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8221 "TARGET_SHMEDIA_FPU"
8223 [(set_attr "type" "fpconv_media")])
8225 (define_expand "fix_truncsfsi2"
8226 [(set (match_operand:SI 0 "fpul_operand" "=y")
8227 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8228 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8233 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8238 (define_insn "*fix_truncsfsi2_media"
8239 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8240 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8241 "TARGET_SHMEDIA_FPU"
8243 [(set_attr "type" "fpconv_media")])
8245 (define_insn "fix_truncsfsi2_i4"
8246 [(set (match_operand:SI 0 "fpul_operand" "=y")
8247 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8248 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8251 [(set_attr "type" "ftrc_s")
8252 (set_attr "fp_mode" "single")])
8254 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8255 ;; fix_truncsfsi2_i4.
8256 ;; (define_insn "fix_truncsfsi2_i4_2"
8257 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8258 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8259 ;; (use (reg:PSI FPSCR_REG))
8260 ;; (clobber (reg:SI FPUL_REG))]
8263 ;; [(set_attr "length" "4")
8264 ;; (set_attr "fp_mode" "single")])
8267 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8268 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8269 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8270 ;; (clobber (reg:SI FPUL_REG))]
8272 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8273 ;; (use (match_dup 2))])
8274 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8276 (define_insn "*fixsfsi"
8277 [(set (match_operand:SI 0 "fpul_operand" "=y")
8278 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8279 "TARGET_SH3E && ! TARGET_SH4"
8281 [(set_attr "type" "fp")])
8283 (define_insn "cmpgtsf_t"
8284 [(set (reg:SI T_REG)
8285 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8286 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8287 "TARGET_SH3E && ! TARGET_SH4"
8289 [(set_attr "type" "fp")
8290 (set_attr "fp_mode" "single")])
8292 (define_insn "cmpeqsf_t"
8293 [(set (reg:SI T_REG)
8294 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8295 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8296 "TARGET_SH3E && ! TARGET_SH4"
8298 [(set_attr "type" "fp")
8299 (set_attr "fp_mode" "single")])
8301 (define_insn "ieee_ccmpeqsf_t"
8302 [(set (reg:SI T_REG)
8303 (ior:SI (reg:SI T_REG)
8304 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8305 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8306 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8307 "* return output_ieee_ccmpeq (insn, operands);"
8308 [(set_attr "length" "4")])
8311 (define_insn "cmpgtsf_t_i4"
8312 [(set (reg:SI T_REG)
8313 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8314 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8315 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8318 [(set_attr "type" "fp")
8319 (set_attr "fp_mode" "single")])
8321 (define_insn "cmpeqsf_t_i4"
8322 [(set (reg:SI T_REG)
8323 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8324 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8325 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8328 [(set_attr "type" "fp")
8329 (set_attr "fp_mode" "single")])
8331 (define_insn "*ieee_ccmpeqsf_t_4"
8332 [(set (reg:SI T_REG)
8333 (ior:SI (reg:SI T_REG)
8334 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8335 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8336 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8337 "TARGET_IEEE && TARGET_SH4"
8338 "* return output_ieee_ccmpeq (insn, operands);"
8339 [(set_attr "length" "4")
8340 (set_attr "fp_mode" "single")])
8342 (define_insn "cmpeqsf_media"
8343 [(set (match_operand:DI 0 "register_operand" "=r")
8344 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8345 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8346 "TARGET_SHMEDIA_FPU"
8347 "fcmpeq.s %1, %2, %0"
8348 [(set_attr "type" "fcmp_media")])
8350 (define_insn "cmpgtsf_media"
8351 [(set (match_operand:DI 0 "register_operand" "=r")
8352 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8353 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8354 "TARGET_SHMEDIA_FPU"
8355 "fcmpgt.s %1, %2, %0"
8356 [(set_attr "type" "fcmp_media")])
8358 (define_insn "cmpgesf_media"
8359 [(set (match_operand:DI 0 "register_operand" "=r")
8360 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8361 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8362 "TARGET_SHMEDIA_FPU"
8363 "fcmpge.s %1, %2, %0"
8364 [(set_attr "type" "fcmp_media")])
8366 (define_insn "cmpunsf_media"
8367 [(set (match_operand:DI 0 "register_operand" "=r")
8368 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8369 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8370 "TARGET_SHMEDIA_FPU"
8371 "fcmpun.s %1, %2, %0"
8372 [(set_attr "type" "fcmp_media")])
8374 (define_expand "cmpsf"
8375 [(set (reg:SI T_REG)
8376 (compare (match_operand:SF 0 "arith_operand" "")
8377 (match_operand:SF 1 "arith_operand" "")))]
8378 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8381 sh_compare_op0 = operands[0];
8382 sh_compare_op1 = operands[1];
8386 (define_expand "negsf2"
8387 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8388 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8389 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8394 expand_sf_unop (&gen_negsf2_i, operands);
8399 (define_insn "*negsf2_media"
8400 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8402 "TARGET_SHMEDIA_FPU"
8404 [(set_attr "type" "fmove_media")])
8406 (define_insn "negsf2_i"
8407 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8408 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8409 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8412 [(set_attr "type" "fmove")
8413 (set_attr "fp_mode" "single")])
8415 (define_expand "sqrtsf2"
8416 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8417 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8418 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8423 expand_sf_unop (&gen_sqrtsf2_i, operands);
8428 (define_insn "*sqrtsf2_media"
8429 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8430 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8431 "TARGET_SHMEDIA_FPU"
8433 [(set_attr "type" "fdiv_media")])
8435 (define_insn "sqrtsf2_i"
8436 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8437 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8438 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8441 [(set_attr "type" "fdiv")
8442 (set_attr "fp_mode" "single")])
8444 (define_expand "abssf2"
8445 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8446 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8447 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8452 expand_sf_unop (&gen_abssf2_i, operands);
8457 (define_insn "*abssf2_media"
8458 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8459 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8460 "TARGET_SHMEDIA_FPU"
8462 [(set_attr "type" "fmove_media")])
8464 (define_insn "abssf2_i"
8465 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8466 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8467 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8470 [(set_attr "type" "fmove")
8471 (set_attr "fp_mode" "single")])
8473 (define_expand "adddf3"
8474 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8475 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8476 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8477 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8482 expand_df_binop (&gen_adddf3_i, operands);
8487 (define_insn "*adddf3_media"
8488 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8489 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8490 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8491 "TARGET_SHMEDIA_FPU"
8493 [(set_attr "type" "dfparith_media")])
8495 (define_insn "adddf3_i"
8496 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8497 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8498 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8499 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8502 [(set_attr "type" "dfp_arith")
8503 (set_attr "fp_mode" "double")])
8505 (define_expand "subdf3"
8506 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8507 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8508 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8509 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8514 expand_df_binop (&gen_subdf3_i, operands);
8519 (define_insn "*subdf3_media"
8520 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8521 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8522 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8523 "TARGET_SHMEDIA_FPU"
8525 [(set_attr "type" "dfparith_media")])
8527 (define_insn "subdf3_i"
8528 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8529 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8530 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8531 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8534 [(set_attr "type" "dfp_arith")
8535 (set_attr "fp_mode" "double")])
8537 (define_expand "muldf3"
8538 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8539 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8540 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8541 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8546 expand_df_binop (&gen_muldf3_i, operands);
8551 (define_insn "*muldf3_media"
8552 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8553 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8554 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8555 "TARGET_SHMEDIA_FPU"
8557 [(set_attr "type" "dfmul_media")])
8559 (define_insn "muldf3_i"
8560 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8561 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8562 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8563 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8566 [(set_attr "type" "dfp_arith")
8567 (set_attr "fp_mode" "double")])
8569 (define_expand "divdf3"
8570 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8571 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8572 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8573 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8578 expand_df_binop (&gen_divdf3_i, operands);
8583 (define_insn "*divdf3_media"
8584 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8585 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8586 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8587 "TARGET_SHMEDIA_FPU"
8589 [(set_attr "type" "dfdiv_media")])
8591 (define_insn "divdf3_i"
8592 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8593 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8594 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8595 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8598 [(set_attr "type" "dfdiv")
8599 (set_attr "fp_mode" "double")])
8601 (define_insn "floatdidf2"
8602 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8603 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8604 "TARGET_SHMEDIA_FPU"
8606 [(set_attr "type" "dfpconv_media")])
8608 (define_expand "floatsidf2"
8609 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8610 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8611 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8616 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8622 (define_insn "*floatsidf2_media"
8623 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8624 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8625 "TARGET_SHMEDIA_FPU"
8627 [(set_attr "type" "dfpconv_media")])
8629 (define_insn "floatsidf2_i"
8630 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8631 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8632 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8635 [(set_attr "type" "dfp_conv")
8636 (set_attr "fp_mode" "double")])
8638 (define_insn "fix_truncdfdi2"
8639 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8640 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8641 "TARGET_SHMEDIA_FPU"
8643 [(set_attr "type" "dfpconv_media")])
8645 (define_expand "fix_truncdfsi2"
8646 [(set (match_operand:SI 0 "fpul_operand" "")
8647 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8648 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8653 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8659 (define_insn "*fix_truncdfsi2_media"
8660 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8661 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8662 "TARGET_SHMEDIA_FPU"
8664 [(set_attr "type" "dfpconv_media")])
8666 (define_insn "fix_truncdfsi2_i"
8667 [(set (match_operand:SI 0 "fpul_operand" "=y")
8668 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8669 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8672 [(set_attr "type" "dfp_conv")
8673 (set_attr "dfp_comp" "no")
8674 (set_attr "fp_mode" "double")])
8676 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8677 ;; fix_truncdfsi2_i.
8678 ;; (define_insn "fix_truncdfsi2_i4"
8679 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8680 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8681 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8682 ;; (clobber (reg:SI FPUL_REG))]
8685 ;; [(set_attr "length" "4")
8686 ;; (set_attr "fp_mode" "double")])
8689 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8690 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8691 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8692 ;; (clobber (reg:SI FPUL_REG))]
8694 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8695 ;; (use (match_dup 2))])
8696 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8698 (define_insn "cmpgtdf_t"
8699 [(set (reg:SI T_REG)
8700 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8701 (match_operand:DF 1 "arith_reg_operand" "f")))
8702 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8705 [(set_attr "type" "dfp_cmp")
8706 (set_attr "fp_mode" "double")])
8708 (define_insn "cmpeqdf_t"
8709 [(set (reg:SI T_REG)
8710 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8711 (match_operand:DF 1 "arith_reg_operand" "f")))
8712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8715 [(set_attr "type" "dfp_cmp")
8716 (set_attr "fp_mode" "double")])
8718 (define_insn "*ieee_ccmpeqdf_t"
8719 [(set (reg:SI T_REG)
8720 (ior:SI (reg:SI T_REG)
8721 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8722 (match_operand:DF 1 "arith_reg_operand" "f"))))
8723 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8724 "TARGET_IEEE && TARGET_SH4"
8725 "* return output_ieee_ccmpeq (insn, operands);"
8726 [(set_attr "length" "4")
8727 (set_attr "fp_mode" "double")])
8729 (define_insn "cmpeqdf_media"
8730 [(set (match_operand:DI 0 "register_operand" "=r")
8731 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8732 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8733 "TARGET_SHMEDIA_FPU"
8735 [(set_attr "type" "fcmp_media")])
8737 (define_insn "cmpgtdf_media"
8738 [(set (match_operand:DI 0 "register_operand" "=r")
8739 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8740 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8741 "TARGET_SHMEDIA_FPU"
8743 [(set_attr "type" "fcmp_media")])
8745 (define_insn "cmpgedf_media"
8746 [(set (match_operand:DI 0 "register_operand" "=r")
8747 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8748 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8749 "TARGET_SHMEDIA_FPU"
8751 [(set_attr "type" "fcmp_media")])
8753 (define_insn "cmpundf_media"
8754 [(set (match_operand:DI 0 "register_operand" "=r")
8755 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8756 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8757 "TARGET_SHMEDIA_FPU"
8759 [(set_attr "type" "fcmp_media")])
8761 (define_expand "cmpdf"
8762 [(set (reg:SI T_REG)
8763 (compare (match_operand:DF 0 "arith_operand" "")
8764 (match_operand:DF 1 "arith_operand" "")))]
8765 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8768 sh_compare_op0 = operands[0];
8769 sh_compare_op1 = operands[1];
8773 (define_expand "negdf2"
8774 [(set (match_operand:DF 0 "arith_reg_operand" "")
8775 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8776 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8781 expand_df_unop (&gen_negdf2_i, operands);
8786 (define_insn "*negdf2_media"
8787 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8788 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8789 "TARGET_SHMEDIA_FPU"
8791 [(set_attr "type" "fmove_media")])
8793 (define_insn "negdf2_i"
8794 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8795 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8796 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8799 [(set_attr "type" "fmove")
8800 (set_attr "fp_mode" "double")])
8802 (define_expand "sqrtdf2"
8803 [(set (match_operand:DF 0 "arith_reg_operand" "")
8804 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8805 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8810 expand_df_unop (&gen_sqrtdf2_i, operands);
8815 (define_insn "*sqrtdf2_media"
8816 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8817 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8818 "TARGET_SHMEDIA_FPU"
8820 [(set_attr "type" "dfdiv_media")])
8822 (define_insn "sqrtdf2_i"
8823 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8824 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8825 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8828 [(set_attr "type" "dfdiv")
8829 (set_attr "fp_mode" "double")])
8831 (define_expand "absdf2"
8832 [(set (match_operand:DF 0 "arith_reg_operand" "")
8833 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8834 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8839 expand_df_unop (&gen_absdf2_i, operands);
8844 (define_insn "*absdf2_media"
8845 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8846 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8847 "TARGET_SHMEDIA_FPU"
8849 [(set_attr "type" "fmove_media")])
8851 (define_insn "absdf2_i"
8852 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8853 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8854 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8857 [(set_attr "type" "fmove")
8858 (set_attr "fp_mode" "double")])
8860 (define_expand "extendsfdf2"
8861 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8862 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8863 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8868 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8874 (define_insn "*extendsfdf2_media"
8875 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8876 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8877 "TARGET_SHMEDIA_FPU"
8879 [(set_attr "type" "dfpconv_media")])
8881 (define_insn "extendsfdf2_i4"
8882 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8883 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8884 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8887 [(set_attr "type" "fp")
8888 (set_attr "fp_mode" "double")])
8890 (define_expand "truncdfsf2"
8891 [(set (match_operand:SF 0 "fpul_operand" "")
8892 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8893 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8898 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8904 (define_insn "*truncdfsf2_media"
8905 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8906 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8907 "TARGET_SHMEDIA_FPU"
8909 [(set_attr "type" "dfpconv_media")])
8911 (define_insn "truncdfsf2_i4"
8912 [(set (match_operand:SF 0 "fpul_operand" "=y")
8913 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8914 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8917 [(set_attr "type" "fp")
8918 (set_attr "fp_mode" "double")])
8920 ;; Bit field extract patterns. These give better code for packed bitfields,
8921 ;; because they allow auto-increment addresses to be generated.
8923 (define_expand "insv"
8924 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8925 (match_operand:SI 1 "immediate_operand" "")
8926 (match_operand:SI 2 "immediate_operand" ""))
8927 (match_operand:SI 3 "general_operand" ""))]
8928 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8931 rtx addr_target, orig_address, shift_reg, qi_val;
8932 HOST_WIDE_INT bitsize, size, v;
8933 rtx x = operands[3];
8935 /* ??? expmed doesn't care for non-register predicates. */
8936 if (! memory_operand (operands[0], VOIDmode)
8937 || ! immediate_operand (operands[1], VOIDmode)
8938 || ! immediate_operand (operands[2], VOIDmode)
8939 || ! general_operand (x, VOIDmode))
8941 /* If this isn't a 16 / 24 / 32 bit field, or if
8942 it doesn't start on a byte boundary, then fail. */
8943 bitsize = INTVAL (operands[1]);
8944 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8945 || (INTVAL (operands[2]) % 8) != 0)
8949 orig_address = XEXP (operands[0], 0);
8950 shift_reg = gen_reg_rtx (SImode);
8951 if (GET_CODE (x) == CONST_INT)
8954 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8958 emit_insn (gen_movsi (shift_reg, operands[3]));
8959 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8961 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8963 operands[0] = replace_equiv_address (operands[0], addr_target);
8964 emit_insn (gen_movqi (operands[0], qi_val));
8968 if (GET_CODE (x) == CONST_INT)
8970 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8973 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8974 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8976 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8977 emit_insn (gen_movqi (operands[0], qi_val));
8983 ;; -------------------------------------------------------------------------
8985 ;; -------------------------------------------------------------------------
8987 ;; This matches cases where a stack pointer increment at the start of the
8988 ;; epilogue combines with a stack slot read loading the return value.
8991 [(set (match_operand:SI 0 "arith_reg_operand" "")
8992 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8993 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8994 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8997 ;; See the comment on the dt combiner pattern above.
9000 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9001 (plus:SI (match_dup 0)
9004 (eq:SI (match_dup 0)
9009 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9010 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9011 ;; reload when the constant is too large for a reg+offset address.
9013 ;; ??? We would get much better code if this was done in reload. This would
9014 ;; require modifying find_reloads_address to recognize that if the constant
9015 ;; is out-of-range for an immediate add, then we get better code by reloading
9016 ;; the constant into a register than by reloading the sum into a register,
9017 ;; since the former is one instruction shorter if the address does not need
9018 ;; to be offsettable. Unfortunately this does not work, because there is
9019 ;; only one register, r0, that can be used as an index register. This register
9020 ;; is also the function return value register. So, if we try to force reload
9021 ;; to use double-reg addresses, then we end up with some instructions that
9022 ;; need to use r0 twice. The only way to fix this is to change the calling
9023 ;; convention so that r0 is not used to return values.
9026 [(set (match_operand:SI 0 "register_operand" "=r")
9027 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9028 (set (mem:SI (match_dup 0))
9029 (match_operand:SI 2 "general_movsrc_operand" ""))]
9030 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9031 "mov.l %2,@(%0,%1)")
9034 [(set (match_operand:SI 0 "register_operand" "=r")
9035 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9036 (set (match_operand:SI 2 "general_movdst_operand" "")
9037 (mem:SI (match_dup 0)))]
9038 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9039 "mov.l @(%0,%1),%2")
9042 [(set (match_operand:SI 0 "register_operand" "=r")
9043 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9044 (set (mem:HI (match_dup 0))
9045 (match_operand:HI 2 "general_movsrc_operand" ""))]
9046 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9047 "mov.w %2,@(%0,%1)")
9050 [(set (match_operand:SI 0 "register_operand" "=r")
9051 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9052 (set (match_operand:HI 2 "general_movdst_operand" "")
9053 (mem:HI (match_dup 0)))]
9054 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9055 "mov.w @(%0,%1),%2")
9058 [(set (match_operand:SI 0 "register_operand" "=r")
9059 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9060 (set (mem:QI (match_dup 0))
9061 (match_operand:QI 2 "general_movsrc_operand" ""))]
9062 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9063 "mov.b %2,@(%0,%1)")
9066 [(set (match_operand:SI 0 "register_operand" "=r")
9067 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9068 (set (match_operand:QI 2 "general_movdst_operand" "")
9069 (mem:QI (match_dup 0)))]
9070 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9071 "mov.b @(%0,%1),%2")
9074 [(set (match_operand:SI 0 "register_operand" "=r")
9075 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9076 (set (mem:SF (match_dup 0))
9077 (match_operand:SF 2 "general_movsrc_operand" ""))]
9078 "TARGET_SH1 && REGNO (operands[0]) == 0
9079 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9080 || (GET_CODE (operands[2]) == SUBREG
9081 && REGNO (SUBREG_REG (operands[2])) < 16))
9082 && reg_unused_after (operands[0], insn)"
9083 "mov.l %2,@(%0,%1)")
9086 [(set (match_operand:SI 0 "register_operand" "=r")
9087 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9088 (set (match_operand:SF 2 "general_movdst_operand" "")
9090 (mem:SF (match_dup 0)))]
9091 "TARGET_SH1 && REGNO (operands[0]) == 0
9092 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9093 || (GET_CODE (operands[2]) == SUBREG
9094 && REGNO (SUBREG_REG (operands[2])) < 16))
9095 && reg_unused_after (operands[0], insn)"
9096 "mov.l @(%0,%1),%2")
9099 [(set (match_operand:SI 0 "register_operand" "=r")
9100 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9101 (set (mem:SF (match_dup 0))
9102 (match_operand:SF 2 "general_movsrc_operand" ""))]
9103 "TARGET_SH3E && REGNO (operands[0]) == 0
9104 && ((GET_CODE (operands[2]) == REG
9105 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9106 || (GET_CODE (operands[2]) == SUBREG
9107 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9108 && reg_unused_after (operands[0], insn)"
9109 "fmov{.s|} %2,@(%0,%1)")
9112 [(set (match_operand:SI 0 "register_operand" "=r")
9113 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9114 (set (match_operand:SF 2 "general_movdst_operand" "")
9116 (mem:SF (match_dup 0)))]
9117 "TARGET_SH3E && REGNO (operands[0]) == 0
9118 && ((GET_CODE (operands[2]) == REG
9119 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9120 || (GET_CODE (operands[2]) == SUBREG
9121 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9122 && reg_unused_after (operands[0], insn)"
9123 "fmov{.s|} @(%0,%1),%2")
9125 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9126 (define_insn "sp_switch_1"
9133 xoperands[0] = sp_switch;
9134 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9135 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9136 return \"mov r0,r15\";
9138 [(set_attr "length" "10")])
9140 ;; Switch back to the original stack for interrupt functions with the
9141 ;; sp_switch attribute. */
9142 (define_insn "sp_switch_2"
9145 "mov.l @r15+,r15\;mov.l @r15+,r0"
9146 [(set_attr "length" "4")])
9148 ;; Integer vector moves
9150 (define_expand "movv8qi"
9151 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9152 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9154 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9156 (define_insn "movv8qi_i"
9157 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9158 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9160 && (register_operand (operands[0], V8QImode)
9161 || register_operand (operands[1], V8QImode))"
9168 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9169 (set_attr "length" "4,4,16,4,4")])
9172 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9173 (subreg:V8QI (const_int 0) 0))]
9176 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9177 (const_int 0) (const_int 0) (const_int 0)
9178 (const_int 0) (const_int 0)]))])
9181 [(set (match_operand 0 "arith_reg_dest" "")
9182 (match_operand 1 "sh_rep_vec" ""))]
9183 "TARGET_SHMEDIA && reload_completed
9184 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9185 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9186 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9187 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9188 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9189 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9190 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9191 [(set (match_dup 0) (match_dup 1))
9195 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9196 rtx elt1 = XVECEXP (operands[1], 0, 1);
9199 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9203 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9204 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9206 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9207 operands[1] = XVECEXP (operands[1], 0, 0);
9210 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9211 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9212 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9213 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9216 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9218 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9224 [(set (match_operand 0 "arith_reg_dest" "")
9225 (match_operand 1 "sh_const_vec" ""))]
9226 "TARGET_SHMEDIA && reload_completed
9227 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9228 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9229 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9230 [(set (match_dup 0) (match_dup 1))]
9233 rtx v = operands[1];
9234 enum machine_mode new_mode
9235 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9237 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9239 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9242 (define_expand "movv2hi"
9243 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9244 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9246 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9248 (define_insn "movv2hi_i"
9249 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9250 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9252 && (register_operand (operands[0], V2HImode)
9253 || register_operand (operands[1], V2HImode))"
9260 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9261 (set_attr "length" "4,4,16,4,4")])
9263 (define_expand "movv4hi"
9264 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9265 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9267 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9269 (define_insn "movv4hi_i"
9270 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9271 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9273 && (register_operand (operands[0], V4HImode)
9274 || register_operand (operands[1], V4HImode))"
9281 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9282 (set_attr "length" "4,4,16,4,4")])
9284 (define_expand "movv2si"
9285 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9286 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9288 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9290 (define_insn "movv2si_i"
9291 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9292 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9294 && (register_operand (operands[0], V2SImode)
9295 || register_operand (operands[1], V2SImode))"
9302 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9303 (set_attr "length" "4,4,16,4,4")])
9305 ;; Multimedia Intrinsics
9307 (define_insn "absv2si2"
9308 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9309 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9312 [(set_attr "type" "mcmp_media")])
9314 (define_insn "absv4hi2"
9315 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9316 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9319 [(set_attr "type" "mcmp_media")])
9321 (define_insn "addv2si3"
9322 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9323 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9324 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9327 [(set_attr "type" "arith_media")])
9329 (define_insn "addv4hi3"
9330 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9331 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9332 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9335 [(set_attr "type" "arith_media")])
9337 (define_insn "ssaddv2si3"
9338 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9339 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9340 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9342 "madds.l %1, %2, %0"
9343 [(set_attr "type" "mcmp_media")])
9345 (define_insn "usaddv8qi3"
9346 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9347 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9348 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9350 "madds.ub %1, %2, %0"
9351 [(set_attr "type" "mcmp_media")])
9353 (define_insn "ssaddv4hi3"
9354 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9355 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9356 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9358 "madds.w %1, %2, %0"
9359 [(set_attr "type" "mcmp_media")])
9361 (define_insn "negcmpeqv8qi"
9362 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9363 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9364 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9366 "mcmpeq.b %N1, %N2, %0"
9367 [(set_attr "type" "mcmp_media")])
9369 (define_insn "negcmpeqv2si"
9370 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9371 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9372 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9374 "mcmpeq.l %N1, %N2, %0"
9375 [(set_attr "type" "mcmp_media")])
9377 (define_insn "negcmpeqv4hi"
9378 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9379 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9380 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9382 "mcmpeq.w %N1, %N2, %0"
9383 [(set_attr "type" "mcmp_media")])
9385 (define_insn "negcmpgtuv8qi"
9386 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9387 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9388 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9390 "mcmpgt.ub %N1, %N2, %0"
9391 [(set_attr "type" "mcmp_media")])
9393 (define_insn "negcmpgtv2si"
9394 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9395 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9396 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9398 "mcmpgt.l %N1, %N2, %0"
9399 [(set_attr "type" "mcmp_media")])
9401 (define_insn "negcmpgtv4hi"
9402 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9403 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9404 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9406 "mcmpgt.w %N1, %N2, %0"
9407 [(set_attr "type" "mcmp_media")])
9410 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9411 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9412 (match_operand:DI 2 "arith_reg_operand" "r"))
9413 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9414 (not:DI (match_dup 2)))))]
9417 [(set_attr "type" "arith_media")])
9419 (define_insn "mcnvs_lw"
9420 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9422 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9423 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9425 "mcnvs.lw %N1, %N2, %0"
9426 [(set_attr "type" "mcmp_media")])
9428 (define_insn "mcnvs_wb"
9429 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9431 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9432 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9434 "mcnvs.wb %N1, %N2, %0"
9435 [(set_attr "type" "mcmp_media")])
9437 (define_insn "mcnvs_wub"
9438 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9440 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9441 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9443 "mcnvs.wub %N1, %N2, %0"
9444 [(set_attr "type" "mcmp_media")])
9446 (define_insn "mextr_rl"
9447 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9448 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9449 (match_operand:HI 3 "mextr_bit_offset" "i"))
9450 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9451 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9452 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9455 static char templ[16];
9457 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9458 (int) INTVAL (operands[3]) >> 3);
9461 [(set_attr "type" "arith_media")])
9463 (define_insn "*mextr_lr"
9464 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9465 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9466 (match_operand:HI 3 "mextr_bit_offset" "i"))
9467 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9468 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9469 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9472 static char templ[16];
9474 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9475 (int) INTVAL (operands[4]) >> 3);
9478 [(set_attr "type" "arith_media")])
9480 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9481 ; vector then varies depending on endianness.
9482 (define_expand "mextr1"
9483 [(match_operand:DI 0 "arith_reg_dest" "")
9484 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9485 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9489 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9490 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9494 (define_expand "mextr2"
9495 [(match_operand:DI 0 "arith_reg_dest" "")
9496 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9497 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9501 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9502 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9506 (define_expand "mextr3"
9507 [(match_operand:DI 0 "arith_reg_dest" "")
9508 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9509 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9513 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9514 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9518 (define_expand "mextr4"
9519 [(match_operand:DI 0 "arith_reg_dest" "")
9520 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9521 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9525 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9526 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9530 (define_expand "mextr5"
9531 [(match_operand:DI 0 "arith_reg_dest" "")
9532 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9533 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9537 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9538 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9542 (define_expand "mextr6"
9543 [(match_operand:DI 0 "arith_reg_dest" "")
9544 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9545 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9549 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9550 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9554 (define_expand "mextr7"
9555 [(match_operand:DI 0 "arith_reg_dest" "")
9556 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9557 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9561 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9562 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9566 (define_expand "mmacfx_wl"
9567 [(match_operand:V2SI 0 "arith_reg_dest" "")
9568 (match_operand:V2HI 1 "extend_reg_operand" "")
9569 (match_operand:V2HI 2 "extend_reg_operand" "")
9570 (match_operand:V2SI 3 "arith_reg_operand" "")]
9574 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9575 operands[1], operands[2]));
9579 (define_insn "mmacfx_wl_i"
9580 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9582 (match_operand:V2SI 1 "arith_reg_operand" "0")
9587 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9588 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9591 "mmacfx.wl %2, %3, %0"
9592 [(set_attr "type" "mac_media")])
9594 (define_expand "mmacnfx_wl"
9595 [(match_operand:V2SI 0 "arith_reg_dest" "")
9596 (match_operand:V2HI 1 "extend_reg_operand" "")
9597 (match_operand:V2HI 2 "extend_reg_operand" "")
9598 (match_operand:V2SI 3 "arith_reg_operand" "")]
9602 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9603 operands[1], operands[2]));
9607 (define_insn "mmacnfx_wl_i"
9608 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9610 (match_operand:V2SI 1 "arith_reg_operand" "0")
9615 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9616 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9619 "mmacnfx.wl %2, %3, %0"
9620 [(set_attr "type" "mac_media")])
9622 (define_insn "mulv2si3"
9623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9624 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9625 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9628 [(set_attr "type" "d2mpy_media")])
9630 (define_insn "mulv4hi3"
9631 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9632 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9633 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9636 [(set_attr "type" "dmpy_media")])
9638 (define_insn "mmulfx_l"
9639 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9643 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9644 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9647 "mmulfx.l %1, %2, %0"
9648 [(set_attr "type" "d2mpy_media")])
9650 (define_insn "mmulfx_w"
9651 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9655 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9656 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9659 "mmulfx.w %1, %2, %0"
9660 [(set_attr "type" "dmpy_media")])
9662 (define_insn "mmulfxrp_w"
9663 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9668 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9669 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9673 "mmulfxrp.w %1, %2, %0"
9674 [(set_attr "type" "dmpy_media")])
9676 (define_expand "mmulhi_wl"
9677 [(match_operand:V2SI 0 "arith_reg_dest" "")
9678 (match_operand:V4HI 1 "arith_reg_operand" "")
9679 (match_operand:V4HI 2 "arith_reg_operand" "")]
9683 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9684 (operands[0], operands[1], operands[2]));
9688 (define_expand "mmullo_wl"
9689 [(match_operand:V2SI 0 "arith_reg_dest" "")
9690 (match_operand:V4HI 1 "arith_reg_operand" "")
9691 (match_operand:V4HI 2 "arith_reg_operand" "")]
9695 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9696 (operands[0], operands[1], operands[2]));
9700 (define_insn "mmul23_wl"
9701 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9704 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9705 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9706 (parallel [(const_int 2) (const_int 3)])))]
9708 "* return (TARGET_LITTLE_ENDIAN
9709 ? \"mmulhi.wl %1, %2, %0\"
9710 : \"mmullo.wl %1, %2, %0\");"
9711 [(set_attr "type" "dmpy_media")])
9713 (define_insn "mmul01_wl"
9714 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9717 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9718 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9719 (parallel [(const_int 0) (const_int 1)])))]
9721 "* return (TARGET_LITTLE_ENDIAN
9722 ? \"mmullo.wl %1, %2, %0\"
9723 : \"mmulhi.wl %1, %2, %0\");"
9724 [(set_attr "type" "dmpy_media")])
9726 (define_expand "mmulsum_wq"
9727 [(match_operand:DI 0 "arith_reg_dest" "")
9728 (match_operand:V4HI 1 "arith_reg_operand" "")
9729 (match_operand:V4HI 2 "arith_reg_operand" "")
9730 (match_operand:DI 3 "arith_reg_operand" "")]
9734 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9735 operands[1], operands[2]));
9739 (define_insn "mmulsum_wq_i"
9740 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9741 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9746 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9747 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9748 (parallel [(const_int 0)]))
9749 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9750 (sign_extend:V4DI (match_dup 3)))
9751 (parallel [(const_int 1)])))
9753 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9754 (sign_extend:V4DI (match_dup 3)))
9755 (parallel [(const_int 2)]))
9756 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9757 (sign_extend:V4DI (match_dup 3)))
9758 (parallel [(const_int 3)]))))))]
9760 "mmulsum.wq %2, %3, %0"
9761 [(set_attr "type" "mac_media")])
9763 (define_expand "mperm_w"
9764 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9765 (match_operand:V4HI 1 "arith_reg_operand" "r")
9766 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9770 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9771 (operands[0], operands[1], operands[2]));
9775 ; This use of vec_select isn't exactly correct according to rtl.texi
9776 ; (because not constant), but it seems a straightforward extension.
9777 (define_insn "mperm_w_little"
9778 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9780 (match_operand:V4HI 1 "arith_reg_operand" "r")
9782 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9783 (const_int 2) (const_int 0))
9784 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9785 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9786 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9787 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9788 "mperm.w %1, %N2, %0"
9789 [(set_attr "type" "arith_media")])
9791 (define_insn "mperm_w_big"
9792 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9794 (match_operand:V4HI 1 "arith_reg_operand" "r")
9796 [(zero_extract:QI (not:QI (match_operand:QI 2
9797 "extend_reg_or_0_operand" "rU"))
9798 (const_int 2) (const_int 0))
9799 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9800 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9801 (zero_extract:QI (not:QI (match_dup 2))
9802 (const_int 2) (const_int 6))])))]
9803 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9804 "mperm.w %1, %N2, %0"
9805 [(set_attr "type" "arith_media")])
9807 (define_insn "mperm_w0"
9808 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9809 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9810 "trunc_hi_operand" "r"))))]
9812 "mperm.w %1, r63, %0"
9813 [(set_attr "type" "arith_media")])
9815 (define_expand "msad_ubq"
9816 [(match_operand:DI 0 "arith_reg_dest" "")
9817 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9818 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9819 (match_operand:DI 3 "arith_reg_operand" "")]
9823 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9824 operands[1], operands[2]));
9828 (define_insn "msad_ubq_i"
9829 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9834 (match_operand:DI 1 "arith_reg_operand" "0")
9835 (abs:DI (vec_select:DI
9838 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9840 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9841 (parallel [(const_int 0)]))))
9842 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9843 (zero_extend:V8DI (match_dup 3)))
9844 (parallel [(const_int 1)]))))
9846 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9847 (zero_extend:V8DI (match_dup 3)))
9848 (parallel [(const_int 2)])))
9849 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9850 (zero_extend:V8DI (match_dup 3)))
9851 (parallel [(const_int 3)])))))
9854 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9855 (zero_extend:V8DI (match_dup 3)))
9856 (parallel [(const_int 4)])))
9857 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9858 (zero_extend:V8DI (match_dup 3)))
9859 (parallel [(const_int 5)]))))
9861 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9862 (zero_extend:V8DI (match_dup 3)))
9863 (parallel [(const_int 6)])))
9864 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9865 (zero_extend:V8DI (match_dup 3)))
9866 (parallel [(const_int 7)])))))))]
9868 "msad.ubq %N2, %N3, %0"
9869 [(set_attr "type" "mac_media")])
9871 (define_insn "mshalds_l"
9872 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9875 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9876 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9879 "mshalds.l %1, %2, %0"
9880 [(set_attr "type" "mcmp_media")])
9882 (define_insn "mshalds_w"
9883 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9886 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9887 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9890 "mshalds.w %1, %2, %0"
9891 [(set_attr "type" "mcmp_media")])
9893 (define_insn "ashrv2si3"
9894 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9895 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9896 (match_operand:DI 2 "arith_reg_operand" "r")))]
9898 "mshard.l %1, %2, %0"
9899 [(set_attr "type" "arith_media")])
9901 (define_insn "ashrv4hi3"
9902 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9903 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9904 (match_operand:DI 2 "arith_reg_operand" "r")))]
9906 "mshard.w %1, %2, %0"
9907 [(set_attr "type" "arith_media")])
9909 (define_insn "mshards_q"
9910 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9912 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9913 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9915 "mshards.q %1, %N2, %0"
9916 [(set_attr "type" "mcmp_media")])
9918 (define_expand "mshfhi_b"
9919 [(match_operand:V8QI 0 "arith_reg_dest" "")
9920 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9921 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9925 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9926 (operands[0], operands[1], operands[2]));
9930 (define_expand "mshflo_b"
9931 [(match_operand:V8QI 0 "arith_reg_dest" "")
9932 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9933 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9937 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9938 (operands[0], operands[1], operands[2]));
9942 (define_insn "mshf4_b"
9944 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9946 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9947 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9948 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9949 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9951 "* return (TARGET_LITTLE_ENDIAN
9952 ? \"mshfhi.b %N1, %N2, %0\"
9953 : \"mshflo.b %N1, %N2, %0\");"
9954 [(set_attr "type" "arith_media")])
9956 (define_insn "mshf0_b"
9958 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9960 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9961 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9962 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9963 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9965 "* return (TARGET_LITTLE_ENDIAN
9966 ? \"mshflo.b %N1, %N2, %0\"
9967 : \"mshfhi.b %N1, %N2, %0\");"
9968 [(set_attr "type" "arith_media")])
9970 (define_expand "mshfhi_l"
9971 [(match_operand:V2SI 0 "arith_reg_dest" "")
9972 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9973 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9977 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9978 (operands[0], operands[1], operands[2]));
9982 (define_expand "mshflo_l"
9983 [(match_operand:V2SI 0 "arith_reg_dest" "")
9984 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9985 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9989 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9990 (operands[0], operands[1], operands[2]));
9994 (define_insn "mshf4_l"
9995 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9997 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9998 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9999 (parallel [(const_int 1) (const_int 3)])))]
10001 "* return (TARGET_LITTLE_ENDIAN
10002 ? \"mshfhi.l %N1, %N2, %0\"
10003 : \"mshflo.l %N1, %N2, %0\");"
10004 [(set_attr "type" "arith_media")])
10006 (define_insn "mshf0_l"
10007 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10009 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10010 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10011 (parallel [(const_int 0) (const_int 2)])))]
10013 "* return (TARGET_LITTLE_ENDIAN
10014 ? \"mshflo.l %N1, %N2, %0\"
10015 : \"mshfhi.l %N1, %N2, %0\");"
10016 [(set_attr "type" "arith_media")])
10018 (define_expand "mshfhi_w"
10019 [(match_operand:V4HI 0 "arith_reg_dest" "")
10020 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10021 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10025 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10026 (operands[0], operands[1], operands[2]));
10030 (define_expand "mshflo_w"
10031 [(match_operand:V4HI 0 "arith_reg_dest" "")
10032 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10033 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10037 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10038 (operands[0], operands[1], operands[2]));
10042 (define_insn "mshf4_w"
10043 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10045 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10046 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10047 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10049 "* return (TARGET_LITTLE_ENDIAN
10050 ? \"mshfhi.w %N1, %N2, %0\"
10051 : \"mshflo.w %N1, %N2, %0\");"
10052 [(set_attr "type" "arith_media")])
10054 (define_insn "mshf0_w"
10055 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10057 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10058 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10059 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10061 "* return (TARGET_LITTLE_ENDIAN
10062 ? \"mshflo.w %N1, %N2, %0\"
10063 : \"mshfhi.w %N1, %N2, %0\");"
10064 [(set_attr "type" "arith_media")])
10066 (define_insn "mshflo_w_x"
10067 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10069 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10070 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10071 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10073 "mshflo.w %N1, %N2, %0"
10074 [(set_attr "type" "arith_media")])
10076 /* These are useful to expand ANDs and as combiner patterns. */
10077 (define_insn_and_split "mshfhi_l_di"
10078 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10079 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10081 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10082 (const_int -4294967296))))]
10085 mshfhi.l %N1, %N2, %0
10087 "TARGET_SHMEDIA && reload_completed
10088 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10089 [(set (match_dup 3) (match_dup 4))
10090 (set (match_dup 5) (match_dup 6))]
10093 operands[3] = gen_lowpart (SImode, operands[0]);
10094 operands[4] = gen_highpart (SImode, operands[1]);
10095 operands[5] = gen_highpart (SImode, operands[0]);
10096 operands[6] = gen_highpart (SImode, operands[2]);
10098 [(set_attr "type" "arith_media")])
10100 (define_insn "*mshfhi_l_di_rev"
10101 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10102 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10103 (const_int -4294967296))
10104 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10107 "mshfhi.l %N2, %N1, %0"
10108 [(set_attr "type" "arith_media")])
10111 [(set (match_operand:DI 0 "arith_reg_dest" "")
10112 (ior:DI (zero_extend:DI (match_operand:SI 1
10113 "extend_reg_or_0_operand" ""))
10114 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10115 (const_int -4294967296))))
10116 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10121 emit_insn (gen_ashldi3_media (operands[3],
10122 simplify_gen_subreg (DImode, operands[1],
10125 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10129 (define_insn "mshflo_l_di"
10130 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10131 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10132 (const_int 4294967295))
10133 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10137 "mshflo.l %N1, %N2, %0"
10138 [(set_attr "type" "arith_media")])
10140 (define_insn "*mshflo_l_di_rev"
10141 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10142 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10144 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10145 (const_int 4294967295))))]
10148 "mshflo.l %N2, %N1, %0"
10149 [(set_attr "type" "arith_media")])
10151 ;; Combiner pattern for trampoline initialization.
10152 (define_insn_and_split "*double_shori"
10153 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10154 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10156 (match_operand:DI 2 "const_int_operand" "n")))]
10158 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10160 "rtx_equal_p (operands[0], operands[1])"
10164 HOST_WIDE_INT v = INTVAL (operands[2]);
10166 emit_insn (gen_shori_media (operands[0], operands[0],
10167 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10168 emit_insn (gen_shori_media (operands[0], operands[0],
10169 gen_int_mode (v, HImode)));
10174 (define_insn "*mshflo_l_di_x"
10175 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10176 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10178 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10182 "mshflo.l %N1, %N2, %0"
10183 [(set_attr "type" "arith_media")])
10185 (define_insn_and_split "concat_v2sf"
10186 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10187 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10188 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10189 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10193 mshflo.l %N1, %N2, %0
10196 "TARGET_SHMEDIA && reload_completed
10197 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10198 [(set (match_dup 3) (match_dup 1))
10199 (set (match_dup 4) (match_dup 2))]
10202 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10203 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10205 [(set_attr "type" "arith_media")])
10207 (define_insn "*mshflo_l_di_x_rev"
10208 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10209 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10211 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10214 "mshflo.l %N2, %N1, %0"
10215 [(set_attr "type" "arith_media")])
10217 (define_insn "ashlv2si3"
10218 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10219 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10220 (match_operand:DI 2 "arith_reg_operand" "r")))]
10222 "mshlld.l %1, %2, %0"
10223 [(set_attr "type" "arith_media")])
10225 (define_insn "ashlv4hi3"
10226 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10227 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10228 (match_operand:DI 2 "arith_reg_operand" "r")))]
10230 "mshlld.w %1, %2, %0"
10231 [(set_attr "type" "arith_media")])
10233 (define_insn "lshrv2si3"
10234 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10235 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10236 (match_operand:DI 2 "arith_reg_operand" "r")))]
10238 "mshlrd.l %1, %2, %0"
10239 [(set_attr "type" "arith_media")])
10241 (define_insn "lshrv4hi3"
10242 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10243 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10244 (match_operand:DI 2 "arith_reg_operand" "r")))]
10246 "mshlrd.w %1, %2, %0"
10247 [(set_attr "type" "arith_media")])
10249 (define_insn "subv2si3"
10250 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10251 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10252 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10254 "msub.l %N1, %2, %0"
10255 [(set_attr "type" "arith_media")])
10257 (define_insn "subv4hi3"
10258 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10259 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10260 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10262 "msub.w %N1, %2, %0"
10263 [(set_attr "type" "arith_media")])
10265 (define_insn "sssubv2si3"
10266 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10267 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10268 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10270 "msubs.l %N1, %2, %0"
10271 [(set_attr "type" "mcmp_media")])
10273 (define_insn "ussubv8qi3"
10274 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10275 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10276 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10278 "msubs.ub %1, %2, %0"
10279 [(set_attr "type" "mcmp_media")])
10281 (define_insn "sssubv4hi3"
10282 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10283 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10284 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10286 "msubs.w %N1, %2, %0"
10287 [(set_attr "type" "mcmp_media")])
10289 ;; Floating Point Intrinsics
10291 (define_insn "fcosa_s"
10292 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10293 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10297 [(set_attr "type" "atrans_media")])
10299 (define_insn "fsina_s"
10300 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10301 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10305 [(set_attr "type" "atrans_media")])
10307 (define_insn "fipr"
10308 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10309 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10310 "fp_arith_reg_operand" "f")
10311 (match_operand:V4SF 2
10312 "fp_arith_reg_operand" "f"))
10313 (parallel [(const_int 0)]))
10314 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10315 (parallel [(const_int 1)])))
10316 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10317 (parallel [(const_int 2)]))
10318 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10319 (parallel [(const_int 3)])))))]
10322 [(set_attr "type" "fparith_media")])
10324 (define_insn "fsrra_s"
10325 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10326 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10330 [(set_attr "type" "atrans_media")])
10332 (define_insn "ftrv"
10333 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10337 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10338 (parallel [(const_int 0) (const_int 5)
10339 (const_int 10) (const_int 15)]))
10340 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10342 (vec_select:V4SF (match_dup 1)
10343 (parallel [(const_int 4) (const_int 9)
10344 (const_int 14) (const_int 3)]))
10345 (vec_select:V4SF (match_dup 2)
10346 (parallel [(const_int 1) (const_int 2)
10347 (const_int 3) (const_int 0)]))))
10350 (vec_select:V4SF (match_dup 1)
10351 (parallel [(const_int 8) (const_int 13)
10352 (const_int 2) (const_int 7)]))
10353 (vec_select:V4SF (match_dup 2)
10354 (parallel [(const_int 2) (const_int 3)
10355 (const_int 0) (const_int 1)])))
10357 (vec_select:V4SF (match_dup 1)
10358 (parallel [(const_int 12) (const_int 1)
10359 (const_int 6) (const_int 11)]))
10360 (vec_select:V4SF (match_dup 2)
10361 (parallel [(const_int 3) (const_int 0)
10362 (const_int 1) (const_int 2)]))))))]
10365 [(set_attr "type" "fparith_media")])
10368 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10369 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10373 [(set_attr "type" "arith_media")])
10375 (define_insn "nsbsi"
10376 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10378 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10382 [(set_attr "type" "arith_media")])
10384 (define_insn "nsbdi"
10385 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10387 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10391 [(set_attr "type" "arith_media")])
10393 (define_expand "ffsdi2"
10394 [(set (match_operand:DI 0 "arith_reg_dest" "")
10395 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10399 rtx scratch = gen_reg_rtx (DImode);
10402 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10403 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10404 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10405 emit_insn (gen_nsbdi (scratch, scratch));
10406 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10407 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10408 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10410 = gen_rtx_EXPR_LIST (REG_EQUAL,
10411 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10415 (define_expand "ffssi2"
10416 [(set (match_operand:SI 0 "arith_reg_dest" "")
10417 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10421 rtx scratch = gen_reg_rtx (SImode);
10422 rtx discratch = gen_reg_rtx (DImode);
10425 emit_insn (gen_adddi3 (discratch,
10426 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10428 emit_insn (gen_andcdi3 (discratch,
10429 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10431 emit_insn (gen_nsbsi (scratch, discratch));
10432 last = emit_insn (gen_subsi3 (operands[0],
10433 force_reg (SImode, GEN_INT (63)), scratch));
10435 = gen_rtx_EXPR_LIST (REG_EQUAL,
10436 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10440 (define_insn "byterev"
10441 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10442 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10443 (parallel [(const_int 7) (const_int 6) (const_int 5)
10444 (const_int 4) (const_int 3) (const_int 2)
10445 (const_int 1) (const_int 0)])))]
10448 [(set_attr "type" "arith_media")])
10450 ;; The following description models the
10451 ;; SH4 pipeline using the DFA based scheduler.
10452 ;; The DFA based description is better way to model
10453 ;; a superscalar pipeline as compared to function unit
10454 ;; reservation model.
10455 ;; 1. The function unit based model is oriented to describe at most one
10456 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10457 ;; pipeline units by same insn. This can be done using DFA based description.
10458 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10459 ;; 3. Writing all unit reservations for an instruction class is more natural description
10460 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10461 ;; old function unit based model.
10462 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10465 ;; Two automata are defined to reduce number of states
10466 ;; which a single large automaton will have.(Factoring)
10468 (define_automaton "inst_pipeline,fpu_pipe")
10470 ;; This unit is basically the decode unit of the processor.
10471 ;; Since SH4 is a dual issue machine,it is as if there are two
10472 ;; units so that any insn can be processed by either one
10473 ;; of the decoding unit.
10475 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10478 ;; The fixed point arithmetic calculator(?? EX Unit).
10480 (define_cpu_unit "int" "inst_pipeline")
10482 ;; f1_1 and f1_2 are floating point units.Actually there is
10483 ;; a f1 unit which can overlap with other f1 unit but
10484 ;; not another F1 unit.It is as though there were two
10487 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10489 ;; The floating point units (except FS - F2 always precedes it.)
10491 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10493 ;; This is basically the MA unit of SH4
10494 ;; used in LOAD/STORE pipeline.
10496 (define_cpu_unit "memory" "inst_pipeline")
10498 ;; However, there are LS group insns that don't use it, even ones that
10499 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10500 (define_cpu_unit "load_store" "inst_pipeline")
10502 ;; The address calculator used for branch instructions.
10503 ;; This will be reserved after "issue" of branch instructions
10504 ;; and this is to make sure that no two branch instructions
10505 ;; can be issued in parallel.
10507 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10509 ;; ----------------------------------------------------
10510 ;; This reservation is to simplify the dual issue description.
10512 (define_reservation "issue" "pipe_01|pipe_02")
10514 ;; This is to express the locking of D stage.
10515 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10517 (define_reservation "d_lock" "pipe_01+pipe_02")
10519 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10520 (define_reservation "F01" "F0+F1")
10522 ;; This is to simplify description where F1,F2,FS
10523 ;; are used simultaneously.
10525 (define_reservation "fpu" "F1+F2")
10527 ;; This is to highlight the fact that f1
10528 ;; cannot overlap with F1.
10530 (exclusion_set "f1_1,f1_2" "F1")
10532 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10534 ;; Although reg moves have a latency of zero
10535 ;; we need to highlight that they use D stage
10540 (define_insn_reservation "reg_mov" 0
10541 (and (eq_attr "pipe_model" "sh4")
10542 (eq_attr "type" "move"))
10547 (define_insn_reservation "freg_mov" 0
10548 (and (eq_attr "pipe_model" "sh4")
10549 (eq_attr "type" "fmove"))
10550 "issue+load_store")
10552 ;; We don't model all pipeline stages; we model the issue ('D') stage
10553 ;; inasmuch as we allow only two instructions to issue simultanously,
10554 ;; and CO instructions prevent any simultanous issue of another instruction.
10555 ;; (This uses pipe_01 and pipe_02).
10556 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10557 ;; Double issue of EX / BR insns is prevented by using the int unit /
10558 ;; pcr_addrcalc unit in the EX stage.
10559 ;; Double issue of BR / LS instructions is prevented by using the
10560 ;; pcr_addrcalc / load_store unit in the issue cycle.
10561 ;; Double issue of FE instructions is prevented by using F0 in the first
10562 ;; pipeline stage after the first D stage.
10563 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10564 ;; (except in the cases outlined above), nor to describe the FS stage after
10567 ;; Other MT group intructions(1 step operations)
10572 (define_insn_reservation "mt" 1
10573 (and (eq_attr "pipe_model" "sh4")
10574 (eq_attr "type" "mt_group"))
10577 ;; Fixed Point Arithmetic Instructions(1 step operations)
10582 (define_insn_reservation "sh4_simple_arith" 1
10583 (and (eq_attr "pipe_model" "sh4")
10584 (eq_attr "insn_class" "ex_group"))
10587 ;; Load and store instructions have no alignment peculiarities for the SH4,
10588 ;; but they use the load-store unit, which they share with the fmove type
10589 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10590 ;; Loads have a latency of two.
10591 ;; However, call insns can only paired with a preceding insn, and have
10592 ;; a delay slot, so that we want two more insns to be scheduled between the
10593 ;; load of the function address and the call. This is equivalent to a
10594 ;; latency of three.
10595 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10596 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10597 ;; We only do this for SImode loads of general registers, to make the work
10598 ;; for ADJUST_COST easier.
10600 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10605 (define_insn_reservation "sh4_load" 2
10606 (and (eq_attr "pipe_model" "sh4")
10607 (eq_attr "type" "load,pcload"))
10608 "issue+load_store,nothing,memory")
10610 ;; calls / sfuncs need an extra instruction for their delay slot.
10611 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10612 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10613 ;; count of a dynamic shift.
10614 (define_insn_reservation "sh4_load_si" 3
10615 (and (eq_attr "pipe_model" "sh4")
10616 (eq_attr "type" "load_si,pcload_si"))
10617 "issue+load_store,nothing,memory")
10619 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10621 ;; The load latency is upped to three higher if the dependent insn does
10622 ;; double precision computation. We want the 'default' latency to reflect
10623 ;; that increased latency because otherwise the insn priorities won't
10624 ;; allow proper scheduling.
10625 (define_insn_reservation "sh4_fload" 3
10626 (and (eq_attr "pipe_model" "sh4")
10627 (eq_attr "type" "fload,pcfload"))
10628 "issue+load_store,nothing,memory")
10630 ;; (define_bypass 2 "sh4_fload" "!")
10632 (define_insn_reservation "sh4_store" 1
10633 (and (eq_attr "pipe_model" "sh4")
10634 (eq_attr "type" "store"))
10635 "issue+load_store,nothing,memory")
10637 ;; Load Store instructions.
10642 (define_insn_reservation "sh4_gp_fpul" 1
10643 (and (eq_attr "pipe_model" "sh4")
10644 (eq_attr "type" "gp_fpul"))
10645 "issue+load_store")
10647 ;; Load Store instructions.
10652 (define_insn_reservation "sh4_fpul_gp" 3
10653 (and (eq_attr "pipe_model" "sh4")
10654 (eq_attr "type" "fpul_gp"))
10655 "issue+load_store")
10657 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10659 ;; Latency when taken: 2 (or 1)
10661 ;; The latency is 1 when displacement is 0.
10662 ;; We can't really do much with the latency, even if we could express it,
10663 ;; but the pairing restrictions are useful to take into account.
10664 ;; ??? If the branch is likely, we might want to fill the delay slot;
10665 ;; if the branch is likely, but not very likely, should we pretend to use
10666 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10668 (define_insn_reservation "sh4_branch" 1
10669 (and (eq_attr "pipe_model" "sh4")
10670 (eq_attr "type" "cbranch,jump"))
10671 "issue+pcr_addrcalc")
10673 ;; Branch Far (JMP,RTS,BRAF)
10677 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10678 ;; can't be distinguished from bra for the "jump" pattern.
10680 (define_insn_reservation "sh4_return" 3
10681 (and (eq_attr "pipe_model" "sh4")
10682 (eq_attr "type" "return,jump_ind"))
10689 ;; this instruction can be executed in any of the pipelines
10690 ;; and blocks the pipeline for next 4 stages.
10692 (define_insn_reservation "sh4_return_from_exp" 5
10693 (and (eq_attr "pipe_model" "sh4")
10694 (eq_attr "type" "rte"))
10702 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10703 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10704 (define_insn_reservation "ocbwb" 6
10705 (and (eq_attr "pipe_model" "sh4")
10706 (eq_attr "type" "cwb"))
10707 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10713 ;; The SX stage is blocked for last 2 cycles.
10714 ;; OTOH, the only time that has an effect for insns generated by the compiler
10715 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10716 ;; or when we are doing a function call - and we don't do inter-function
10717 ;; scheduling. For the function call case, it's really best that we end with
10718 ;; something that models an rts.
10720 (define_insn_reservation "sh4_lds_to_pr" 3
10721 (and (eq_attr "pipe_model" "sh4")
10722 (eq_attr "type" "prset") )
10725 ;; calls introduce a longisch delay that is likely to flush the pipelines
10726 ;; of the caller's instructions. Ordinary functions tend to end with a
10727 ;; load to restore a register (in the delay slot of rts), while sfuncs
10728 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10729 ;; since there are no instructions that contend for memory access early.
10730 ;; We could, of course, provide exact scheduling information for specific
10731 ;; sfuncs, if that should prove useful.
10733 (define_insn_reservation "sh4_call" 16
10734 (and (eq_attr "pipe_model" "sh4")
10735 (eq_attr "type" "call,sfunc"))
10742 ;; The SX unit is blocked for last 2 cycles.
10744 (define_insn_reservation "ldsmem_to_pr" 3
10745 (and (eq_attr "pipe_model" "sh4")
10746 (eq_attr "type" "pload"))
10753 ;; The SX unit in second and third cycles.
10755 (define_insn_reservation "sts_from_pr" 2
10756 (and (eq_attr "pipe_model" "sh4")
10757 (eq_attr "type" "prget"))
10765 (define_insn_reservation "sh4_prstore_mem" 2
10766 (and (eq_attr "pipe_model" "sh4")
10767 (eq_attr "type" "pstore"))
10768 "d_lock*2,nothing,memory")
10774 ;; F1 is blocked for last three cycles.
10776 (define_insn_reservation "fpscr_load" 4
10777 (and (eq_attr "pipe_model" "sh4")
10778 (eq_attr "type" "gp_fpscr"))
10779 "d_lock,nothing,F1*3")
10784 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10786 ;; F1 is blocked for last three cycles.
10788 (define_insn_reservation "fpscr_load_mem" 4
10789 (and (eq_attr "pipe_model" "sh4")
10790 (eq_attr "type" "mem_fpscr"))
10791 "d_lock,nothing,(F1+memory),F1*2")
10794 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10799 (define_insn_reservation "multi" 4
10800 (and (eq_attr "pipe_model" "sh4")
10801 (eq_attr "type" "smpy,dmpy"))
10802 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10804 ;; Fixed STS from MACL / MACH
10809 (define_insn_reservation "sh4_mac_gp" 3
10810 (and (eq_attr "pipe_model" "sh4")
10811 (eq_attr "type" "mac_gp"))
10815 ;; Single precision floating point computation FCMP/EQ,
10816 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10821 (define_insn_reservation "fp_arith" 3
10822 (and (eq_attr "pipe_model" "sh4")
10823 (eq_attr "type" "fp"))
10826 (define_insn_reservation "fp_arith_ftrc" 3
10827 (and (eq_attr "pipe_model" "sh4")
10828 (eq_attr "type" "ftrc_s"))
10831 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10833 ;; Single Precision FDIV/SQRT
10835 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10837 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10839 (define_insn_reservation "fp_div" 12
10840 (and (eq_attr "pipe_model" "sh4")
10841 (eq_attr "type" "fdiv"))
10842 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10844 ;; Double Precision floating point computation
10845 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10847 ;; Latency: (3,4)/5
10850 (define_insn_reservation "dp_float" 4
10851 (and (eq_attr "pipe_model" "sh4")
10852 (eq_attr "type" "dfp_conv"))
10853 "issue,F01,F1+F2,F2")
10855 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10857 ;; Latency: (7,8)/9
10860 (define_insn_reservation "fp_double_arith" 8
10861 (and (eq_attr "pipe_model" "sh4")
10862 (eq_attr "type" "dfp_arith"))
10863 "issue,F01,F1+F2,fpu*4,F2")
10865 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10870 (define_insn_reservation "fp_double_cmp" 3
10871 (and (eq_attr "pipe_model" "sh4")
10872 (eq_attr "type" "dfp_cmp"))
10873 "d_lock,(d_lock+F01),F1+F2,F2")
10875 ;; Double precision FDIV/SQRT
10877 ;; Latency: (24,25)/26
10880 (define_insn_reservation "dp_div" 25
10881 (and (eq_attr "pipe_model" "sh4")
10882 (eq_attr "type" "dfdiv"))
10883 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10886 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10887 ;; case, we'd get a d_lock instead of issue at the end.
10888 (define_insn_reservation "arith3" 3
10889 (and (eq_attr "pipe_model" "sh4")
10890 (eq_attr "type" "arith3"))
10891 "issue,d_lock+pcr_addrcalc,issue")
10893 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10894 (define_insn_reservation "arith3b" 2
10895 (and (eq_attr "pipe_model" "sh4")
10896 (eq_attr "type" "arith3"))
10897 "issue,d_lock+pcr_addrcalc")