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 (define_insn "movsi_ie"
3412 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
3413 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3415 && (register_operand (operands[0], SImode)
3416 || register_operand (operands[1], SImode))"
3437 ! move optimized away"
3438 [(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,nil")
3439 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
3440 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3442 (define_insn "movsi_i_lowpart"
3443 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3444 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3446 && (register_operand (operands[0], SImode)
3447 || register_operand (operands[1], SImode))"
3457 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3459 (define_insn "*movsi_media"
3460 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3461 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3463 && (register_operand (operands[0], SImode)
3464 || register_operand (operands[1], SImode))"
3479 [(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")
3480 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3482 (define_insn "*movsi_media_nofpu"
3483 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3484 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3486 && (register_operand (operands[0], SImode)
3487 || register_operand (operands[1], SImode))"
3497 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3498 (set_attr "length" "4,4,8,4,4,4,4,12")])
3501 [(set (match_operand:SI 0 "arith_reg_operand" "")
3502 (match_operand:SI 1 "immediate_operand" ""))]
3503 "TARGET_SHMEDIA && reload_completed
3504 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3505 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3508 operands[2] = shallow_copy_rtx (operands[1]);
3509 PUT_MODE (operands[2], DImode);
3513 [(set (match_operand:SI 0 "register_operand" "")
3514 (match_operand:SI 1 "immediate_operand" ""))]
3515 "TARGET_SHMEDIA && reload_completed
3516 && ((GET_CODE (operands[1]) == CONST_INT
3517 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3518 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3519 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3521 (define_expand "movsi"
3522 [(set (match_operand:SI 0 "general_movdst_operand" "")
3523 (match_operand:SI 1 "general_movsrc_operand" ""))]
3525 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3527 (define_expand "ic_invalidate_line"
3528 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3529 (match_dup 1)] UNSPEC_ICACHE)
3530 (clobber (scratch:SI))])]
3531 "TARGET_HARD_SH4 || TARGET_SH5"
3536 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3539 else if (TARGET_SHCOMPACT)
3541 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3542 operands[1] = force_reg (Pmode, operands[1]);
3543 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3546 operands[0] = force_reg (Pmode, operands[0]);
3547 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3551 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3552 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3553 ;; the requirement *1*00 for associative address writes. The alignment of
3554 ;; %0 implies that its least significant bit is cleared,
3555 ;; thus we clear the V bit of a matching entry if there is one.
3556 (define_insn "ic_invalidate_line_i"
3557 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3558 (match_operand:SI 1 "register_operand" "r")]
3560 (clobber (match_scratch:SI 2 "=&r"))]
3562 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3563 [(set_attr "length" "8")
3564 (set_attr "type" "cwb")])
3566 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3567 ;; an add in the code that calculates the address.
3568 (define_insn "ic_invalidate_line_media"
3569 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3572 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3573 [(set_attr "length" "16")
3574 (set_attr "type" "invalidate_line_media")])
3576 (define_insn "ic_invalidate_line_compact"
3577 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3578 (match_operand:SI 1 "register_operand" "r")]
3580 (clobber (reg:SI PR_REG))]
3583 [(set_attr "type" "sfunc")
3584 (set_attr "needs_delay_slot" "yes")])
3586 (define_expand "initialize_trampoline"
3587 [(match_operand:SI 0 "" "")
3588 (match_operand:SI 1 "" "")
3589 (match_operand:SI 2 "" "")]
3595 tramp = force_reg (Pmode, operands[0]);
3596 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3597 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3598 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3600 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3604 (define_insn "initialize_trampoline_compact"
3605 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3606 (match_operand:SI 1 "register_operand" "r")
3607 (reg:SI R2_REG) (reg:SI R3_REG)]
3610 (clobber (reg:SI PR_REG))]
3613 [(set_attr "type" "sfunc")
3614 (set_attr "needs_delay_slot" "yes")])
3616 (define_insn "movqi_i"
3617 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3618 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3620 && (arith_reg_operand (operands[0], QImode)
3621 || arith_reg_operand (operands[1], QImode))"
3629 [(set_attr "type" "move,load,store,move,move,move")])
3631 (define_insn "*movqi_media"
3632 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3633 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3635 && (arith_reg_operand (operands[0], QImode)
3636 || arith_reg_operand (operands[1], QImode))"
3642 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3644 (define_expand "movqi"
3645 [(set (match_operand:QI 0 "general_operand" "")
3646 (match_operand:QI 1 "general_operand" ""))]
3648 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3650 (define_expand "reload_inqi"
3651 [(set (match_operand:SI 2 "" "=&r")
3652 (match_operand:QI 1 "inqhi_operand" ""))
3653 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3654 (truncate:HI (match_dup 3)))]
3658 rtx inner = XEXP (operands[1], 0);
3659 int regno = REGNO (inner);
3661 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3662 operands[1] = gen_rtx_REG (SImode, regno);
3663 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3666 (define_insn "movhi_i"
3667 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3668 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3670 && (arith_reg_operand (operands[0], HImode)
3671 || arith_reg_operand (operands[1], HImode))"
3681 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3683 (define_insn "*movhi_media"
3684 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3685 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3687 && (arith_reg_operand (operands[0], HImode)
3688 || arith_reg_operand (operands[1], HImode))"
3695 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3698 [(set (match_operand:HI 0 "register_operand" "")
3699 (match_operand:HI 1 "immediate_operand" ""))]
3700 "TARGET_SHMEDIA && reload_completed
3701 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3702 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3704 (define_expand "movhi"
3705 [(set (match_operand:HI 0 "general_movdst_operand" "")
3706 (match_operand:HI 1 "general_movsrc_operand" ""))]
3708 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3710 (define_expand "reload_inhi"
3711 [(set (match_operand:SI 2 "" "=&r")
3712 (match_operand:HI 1 "inqhi_operand" ""))
3713 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3714 (truncate:HI (match_dup 3)))]
3718 rtx inner = XEXP (operands[1], 0);
3719 int regno = REGNO (inner);
3721 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3722 operands[1] = gen_rtx_REG (SImode, regno);
3723 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3726 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3727 ;; compiled with -m2 -ml -O3 -funroll-loops
3728 (define_insn "*movdi_i"
3729 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3730 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3732 && (arith_reg_operand (operands[0], DImode)
3733 || arith_reg_operand (operands[1], DImode))"
3734 "* return output_movedouble (insn, operands, DImode);"
3735 [(set_attr "length" "4")
3736 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3738 ;; If the output is a register and the input is memory or a register, we have
3739 ;; to be careful and see which word needs to be loaded first.
3742 [(set (match_operand:DI 0 "general_movdst_operand" "")
3743 (match_operand:DI 1 "general_movsrc_operand" ""))]
3744 "TARGET_SH1 && reload_completed"
3745 [(set (match_dup 2) (match_dup 3))
3746 (set (match_dup 4) (match_dup 5))]
3751 if ((GET_CODE (operands[0]) == MEM
3752 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3753 || (GET_CODE (operands[1]) == MEM
3754 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3757 if (GET_CODE (operands[0]) == REG)
3758 regno = REGNO (operands[0]);
3759 else if (GET_CODE (operands[0]) == SUBREG)
3760 regno = subreg_regno (operands[0]);
3761 else if (GET_CODE (operands[0]) == MEM)
3767 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3769 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3770 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3771 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3772 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3776 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3777 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3778 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3779 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3782 if (operands[2] == 0 || operands[3] == 0
3783 || operands[4] == 0 || operands[5] == 0)
3787 (define_insn "*movdi_media"
3788 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3789 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3791 && (register_operand (operands[0], DImode)
3792 || register_operand (operands[1], DImode))"
3807 [(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")
3808 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3810 (define_insn "*movdi_media_nofpu"
3811 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3812 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3814 && (register_operand (operands[0], DImode)
3815 || register_operand (operands[1], DImode))"
3825 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3826 (set_attr "length" "4,4,16,4,4,4,4,*")])
3829 [(set (match_operand:DI 0 "arith_reg_operand" "")
3830 (match_operand:DI 1 "immediate_operand" ""))]
3831 "TARGET_SHMEDIA && reload_completed
3832 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3833 [(set (match_dup 0) (match_dup 1))]
3838 if (TARGET_SHMEDIA64)
3839 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3841 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3843 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3849 (define_expand "movdi_const"
3850 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3851 (const:DI (sign_extend:DI
3854 (match_operand:DI 1 "immediate_operand" "s")
3857 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3865 (const_int 32)))))))))
3867 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3875 (const_int 16)))))))))
3877 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3883 (match_dup 1))))))))]
3884 "TARGET_SHMEDIA64 && reload_completed
3885 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3888 sh_mark_label (operands[1], 4);
3891 (define_expand "movdi_const_32bit"
3892 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3893 (const:DI (sign_extend:DI
3896 (match_operand:DI 1 "immediate_operand" "s")
3899 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3905 (match_dup 1))))))))]
3906 "TARGET_SHMEDIA32 && reload_completed
3907 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3910 sh_mark_label (operands[1], 2);
3913 (define_expand "movdi_const_16bit"
3914 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3915 (const:DI (sign_extend:DI
3917 (match_operand:DI 1 "immediate_operand" "s")))))]
3918 "TARGET_SHMEDIA && flag_pic && reload_completed
3919 && GET_CODE (operands[1]) == SYMBOL_REF"
3923 [(set (match_operand:DI 0 "arith_reg_operand" "")
3924 (match_operand:DI 1 "immediate_operand" ""))]
3925 "TARGET_SHMEDIA && reload_completed
3926 && GET_CODE (operands[1]) == CONST_INT
3927 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3928 [(set (match_dup 0) (match_dup 2))
3932 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3933 unsigned HOST_WIDE_INT low = val;
3934 unsigned HOST_WIDE_INT high = val;
3935 unsigned HOST_WIDE_INT sign;
3936 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3938 /* Sign-extend the 16 least-significant bits. */
3943 /* Arithmetic shift right the word by 16 bits. */
3946 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3951 /* If we can't generate the constant with a two-insn movi / shori
3952 sequence, try some other strategies. */
3953 if (! CONST_OK_FOR_J (high))
3955 /* Try constant load / left shift. We know VAL != 0. */
3956 val2 = val ^ (val-1);
3959 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3961 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3962 || (! CONST_OK_FOR_J (high >> 16)
3963 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3965 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3966 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3967 GEN_INT (trailing_zeroes));
3971 /* Try constant load / right shift. */
3972 val2 = (val >> 15) + 1;
3973 if (val2 == (val2 & -val2))
3975 int shift = 49 - exact_log2 (val2);
3977 val2 = trunc_int_for_mode (val << shift, DImode);
3978 if (CONST_OK_FOR_J (val2))
3980 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3986 val2 = val & 0xffff;
3987 if ((val >> 16 & 0xffff) == val2
3988 && (val >> 32 & 0xffff) == val2
3989 && (val >> 48 & 0xffff) == val2)
3991 val2 = (HOST_WIDE_INT) val >> 48;
3992 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3993 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3996 /* Try movi / mshflo.l */
3997 val2 = (HOST_WIDE_INT) val >> 32;
3998 if (val2 == trunc_int_for_mode (val, SImode))
4000 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4004 /* Try movi / mshflo.l w/ r63. */
4005 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4006 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4008 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4014 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4017 operands[2] = GEN_INT (val2);
4021 [(set (match_operand:DI 0 "arith_reg_operand" "")
4022 (match_operand:DI 1 "immediate_operand" ""))]
4023 "TARGET_SHMEDIA && reload_completed
4024 && GET_CODE (operands[1]) == CONST_DOUBLE"
4025 [(set (match_dup 0) (match_dup 2))
4027 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4028 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4031 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4032 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4033 unsigned HOST_WIDE_INT val = low;
4034 unsigned HOST_WIDE_INT sign;
4036 /* Sign-extend the 16 least-significant bits. */
4040 operands[1] = GEN_INT (val);
4042 /* Arithmetic shift right the double-word by 16 bits. */
4044 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4047 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4051 /* This will only be true if high is a sign-extension of low, i.e.,
4052 it must be either 0 or (unsigned)-1, and be zero iff the
4053 most-significant bit of low is set. */
4054 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4055 operands[2] = GEN_INT (low);
4057 operands[2] = immed_double_const (low, high, DImode);
4060 (define_insn "shori_media"
4061 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4062 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4066 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4071 [(set_attr "type" "arith_media,*")])
4073 (define_expand "movdi"
4074 [(set (match_operand:DI 0 "general_movdst_operand" "")
4075 (match_operand:DI 1 "general_movsrc_operand" ""))]
4077 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4079 (define_insn "movdf_media"
4080 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4081 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4083 && (register_operand (operands[0], DFmode)
4084 || register_operand (operands[1], DFmode))"
4095 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4097 (define_insn "movdf_media_nofpu"
4098 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4099 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4101 && (register_operand (operands[0], DFmode)
4102 || register_operand (operands[1], DFmode))"
4108 [(set_attr "type" "arith_media,*,load_media,store_media")])
4111 [(set (match_operand:DF 0 "arith_reg_operand" "")
4112 (match_operand:DF 1 "immediate_operand" ""))]
4113 "TARGET_SHMEDIA && reload_completed"
4114 [(set (match_dup 3) (match_dup 2))]
4117 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4119 REAL_VALUE_TYPE value;
4121 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4122 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4124 if (HOST_BITS_PER_WIDE_INT >= 64)
4125 operands[2] = immed_double_const ((unsigned long) values[endian]
4126 | ((HOST_WIDE_INT) values[1 - endian]
4128 else if (HOST_BITS_PER_WIDE_INT == 32)
4129 operands[2] = immed_double_const (values[endian], values[1 - endian],
4134 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4137 ;; ??? This should be a define expand.
4139 (define_insn "movdf_k"
4140 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4141 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4143 && (! TARGET_SH4 || reload_completed
4144 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4145 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4146 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4147 && (arith_reg_operand (operands[0], DFmode)
4148 || arith_reg_operand (operands[1], DFmode))"
4149 "* return output_movedouble (insn, operands, DFmode);"
4150 [(set_attr "length" "4")
4151 (set_attr "type" "move,pcload,load,store")])
4153 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4154 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4155 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4156 ;; the d/m/c/X alternative, which is split later into single-precision
4157 ;; instructions. And when not optimizing, no splits are done before fixing
4158 ;; up pcloads, so we need usable length information for that.
4159 (define_insn "movdf_i4"
4160 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4161 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4162 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4163 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4165 && (arith_reg_operand (operands[0], DFmode)
4166 || arith_reg_operand (operands[1], DFmode))"
4178 [(set_attr_alternative "length"
4179 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4181 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4182 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4183 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4185 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4186 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4187 ;; increment or decrement r15 explicitly.
4189 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4190 (const_int 10) (const_int 8))
4192 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4193 (const_int 10) (const_int 8))])
4194 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4195 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4196 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4197 (const_string "double")
4198 (const_string "none")))])
4200 ;; Moving DFmode between fp/general registers through memory
4201 ;; (the top of the stack) is faster than moving through fpul even for
4202 ;; little endian. Because the type of an instruction is important for its
4203 ;; scheduling, it is beneficial to split these operations, rather than
4204 ;; emitting them in one single chunk, even if this will expose a stack
4205 ;; use that will prevent scheduling of other stack accesses beyond this
4208 [(set (match_operand:DF 0 "register_operand" "")
4209 (match_operand:DF 1 "register_operand" ""))
4210 (use (match_operand:PSI 2 "fpscr_operand" ""))
4211 (clobber (match_scratch:SI 3 "=X"))]
4212 "TARGET_SH4 && reload_completed
4213 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4219 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4221 emit_move_insn (stack_pointer_rtx,
4222 plus_constant (stack_pointer_rtx, -8));
4223 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4226 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4227 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4228 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4229 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4230 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4231 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4233 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4234 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4235 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4236 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4238 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4242 ;; local-alloc sometimes allocates scratch registers even when not required,
4243 ;; so we must be prepared to handle these.
4245 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4247 [(set (match_operand:DF 0 "general_movdst_operand" "")
4248 (match_operand:DF 1 "general_movsrc_operand" ""))
4249 (use (match_operand:PSI 2 "fpscr_operand" ""))
4250 (clobber (match_scratch:SI 3 ""))]
4253 && true_regnum (operands[0]) < 16
4254 && true_regnum (operands[1]) < 16"
4255 [(set (match_dup 0) (match_dup 1))]
4258 /* If this was a reg <-> mem operation with base + index reg addressing,
4259 we have to handle this in a special way. */
4260 rtx mem = operands[0];
4262 if (! memory_operand (mem, DFmode))
4267 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4268 mem = SUBREG_REG (mem);
4269 if (GET_CODE (mem) == MEM)
4271 rtx addr = XEXP (mem, 0);
4272 if (GET_CODE (addr) == PLUS
4273 && GET_CODE (XEXP (addr, 0)) == REG
4274 && GET_CODE (XEXP (addr, 1)) == REG)
4277 rtx reg0 = gen_rtx (REG, Pmode, 0);
4278 rtx regop = operands[store_p], word0 ,word1;
4280 if (GET_CODE (regop) == SUBREG)
4281 alter_subreg (®op);
4282 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4286 mem = copy_rtx (mem);
4287 PUT_MODE (mem, SImode);
4288 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4289 alter_subreg (&word0);
4290 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4291 alter_subreg (&word1);
4292 if (store_p || ! refers_to_regno_p (REGNO (word0),
4293 REGNO (word0) + 1, addr, 0))
4296 ? gen_movsi_ie (mem, word0)
4297 : gen_movsi_ie (word0, mem));
4298 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4299 mem = copy_rtx (mem);
4301 ? gen_movsi_ie (mem, word1)
4302 : gen_movsi_ie (word1, mem));
4303 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4307 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4308 emit_insn (gen_movsi_ie (word1, mem));
4309 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4310 mem = copy_rtx (mem);
4311 emit_insn (gen_movsi_ie (word0, mem));
4318 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4320 [(set (match_operand:DF 0 "register_operand" "")
4321 (match_operand:DF 1 "memory_operand" ""))
4322 (use (match_operand:PSI 2 "fpscr_operand" ""))
4323 (clobber (reg:SI R0_REG))]
4324 "TARGET_SH4 && reload_completed"
4325 [(parallel [(set (match_dup 0) (match_dup 1))
4327 (clobber (scratch:SI))])]
4330 (define_expand "reload_indf"
4331 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4332 (match_operand:DF 1 "immediate_operand" "FQ"))
4333 (use (reg:PSI FPSCR_REG))
4334 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4338 (define_expand "reload_outdf"
4339 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4340 (match_operand:DF 1 "register_operand" "af,r"))
4341 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4345 ;; Simplify no-op moves.
4347 [(set (match_operand:SF 0 "register_operand" "")
4348 (match_operand:SF 1 "register_operand" ""))
4349 (use (match_operand:PSI 2 "fpscr_operand" ""))
4350 (clobber (match_scratch:SI 3 "X"))]
4351 "TARGET_SH3E && reload_completed
4352 && true_regnum (operands[0]) == true_regnum (operands[1])"
4353 [(set (match_dup 0) (match_dup 0))]
4356 ;; fmovd substitute post-reload splits
4358 [(set (match_operand:DF 0 "register_operand" "")
4359 (match_operand:DF 1 "register_operand" ""))
4360 (use (match_operand:PSI 2 "fpscr_operand" ""))
4361 (clobber (match_scratch:SI 3 "X"))]
4362 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4363 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4364 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4368 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4369 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4370 gen_rtx (REG, SFmode, src), operands[2]));
4371 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4372 gen_rtx (REG, SFmode, src + 1), operands[2]));
4377 [(set (match_operand:DF 0 "register_operand" "")
4378 (mem:DF (match_operand:SI 1 "register_operand" "")))
4379 (use (match_operand:PSI 2 "fpscr_operand" ""))
4380 (clobber (match_scratch:SI 3 ""))]
4381 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4382 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4383 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4387 int regno = true_regnum (operands[0]);
4389 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4391 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4392 regno + !! TARGET_LITTLE_ENDIAN),
4393 mem2, operands[2]));
4394 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4395 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4396 regno + ! TARGET_LITTLE_ENDIAN),
4397 gen_rtx (MEM, SFmode, operands[1]),
4403 [(set (match_operand:DF 0 "register_operand" "")
4404 (match_operand:DF 1 "memory_operand" ""))
4405 (use (match_operand:PSI 2 "fpscr_operand" ""))
4406 (clobber (match_scratch:SI 3 ""))]
4407 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4408 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4412 int regno = true_regnum (operands[0]);
4413 rtx addr, insn, adjust = NULL_RTX;
4414 rtx mem2 = copy_rtx (operands[1]);
4415 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4416 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4418 PUT_MODE (mem2, SFmode);
4419 operands[1] = copy_rtx (mem2);
4420 addr = XEXP (mem2, 0);
4421 if (GET_CODE (addr) != POST_INC)
4423 /* If we have to modify the stack pointer, the value that we have
4424 read with post-increment might be modified by an interrupt,
4425 so write it back. */
4426 if (REGNO (addr) == STACK_POINTER_REGNUM)
4427 adjust = gen_push_e (reg0);
4429 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4430 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4432 addr = XEXP (addr, 0);
4433 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4434 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4435 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4439 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4444 [(set (match_operand:DF 0 "memory_operand" "")
4445 (match_operand:DF 1 "register_operand" ""))
4446 (use (match_operand:PSI 2 "fpscr_operand" ""))
4447 (clobber (match_scratch:SI 3 ""))]
4448 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4449 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4453 int regno = true_regnum (operands[1]);
4454 rtx insn, addr, adjust = NULL_RTX;
4456 operands[0] = copy_rtx (operands[0]);
4457 PUT_MODE (operands[0], SFmode);
4458 insn = emit_insn (gen_movsf_ie (operands[0],
4459 gen_rtx (REG, SFmode,
4460 regno + ! TARGET_LITTLE_ENDIAN),
4462 operands[0] = copy_rtx (operands[0]);
4463 addr = XEXP (operands[0], 0);
4464 if (GET_CODE (addr) != PRE_DEC)
4466 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4467 emit_insn_before (adjust, insn);
4468 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4470 addr = XEXP (addr, 0);
4472 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4473 insn = emit_insn (gen_movsf_ie (operands[0],
4474 gen_rtx (REG, SFmode,
4475 regno + !! TARGET_LITTLE_ENDIAN),
4477 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4481 ;; If the output is a register and the input is memory or a register, we have
4482 ;; to be careful and see which word needs to be loaded first.
4485 [(set (match_operand:DF 0 "general_movdst_operand" "")
4486 (match_operand:DF 1 "general_movsrc_operand" ""))]
4487 "TARGET_SH1 && reload_completed"
4488 [(set (match_dup 2) (match_dup 3))
4489 (set (match_dup 4) (match_dup 5))]
4494 if ((GET_CODE (operands[0]) == MEM
4495 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4496 || (GET_CODE (operands[1]) == MEM
4497 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4500 if (GET_CODE (operands[0]) == REG)
4501 regno = REGNO (operands[0]);
4502 else if (GET_CODE (operands[0]) == SUBREG)
4503 regno = subreg_regno (operands[0]);
4504 else if (GET_CODE (operands[0]) == MEM)
4510 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4512 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4513 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4514 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4515 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4519 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4520 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4521 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4522 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4525 if (operands[2] == 0 || operands[3] == 0
4526 || operands[4] == 0 || operands[5] == 0)
4530 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4531 ;; used only once, let combine add in the index again.
4534 [(set (match_operand:SI 0 "register_operand" "")
4535 (match_operand:SI 1 "" ""))
4536 (clobber (match_operand 2 "register_operand" ""))]
4537 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4538 [(use (reg:SI R0_REG))]
4541 rtx addr, reg, const_int;
4543 if (GET_CODE (operands[1]) != MEM)
4545 addr = XEXP (operands[1], 0);
4546 if (GET_CODE (addr) != PLUS)
4548 reg = XEXP (addr, 0);
4549 const_int = XEXP (addr, 1);
4550 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4551 && GET_CODE (const_int) == CONST_INT))
4553 emit_move_insn (operands[2], const_int);
4554 emit_move_insn (operands[0],
4555 change_address (operands[1], VOIDmode,
4556 gen_rtx_PLUS (SImode, reg, operands[2])));
4561 [(set (match_operand:SI 1 "" "")
4562 (match_operand:SI 0 "register_operand" ""))
4563 (clobber (match_operand 2 "register_operand" ""))]
4564 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4565 [(use (reg:SI R0_REG))]
4568 rtx addr, reg, const_int;
4570 if (GET_CODE (operands[1]) != MEM)
4572 addr = XEXP (operands[1], 0);
4573 if (GET_CODE (addr) != PLUS)
4575 reg = XEXP (addr, 0);
4576 const_int = XEXP (addr, 1);
4577 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4578 && GET_CODE (const_int) == CONST_INT))
4580 emit_move_insn (operands[2], const_int);
4581 emit_move_insn (change_address (operands[1], VOIDmode,
4582 gen_rtx_PLUS (SImode, reg, operands[2])),
4587 (define_expand "movdf"
4588 [(set (match_operand:DF 0 "general_movdst_operand" "")
4589 (match_operand:DF 1 "general_movsrc_operand" ""))]
4593 if (prepare_move_operands (operands, DFmode)) DONE;
4596 if (TARGET_SHMEDIA_FPU)
4597 emit_insn (gen_movdf_media (operands[0], operands[1]));
4599 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4604 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4609 ;;This is incompatible with the way gcc uses subregs.
4610 ;;(define_insn "movv2sf_i"
4611 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4612 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4613 ;; "TARGET_SHMEDIA_FPU
4614 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4615 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4619 ;; fst%M0.p %m0, %1"
4620 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4622 (define_insn_and_split "movv2sf_i"
4623 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4624 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4625 "TARGET_SHMEDIA_FPU"
4627 "TARGET_SHMEDIA_FPU && reload_completed"
4628 [(set (match_dup 0) (match_dup 1))]
4631 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4632 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4635 (define_expand "movv2sf"
4636 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4637 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4638 "TARGET_SHMEDIA_FPU"
4641 if (prepare_move_operands (operands, V2SFmode))
4645 (define_expand "addv2sf3"
4646 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4647 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4648 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4649 "TARGET_SHMEDIA_FPU"
4652 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4656 (define_expand "subv2sf3"
4657 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4658 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4659 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4660 "TARGET_SHMEDIA_FPU"
4663 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4667 (define_expand "mulv2sf3"
4668 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4669 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4670 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4671 "TARGET_SHMEDIA_FPU"
4674 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4678 (define_expand "divv2sf3"
4679 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4680 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4681 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4682 "TARGET_SHMEDIA_FPU"
4685 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4689 (define_insn_and_split "*movv4sf_i"
4690 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4691 (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4692 "TARGET_SHMEDIA_FPU"
4694 "&& reload_completed"
4700 for (i = 0; i < 4/2; i++)
4704 if (GET_CODE (operands[0]) == MEM)
4705 x = gen_rtx_MEM (V2SFmode,
4706 plus_constant (XEXP (operands[0], 0),
4707 i * GET_MODE_SIZE (V2SFmode)));
4709 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4711 if (GET_CODE (operands[1]) == MEM)
4712 y = gen_rtx_MEM (V2SFmode,
4713 plus_constant (XEXP (operands[1], 0),
4714 i * GET_MODE_SIZE (V2SFmode)));
4716 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4718 emit_insn (gen_movv2sf_i (x, y));
4723 [(set_attr "length" "8")])
4725 (define_expand "movv4sf"
4726 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4727 (match_operand:V4SF 1 "general_operand" ""))]
4728 "TARGET_SHMEDIA_FPU"
4731 if (prepare_move_operands (operands, V4SFmode))
4735 (define_insn_and_split "*movv16sf_i"
4736 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4737 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4738 "TARGET_SHMEDIA_FPU"
4740 "&& reload_completed"
4746 for (i = 0; i < 16/2; i++)
4750 if (GET_CODE (operands[0]) == MEM)
4751 x = gen_rtx_MEM (V2SFmode,
4752 plus_constant (XEXP (operands[0], 0),
4753 i * GET_MODE_SIZE (V2SFmode)));
4756 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4760 if (GET_CODE (operands[1]) == MEM)
4761 y = gen_rtx_MEM (V2SFmode,
4762 plus_constant (XEXP (operands[1], 0),
4763 i * GET_MODE_SIZE (V2SFmode)));
4766 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4770 emit_insn (gen_movv2sf_i (x, y));
4775 [(set_attr "length" "32")])
4777 (define_expand "movv16sf"
4778 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4779 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4780 "TARGET_SHMEDIA_FPU"
4783 if (prepare_move_operands (operands, V16SFmode))
4787 (define_insn "movsf_media"
4788 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4789 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4791 && (register_operand (operands[0], SFmode)
4792 || register_operand (operands[1], SFmode))"
4803 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4805 (define_insn "movsf_media_nofpu"
4806 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4807 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4809 && (register_operand (operands[0], SFmode)
4810 || register_operand (operands[1], SFmode))"
4816 [(set_attr "type" "arith_media,*,load_media,store_media")])
4819 [(set (match_operand:SF 0 "arith_reg_operand" "")
4820 (match_operand:SF 1 "immediate_operand" ""))]
4821 "TARGET_SHMEDIA && reload_completed
4822 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4823 [(set (match_dup 3) (match_dup 2))]
4827 REAL_VALUE_TYPE value;
4829 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4830 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4831 operands[2] = GEN_INT (values);
4833 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4836 (define_insn "movsf_i"
4837 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4838 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4841 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4842 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4843 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4844 && (arith_reg_operand (operands[0], SFmode)
4845 || arith_reg_operand (operands[1], SFmode))"
4854 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4856 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4857 ;; update_flow_info would not know where to put REG_EQUAL notes
4858 ;; when the destination changes mode.
4859 (define_insn "movsf_ie"
4860 [(set (match_operand:SF 0 "general_movdst_operand"
4861 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4862 (match_operand:SF 1 "general_movsrc_operand"
4863 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4864 (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"))
4865 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4868 && (arith_reg_operand (operands[0], SFmode)
4869 || arith_reg_operand (operands[1], SFmode)
4870 || arith_reg_operand (operands[3], SImode)
4871 || (fpul_operand (operands[0], SFmode)
4872 && memory_operand (operands[1], SFmode)
4873 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4874 || (fpul_operand (operands[1], SFmode)
4875 && memory_operand (operands[0], SFmode)
4876 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4896 ! move optimized away"
4897 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4898 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4899 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4900 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4901 (const_string "single")
4902 (const_string "none")))])
4905 [(set (match_operand:SF 0 "register_operand" "")
4906 (match_operand:SF 1 "register_operand" ""))
4907 (use (match_operand:PSI 2 "fpscr_operand" ""))
4908 (clobber (reg:SI FPUL_REG))]
4910 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4912 (clobber (scratch:SI))])
4913 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4915 (clobber (scratch:SI))])]
4918 (define_expand "movsf"
4919 [(set (match_operand:SF 0 "general_movdst_operand" "")
4920 (match_operand:SF 1 "general_movsrc_operand" ""))]
4924 if (prepare_move_operands (operands, SFmode))
4928 if (TARGET_SHMEDIA_FPU)
4929 emit_insn (gen_movsf_media (operands[0], operands[1]));
4931 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4936 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4941 (define_insn "mov_nop"
4942 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4945 [(set_attr "length" "0")
4946 (set_attr "type" "nil")])
4948 (define_expand "reload_insf"
4949 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4950 (match_operand:SF 1 "immediate_operand" "FQ"))
4951 (use (reg:PSI FPSCR_REG))
4952 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4956 (define_expand "reload_insi"
4957 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4958 (match_operand:SF 1 "immediate_operand" "FQ"))
4959 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4963 (define_insn "*movsi_y"
4964 [(set (match_operand:SI 0 "register_operand" "=y,y")
4965 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4966 (clobber (match_scratch:SI 2 "=&z,r"))]
4968 && (reload_in_progress || reload_completed)"
4970 [(set_attr "length" "4")
4971 (set_attr "type" "pcload,move")])
4974 [(set (match_operand:SI 0 "register_operand" "")
4975 (match_operand:SI 1 "immediate_operand" ""))
4976 (clobber (match_operand:SI 2 "register_operand" ""))]
4978 [(set (match_dup 2) (match_dup 1))
4979 (set (match_dup 0) (match_dup 2))]
4983 [(set (match_operand:SI 0 "register_operand" "")
4984 (match_operand:SI 1 "memory_operand" ""))
4985 (clobber (reg:SI R0_REG))]
4987 [(set (match_dup 0) (match_dup 1))]
4990 ;; ------------------------------------------------------------------------
4991 ;; Define the real conditional branch instructions.
4992 ;; ------------------------------------------------------------------------
4994 (define_insn "branch_true"
4995 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4996 (label_ref (match_operand 0 "" ""))
4999 "* return output_branch (1, insn, operands);"
5000 [(set_attr "type" "cbranch")])
5002 (define_insn "branch_false"
5003 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5004 (label_ref (match_operand 0 "" ""))
5007 "* return output_branch (0, insn, operands);"
5008 [(set_attr "type" "cbranch")])
5010 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5011 ;; which destination is too far away.
5012 ;; The const_int_operand is distinct for each branch target; it avoids
5013 ;; unwanted matches with redundant_insn.
5014 (define_insn "block_branch_redirect"
5015 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5018 [(set_attr "length" "0")])
5020 ;; This one has the additional purpose to record a possible scratch register
5021 ;; for the following branch.
5022 (define_insn "indirect_jump_scratch"
5023 [(set (match_operand:SI 0 "register_operand" "=r")
5024 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5027 [(set_attr "length" "0")])
5029 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5030 ;; being pulled into the delay slot of a condbranch that has been made to
5031 ;; jump around the unconditional jump because it was out of range.
5032 (define_insn "stuff_delay_slot"
5034 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5035 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5038 [(set_attr "length" "0")
5039 (set_attr "cond_delay_slot" "yes")])
5041 ;; Conditional branch insns
5043 (define_expand "beq_media"
5045 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5046 (match_operand:DI 2 "arith_operand" "r,O"))
5047 (label_ref:DI (match_operand 0 "" ""))
5052 (define_insn "*beq_media_i"
5054 (if_then_else (match_operator 3 "equality_comparison_operator"
5055 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5056 (match_operand:DI 2 "arith_operand" "r,O")])
5057 (match_operand:DI 0 "target_operand" "b,b")
5063 [(set_attr "type" "cbranch_media")])
5065 (define_expand "bne_media"
5067 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5068 (match_operand:DI 2 "arith_operand" "r,O"))
5069 (label_ref:DI (match_operand 0 "" ""))
5074 (define_expand "bgt_media"
5076 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5077 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5078 (label_ref:DI (match_operand 0 "" ""))
5083 (define_expand "bge_media"
5085 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5086 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5087 (label_ref:DI (match_operand 0 "" ""))
5092 (define_expand "bgtu_media"
5094 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5095 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5096 (label_ref:DI (match_operand 0 "" ""))
5101 (define_expand "bgeu_media"
5103 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5104 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5105 (label_ref:DI (match_operand 0 "" ""))
5110 (define_insn "*bgt_media_i"
5112 (if_then_else (match_operator 3 "greater_comparison_operator"
5113 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5114 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5115 (match_operand:DI 0 "target_operand" "b")
5118 "b%o3%' %N1, %N2, %0"
5119 [(set_attr "type" "cbranch_media")])
5121 ;; These are only needed to make invert_jump() happy.
5122 (define_insn "*blt_media_i"
5124 (if_then_else (match_operator 3 "less_comparison_operator"
5125 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5126 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5127 (match_operand:DI 0 "target_operand" "b")
5130 "b%o3%' %N2, %N1, %0"
5131 [(set_attr "type" "cbranch_media")])
5133 (define_expand "beq"
5135 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5136 (label_ref (match_operand 0 "" ""))
5143 if (GET_MODE (sh_compare_op0) != DImode)
5145 rtx tmp = gen_reg_rtx (DImode);
5147 emit_insn (gen_seq (tmp));
5148 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5152 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5153 emit_jump_insn (gen_beq_media (operands[0],
5154 sh_compare_op0, sh_compare_op1));
5158 from_compare (operands, EQ);
5161 (define_expand "bne"
5163 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5164 (label_ref (match_operand 0 "" ""))
5171 if (GET_MODE (sh_compare_op0) != DImode)
5173 rtx tmp = gen_reg_rtx (DImode);
5175 emit_insn (gen_seq (tmp));
5176 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5180 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5181 emit_jump_insn (gen_bne_media (operands[0],
5182 sh_compare_op0, sh_compare_op1));
5186 from_compare (operands, EQ);
5189 (define_expand "bgt"
5191 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5192 (label_ref (match_operand 0 "" ""))
5199 if (GET_MODE (sh_compare_op0) != DImode)
5201 rtx tmp = gen_reg_rtx (DImode);
5203 emit_insn (gen_sgt (tmp));
5204 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5208 if (sh_compare_op0 != const0_rtx)
5209 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5210 if (sh_compare_op1 != const0_rtx)
5211 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5212 emit_jump_insn (gen_bgt_media (operands[0],
5213 sh_compare_op0, sh_compare_op1));
5217 from_compare (operands, GT);
5220 (define_expand "blt"
5222 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5223 (label_ref (match_operand 0 "" ""))
5230 if (GET_MODE (sh_compare_op0) != DImode)
5232 rtx tmp = gen_reg_rtx (DImode);
5234 emit_insn (gen_slt (tmp));
5235 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5239 if (sh_compare_op0 != const0_rtx)
5240 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5241 if (sh_compare_op1 != const0_rtx)
5242 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5243 emit_jump_insn (gen_bgt_media (operands[0],
5244 sh_compare_op1, sh_compare_op0));
5248 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5250 rtx tmp = sh_compare_op0;
5251 sh_compare_op0 = sh_compare_op1;
5252 sh_compare_op1 = tmp;
5253 emit_insn (gen_bgt (operands[0]));
5256 from_compare (operands, GE);
5259 (define_expand "ble"
5261 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5262 (label_ref (match_operand 0 "" ""))
5269 if (GET_MODE (sh_compare_op0) != DImode)
5271 rtx tmp = gen_reg_rtx (DImode);
5273 emit_insn (gen_sle (tmp));
5274 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5278 if (sh_compare_op0 != const0_rtx)
5279 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5280 if (sh_compare_op1 != const0_rtx)
5281 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5282 emit_jump_insn (gen_bge_media (operands[0],
5283 sh_compare_op1, sh_compare_op0));
5289 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5291 rtx tmp = sh_compare_op0;
5292 sh_compare_op0 = sh_compare_op1;
5293 sh_compare_op1 = tmp;
5294 emit_insn (gen_bge (operands[0]));
5297 from_compare (operands, GT);
5300 (define_expand "bge"
5302 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5303 (label_ref (match_operand 0 "" ""))
5310 if (GET_MODE (sh_compare_op0) != DImode)
5312 rtx tmp = gen_reg_rtx (DImode);
5314 emit_insn (gen_sge (tmp));
5315 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5319 if (sh_compare_op0 != const0_rtx)
5320 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5321 if (sh_compare_op1 != const0_rtx)
5322 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5323 emit_jump_insn (gen_bge_media (operands[0],
5324 sh_compare_op0, sh_compare_op1));
5330 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5332 rtx tmp = sh_compare_op0;
5333 sh_compare_op0 = sh_compare_op1;
5334 sh_compare_op1 = tmp;
5335 emit_insn (gen_ble (operands[0]));
5338 from_compare (operands, GE);
5341 (define_expand "bgtu"
5343 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5344 (label_ref (match_operand 0 "" ""))
5351 if (sh_compare_op0 != const0_rtx)
5352 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5353 if (sh_compare_op1 != const0_rtx)
5354 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5355 emit_jump_insn (gen_bgtu_media (operands[0],
5356 sh_compare_op0, sh_compare_op1));
5360 from_compare (operands, GTU);
5363 (define_expand "bltu"
5365 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5366 (label_ref (match_operand 0 "" ""))
5373 if (sh_compare_op0 != const0_rtx)
5374 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5375 if (sh_compare_op1 != const0_rtx)
5376 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5377 emit_jump_insn (gen_bgtu_media (operands[0],
5378 sh_compare_op1, sh_compare_op0));
5382 from_compare (operands, GEU);
5385 (define_expand "bgeu"
5387 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5388 (label_ref (match_operand 0 "" ""))
5395 if (sh_compare_op0 != const0_rtx)
5396 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5397 if (sh_compare_op1 != const0_rtx)
5398 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5399 emit_jump_insn (gen_bgeu_media (operands[0],
5400 sh_compare_op0, sh_compare_op1));
5404 from_compare (operands, GEU);
5407 (define_expand "bleu"
5409 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5410 (label_ref (match_operand 0 "" ""))
5417 if (sh_compare_op0 != const0_rtx)
5418 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5419 if (sh_compare_op1 != const0_rtx)
5420 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5421 emit_jump_insn (gen_bgeu_media (operands[0],
5422 sh_compare_op1, sh_compare_op0));
5426 from_compare (operands, GTU);
5429 (define_expand "bunordered"
5430 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5432 (if_then_else (ne (match_dup 1) (const_int 0))
5433 (label_ref:DI (match_operand 0 "" ""))
5438 operands[1] = gen_reg_rtx (DImode);
5439 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5440 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5443 ;; ------------------------------------------------------------------------
5444 ;; Jump and linkage insns
5445 ;; ------------------------------------------------------------------------
5447 (define_insn "jump_compact"
5449 (label_ref (match_operand 0 "" "")))]
5453 /* The length is 16 if the delay slot is unfilled. */
5454 if (get_attr_length(insn) > 4)
5455 return output_far_jump(insn, operands[0]);
5457 return \"bra %l0%#\";
5459 [(set_attr "type" "jump")
5460 (set_attr "needs_delay_slot" "yes")])
5462 (define_insn "jump_media"
5464 (match_operand:DI 0 "target_operand" "b"))]
5467 [(set_attr "type" "jump_media")])
5469 (define_expand "jump"
5471 (label_ref (match_operand 0 "" "")))]
5476 emit_jump_insn (gen_jump_compact (operands[0]));
5477 else if (TARGET_SHMEDIA)
5479 if (reload_in_progress || reload_completed)
5481 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5487 (define_insn "force_mode_for_call"
5488 [(use (reg:PSI FPSCR_REG))]
5491 [(set_attr "length" "0")
5492 (set (attr "fp_mode")
5493 (if_then_else (eq_attr "fpu_single" "yes")
5494 (const_string "single") (const_string "double")))])
5496 (define_insn "calli"
5497 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5498 (match_operand 1 "" ""))
5499 (use (reg:PSI FPSCR_REG))
5500 (clobber (reg:SI PR_REG))]
5503 [(set_attr "type" "call")
5504 (set (attr "fp_mode")
5505 (if_then_else (eq_attr "fpu_single" "yes")
5506 (const_string "single") (const_string "double")))
5507 (set_attr "needs_delay_slot" "yes")])
5509 ;; This is a pc-rel call, using bsrf, for use with PIC.
5511 (define_insn "calli_pcrel"
5512 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5513 (match_operand 1 "" ""))
5514 (use (reg:PSI FPSCR_REG))
5515 (use (reg:SI PIC_REG))
5516 (use (match_operand 2 "" ""))
5517 (clobber (reg:SI PR_REG))]
5520 [(set_attr "type" "call")
5521 (set (attr "fp_mode")
5522 (if_then_else (eq_attr "fpu_single" "yes")
5523 (const_string "single") (const_string "double")))
5524 (set_attr "needs_delay_slot" "yes")])
5526 (define_insn_and_split "call_pcrel"
5527 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5528 (match_operand 1 "" ""))
5529 (use (reg:PSI FPSCR_REG))
5530 (use (reg:SI PIC_REG))
5531 (clobber (reg:SI PR_REG))
5532 (clobber (match_scratch:SI 2 "=r"))]
5539 rtx lab = PATTERN (gen_call_site ());
5541 if (SYMBOL_REF_FLAG (operands[0]))
5542 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5544 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5545 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5548 [(set_attr "type" "call")
5549 (set (attr "fp_mode")
5550 (if_then_else (eq_attr "fpu_single" "yes")
5551 (const_string "single") (const_string "double")))
5552 (set_attr "needs_delay_slot" "yes")])
5554 (define_insn "call_compact"
5555 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5556 (match_operand 1 "" ""))
5557 (match_operand 2 "immediate_operand" "n")
5558 (use (reg:SI R0_REG))
5559 (use (reg:SI R1_REG))
5560 (use (reg:PSI FPSCR_REG))
5561 (clobber (reg:SI PR_REG))]
5562 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5564 [(set_attr "type" "call")
5565 (set (attr "fp_mode")
5566 (if_then_else (eq_attr "fpu_single" "yes")
5567 (const_string "single") (const_string "double")))
5568 (set_attr "needs_delay_slot" "yes")])
5570 (define_insn "call_compact_rettramp"
5571 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5572 (match_operand 1 "" ""))
5573 (match_operand 2 "immediate_operand" "n")
5574 (use (reg:SI R0_REG))
5575 (use (reg:SI R1_REG))
5576 (use (reg:PSI FPSCR_REG))
5577 (clobber (reg:SI R10_REG))
5578 (clobber (reg:SI PR_REG))]
5579 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5581 [(set_attr "type" "call")
5582 (set (attr "fp_mode")
5583 (if_then_else (eq_attr "fpu_single" "yes")
5584 (const_string "single") (const_string "double")))
5585 (set_attr "needs_delay_slot" "yes")])
5587 (define_insn "call_media"
5588 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5589 (match_operand 1 "" ""))
5590 (clobber (reg:DI PR_MEDIA_REG))]
5593 [(set_attr "type" "jump_media")])
5595 (define_insn "call_valuei"
5596 [(set (match_operand 0 "" "=rf")
5597 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5598 (match_operand 2 "" "")))
5599 (use (reg:PSI FPSCR_REG))
5600 (clobber (reg:SI PR_REG))]
5603 [(set_attr "type" "call")
5604 (set (attr "fp_mode")
5605 (if_then_else (eq_attr "fpu_single" "yes")
5606 (const_string "single") (const_string "double")))
5607 (set_attr "needs_delay_slot" "yes")])
5609 (define_insn "call_valuei_pcrel"
5610 [(set (match_operand 0 "" "=rf")
5611 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5612 (match_operand 2 "" "")))
5613 (use (reg:PSI FPSCR_REG))
5614 (use (reg:SI PIC_REG))
5615 (use (match_operand 3 "" ""))
5616 (clobber (reg:SI PR_REG))]
5619 [(set_attr "type" "call")
5620 (set (attr "fp_mode")
5621 (if_then_else (eq_attr "fpu_single" "yes")
5622 (const_string "single") (const_string "double")))
5623 (set_attr "needs_delay_slot" "yes")])
5625 (define_insn_and_split "call_value_pcrel"
5626 [(set (match_operand 0 "" "=rf")
5627 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5628 (match_operand 2 "" "")))
5629 (use (reg:PSI FPSCR_REG))
5630 (use (reg:SI PIC_REG))
5631 (clobber (reg:SI PR_REG))
5632 (clobber (match_scratch:SI 3 "=r"))]
5639 rtx lab = PATTERN (gen_call_site ());
5641 if (SYMBOL_REF_FLAG (operands[1]))
5642 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5644 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5645 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5649 [(set_attr "type" "call")
5650 (set (attr "fp_mode")
5651 (if_then_else (eq_attr "fpu_single" "yes")
5652 (const_string "single") (const_string "double")))
5653 (set_attr "needs_delay_slot" "yes")])
5655 (define_insn "call_value_compact"
5656 [(set (match_operand 0 "" "=rf")
5657 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5658 (match_operand 2 "" "")))
5659 (match_operand 3 "immediate_operand" "n")
5660 (use (reg:SI R0_REG))
5661 (use (reg:SI R1_REG))
5662 (use (reg:PSI FPSCR_REG))
5663 (clobber (reg:SI PR_REG))]
5664 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5666 [(set_attr "type" "call")
5667 (set (attr "fp_mode")
5668 (if_then_else (eq_attr "fpu_single" "yes")
5669 (const_string "single") (const_string "double")))
5670 (set_attr "needs_delay_slot" "yes")])
5672 (define_insn "call_value_compact_rettramp"
5673 [(set (match_operand 0 "" "=rf")
5674 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5675 (match_operand 2 "" "")))
5676 (match_operand 3 "immediate_operand" "n")
5677 (use (reg:SI R0_REG))
5678 (use (reg:SI R1_REG))
5679 (use (reg:PSI FPSCR_REG))
5680 (clobber (reg:SI R10_REG))
5681 (clobber (reg:SI PR_REG))]
5682 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5684 [(set_attr "type" "call")
5685 (set (attr "fp_mode")
5686 (if_then_else (eq_attr "fpu_single" "yes")
5687 (const_string "single") (const_string "double")))
5688 (set_attr "needs_delay_slot" "yes")])
5690 (define_insn "call_value_media"
5691 [(set (match_operand 0 "" "=rf")
5692 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5693 (match_operand 2 "" "")))
5694 (clobber (reg:DI PR_MEDIA_REG))]
5697 [(set_attr "type" "jump_media")])
5699 (define_expand "call"
5700 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5701 (match_operand 1 "" ""))
5702 (match_operand 2 "" "")
5703 (use (reg:PSI FPSCR_REG))
5704 (clobber (reg:SI PR_REG))])]
5710 operands[0] = XEXP (operands[0], 0);
5711 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5713 if (! SYMBOL_REF_FLAG (operands[0]))
5715 rtx reg = gen_reg_rtx (Pmode);
5717 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5722 operands[0] = gen_sym2PIC (operands[0]);
5723 PUT_MODE (operands[0], Pmode);
5726 if (GET_MODE (operands[0]) == SImode)
5728 if (GET_CODE (operands[0]) == REG)
5729 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5730 else if (GET_CODE (operands[0]) == SUBREG)
5732 operands[0] = SUBREG_REG (operands[0]);
5733 if (GET_MODE (operands[0]) != DImode)
5734 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5738 operands[0] = shallow_copy_rtx (operands[0]);
5739 PUT_MODE (operands[0], DImode);
5742 if (! target_reg_operand (operands[0], DImode))
5743 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5744 emit_call_insn (gen_call_media (operands[0], operands[1]));
5747 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5749 rtx cookie_rtx = operands[2];
5750 long cookie = INTVAL (cookie_rtx);
5751 rtx func = XEXP (operands[0], 0);
5756 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5758 rtx reg = gen_reg_rtx (Pmode);
5760 emit_insn (gen_symGOTPLT2reg (reg, func));
5764 func = legitimize_pic_address (func, Pmode, 0);
5767 r0 = gen_rtx_REG (SImode, R0_REG);
5768 r1 = gen_rtx_REG (SImode, R1_REG);
5770 /* Since such a call function may use all call-clobbered
5771 registers, we force a mode switch earlier, so that we don't
5772 run out of registers when adjusting fpscr for the call. */
5773 emit_insn (gen_force_mode_for_call ());
5775 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5776 \"__GCC_shcompact_call_trampoline\");
5779 rtx reg = gen_reg_rtx (Pmode);
5781 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5784 operands[0] = force_reg (SImode, operands[0]);
5786 emit_move_insn (r0, func);
5787 emit_move_insn (r1, cookie_rtx);
5789 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5790 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5793 emit_call_insn (gen_call_compact (operands[0], operands[1],
5798 else if (TARGET_SHCOMPACT && flag_pic
5799 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5800 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5802 rtx reg = gen_reg_rtx (Pmode);
5804 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5805 XEXP (operands[0], 0) = reg;
5807 if (flag_pic && TARGET_SH2
5808 && GET_CODE (operands[0]) == MEM
5809 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5811 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5815 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5817 emit_call_insn (gen_calli (operands[0], operands[1]));
5821 (define_insn "call_pop_compact"
5822 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5823 (match_operand 1 "" ""))
5824 (match_operand 2 "immediate_operand" "n")
5825 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5826 (match_operand 3 "immediate_operand" "n")))
5827 (use (reg:SI R0_REG))
5828 (use (reg:SI R1_REG))
5829 (use (reg:PSI FPSCR_REG))
5830 (clobber (reg:SI PR_REG))]
5831 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5833 [(set_attr "type" "call")
5834 (set (attr "fp_mode")
5835 (if_then_else (eq_attr "fpu_single" "yes")
5836 (const_string "single") (const_string "double")))
5837 (set_attr "needs_delay_slot" "yes")])
5839 (define_insn "call_pop_compact_rettramp"
5840 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5841 (match_operand 1 "" ""))
5842 (match_operand 2 "immediate_operand" "n")
5843 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5844 (match_operand 3 "immediate_operand" "n")))
5845 (use (reg:SI R0_REG))
5846 (use (reg:SI R1_REG))
5847 (use (reg:PSI FPSCR_REG))
5848 (clobber (reg:SI R10_REG))
5849 (clobber (reg:SI PR_REG))]
5850 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5852 [(set_attr "type" "call")
5853 (set (attr "fp_mode")
5854 (if_then_else (eq_attr "fpu_single" "yes")
5855 (const_string "single") (const_string "double")))
5856 (set_attr "needs_delay_slot" "yes")])
5858 (define_expand "call_pop"
5859 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5860 (match_operand 1 "" ""))
5861 (match_operand 2 "" "")
5862 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5863 (match_operand 3 "" "")))])]
5867 if (operands[2] && INTVAL (operands[2]))
5869 rtx cookie_rtx = operands[2];
5870 long cookie = INTVAL (cookie_rtx);
5871 rtx func = XEXP (operands[0], 0);
5876 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5878 rtx reg = gen_reg_rtx (Pmode);
5880 emit_insn (gen_symGOTPLT2reg (reg, func));
5884 func = legitimize_pic_address (func, Pmode, 0);
5887 r0 = gen_rtx_REG (SImode, R0_REG);
5888 r1 = gen_rtx_REG (SImode, R1_REG);
5890 /* Since such a call function may use all call-clobbered
5891 registers, we force a mode switch earlier, so that we don't
5892 run out of registers when adjusting fpscr for the call. */
5893 emit_insn (gen_force_mode_for_call ());
5895 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5896 \"__GCC_shcompact_call_trampoline\");
5899 rtx reg = gen_reg_rtx (Pmode);
5901 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5904 operands[0] = force_reg (SImode, operands[0]);
5906 emit_move_insn (r0, func);
5907 emit_move_insn (r1, cookie_rtx);
5909 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5910 emit_call_insn (gen_call_pop_compact_rettramp
5911 (operands[0], operands[1], operands[2], operands[3]));
5913 emit_call_insn (gen_call_pop_compact
5914 (operands[0], operands[1], operands[2], operands[3]));
5922 (define_expand "call_value"
5923 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5924 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5925 (match_operand 2 "" "")))
5926 (match_operand 3 "" "")
5927 (use (reg:PSI FPSCR_REG))
5928 (clobber (reg:SI PR_REG))])]
5934 operands[1] = XEXP (operands[1], 0);
5935 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5937 if (! SYMBOL_REF_FLAG (operands[1]))
5939 rtx reg = gen_reg_rtx (Pmode);
5941 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5946 operands[1] = gen_sym2PIC (operands[1]);
5947 PUT_MODE (operands[1], Pmode);
5950 if (GET_MODE (operands[1]) == SImode)
5952 if (GET_CODE (operands[1]) == REG)
5953 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5954 else if (GET_CODE (operands[1]) == SUBREG)
5956 operands[1] = SUBREG_REG (operands[1]);
5957 if (GET_MODE (operands[1]) != DImode)
5958 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5962 operands[1] = shallow_copy_rtx (operands[1]);
5963 PUT_MODE (operands[1], DImode);
5966 if (! target_reg_operand (operands[1], DImode))
5967 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5968 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5972 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5974 rtx cookie_rtx = operands[3];
5975 long cookie = INTVAL (cookie_rtx);
5976 rtx func = XEXP (operands[1], 0);
5981 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5983 rtx reg = gen_reg_rtx (Pmode);
5985 emit_insn (gen_symGOTPLT2reg (reg, func));
5989 func = legitimize_pic_address (func, Pmode, 0);
5992 r0 = gen_rtx_REG (SImode, R0_REG);
5993 r1 = gen_rtx_REG (SImode, R1_REG);
5995 /* Since such a call function may use all call-clobbered
5996 registers, we force a mode switch earlier, so that we don't
5997 run out of registers when adjusting fpscr for the call. */
5998 emit_insn (gen_force_mode_for_call ());
6000 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6001 \"__GCC_shcompact_call_trampoline\");
6004 rtx reg = gen_reg_rtx (Pmode);
6006 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6009 operands[1] = force_reg (SImode, operands[1]);
6011 emit_move_insn (r0, func);
6012 emit_move_insn (r1, cookie_rtx);
6014 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6015 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6020 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6021 operands[2], operands[3]));
6025 else if (TARGET_SHCOMPACT && flag_pic
6026 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6027 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6029 rtx reg = gen_reg_rtx (Pmode);
6031 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6032 XEXP (operands[1], 0) = reg;
6034 if (flag_pic && TARGET_SH2
6035 && GET_CODE (operands[1]) == MEM
6036 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6038 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6043 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6045 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6049 (define_insn "sibcalli"
6050 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6051 (match_operand 1 "" ""))
6052 (use (reg:PSI FPSCR_REG))
6056 [(set_attr "needs_delay_slot" "yes")
6057 (set (attr "fp_mode")
6058 (if_then_else (eq_attr "fpu_single" "yes")
6059 (const_string "single") (const_string "double")))
6060 (set_attr "type" "jump_ind")])
6062 (define_insn "sibcalli_pcrel"
6063 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6064 (match_operand 1 "" ""))
6065 (use (match_operand 2 "" ""))
6066 (use (reg:PSI FPSCR_REG))
6070 [(set_attr "needs_delay_slot" "yes")
6071 (set (attr "fp_mode")
6072 (if_then_else (eq_attr "fpu_single" "yes")
6073 (const_string "single") (const_string "double")))
6074 (set_attr "type" "jump_ind")])
6076 (define_insn_and_split "sibcall_pcrel"
6077 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6078 (match_operand 1 "" ""))
6079 (use (reg:PSI FPSCR_REG))
6080 (clobber (match_scratch:SI 2 "=k"))
6088 rtx lab = PATTERN (gen_call_site ());
6091 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6092 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6094 SIBLING_CALL_P (call_insn) = 1;
6097 [(set_attr "needs_delay_slot" "yes")
6098 (set (attr "fp_mode")
6099 (if_then_else (eq_attr "fpu_single" "yes")
6100 (const_string "single") (const_string "double")))
6101 (set_attr "type" "jump_ind")])
6103 (define_insn "sibcall_compact"
6104 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6105 (match_operand 1 "" ""))
6107 (use (match_operand:SI 2 "register_operand" "z,x"))
6108 (use (reg:SI R1_REG))
6109 (use (reg:PSI FPSCR_REG))
6110 ;; We want to make sure the `x' above will only match MACH_REG
6111 ;; because sibcall_epilogue may clobber MACL_REG.
6112 (clobber (reg:SI MACL_REG))]
6116 jmp @%0\\n sts %2, r0"
6117 [(set_attr "needs_delay_slot" "yes,no")
6118 (set_attr "length" "2,4")
6119 (set (attr "fp_mode") (const_string "single"))
6120 (set_attr "type" "jump_ind")])
6122 (define_insn "sibcall_media"
6123 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6124 (match_operand 1 "" ""))
6128 [(set_attr "type" "jump_media")])
6130 (define_expand "sibcall"
6132 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6133 (match_operand 1 "" ""))
6134 (match_operand 2 "" "")
6135 (use (reg:PSI FPSCR_REG))
6142 operands[0] = XEXP (operands[0], 0);
6143 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6145 if (! SYMBOL_REF_FLAG (operands[0]))
6147 rtx reg = gen_reg_rtx (Pmode);
6149 /* We must not use GOTPLT for sibcalls, because PIC_REG
6150 must be restored before the PLT code gets to run. */
6151 emit_insn (gen_symGOT2reg (reg, operands[0]));
6156 operands[0] = gen_sym2PIC (operands[0]);
6157 PUT_MODE (operands[0], Pmode);
6160 if (GET_MODE (operands[0]) == SImode)
6162 if (GET_CODE (operands[0]) == REG)
6163 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6164 else if (GET_CODE (operands[0]) == SUBREG)
6166 operands[0] = SUBREG_REG (operands[0]);
6167 if (GET_MODE (operands[0]) != DImode)
6168 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6172 operands[0] = shallow_copy_rtx (operands[0]);
6173 PUT_MODE (operands[0], DImode);
6176 if (! target_reg_operand (operands[0], DImode))
6177 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6178 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6181 else if (TARGET_SHCOMPACT && operands[2]
6182 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6184 rtx cookie_rtx = operands[2];
6185 long cookie = INTVAL (cookie_rtx);
6186 rtx func = XEXP (operands[0], 0);
6191 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6193 rtx reg = gen_reg_rtx (Pmode);
6195 emit_insn (gen_symGOT2reg (reg, func));
6199 func = legitimize_pic_address (func, Pmode, 0);
6202 /* FIXME: if we could tell whether all argument registers are
6203 already taken, we could decide whether to force the use of
6204 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6205 simple way to tell. We could use the CALL_COOKIE, but we
6206 can't currently tell a register used for regular argument
6207 passing from one that is unused. If we leave it up to reload
6208 to decide which register to use, it seems to always choose
6209 R0_REG, which leaves no available registers in SIBCALL_REGS
6210 to hold the address of the trampoline. */
6211 mach = gen_rtx_REG (SImode, MACH_REG);
6212 r1 = gen_rtx_REG (SImode, R1_REG);
6214 /* Since such a call function may use all call-clobbered
6215 registers, we force a mode switch earlier, so that we don't
6216 run out of registers when adjusting fpscr for the call. */
6217 emit_insn (gen_force_mode_for_call ());
6219 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6220 \"__GCC_shcompact_call_trampoline\");
6223 rtx reg = gen_reg_rtx (Pmode);
6225 emit_insn (gen_symGOT2reg (reg, operands[0]));
6228 operands[0] = force_reg (SImode, operands[0]);
6230 /* We don't need a return trampoline, since the callee will
6231 return directly to the upper caller. */
6232 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6234 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6235 cookie_rtx = GEN_INT (cookie);
6238 emit_move_insn (mach, func);
6239 emit_move_insn (r1, cookie_rtx);
6241 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6244 else if (TARGET_SHCOMPACT && flag_pic
6245 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6246 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6248 rtx reg = gen_reg_rtx (Pmode);
6250 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6251 XEXP (operands[0], 0) = reg;
6253 if (flag_pic && TARGET_SH2
6254 && GET_CODE (operands[0]) == MEM
6255 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6256 /* The PLT needs the PIC register, but the epilogue would have
6257 to restore it, so we can only use PC-relative PIC calls for
6258 static functions. */
6259 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6261 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6265 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6267 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6271 (define_expand "sibcall_value"
6272 [(set (match_operand 0 "" "")
6273 (call (match_operand 1 "" "")
6274 (match_operand 2 "" "")))
6275 (match_operand 3 "" "")]
6279 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6283 (define_insn "call_value_pop_compact"
6284 [(set (match_operand 0 "" "=rf")
6285 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6286 (match_operand 2 "" "")))
6287 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6288 (match_operand 4 "immediate_operand" "n")))
6289 (match_operand 3 "immediate_operand" "n")
6290 (use (reg:SI R0_REG))
6291 (use (reg:SI R1_REG))
6292 (use (reg:PSI FPSCR_REG))
6293 (clobber (reg:SI PR_REG))]
6294 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6296 [(set_attr "type" "call")
6297 (set (attr "fp_mode")
6298 (if_then_else (eq_attr "fpu_single" "yes")
6299 (const_string "single") (const_string "double")))
6300 (set_attr "needs_delay_slot" "yes")])
6302 (define_insn "call_value_pop_compact_rettramp"
6303 [(set (match_operand 0 "" "=rf")
6304 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6305 (match_operand 2 "" "")))
6306 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6307 (match_operand 4 "immediate_operand" "n")))
6308 (match_operand 3 "immediate_operand" "n")
6309 (use (reg:SI R0_REG))
6310 (use (reg:SI R1_REG))
6311 (use (reg:PSI FPSCR_REG))
6312 (clobber (reg:SI R10_REG))
6313 (clobber (reg:SI PR_REG))]
6314 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6316 [(set_attr "type" "call")
6317 (set (attr "fp_mode")
6318 (if_then_else (eq_attr "fpu_single" "yes")
6319 (const_string "single") (const_string "double")))
6320 (set_attr "needs_delay_slot" "yes")])
6322 (define_expand "call_value_pop"
6323 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6324 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6325 (match_operand 2 "" "")))
6326 (match_operand 3 "" "")
6327 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6328 (match_operand 4 "" "")))])]
6332 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6334 rtx cookie_rtx = operands[3];
6335 long cookie = INTVAL (cookie_rtx);
6336 rtx func = XEXP (operands[1], 0);
6341 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6343 rtx reg = gen_reg_rtx (Pmode);
6345 emit_insn (gen_symGOTPLT2reg (reg, func));
6349 func = legitimize_pic_address (func, Pmode, 0);
6352 r0 = gen_rtx_REG (SImode, R0_REG);
6353 r1 = gen_rtx_REG (SImode, R1_REG);
6355 /* Since such a call function may use all call-clobbered
6356 registers, we force a mode switch earlier, so that we don't
6357 run out of registers when adjusting fpscr for the call. */
6358 emit_insn (gen_force_mode_for_call ());
6360 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6361 \"__GCC_shcompact_call_trampoline\");
6364 rtx reg = gen_reg_rtx (Pmode);
6366 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6369 operands[1] = force_reg (SImode, operands[1]);
6371 emit_move_insn (r0, func);
6372 emit_move_insn (r1, cookie_rtx);
6374 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6375 emit_call_insn (gen_call_value_pop_compact_rettramp
6376 (operands[0], operands[1], operands[2],
6377 operands[3], operands[4]));
6379 emit_call_insn (gen_call_value_pop_compact
6380 (operands[0], operands[1], operands[2],
6381 operands[3], operands[4]));
6389 (define_expand "sibcall_epilogue"
6394 sh_expand_epilogue ();
6395 if (TARGET_SHCOMPACT)
6399 /* If epilogue clobbers r0, preserve it in macl. */
6400 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6401 if ((set = single_set (insn))
6402 && GET_CODE (SET_DEST (set)) == REG
6403 && REGNO (SET_DEST (set)) == R0_REG)
6405 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6406 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6409 /* We can't tell at this point whether the sibcall is a
6410 sibcall_compact and, if it is, whether it uses r0 or
6411 mach as operand 2, so let the instructions that
6412 preserve r0 be optimized away if r0 turns out to be
6414 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6415 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6417 i = emit_move_insn (r0, tmp);
6418 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6426 (define_insn "indirect_jump_compact"
6428 (match_operand:SI 0 "arith_reg_operand" "r"))]
6431 [(set_attr "needs_delay_slot" "yes")
6432 (set_attr "type" "jump_ind")])
6434 (define_expand "indirect_jump"
6436 (match_operand 0 "register_operand" ""))]
6440 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6441 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6444 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6445 ;; which can be present in structured code from indirect jumps which can not
6446 ;; be present in structured code. This allows -fprofile-arcs to work.
6448 ;; For SH1 processors.
6449 (define_insn "casesi_jump_1"
6451 (match_operand:SI 0 "register_operand" "r"))
6452 (use (label_ref (match_operand 1 "" "")))]
6455 [(set_attr "needs_delay_slot" "yes")
6456 (set_attr "type" "jump_ind")])
6458 ;; For all later processors.
6459 (define_insn "casesi_jump_2"
6460 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6461 (label_ref (match_operand 1 "" ""))))
6462 (use (label_ref (match_operand 2 "" "")))]
6464 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6466 [(set_attr "needs_delay_slot" "yes")
6467 (set_attr "type" "jump_ind")])
6469 (define_insn "casesi_jump_media"
6470 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6471 (use (label_ref (match_operand 1 "" "")))]
6474 [(set_attr "type" "jump_media")])
6476 ;; Call subroutine returning any type.
6477 ;; ??? This probably doesn't work.
6479 (define_expand "untyped_call"
6480 [(parallel [(call (match_operand 0 "" "")
6482 (match_operand 1 "" "")
6483 (match_operand 2 "" "")])]
6484 "TARGET_SH3E || TARGET_SHMEDIA"
6489 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6491 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6493 rtx set = XVECEXP (operands[2], 0, i);
6494 emit_move_insn (SET_DEST (set), SET_SRC (set));
6497 /* The optimizer does not know that the call sets the function value
6498 registers we stored in the result block. We avoid problems by
6499 claiming that all hard registers are used and clobbered at this
6501 emit_insn (gen_blockage ());
6506 ;; ------------------------------------------------------------------------
6508 ;; ------------------------------------------------------------------------
6511 [(set (reg:SI T_REG)
6512 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6513 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6516 [(set_attr "type" "arith")])
6523 ;; Load address of a label. This is only generated by the casesi expand,
6524 ;; and by machine_dependent_reorg (fixing up fp moves).
6525 ;; This must use unspec, because this only works for labels that are
6529 [(set (reg:SI R0_REG)
6530 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6533 [(set_attr "in_delay_slot" "no")
6534 (set_attr "type" "arith")])
6536 ;; machine_dependent_reorg() will make this a `mova'.
6537 (define_insn "mova_const"
6538 [(set (reg:SI R0_REG)
6539 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6542 [(set_attr "in_delay_slot" "no")
6543 (set_attr "type" "arith")])
6545 (define_expand "GOTaddr2picreg"
6546 [(set (reg:SI R0_REG)
6547 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6549 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6550 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6553 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6554 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6557 operands[1] = gen_datalabel_ref (operands[1]);
6561 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6562 rtx dipic = operands[0];
6563 rtx lab = PATTERN (gen_call_site ());
6566 equiv = operands[1];
6567 operands[1] = gen_rtx_MINUS (DImode,
6571 gen_rtx_MINUS (DImode,
6572 gen_rtx_CONST (DImode,
6575 operands[1] = gen_sym2PIC (operands[1]);
6576 PUT_MODE (operands[1], DImode);
6578 if (GET_MODE (dipic) != DImode)
6579 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6581 if (TARGET_SHMEDIA64)
6582 emit_insn (gen_movdi_const (dipic, operands[1]));
6584 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6586 emit_insn (gen_ptrel (tr, dipic, lab));
6588 if (GET_MODE (operands[0]) != GET_MODE (tr))
6589 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6591 insn = emit_move_insn (operands[0], tr);
6593 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6601 ;; When generating PIC, we must match label_refs especially, because
6602 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6603 ;; them to do, because they can't be loaded directly into
6604 ;; non-branch-target registers.
6606 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6607 (match_operand:DI 1 "" "T"))]
6608 "TARGET_SHMEDIA && flag_pic
6609 && EXTRA_CONSTRAINT_T (operands[1])"
6611 [(set_attr "type" "pt_media")
6612 (set_attr "length" "*")])
6615 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6616 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6617 UNSPEC_DATALABEL)))]
6618 "TARGET_SHMEDIA && flag_pic
6619 && EXTRA_CONSTRAINT_T (operands[1])"
6620 "ptb/u datalabel %1, %0"
6621 [(set_attr "type" "pt_media")
6622 (set_attr "length" "*")])
6624 (define_insn "ptrel"
6625 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6626 (plus:DI (match_operand:DI 1 "register_operand" "r")
6628 (match_operand:DI 2 "" "")]
6630 "%O2: ptrel/u %1, %0"
6631 [(set_attr "type" "ptabs_media")])
6633 (define_expand "builtin_setjmp_receiver"
6634 [(match_operand 0 "" "")]
6638 emit_insn (gen_GOTaddr2picreg ());
6642 (define_expand "call_site"
6643 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6647 static HOST_WIDE_INT i = 0;
6648 operands[0] = GEN_INT (i);
6652 (define_expand "sym_label2reg"
6653 [(set (match_operand:SI 0 "" "")
6656 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6659 (match_operand:SI 2 "" "")
6663 (define_expand "symGOT_load"
6664 [(set (match_dup 2) (match_operand 1 "" ""))
6665 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6666 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6672 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6673 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6677 rtx reg = operands[2];
6679 if (GET_MODE (reg) != DImode)
6680 reg = gen_rtx_SUBREG (DImode, reg, 0);
6683 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6685 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6688 emit_move_insn (operands[2], operands[1]);
6690 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6692 gen_rtx_REG (Pmode, PIC_REG)));
6694 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6696 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6703 (define_expand "sym2GOT"
6704 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6708 (define_expand "symGOT2reg"
6709 [(match_operand 0 "" "") (match_operand 1 "" "")]
6715 gotsym = gen_sym2GOT (operands[1]);
6716 PUT_MODE (gotsym, Pmode);
6717 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6719 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6724 (define_expand "sym2GOTPLT"
6725 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6729 (define_expand "symGOTPLT2reg"
6730 [(match_operand 0 "" "") (match_operand 1 "" "")]
6734 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6738 (define_expand "sym2GOTOFF"
6739 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6743 (define_expand "symGOTOFF2reg"
6744 [(match_operand 0 "" "") (match_operand 1 "" "")]
6748 rtx gotoffsym, insn;
6749 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6751 gotoffsym = gen_sym2GOTOFF (operands[1]);
6752 PUT_MODE (gotoffsym, Pmode);
6753 emit_move_insn (t, gotoffsym);
6754 insn = emit_move_insn (operands[0],
6755 gen_rtx_PLUS (Pmode, t,
6756 gen_rtx_REG (Pmode, PIC_REG)));
6758 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6764 (define_expand "symPLT_label2reg"
6765 [(set (match_operand:SI 0 "" "")
6768 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6772 (match_operand:SI 2 "" "")
6774 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6775 ;; Even though the PIC register is not really used by the call
6776 ;; sequence in which this is expanded, the PLT code assumes the PIC
6777 ;; register is set, so we must not skip its initialization. Since
6778 ;; we only use this expand as part of calling sequences, and never
6779 ;; to take the address of a function, this is the best point to
6780 ;; insert the (use). Using the PLT to take the address of a
6781 ;; function would be wrong, not only because the PLT entry could
6782 ;; then be called from a function that doesn't initialize the PIC
6783 ;; register to the proper GOT, but also because pointers to the
6784 ;; same function might not compare equal, should they be set by
6785 ;; different shared libraries.
6786 (use (reg:SI PIC_REG))]
6790 (define_expand "sym2PIC"
6791 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6795 ;; case instruction for switch statements.
6797 ;; Operand 0 is index
6798 ;; operand 1 is the minimum bound
6799 ;; operand 2 is the maximum bound - minimum bound + 1
6800 ;; operand 3 is CODE_LABEL for the table;
6801 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6803 (define_expand "casesi"
6804 [(match_operand:SI 0 "arith_reg_operand" "")
6805 (match_operand:SI 1 "arith_reg_operand" "")
6806 (match_operand:SI 2 "arith_reg_operand" "")
6807 (match_operand 3 "" "") (match_operand 4 "" "")]
6811 rtx reg = gen_reg_rtx (SImode);
6812 rtx reg2 = gen_reg_rtx (SImode);
6815 rtx reg = gen_reg_rtx (DImode);
6816 rtx reg2 = gen_reg_rtx (DImode);
6817 rtx reg3 = gen_reg_rtx (DImode);
6818 rtx reg4 = gen_reg_rtx (DImode);
6819 rtx reg5 = gen_reg_rtx (DImode);
6821 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6822 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6823 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6825 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6826 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6827 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6828 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6829 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6830 (DImode, operands[3])));
6831 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6832 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6833 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6837 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6838 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6839 /* If optimizing, casesi_worker depends on the mode of the instruction
6840 before label it 'uses' - operands[3]. */
6841 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6843 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6845 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6847 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6848 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6849 operands[3], but to lab. We will fix this up in
6850 machine_dependent_reorg. */
6855 (define_expand "casesi_0"
6856 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6857 (set (match_dup 4) (minus:SI (match_dup 4)
6858 (match_operand:SI 1 "arith_operand" "")))
6860 (gtu:SI (match_dup 4)
6861 (match_operand:SI 2 "arith_reg_operand" "")))
6863 (if_then_else (ne (reg:SI T_REG)
6865 (label_ref (match_operand 3 "" ""))
6870 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6871 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6872 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6874 (define_insn "casesi_worker_0"
6875 [(set (match_operand:SI 0 "register_operand" "=r,r")
6876 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6877 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6878 (clobber (match_scratch:SI 3 "=X,1"))
6879 (clobber (match_scratch:SI 4 "=&z,z"))]
6884 [(set (match_operand:SI 0 "register_operand" "")
6885 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6886 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6887 (clobber (match_scratch:SI 3 ""))
6888 (clobber (match_scratch:SI 4 ""))]
6889 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6890 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6891 (parallel [(set (match_dup 0)
6892 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6893 (label_ref (match_dup 2))] UNSPEC_CASESI))
6894 (clobber (match_dup 3))])
6895 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6896 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6899 [(set (match_operand:SI 0 "register_operand" "")
6900 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6901 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6902 (clobber (match_scratch:SI 3 ""))
6903 (clobber (match_scratch:SI 4 ""))]
6904 "TARGET_SH2 && reload_completed"
6905 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6906 (parallel [(set (match_dup 0)
6907 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6908 (label_ref (match_dup 2))] UNSPEC_CASESI))
6909 (clobber (match_dup 3))])]
6910 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6912 (define_insn "*casesi_worker"
6913 [(set (match_operand:SI 0 "register_operand" "=r,r")
6914 (unspec:SI [(reg:SI R0_REG)
6915 (match_operand:SI 1 "register_operand" "0,r")
6916 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6917 (clobber (match_scratch:SI 3 "=X,1"))]
6921 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6923 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6926 switch (GET_MODE (diff_vec))
6929 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6931 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6933 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6934 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6935 return \"mov.b @(r0,%1),%0\";
6940 [(set_attr "length" "4")])
6942 (define_insn "casesi_shift_media"
6943 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6944 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6945 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6950 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6952 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6955 switch (GET_MODE (diff_vec))
6958 return \"shlli %1, 2, %0\";
6960 return \"shlli %1, 1, %0\";
6962 if (rtx_equal_p (operands[0], operands[1]))
6964 return \"add %1, r63, %0\";
6969 [(set_attr "type" "arith_media")])
6971 (define_insn "casesi_load_media"
6972 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6973 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6974 (match_operand 2 "arith_reg_operand" "r")
6975 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6979 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6981 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6984 switch (GET_MODE (diff_vec))
6987 return \"ldx.l %1, %2, %0\";
6990 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6991 return \"ldx.uw %1, %2, %0\";
6993 return \"ldx.w %1, %2, %0\";
6995 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6996 return \"ldx.ub %1, %2, %0\";
6997 return \"ldx.b %1, %2, %0\";
7002 [(set_attr "type" "load_media")])
7004 (define_expand "return"
7006 "reload_completed && ! sh_need_epilogue ()"
7011 emit_jump_insn (gen_return_media ());
7015 if (TARGET_SHCOMPACT
7016 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7018 emit_jump_insn (gen_shcompact_return_tramp ());
7023 (define_insn "*return_i"
7025 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7026 && (current_function_args_info.call_cookie
7027 & CALL_COOKIE_RET_TRAMP (1)))
7028 && reload_completed"
7030 [(set_attr "type" "return")
7031 (set_attr "needs_delay_slot" "yes")])
7033 (define_expand "shcompact_return_tramp"
7036 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7039 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7040 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7041 \"__GCC_shcompact_return_trampoline\");
7044 emit_insn (gen_symGOTPLT2reg (reg, sym));
7046 emit_move_insn (reg, sym);
7048 emit_jump_insn (gen_shcompact_return_tramp_i ());
7052 (define_insn "shcompact_return_tramp_i"
7053 [(parallel [(return) (use (reg:SI R0_REG))])]
7055 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7057 [(set_attr "type" "jump_ind")
7058 (set_attr "needs_delay_slot" "yes")])
7060 (define_insn "return_media_i"
7061 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7062 "TARGET_SHMEDIA && reload_completed"
7064 [(set_attr "type" "jump_media")])
7066 (define_expand "return_media"
7068 "TARGET_SHMEDIA && reload_completed"
7071 int tr_regno = sh_media_register_for_return ();
7076 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7079 tr = gen_rtx_REG (DImode, tr_regno);
7080 emit_move_insn (tr, r18);
7083 tr = gen_rtx_REG (DImode, tr_regno);
7085 emit_jump_insn (gen_return_media_i (tr));
7089 (define_insn "shcompact_preserve_incoming_args"
7090 [(set (match_operand:SI 0 "register_operand" "+r")
7091 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7094 [(set_attr "length" "0")])
7096 (define_insn "shcompact_incoming_args"
7097 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7098 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7099 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7100 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7101 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7102 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7103 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7104 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7105 (set (mem:BLK (reg:SI MACL_REG))
7106 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7107 (use (reg:SI R0_REG))
7108 (clobber (reg:SI R0_REG))
7109 (clobber (reg:SI MACL_REG))
7110 (clobber (reg:SI MACH_REG))
7111 (clobber (reg:SI PR_REG))]
7114 [(set_attr "needs_delay_slot" "yes")])
7116 (define_insn "shmedia_save_restore_regs_compact"
7117 [(set (reg:SI SP_REG)
7118 (plus:SI (reg:SI SP_REG)
7119 (match_operand:SI 0 "immediate_operand" "i")))
7120 (use (reg:SI R0_REG))
7121 (clobber (reg:SI PR_REG))]
7123 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7124 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7126 [(set_attr "needs_delay_slot" "yes")])
7128 (define_expand "prologue"
7131 "sh_expand_prologue (); DONE;")
7133 (define_expand "epilogue"
7138 sh_expand_epilogue ();
7139 emit_jump_insn (gen_return ());
7143 (define_insn "blockage"
7144 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7147 [(set_attr "length" "0")])
7149 ;; ------------------------------------------------------------------------
7151 ;; ------------------------------------------------------------------------
7154 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7155 (eq:SI (reg:SI T_REG) (const_int 1)))]
7158 [(set_attr "type" "arith")])
7160 (define_expand "seq"
7161 [(set (match_operand:SI 0 "arith_reg_operand" "")
7168 if (GET_MODE (operands[0]) != DImode)
7169 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7170 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7171 if (sh_compare_op1 != const0_rtx)
7172 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7173 ? GET_MODE (sh_compare_op0)
7174 : GET_MODE (sh_compare_op1),
7177 switch (GET_MODE (sh_compare_op0))
7180 emit_insn (gen_cmpeqdi_media (operands[0],
7181 sh_compare_op0, sh_compare_op1));
7185 if (! TARGET_SHMEDIA_FPU)
7187 emit_insn (gen_cmpeqsf_media (operands[0],
7188 sh_compare_op0, sh_compare_op1));
7192 if (! TARGET_SHMEDIA_FPU)
7194 emit_insn (gen_cmpeqdf_media (operands[0],
7195 sh_compare_op0, sh_compare_op1));
7203 operands[1] = prepare_scc_operands (EQ);
7206 (define_expand "slt"
7207 [(set (match_operand:SI 0 "arith_reg_operand" "")
7214 if (GET_MODE (operands[0]) != DImode)
7215 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7216 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7217 if (sh_compare_op1 != const0_rtx)
7218 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7219 ? GET_MODE (sh_compare_op0)
7220 : GET_MODE (sh_compare_op1),
7223 switch (GET_MODE (sh_compare_op0))
7226 emit_insn (gen_cmpgtdi_media (operands[0],
7227 sh_compare_op1, sh_compare_op0));
7231 if (! TARGET_SHMEDIA_FPU)
7233 emit_insn (gen_cmpgtsf_media (operands[0],
7234 sh_compare_op1, sh_compare_op0));
7238 if (! TARGET_SHMEDIA_FPU)
7240 emit_insn (gen_cmpgtdf_media (operands[0],
7241 sh_compare_op1, sh_compare_op0));
7249 operands[1] = prepare_scc_operands (LT);
7252 (define_expand "sle"
7253 [(match_operand:SI 0 "arith_reg_operand" "")]
7257 rtx tmp = sh_compare_op0;
7261 if (GET_MODE (operands[0]) != DImode)
7262 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7263 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7264 if (sh_compare_op1 != const0_rtx)
7265 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7266 ? GET_MODE (sh_compare_op0)
7267 : GET_MODE (sh_compare_op1),
7270 switch (GET_MODE (sh_compare_op0))
7274 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7276 emit_insn (gen_cmpgtdi_media (tmp,
7277 sh_compare_op0, sh_compare_op1));
7278 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7283 if (! TARGET_SHMEDIA_FPU)
7285 emit_insn (gen_cmpgesf_media (operands[0],
7286 sh_compare_op1, sh_compare_op0));
7290 if (! TARGET_SHMEDIA_FPU)
7292 emit_insn (gen_cmpgedf_media (operands[0],
7293 sh_compare_op1, sh_compare_op0));
7302 sh_compare_op0 = sh_compare_op1;
7303 sh_compare_op1 = tmp;
7304 emit_insn (gen_sge (operands[0]));
7308 (define_expand "sgt"
7309 [(set (match_operand:SI 0 "arith_reg_operand" "")
7316 if (GET_MODE (operands[0]) != DImode)
7317 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7318 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7319 if (sh_compare_op1 != const0_rtx)
7320 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7321 ? GET_MODE (sh_compare_op0)
7322 : GET_MODE (sh_compare_op1),
7325 switch (GET_MODE (sh_compare_op0))
7328 emit_insn (gen_cmpgtdi_media (operands[0],
7329 sh_compare_op0, sh_compare_op1));
7333 if (! TARGET_SHMEDIA_FPU)
7335 emit_insn (gen_cmpgtsf_media (operands[0],
7336 sh_compare_op0, sh_compare_op1));
7340 if (! TARGET_SHMEDIA_FPU)
7342 emit_insn (gen_cmpgtdf_media (operands[0],
7343 sh_compare_op0, sh_compare_op1));
7351 operands[1] = prepare_scc_operands (GT);
7354 (define_expand "sge"
7355 [(set (match_operand:SI 0 "arith_reg_operand" "")
7362 if (GET_MODE (operands[0]) != DImode)
7363 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7364 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7365 if (sh_compare_op1 != const0_rtx)
7366 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7367 ? GET_MODE (sh_compare_op0)
7368 : GET_MODE (sh_compare_op1),
7371 switch (GET_MODE (sh_compare_op0))
7375 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7377 emit_insn (gen_cmpgtdi_media (tmp,
7378 sh_compare_op1, sh_compare_op0));
7379 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7384 if (! TARGET_SHMEDIA_FPU)
7386 emit_insn (gen_cmpgesf_media (operands[0],
7387 sh_compare_op0, sh_compare_op1));
7391 if (! TARGET_SHMEDIA_FPU)
7393 emit_insn (gen_cmpgedf_media (operands[0],
7394 sh_compare_op0, sh_compare_op1));
7403 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7407 rtx lab = gen_label_rtx ();
7408 prepare_scc_operands (EQ);
7409 emit_jump_insn (gen_branch_true (lab));
7410 prepare_scc_operands (GT);
7412 emit_insn (gen_movt (operands[0]));
7415 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7418 operands[1] = prepare_scc_operands (GE);
7421 (define_expand "sgtu"
7422 [(set (match_operand:SI 0 "arith_reg_operand" "")
7429 if (GET_MODE (operands[0]) != DImode)
7430 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7431 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7432 if (sh_compare_op1 != const0_rtx)
7433 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7434 ? GET_MODE (sh_compare_op0)
7435 : GET_MODE (sh_compare_op1),
7438 emit_insn (gen_cmpgtudi_media (operands[0],
7439 sh_compare_op0, sh_compare_op1));
7442 operands[1] = prepare_scc_operands (GTU);
7445 (define_expand "sltu"
7446 [(set (match_operand:SI 0 "arith_reg_operand" "")
7453 if (GET_MODE (operands[0]) != DImode)
7454 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7455 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7456 if (sh_compare_op1 != const0_rtx)
7457 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7458 ? GET_MODE (sh_compare_op0)
7459 : GET_MODE (sh_compare_op1),
7462 emit_insn (gen_cmpgtudi_media (operands[0],
7463 sh_compare_op1, sh_compare_op0));
7466 operands[1] = prepare_scc_operands (LTU);
7469 (define_expand "sleu"
7470 [(set (match_operand:SI 0 "arith_reg_operand" "")
7479 if (GET_MODE (operands[0]) != DImode)
7480 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7481 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7482 if (sh_compare_op1 != const0_rtx)
7483 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7484 ? GET_MODE (sh_compare_op0)
7485 : GET_MODE (sh_compare_op1),
7488 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7490 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7491 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7495 operands[1] = prepare_scc_operands (LEU);
7498 (define_expand "sgeu"
7499 [(set (match_operand:SI 0 "arith_reg_operand" "")
7508 if (GET_MODE (operands[0]) != DImode)
7509 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7510 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7511 if (sh_compare_op1 != const0_rtx)
7512 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7513 ? GET_MODE (sh_compare_op0)
7514 : GET_MODE (sh_compare_op1),
7517 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7519 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7520 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7525 operands[1] = prepare_scc_operands (GEU);
7528 ;; sne moves the complement of the T reg to DEST like this:
7532 ;; This is better than xoring compare result with 1 because it does
7533 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7536 (define_expand "sne"
7537 [(set (match_dup 2) (const_int -1))
7538 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7539 (neg:SI (plus:SI (match_dup 1)
7542 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7551 if (GET_MODE (operands[0]) != DImode)
7552 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7554 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7557 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7558 if (sh_compare_op1 != const0_rtx)
7559 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7560 ? GET_MODE (sh_compare_op0)
7561 : GET_MODE (sh_compare_op1),
7564 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7566 emit_insn (gen_seq (tmp));
7567 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7572 operands[1] = prepare_scc_operands (EQ);
7573 operands[2] = gen_reg_rtx (SImode);
7576 (define_expand "sunordered"
7577 [(set (match_operand:DI 0 "arith_reg_operand" "")
7578 (unordered:DI (match_dup 1) (match_dup 2)))]
7579 "TARGET_SHMEDIA_FPU"
7582 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7583 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7586 ;; Use the same trick for FP sle / sge
7587 (define_expand "movnegt"
7588 [(set (match_dup 2) (const_int -1))
7589 (parallel [(set (match_operand 0 "" "")
7590 (neg:SI (plus:SI (match_dup 1)
7593 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7596 "operands[2] = gen_reg_rtx (SImode);")
7598 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7599 ;; This prevents a regression that occurred when we switched from xor to
7603 [(set (match_operand:SI 0 "arith_reg_operand" "")
7604 (plus:SI (reg:SI T_REG)
7607 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7608 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7611 ;; -------------------------------------------------------------------------
7612 ;; Instructions to cope with inline literal tables
7613 ;; -------------------------------------------------------------------------
7615 ; 2 byte integer in line
7617 (define_insn "consttable_2"
7618 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7619 (match_operand 1 "" "")]
7624 if (operands[1] != const0_rtx)
7625 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7628 [(set_attr "length" "2")
7629 (set_attr "in_delay_slot" "no")])
7631 ; 4 byte integer in line
7633 (define_insn "consttable_4"
7634 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7635 (match_operand 1 "" "")]
7640 if (operands[1] != const0_rtx)
7641 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7644 [(set_attr "length" "4")
7645 (set_attr "in_delay_slot" "no")])
7647 ; 8 byte integer in line
7649 (define_insn "consttable_8"
7650 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7651 (match_operand 1 "" "")]
7656 if (operands[1] != const0_rtx)
7657 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7660 [(set_attr "length" "8")
7661 (set_attr "in_delay_slot" "no")])
7663 ; 4 byte floating point
7665 (define_insn "consttable_sf"
7666 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7667 (match_operand 1 "" "")]
7672 if (operands[1] != const0_rtx)
7675 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7676 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7680 [(set_attr "length" "4")
7681 (set_attr "in_delay_slot" "no")])
7683 ; 8 byte floating point
7685 (define_insn "consttable_df"
7686 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7687 (match_operand 1 "" "")]
7692 if (operands[1] != const0_rtx)
7695 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7696 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7700 [(set_attr "length" "8")
7701 (set_attr "in_delay_slot" "no")])
7703 ;; Alignment is needed for some constant tables; it may also be added for
7704 ;; Instructions at the start of loops, or after unconditional branches.
7705 ;; ??? We would get more accurate lengths if we did instruction
7706 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7707 ;; here is too conservative.
7709 ; align to a two byte boundary
7711 (define_expand "align_2"
7712 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7716 ; align to a four byte boundary
7717 ;; align_4 and align_log are instructions for the starts of loops, or
7718 ;; after unconditional branches, which may take up extra room.
7720 (define_expand "align_4"
7721 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7725 ; align to a cache line boundary
7727 (define_insn "align_log"
7728 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7731 [(set_attr "length" "0")
7732 (set_attr "in_delay_slot" "no")])
7734 ; emitted at the end of the literal table, used to emit the
7735 ; 32bit branch labels if needed.
7737 (define_insn "consttable_end"
7738 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7740 "* return output_jump_label_table ();"
7741 [(set_attr "in_delay_slot" "no")])
7743 ; emitted at the end of the window in the literal table.
7745 (define_insn "consttable_window_end"
7746 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7749 [(set_attr "length" "0")
7750 (set_attr "in_delay_slot" "no")])
7752 ;; -------------------------------------------------------------------------
7754 ;; -------------------------------------------------------------------------
7756 ;; String/block move insn.
7758 (define_expand "movstrsi"
7759 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7760 (mem:BLK (match_operand:BLK 1 "" "")))
7761 (use (match_operand:SI 2 "nonmemory_operand" ""))
7762 (use (match_operand:SI 3 "immediate_operand" ""))
7763 (clobber (reg:SI PR_REG))
7764 (clobber (reg:SI R4_REG))
7765 (clobber (reg:SI R5_REG))
7766 (clobber (reg:SI R0_REG))])]
7767 "TARGET_SH1 && ! TARGET_SH5"
7770 if(expand_block_move (operands))
7775 (define_insn "block_move_real"
7776 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7777 (mem:BLK (reg:SI R5_REG)))
7778 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7779 (clobber (reg:SI PR_REG))
7780 (clobber (reg:SI R0_REG))])]
7781 "TARGET_SH1 && ! TARGET_HARD_SH4"
7783 [(set_attr "type" "sfunc")
7784 (set_attr "needs_delay_slot" "yes")])
7786 (define_insn "block_lump_real"
7787 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7788 (mem:BLK (reg:SI R5_REG)))
7789 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7790 (use (reg:SI R6_REG))
7791 (clobber (reg:SI PR_REG))
7792 (clobber (reg:SI T_REG))
7793 (clobber (reg:SI R4_REG))
7794 (clobber (reg:SI R5_REG))
7795 (clobber (reg:SI R6_REG))
7796 (clobber (reg:SI R0_REG))])]
7797 "TARGET_SH1 && ! TARGET_HARD_SH4"
7799 [(set_attr "type" "sfunc")
7800 (set_attr "needs_delay_slot" "yes")])
7802 (define_insn "block_move_real_i4"
7803 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7804 (mem:BLK (reg:SI R5_REG)))
7805 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7806 (clobber (reg:SI PR_REG))
7807 (clobber (reg:SI R0_REG))
7808 (clobber (reg:SI R1_REG))
7809 (clobber (reg:SI R2_REG))])]
7812 [(set_attr "type" "sfunc")
7813 (set_attr "needs_delay_slot" "yes")])
7815 (define_insn "block_lump_real_i4"
7816 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7817 (mem:BLK (reg:SI R5_REG)))
7818 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7819 (use (reg:SI R6_REG))
7820 (clobber (reg:SI PR_REG))
7821 (clobber (reg:SI T_REG))
7822 (clobber (reg:SI R4_REG))
7823 (clobber (reg:SI R5_REG))
7824 (clobber (reg:SI R6_REG))
7825 (clobber (reg:SI R0_REG))
7826 (clobber (reg:SI R1_REG))
7827 (clobber (reg:SI R2_REG))
7828 (clobber (reg:SI R3_REG))])]
7831 [(set_attr "type" "sfunc")
7832 (set_attr "needs_delay_slot" "yes")])
7834 ;; -------------------------------------------------------------------------
7835 ;; Floating point instructions.
7836 ;; -------------------------------------------------------------------------
7838 ;; ??? All patterns should have a type attribute.
7840 (define_expand "fpu_switch0"
7841 [(set (match_operand:SI 0 "" "") (match_dup 2))
7842 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7846 operands[1] = get_fpscr_rtx ();
7847 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7849 operands[2] = legitimize_pic_address (operands[2], SImode,
7850 no_new_pseudos ? operands[0] : 0);
7853 (define_expand "fpu_switch1"
7854 [(set (match_operand:SI 0 "" "") (match_dup 2))
7855 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7856 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7860 operands[1] = get_fpscr_rtx ();
7861 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7863 operands[2] = legitimize_pic_address (operands[2], SImode,
7864 no_new_pseudos ? operands[0] : 0);
7865 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7868 (define_expand "movpsi"
7869 [(set (match_operand:PSI 0 "register_operand" "")
7870 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7874 ;; The c / m alternative is a fake to guide reload to load directly into
7875 ;; fpscr, since reload doesn't know how to use post-increment.
7876 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7877 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7878 ;; predicate after reload.
7879 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7880 ;; like a mac -> gpr move.
7881 (define_insn "fpu_switch"
7882 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
7883 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
7885 && (! reload_completed
7886 || true_regnum (operands[0]) != FPSCR_REG
7887 || GET_CODE (operands[1]) != MEM
7888 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7890 ! precision stays the same
7899 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
7900 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
7903 [(set (reg:PSI FPSCR_REG)
7904 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7905 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7906 [(set (match_dup 0) (match_dup 0))]
7909 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7910 gen_rtx (MEM, PSImode,
7911 gen_rtx (POST_INC, Pmode,
7913 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7917 [(set (reg:PSI FPSCR_REG)
7918 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7920 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7923 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7924 gen_rtx (MEM, PSImode,
7925 gen_rtx (POST_INC, Pmode,
7927 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7930 ;; ??? This uses the fp unit, but has no type indicating that.
7931 ;; If we did that, this would either give a bogus latency or introduce
7932 ;; a bogus FIFO constraint.
7933 ;; Since this insn is currently only used for prologues/epilogues,
7934 ;; it is probably best to claim no function unit, which matches the
7936 (define_insn "toggle_sz"
7937 [(set (reg:PSI FPSCR_REG)
7938 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7942 (define_expand "addsf3"
7943 [(set (match_operand:SF 0 "arith_reg_operand" "")
7944 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7945 (match_operand:SF 2 "arith_reg_operand" "")))]
7946 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7951 expand_sf_binop (&gen_addsf3_i, operands);
7956 (define_insn "*addsf3_media"
7957 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7958 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7959 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7960 "TARGET_SHMEDIA_FPU"
7962 [(set_attr "type" "fparith_media")])
7964 (define_insn_and_split "unary_sf_op"
7965 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7970 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7971 (match_operator:SF 2 "unary_float_operator"
7972 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7973 (parallel [(match_operand 4
7974 "const_int_operand" "n")]))]))
7975 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7976 "TARGET_SHMEDIA_FPU"
7978 "TARGET_SHMEDIA_FPU && reload_completed"
7979 [(set (match_dup 5) (match_dup 6))]
7982 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7983 rtx op1 = gen_rtx_REG (SFmode,
7984 (true_regnum (operands[1])
7985 + (INTVAL (operands[4]) ^ endian)));
7987 operands[7] = gen_rtx_REG (SFmode,
7988 (true_regnum (operands[0])
7989 + (INTVAL (operands[3]) ^ endian)));
7990 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7992 [(set_attr "type" "fparith_media")])
7994 (define_insn_and_split "binary_sf_op"
7995 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8000 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8001 (match_operator:SF 3 "binary_float_operator"
8002 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8003 (parallel [(match_operand 5
8004 "const_int_operand" "n")]))
8005 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8006 (parallel [(match_operand 6
8007 "const_int_operand" "n")]))]))
8008 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8009 "TARGET_SHMEDIA_FPU"
8011 "TARGET_SHMEDIA_FPU && reload_completed"
8012 [(set (match_dup 7) (match_dup 8))]
8015 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8016 rtx op1 = gen_rtx_REG (SFmode,
8017 (true_regnum (operands[1])
8018 + (INTVAL (operands[5]) ^ endian)));
8019 rtx op2 = gen_rtx_REG (SFmode,
8020 (true_regnum (operands[2])
8021 + (INTVAL (operands[6]) ^ endian)));
8023 operands[7] = gen_rtx_REG (SFmode,
8024 (true_regnum (operands[0])
8025 + (INTVAL (operands[4]) ^ endian)));
8026 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8028 [(set_attr "type" "fparith_media")])
8030 (define_insn "addsf3_i"
8031 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8032 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8033 (match_operand:SF 2 "arith_reg_operand" "f")))
8034 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8037 [(set_attr "type" "fp")
8038 (set_attr "fp_mode" "single")])
8040 (define_expand "subsf3"
8041 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8042 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8043 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8044 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8049 expand_sf_binop (&gen_subsf3_i, operands);
8054 (define_insn "*subsf3_media"
8055 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8056 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8057 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8058 "TARGET_SHMEDIA_FPU"
8060 [(set_attr "type" "fparith_media")])
8062 (define_insn "subsf3_i"
8063 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8064 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8065 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8066 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8069 [(set_attr "type" "fp")
8070 (set_attr "fp_mode" "single")])
8072 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8073 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8074 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8075 ;; SH3E, we use a separate insn for SH3E mulsf3.
8077 (define_expand "mulsf3"
8078 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8079 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8080 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8081 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8085 expand_sf_binop (&gen_mulsf3_i4, operands);
8086 else if (TARGET_SH3E)
8087 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8088 if (! TARGET_SHMEDIA)
8092 (define_insn "*mulsf3_media"
8093 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8094 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8095 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8096 "TARGET_SHMEDIA_FPU"
8098 [(set_attr "type" "fparith_media")])
8100 (define_insn "mulsf3_i4"
8101 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8102 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8103 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8104 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8107 [(set_attr "type" "fp")
8108 (set_attr "fp_mode" "single")])
8110 (define_insn "mulsf3_ie"
8111 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8112 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8113 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8114 "TARGET_SH3E && ! TARGET_SH4"
8116 [(set_attr "type" "fp")])
8118 (define_insn "*mac_media"
8119 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8120 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8121 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8122 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8123 "TARGET_SHMEDIA_FPU"
8125 [(set_attr "type" "fparith_media")])
8127 (define_insn "*macsf3"
8128 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8129 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8130 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8131 (match_operand:SF 3 "arith_reg_operand" "0")))
8132 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8133 "TARGET_SH3E && ! TARGET_SH4"
8135 [(set_attr "type" "fp")
8136 (set_attr "fp_mode" "single")])
8138 (define_expand "divsf3"
8139 [(set (match_operand:SF 0 "arith_reg_operand" "")
8140 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8141 (match_operand:SF 2 "arith_reg_operand" "")))]
8142 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8147 expand_sf_binop (&gen_divsf3_i, operands);
8152 (define_insn "*divsf3_media"
8153 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8154 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8155 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8156 "TARGET_SHMEDIA_FPU"
8158 [(set_attr "type" "fdiv_media")])
8160 (define_insn "divsf3_i"
8161 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8162 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8163 (match_operand:SF 2 "arith_reg_operand" "f")))
8164 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8167 [(set_attr "type" "fdiv")
8168 (set_attr "fp_mode" "single")])
8170 (define_insn "floatdisf2"
8171 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8172 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8173 "TARGET_SHMEDIA_FPU"
8175 [(set_attr "type" "fpconv_media")])
8177 (define_expand "floatsisf2"
8178 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8179 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8180 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8185 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8190 (define_insn "*floatsisf2_media"
8191 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8192 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8193 "TARGET_SHMEDIA_FPU"
8195 [(set_attr "type" "fpconv_media")])
8197 (define_insn "floatsisf2_i4"
8198 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8199 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8200 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8203 [(set_attr "type" "fp")
8204 (set_attr "fp_mode" "single")])
8206 (define_insn "*floatsisf2_ie"
8207 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8208 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8209 "TARGET_SH3E && ! TARGET_SH4"
8211 [(set_attr "type" "fp")])
8213 (define_insn "fix_truncsfdi2"
8214 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8215 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8216 "TARGET_SHMEDIA_FPU"
8218 [(set_attr "type" "fpconv_media")])
8220 (define_expand "fix_truncsfsi2"
8221 [(set (match_operand:SI 0 "fpul_operand" "=y")
8222 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8223 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8228 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8233 (define_insn "*fix_truncsfsi2_media"
8234 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8235 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8236 "TARGET_SHMEDIA_FPU"
8238 [(set_attr "type" "fpconv_media")])
8240 (define_insn "fix_truncsfsi2_i4"
8241 [(set (match_operand:SI 0 "fpul_operand" "=y")
8242 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8243 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8246 [(set_attr "type" "ftrc_s")
8247 (set_attr "fp_mode" "single")])
8249 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8250 ;; fix_truncsfsi2_i4.
8251 ;; (define_insn "fix_truncsfsi2_i4_2"
8252 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8253 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8254 ;; (use (reg:PSI FPSCR_REG))
8255 ;; (clobber (reg:SI FPUL_REG))]
8258 ;; [(set_attr "length" "4")
8259 ;; (set_attr "fp_mode" "single")])
8262 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8263 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8264 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8265 ;; (clobber (reg:SI FPUL_REG))]
8267 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8268 ;; (use (match_dup 2))])
8269 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8271 (define_insn "*fixsfsi"
8272 [(set (match_operand:SI 0 "fpul_operand" "=y")
8273 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8274 "TARGET_SH3E && ! TARGET_SH4"
8276 [(set_attr "type" "fp")])
8278 (define_insn "cmpgtsf_t"
8279 [(set (reg:SI T_REG)
8280 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8281 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8282 "TARGET_SH3E && ! TARGET_SH4"
8284 [(set_attr "type" "fp")
8285 (set_attr "fp_mode" "single")])
8287 (define_insn "cmpeqsf_t"
8288 [(set (reg:SI T_REG)
8289 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8290 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8291 "TARGET_SH3E && ! TARGET_SH4"
8293 [(set_attr "type" "fp")
8294 (set_attr "fp_mode" "single")])
8296 (define_insn "ieee_ccmpeqsf_t"
8297 [(set (reg:SI T_REG)
8298 (ior:SI (reg:SI T_REG)
8299 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8300 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8301 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8302 "* return output_ieee_ccmpeq (insn, operands);"
8303 [(set_attr "length" "4")])
8306 (define_insn "cmpgtsf_t_i4"
8307 [(set (reg:SI T_REG)
8308 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8309 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8310 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8313 [(set_attr "type" "fp")
8314 (set_attr "fp_mode" "single")])
8316 (define_insn "cmpeqsf_t_i4"
8317 [(set (reg:SI T_REG)
8318 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8319 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8320 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8323 [(set_attr "type" "fp")
8324 (set_attr "fp_mode" "single")])
8326 (define_insn "*ieee_ccmpeqsf_t_4"
8327 [(set (reg:SI T_REG)
8328 (ior:SI (reg:SI T_REG)
8329 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8330 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8331 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8332 "TARGET_IEEE && TARGET_SH4"
8333 "* return output_ieee_ccmpeq (insn, operands);"
8334 [(set_attr "length" "4")
8335 (set_attr "fp_mode" "single")])
8337 (define_insn "cmpeqsf_media"
8338 [(set (match_operand:DI 0 "register_operand" "=r")
8339 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8340 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8341 "TARGET_SHMEDIA_FPU"
8342 "fcmpeq.s %1, %2, %0"
8343 [(set_attr "type" "fcmp_media")])
8345 (define_insn "cmpgtsf_media"
8346 [(set (match_operand:DI 0 "register_operand" "=r")
8347 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8348 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8349 "TARGET_SHMEDIA_FPU"
8350 "fcmpgt.s %1, %2, %0"
8351 [(set_attr "type" "fcmp_media")])
8353 (define_insn "cmpgesf_media"
8354 [(set (match_operand:DI 0 "register_operand" "=r")
8355 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8356 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8357 "TARGET_SHMEDIA_FPU"
8358 "fcmpge.s %1, %2, %0"
8359 [(set_attr "type" "fcmp_media")])
8361 (define_insn "cmpunsf_media"
8362 [(set (match_operand:DI 0 "register_operand" "=r")
8363 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8364 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8365 "TARGET_SHMEDIA_FPU"
8366 "fcmpun.s %1, %2, %0"
8367 [(set_attr "type" "fcmp_media")])
8369 (define_expand "cmpsf"
8370 [(set (reg:SI T_REG)
8371 (compare (match_operand:SF 0 "arith_operand" "")
8372 (match_operand:SF 1 "arith_operand" "")))]
8373 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8376 sh_compare_op0 = operands[0];
8377 sh_compare_op1 = operands[1];
8381 (define_expand "negsf2"
8382 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8383 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8384 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8389 expand_sf_unop (&gen_negsf2_i, operands);
8394 (define_insn "*negsf2_media"
8395 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8396 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8397 "TARGET_SHMEDIA_FPU"
8399 [(set_attr "type" "fmove_media")])
8401 (define_insn "negsf2_i"
8402 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8403 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8404 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8407 [(set_attr "type" "fmove")
8408 (set_attr "fp_mode" "single")])
8410 (define_expand "sqrtsf2"
8411 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8412 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8413 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8418 expand_sf_unop (&gen_sqrtsf2_i, operands);
8423 (define_insn "*sqrtsf2_media"
8424 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8425 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8426 "TARGET_SHMEDIA_FPU"
8428 [(set_attr "type" "fdiv_media")])
8430 (define_insn "sqrtsf2_i"
8431 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8432 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8433 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8436 [(set_attr "type" "fdiv")
8437 (set_attr "fp_mode" "single")])
8439 (define_expand "abssf2"
8440 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8441 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8442 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8447 expand_sf_unop (&gen_abssf2_i, operands);
8452 (define_insn "*abssf2_media"
8453 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8454 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8455 "TARGET_SHMEDIA_FPU"
8457 [(set_attr "type" "fmove_media")])
8459 (define_insn "abssf2_i"
8460 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8461 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8462 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8465 [(set_attr "type" "fmove")
8466 (set_attr "fp_mode" "single")])
8468 (define_expand "adddf3"
8469 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8470 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8471 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8472 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8477 expand_df_binop (&gen_adddf3_i, operands);
8482 (define_insn "*adddf3_media"
8483 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8484 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8485 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8486 "TARGET_SHMEDIA_FPU"
8488 [(set_attr "type" "dfparith_media")])
8490 (define_insn "adddf3_i"
8491 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8492 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8493 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8494 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8497 [(set_attr "type" "dfp_arith")
8498 (set_attr "fp_mode" "double")])
8500 (define_expand "subdf3"
8501 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8502 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8503 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8504 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8509 expand_df_binop (&gen_subdf3_i, operands);
8514 (define_insn "*subdf3_media"
8515 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8516 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8517 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8518 "TARGET_SHMEDIA_FPU"
8520 [(set_attr "type" "dfparith_media")])
8522 (define_insn "subdf3_i"
8523 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8524 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8525 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8526 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8529 [(set_attr "type" "dfp_arith")
8530 (set_attr "fp_mode" "double")])
8532 (define_expand "muldf3"
8533 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8534 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8535 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8536 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8541 expand_df_binop (&gen_muldf3_i, operands);
8546 (define_insn "*muldf3_media"
8547 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8548 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8549 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8550 "TARGET_SHMEDIA_FPU"
8552 [(set_attr "type" "dfmul_media")])
8554 (define_insn "muldf3_i"
8555 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8556 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8557 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8558 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8561 [(set_attr "type" "dfp_arith")
8562 (set_attr "fp_mode" "double")])
8564 (define_expand "divdf3"
8565 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8566 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8567 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8568 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8573 expand_df_binop (&gen_divdf3_i, operands);
8578 (define_insn "*divdf3_media"
8579 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8580 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8581 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8582 "TARGET_SHMEDIA_FPU"
8584 [(set_attr "type" "dfdiv_media")])
8586 (define_insn "divdf3_i"
8587 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8588 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8589 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8590 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8593 [(set_attr "type" "dfdiv")
8594 (set_attr "fp_mode" "double")])
8596 (define_insn "floatdidf2"
8597 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8598 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8599 "TARGET_SHMEDIA_FPU"
8601 [(set_attr "type" "dfpconv_media")])
8603 (define_expand "floatsidf2"
8604 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8605 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8606 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8611 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8617 (define_insn "*floatsidf2_media"
8618 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8619 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8620 "TARGET_SHMEDIA_FPU"
8622 [(set_attr "type" "dfpconv_media")])
8624 (define_insn "floatsidf2_i"
8625 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8626 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8627 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8630 [(set_attr "type" "dfp_conv")
8631 (set_attr "fp_mode" "double")])
8633 (define_insn "fix_truncdfdi2"
8634 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8635 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8636 "TARGET_SHMEDIA_FPU"
8638 [(set_attr "type" "dfpconv_media")])
8640 (define_expand "fix_truncdfsi2"
8641 [(set (match_operand:SI 0 "fpul_operand" "")
8642 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8643 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8648 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8654 (define_insn "*fix_truncdfsi2_media"
8655 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8656 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8657 "TARGET_SHMEDIA_FPU"
8659 [(set_attr "type" "dfpconv_media")])
8661 (define_insn "fix_truncdfsi2_i"
8662 [(set (match_operand:SI 0 "fpul_operand" "=y")
8663 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8664 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8667 [(set_attr "type" "dfp_conv")
8668 (set_attr "dfp_comp" "no")
8669 (set_attr "fp_mode" "double")])
8671 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8672 ;; fix_truncdfsi2_i.
8673 ;; (define_insn "fix_truncdfsi2_i4"
8674 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8675 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8676 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8677 ;; (clobber (reg:SI FPUL_REG))]
8680 ;; [(set_attr "length" "4")
8681 ;; (set_attr "fp_mode" "double")])
8684 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8685 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8686 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8687 ;; (clobber (reg:SI FPUL_REG))]
8689 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8690 ;; (use (match_dup 2))])
8691 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8693 (define_insn "cmpgtdf_t"
8694 [(set (reg:SI T_REG)
8695 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8696 (match_operand:DF 1 "arith_reg_operand" "f")))
8697 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8700 [(set_attr "type" "dfp_cmp")
8701 (set_attr "fp_mode" "double")])
8703 (define_insn "cmpeqdf_t"
8704 [(set (reg:SI T_REG)
8705 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8706 (match_operand:DF 1 "arith_reg_operand" "f")))
8707 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8710 [(set_attr "type" "dfp_cmp")
8711 (set_attr "fp_mode" "double")])
8713 (define_insn "*ieee_ccmpeqdf_t"
8714 [(set (reg:SI T_REG)
8715 (ior:SI (reg:SI T_REG)
8716 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8717 (match_operand:DF 1 "arith_reg_operand" "f"))))
8718 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8719 "TARGET_IEEE && TARGET_SH4"
8720 "* return output_ieee_ccmpeq (insn, operands);"
8721 [(set_attr "length" "4")
8722 (set_attr "fp_mode" "double")])
8724 (define_insn "cmpeqdf_media"
8725 [(set (match_operand:DI 0 "register_operand" "=r")
8726 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8727 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8728 "TARGET_SHMEDIA_FPU"
8730 [(set_attr "type" "fcmp_media")])
8732 (define_insn "cmpgtdf_media"
8733 [(set (match_operand:DI 0 "register_operand" "=r")
8734 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8735 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8736 "TARGET_SHMEDIA_FPU"
8738 [(set_attr "type" "fcmp_media")])
8740 (define_insn "cmpgedf_media"
8741 [(set (match_operand:DI 0 "register_operand" "=r")
8742 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8743 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8744 "TARGET_SHMEDIA_FPU"
8746 [(set_attr "type" "fcmp_media")])
8748 (define_insn "cmpundf_media"
8749 [(set (match_operand:DI 0 "register_operand" "=r")
8750 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8751 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8752 "TARGET_SHMEDIA_FPU"
8754 [(set_attr "type" "fcmp_media")])
8756 (define_expand "cmpdf"
8757 [(set (reg:SI T_REG)
8758 (compare (match_operand:DF 0 "arith_operand" "")
8759 (match_operand:DF 1 "arith_operand" "")))]
8760 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8763 sh_compare_op0 = operands[0];
8764 sh_compare_op1 = operands[1];
8768 (define_expand "negdf2"
8769 [(set (match_operand:DF 0 "arith_reg_operand" "")
8770 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8771 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8776 expand_df_unop (&gen_negdf2_i, operands);
8781 (define_insn "*negdf2_media"
8782 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8783 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8784 "TARGET_SHMEDIA_FPU"
8786 [(set_attr "type" "fmove_media")])
8788 (define_insn "negdf2_i"
8789 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8790 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8791 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8794 [(set_attr "type" "fmove")
8795 (set_attr "fp_mode" "double")])
8797 (define_expand "sqrtdf2"
8798 [(set (match_operand:DF 0 "arith_reg_operand" "")
8799 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8800 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8805 expand_df_unop (&gen_sqrtdf2_i, operands);
8810 (define_insn "*sqrtdf2_media"
8811 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8812 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8813 "TARGET_SHMEDIA_FPU"
8815 [(set_attr "type" "dfdiv_media")])
8817 (define_insn "sqrtdf2_i"
8818 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8819 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8820 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8823 [(set_attr "type" "dfdiv")
8824 (set_attr "fp_mode" "double")])
8826 (define_expand "absdf2"
8827 [(set (match_operand:DF 0 "arith_reg_operand" "")
8828 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8829 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8834 expand_df_unop (&gen_absdf2_i, operands);
8839 (define_insn "*absdf2_media"
8840 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8841 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8842 "TARGET_SHMEDIA_FPU"
8844 [(set_attr "type" "fmove_media")])
8846 (define_insn "absdf2_i"
8847 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8848 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8849 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8852 [(set_attr "type" "fmove")
8853 (set_attr "fp_mode" "double")])
8855 (define_expand "extendsfdf2"
8856 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8857 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8858 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8863 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8869 (define_insn "*extendsfdf2_media"
8870 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8871 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8872 "TARGET_SHMEDIA_FPU"
8874 [(set_attr "type" "dfpconv_media")])
8876 (define_insn "extendsfdf2_i4"
8877 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8878 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8879 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8882 [(set_attr "type" "fp")
8883 (set_attr "fp_mode" "double")])
8885 (define_expand "truncdfsf2"
8886 [(set (match_operand:SF 0 "fpul_operand" "")
8887 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8888 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8893 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8899 (define_insn "*truncdfsf2_media"
8900 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8901 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8902 "TARGET_SHMEDIA_FPU"
8904 [(set_attr "type" "dfpconv_media")])
8906 (define_insn "truncdfsf2_i4"
8907 [(set (match_operand:SF 0 "fpul_operand" "=y")
8908 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8909 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8912 [(set_attr "type" "fp")
8913 (set_attr "fp_mode" "double")])
8915 ;; Bit field extract patterns. These give better code for packed bitfields,
8916 ;; because they allow auto-increment addresses to be generated.
8918 (define_expand "insv"
8919 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8920 (match_operand:SI 1 "immediate_operand" "")
8921 (match_operand:SI 2 "immediate_operand" ""))
8922 (match_operand:SI 3 "general_operand" ""))]
8923 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8926 rtx addr_target, orig_address, shift_reg, qi_val;
8927 HOST_WIDE_INT bitsize, size, v;
8928 rtx x = operands[3];
8930 /* ??? expmed doesn't care for non-register predicates. */
8931 if (! memory_operand (operands[0], VOIDmode)
8932 || ! immediate_operand (operands[1], VOIDmode)
8933 || ! immediate_operand (operands[2], VOIDmode)
8934 || ! general_operand (x, VOIDmode))
8936 /* If this isn't a 16 / 24 / 32 bit field, or if
8937 it doesn't start on a byte boundary, then fail. */
8938 bitsize = INTVAL (operands[1]);
8939 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8940 || (INTVAL (operands[2]) % 8) != 0)
8944 orig_address = XEXP (operands[0], 0);
8945 shift_reg = gen_reg_rtx (SImode);
8946 if (GET_CODE (x) == CONST_INT)
8949 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8953 emit_insn (gen_movsi (shift_reg, operands[3]));
8954 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8956 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8958 operands[0] = replace_equiv_address (operands[0], addr_target);
8959 emit_insn (gen_movqi (operands[0], qi_val));
8963 if (GET_CODE (x) == CONST_INT)
8965 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8968 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8969 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8971 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8972 emit_insn (gen_movqi (operands[0], qi_val));
8978 ;; -------------------------------------------------------------------------
8980 ;; -------------------------------------------------------------------------
8982 ;; This matches cases where a stack pointer increment at the start of the
8983 ;; epilogue combines with a stack slot read loading the return value.
8986 [(set (match_operand:SI 0 "arith_reg_operand" "")
8987 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8988 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8989 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8992 ;; See the comment on the dt combiner pattern above.
8995 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8996 (plus:SI (match_dup 0)
8999 (eq:SI (match_dup 0)
9004 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9005 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9006 ;; reload when the constant is too large for a reg+offset address.
9008 ;; ??? We would get much better code if this was done in reload. This would
9009 ;; require modifying find_reloads_address to recognize that if the constant
9010 ;; is out-of-range for an immediate add, then we get better code by reloading
9011 ;; the constant into a register than by reloading the sum into a register,
9012 ;; since the former is one instruction shorter if the address does not need
9013 ;; to be offsettable. Unfortunately this does not work, because there is
9014 ;; only one register, r0, that can be used as an index register. This register
9015 ;; is also the function return value register. So, if we try to force reload
9016 ;; to use double-reg addresses, then we end up with some instructions that
9017 ;; need to use r0 twice. The only way to fix this is to change the calling
9018 ;; convention so that r0 is not used to return values.
9021 [(set (match_operand:SI 0 "register_operand" "=r")
9022 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9023 (set (mem:SI (match_dup 0))
9024 (match_operand:SI 2 "general_movsrc_operand" ""))]
9025 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9026 "mov.l %2,@(%0,%1)")
9029 [(set (match_operand:SI 0 "register_operand" "=r")
9030 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9031 (set (match_operand:SI 2 "general_movdst_operand" "")
9032 (mem:SI (match_dup 0)))]
9033 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9034 "mov.l @(%0,%1),%2")
9037 [(set (match_operand:SI 0 "register_operand" "=r")
9038 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9039 (set (mem:HI (match_dup 0))
9040 (match_operand:HI 2 "general_movsrc_operand" ""))]
9041 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9042 "mov.w %2,@(%0,%1)")
9045 [(set (match_operand:SI 0 "register_operand" "=r")
9046 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9047 (set (match_operand:HI 2 "general_movdst_operand" "")
9048 (mem:HI (match_dup 0)))]
9049 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9050 "mov.w @(%0,%1),%2")
9053 [(set (match_operand:SI 0 "register_operand" "=r")
9054 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9055 (set (mem:QI (match_dup 0))
9056 (match_operand:QI 2 "general_movsrc_operand" ""))]
9057 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9058 "mov.b %2,@(%0,%1)")
9061 [(set (match_operand:SI 0 "register_operand" "=r")
9062 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9063 (set (match_operand:QI 2 "general_movdst_operand" "")
9064 (mem:QI (match_dup 0)))]
9065 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9066 "mov.b @(%0,%1),%2")
9069 [(set (match_operand:SI 0 "register_operand" "=r")
9070 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9071 (set (mem:SF (match_dup 0))
9072 (match_operand:SF 2 "general_movsrc_operand" ""))]
9073 "TARGET_SH1 && REGNO (operands[0]) == 0
9074 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9075 || (GET_CODE (operands[2]) == SUBREG
9076 && REGNO (SUBREG_REG (operands[2])) < 16))
9077 && reg_unused_after (operands[0], insn)"
9078 "mov.l %2,@(%0,%1)")
9081 [(set (match_operand:SI 0 "register_operand" "=r")
9082 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9083 (set (match_operand:SF 2 "general_movdst_operand" "")
9085 (mem:SF (match_dup 0)))]
9086 "TARGET_SH1 && REGNO (operands[0]) == 0
9087 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9088 || (GET_CODE (operands[2]) == SUBREG
9089 && REGNO (SUBREG_REG (operands[2])) < 16))
9090 && reg_unused_after (operands[0], insn)"
9091 "mov.l @(%0,%1),%2")
9094 [(set (match_operand:SI 0 "register_operand" "=r")
9095 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9096 (set (mem:SF (match_dup 0))
9097 (match_operand:SF 2 "general_movsrc_operand" ""))]
9098 "TARGET_SH3E && REGNO (operands[0]) == 0
9099 && ((GET_CODE (operands[2]) == REG
9100 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9101 || (GET_CODE (operands[2]) == SUBREG
9102 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9103 && reg_unused_after (operands[0], insn)"
9104 "fmov{.s|} %2,@(%0,%1)")
9107 [(set (match_operand:SI 0 "register_operand" "=r")
9108 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9109 (set (match_operand:SF 2 "general_movdst_operand" "")
9111 (mem:SF (match_dup 0)))]
9112 "TARGET_SH3E && REGNO (operands[0]) == 0
9113 && ((GET_CODE (operands[2]) == REG
9114 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9115 || (GET_CODE (operands[2]) == SUBREG
9116 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9117 && reg_unused_after (operands[0], insn)"
9118 "fmov{.s|} @(%0,%1),%2")
9120 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9121 (define_insn "sp_switch_1"
9128 xoperands[0] = sp_switch;
9129 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9130 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9131 return \"mov r0,r15\";
9133 [(set_attr "length" "10")])
9135 ;; Switch back to the original stack for interrupt functions with the
9136 ;; sp_switch attribute. */
9137 (define_insn "sp_switch_2"
9140 "mov.l @r15+,r15\;mov.l @r15+,r0"
9141 [(set_attr "length" "4")])
9143 ;; Integer vector moves
9145 (define_expand "movv8qi"
9146 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9147 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9149 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9151 (define_insn "movv8qi_i"
9152 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9153 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9155 && (register_operand (operands[0], V8QImode)
9156 || register_operand (operands[1], V8QImode))"
9163 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9164 (set_attr "length" "4,4,16,4,4")])
9167 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9168 (subreg:V8QI (const_int 0) 0))]
9171 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9172 (const_int 0) (const_int 0) (const_int 0)
9173 (const_int 0) (const_int 0)]))])
9176 [(set (match_operand 0 "arith_reg_dest" "")
9177 (match_operand 1 "sh_rep_vec" ""))]
9178 "TARGET_SHMEDIA && reload_completed
9179 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9180 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9181 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9182 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9183 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9184 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9185 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9186 [(set (match_dup 0) (match_dup 1))
9190 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9191 rtx elt1 = XVECEXP (operands[1], 0, 1);
9194 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9198 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9199 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9201 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9202 operands[1] = XVECEXP (operands[1], 0, 0);
9205 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9206 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9207 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9208 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9211 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9213 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9219 [(set (match_operand 0 "arith_reg_dest" "")
9220 (match_operand 1 "sh_const_vec" ""))]
9221 "TARGET_SHMEDIA && reload_completed
9222 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9223 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9224 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9225 [(set (match_dup 0) (match_dup 1))]
9228 rtx v = operands[1];
9229 enum machine_mode new_mode
9230 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9232 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9234 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9237 (define_expand "movv2hi"
9238 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9239 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9241 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9243 (define_insn "movv2hi_i"
9244 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9245 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9247 && (register_operand (operands[0], V2HImode)
9248 || register_operand (operands[1], V2HImode))"
9255 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9256 (set_attr "length" "4,4,16,4,4")])
9258 (define_expand "movv4hi"
9259 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9260 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9262 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9264 (define_insn "movv4hi_i"
9265 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9266 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9268 && (register_operand (operands[0], V4HImode)
9269 || register_operand (operands[1], V4HImode))"
9276 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9277 (set_attr "length" "4,4,16,4,4")])
9279 (define_expand "movv2si"
9280 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9281 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9283 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9285 (define_insn "movv2si_i"
9286 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9287 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9289 && (register_operand (operands[0], V2SImode)
9290 || register_operand (operands[1], V2SImode))"
9297 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9298 (set_attr "length" "4,4,16,4,4")])
9300 ;; Multimedia Intrinsics
9302 (define_insn "absv2si2"
9303 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9304 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9307 [(set_attr "type" "mcmp_media")])
9309 (define_insn "absv4hi2"
9310 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9311 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9314 [(set_attr "type" "mcmp_media")])
9316 (define_insn "addv2si3"
9317 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9318 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9319 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9322 [(set_attr "type" "arith_media")])
9324 (define_insn "addv4hi3"
9325 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9326 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9327 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9330 [(set_attr "type" "arith_media")])
9332 (define_insn "ssaddv2si3"
9333 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9334 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9335 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9337 "madds.l %1, %2, %0"
9338 [(set_attr "type" "mcmp_media")])
9340 (define_insn "usaddv8qi3"
9341 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9342 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9343 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9345 "madds.ub %1, %2, %0"
9346 [(set_attr "type" "mcmp_media")])
9348 (define_insn "ssaddv4hi3"
9349 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9350 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9351 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9353 "madds.w %1, %2, %0"
9354 [(set_attr "type" "mcmp_media")])
9356 (define_insn "negcmpeqv8qi"
9357 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9358 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9359 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9361 "mcmpeq.b %N1, %N2, %0"
9362 [(set_attr "type" "mcmp_media")])
9364 (define_insn "negcmpeqv2si"
9365 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9366 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9367 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9369 "mcmpeq.l %N1, %N2, %0"
9370 [(set_attr "type" "mcmp_media")])
9372 (define_insn "negcmpeqv4hi"
9373 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9374 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9375 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9377 "mcmpeq.w %N1, %N2, %0"
9378 [(set_attr "type" "mcmp_media")])
9380 (define_insn "negcmpgtuv8qi"
9381 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9382 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9383 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9385 "mcmpgt.ub %N1, %N2, %0"
9386 [(set_attr "type" "mcmp_media")])
9388 (define_insn "negcmpgtv2si"
9389 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9390 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9391 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9393 "mcmpgt.l %N1, %N2, %0"
9394 [(set_attr "type" "mcmp_media")])
9396 (define_insn "negcmpgtv4hi"
9397 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9398 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9399 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9401 "mcmpgt.w %N1, %N2, %0"
9402 [(set_attr "type" "mcmp_media")])
9405 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9406 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9407 (match_operand:DI 2 "arith_reg_operand" "r"))
9408 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9409 (not:DI (match_dup 2)))))]
9412 [(set_attr "type" "arith_media")])
9414 (define_insn "mcnvs_lw"
9415 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9417 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9418 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9420 "mcnvs.lw %N1, %N2, %0"
9421 [(set_attr "type" "mcmp_media")])
9423 (define_insn "mcnvs_wb"
9424 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9426 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9427 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9429 "mcnvs.wb %N1, %N2, %0"
9430 [(set_attr "type" "mcmp_media")])
9432 (define_insn "mcnvs_wub"
9433 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9435 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9436 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9438 "mcnvs.wub %N1, %N2, %0"
9439 [(set_attr "type" "mcmp_media")])
9441 (define_insn "mextr_rl"
9442 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9443 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9444 (match_operand:HI 3 "mextr_bit_offset" "i"))
9445 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9446 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9447 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9450 static char templ[16];
9452 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9453 (int) INTVAL (operands[3]) >> 3);
9456 [(set_attr "type" "arith_media")])
9458 (define_insn "*mextr_lr"
9459 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9460 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9461 (match_operand:HI 3 "mextr_bit_offset" "i"))
9462 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9463 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9464 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9467 static char templ[16];
9469 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9470 (int) INTVAL (operands[4]) >> 3);
9473 [(set_attr "type" "arith_media")])
9475 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9476 ; vector then varies depending on endianness.
9477 (define_expand "mextr1"
9478 [(match_operand:DI 0 "arith_reg_dest" "")
9479 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9480 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9484 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9485 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9489 (define_expand "mextr2"
9490 [(match_operand:DI 0 "arith_reg_dest" "")
9491 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9492 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9496 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9497 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9501 (define_expand "mextr3"
9502 [(match_operand:DI 0 "arith_reg_dest" "")
9503 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9504 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9508 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9509 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9513 (define_expand "mextr4"
9514 [(match_operand:DI 0 "arith_reg_dest" "")
9515 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9516 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9520 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9521 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9525 (define_expand "mextr5"
9526 [(match_operand:DI 0 "arith_reg_dest" "")
9527 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9528 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9532 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9533 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9537 (define_expand "mextr6"
9538 [(match_operand:DI 0 "arith_reg_dest" "")
9539 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9540 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9544 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9545 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9549 (define_expand "mextr7"
9550 [(match_operand:DI 0 "arith_reg_dest" "")
9551 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9552 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9556 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9557 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9561 (define_expand "mmacfx_wl"
9562 [(match_operand:V2SI 0 "arith_reg_dest" "")
9563 (match_operand:V2HI 1 "extend_reg_operand" "")
9564 (match_operand:V2HI 2 "extend_reg_operand" "")
9565 (match_operand:V2SI 3 "arith_reg_operand" "")]
9569 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9570 operands[1], operands[2]));
9574 (define_insn "mmacfx_wl_i"
9575 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9577 (match_operand:V2SI 1 "arith_reg_operand" "0")
9582 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9583 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9586 "mmacfx.wl %2, %3, %0"
9587 [(set_attr "type" "mac_media")])
9589 (define_expand "mmacnfx_wl"
9590 [(match_operand:V2SI 0 "arith_reg_dest" "")
9591 (match_operand:V2HI 1 "extend_reg_operand" "")
9592 (match_operand:V2HI 2 "extend_reg_operand" "")
9593 (match_operand:V2SI 3 "arith_reg_operand" "")]
9597 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9598 operands[1], operands[2]));
9602 (define_insn "mmacnfx_wl_i"
9603 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9605 (match_operand:V2SI 1 "arith_reg_operand" "0")
9610 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9611 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9614 "mmacnfx.wl %2, %3, %0"
9615 [(set_attr "type" "mac_media")])
9617 (define_insn "mulv2si3"
9618 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9619 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9620 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9623 [(set_attr "type" "d2mpy_media")])
9625 (define_insn "mulv4hi3"
9626 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9627 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9628 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9631 [(set_attr "type" "dmpy_media")])
9633 (define_insn "mmulfx_l"
9634 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9638 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9639 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9642 "mmulfx.l %1, %2, %0"
9643 [(set_attr "type" "d2mpy_media")])
9645 (define_insn "mmulfx_w"
9646 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9650 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9651 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9654 "mmulfx.w %1, %2, %0"
9655 [(set_attr "type" "dmpy_media")])
9657 (define_insn "mmulfxrp_w"
9658 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9663 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9664 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9668 "mmulfxrp.w %1, %2, %0"
9669 [(set_attr "type" "dmpy_media")])
9671 (define_expand "mmulhi_wl"
9672 [(match_operand:V2SI 0 "arith_reg_dest" "")
9673 (match_operand:V4HI 1 "arith_reg_operand" "")
9674 (match_operand:V4HI 2 "arith_reg_operand" "")]
9678 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9679 (operands[0], operands[1], operands[2]));
9683 (define_expand "mmullo_wl"
9684 [(match_operand:V2SI 0 "arith_reg_dest" "")
9685 (match_operand:V4HI 1 "arith_reg_operand" "")
9686 (match_operand:V4HI 2 "arith_reg_operand" "")]
9690 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9691 (operands[0], operands[1], operands[2]));
9695 (define_insn "mmul23_wl"
9696 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9699 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9700 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9701 (parallel [(const_int 2) (const_int 3)])))]
9703 "* return (TARGET_LITTLE_ENDIAN
9704 ? \"mmulhi.wl %1, %2, %0\"
9705 : \"mmullo.wl %1, %2, %0\");"
9706 [(set_attr "type" "dmpy_media")])
9708 (define_insn "mmul01_wl"
9709 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9712 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9713 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9714 (parallel [(const_int 0) (const_int 1)])))]
9716 "* return (TARGET_LITTLE_ENDIAN
9717 ? \"mmullo.wl %1, %2, %0\"
9718 : \"mmulhi.wl %1, %2, %0\");"
9719 [(set_attr "type" "dmpy_media")])
9721 (define_expand "mmulsum_wq"
9722 [(match_operand:DI 0 "arith_reg_dest" "")
9723 (match_operand:V4HI 1 "arith_reg_operand" "")
9724 (match_operand:V4HI 2 "arith_reg_operand" "")
9725 (match_operand:DI 3 "arith_reg_operand" "")]
9729 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9730 operands[1], operands[2]));
9734 (define_insn "mmulsum_wq_i"
9735 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9736 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9741 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9742 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9743 (parallel [(const_int 0)]))
9744 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9745 (sign_extend:V4DI (match_dup 3)))
9746 (parallel [(const_int 1)])))
9748 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9749 (sign_extend:V4DI (match_dup 3)))
9750 (parallel [(const_int 2)]))
9751 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9752 (sign_extend:V4DI (match_dup 3)))
9753 (parallel [(const_int 3)]))))))]
9755 "mmulsum.wq %2, %3, %0"
9756 [(set_attr "type" "mac_media")])
9758 (define_expand "mperm_w"
9759 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9760 (match_operand:V4HI 1 "arith_reg_operand" "r")
9761 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9765 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9766 (operands[0], operands[1], operands[2]));
9770 ; This use of vec_select isn't exactly correct according to rtl.texi
9771 ; (because not constant), but it seems a straightforward extension.
9772 (define_insn "mperm_w_little"
9773 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9775 (match_operand:V4HI 1 "arith_reg_operand" "r")
9777 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9778 (const_int 2) (const_int 0))
9779 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9780 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9781 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9782 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9783 "mperm.w %1, %N2, %0"
9784 [(set_attr "type" "arith_media")])
9786 (define_insn "mperm_w_big"
9787 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9789 (match_operand:V4HI 1 "arith_reg_operand" "r")
9791 [(zero_extract:QI (not:QI (match_operand:QI 2
9792 "extend_reg_or_0_operand" "rU"))
9793 (const_int 2) (const_int 0))
9794 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9795 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9796 (zero_extract:QI (not:QI (match_dup 2))
9797 (const_int 2) (const_int 6))])))]
9798 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9799 "mperm.w %1, %N2, %0"
9800 [(set_attr "type" "arith_media")])
9802 (define_insn "mperm_w0"
9803 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9804 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9805 "trunc_hi_operand" "r"))))]
9807 "mperm.w %1, r63, %0"
9808 [(set_attr "type" "arith_media")])
9810 (define_expand "msad_ubq"
9811 [(match_operand:DI 0 "arith_reg_dest" "")
9812 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9813 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9814 (match_operand:DI 3 "arith_reg_operand" "")]
9818 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9819 operands[1], operands[2]));
9823 (define_insn "msad_ubq_i"
9824 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9829 (match_operand:DI 1 "arith_reg_operand" "0")
9830 (abs:DI (vec_select:DI
9833 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9835 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9836 (parallel [(const_int 0)]))))
9837 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9838 (zero_extend:V8DI (match_dup 3)))
9839 (parallel [(const_int 1)]))))
9841 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9842 (zero_extend:V8DI (match_dup 3)))
9843 (parallel [(const_int 2)])))
9844 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9845 (zero_extend:V8DI (match_dup 3)))
9846 (parallel [(const_int 3)])))))
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 4)])))
9852 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9853 (zero_extend:V8DI (match_dup 3)))
9854 (parallel [(const_int 5)]))))
9856 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9857 (zero_extend:V8DI (match_dup 3)))
9858 (parallel [(const_int 6)])))
9859 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9860 (zero_extend:V8DI (match_dup 3)))
9861 (parallel [(const_int 7)])))))))]
9863 "msad.ubq %N2, %N3, %0"
9864 [(set_attr "type" "mac_media")])
9866 (define_insn "mshalds_l"
9867 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9870 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9871 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9874 "mshalds.l %1, %2, %0"
9875 [(set_attr "type" "mcmp_media")])
9877 (define_insn "mshalds_w"
9878 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9881 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9882 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9885 "mshalds.w %1, %2, %0"
9886 [(set_attr "type" "mcmp_media")])
9888 (define_insn "ashrv2si3"
9889 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9890 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9891 (match_operand:DI 2 "arith_reg_operand" "r")))]
9893 "mshard.l %1, %2, %0"
9894 [(set_attr "type" "arith_media")])
9896 (define_insn "ashrv4hi3"
9897 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9898 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9899 (match_operand:DI 2 "arith_reg_operand" "r")))]
9901 "mshard.w %1, %2, %0"
9902 [(set_attr "type" "arith_media")])
9904 (define_insn "mshards_q"
9905 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9907 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9908 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9910 "mshards.q %1, %N2, %0"
9911 [(set_attr "type" "mcmp_media")])
9913 (define_expand "mshfhi_b"
9914 [(match_operand:V8QI 0 "arith_reg_dest" "")
9915 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9916 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9920 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9921 (operands[0], operands[1], operands[2]));
9925 (define_expand "mshflo_b"
9926 [(match_operand:V8QI 0 "arith_reg_dest" "")
9927 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9928 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9932 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9933 (operands[0], operands[1], operands[2]));
9937 (define_insn "mshf4_b"
9939 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9941 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9942 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9943 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9944 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9946 "* return (TARGET_LITTLE_ENDIAN
9947 ? \"mshfhi.b %N1, %N2, %0\"
9948 : \"mshflo.b %N1, %N2, %0\");"
9949 [(set_attr "type" "arith_media")])
9951 (define_insn "mshf0_b"
9953 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9955 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9956 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9957 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9958 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9960 "* return (TARGET_LITTLE_ENDIAN
9961 ? \"mshflo.b %N1, %N2, %0\"
9962 : \"mshfhi.b %N1, %N2, %0\");"
9963 [(set_attr "type" "arith_media")])
9965 (define_expand "mshfhi_l"
9966 [(match_operand:V2SI 0 "arith_reg_dest" "")
9967 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9968 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9972 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9973 (operands[0], operands[1], operands[2]));
9977 (define_expand "mshflo_l"
9978 [(match_operand:V2SI 0 "arith_reg_dest" "")
9979 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9980 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9984 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9985 (operands[0], operands[1], operands[2]));
9989 (define_insn "mshf4_l"
9990 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9992 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9993 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9994 (parallel [(const_int 1) (const_int 3)])))]
9996 "* return (TARGET_LITTLE_ENDIAN
9997 ? \"mshfhi.l %N1, %N2, %0\"
9998 : \"mshflo.l %N1, %N2, %0\");"
9999 [(set_attr "type" "arith_media")])
10001 (define_insn "mshf0_l"
10002 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10004 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10005 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10006 (parallel [(const_int 0) (const_int 2)])))]
10008 "* return (TARGET_LITTLE_ENDIAN
10009 ? \"mshflo.l %N1, %N2, %0\"
10010 : \"mshfhi.l %N1, %N2, %0\");"
10011 [(set_attr "type" "arith_media")])
10013 (define_expand "mshfhi_w"
10014 [(match_operand:V4HI 0 "arith_reg_dest" "")
10015 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10016 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10020 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10021 (operands[0], operands[1], operands[2]));
10025 (define_expand "mshflo_w"
10026 [(match_operand:V4HI 0 "arith_reg_dest" "")
10027 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10028 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10032 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10033 (operands[0], operands[1], operands[2]));
10037 (define_insn "mshf4_w"
10038 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10040 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10041 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10042 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10044 "* return (TARGET_LITTLE_ENDIAN
10045 ? \"mshfhi.w %N1, %N2, %0\"
10046 : \"mshflo.w %N1, %N2, %0\");"
10047 [(set_attr "type" "arith_media")])
10049 (define_insn "mshf0_w"
10050 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10052 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10053 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10054 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10056 "* return (TARGET_LITTLE_ENDIAN
10057 ? \"mshflo.w %N1, %N2, %0\"
10058 : \"mshfhi.w %N1, %N2, %0\");"
10059 [(set_attr "type" "arith_media")])
10061 (define_insn "mshflo_w_x"
10062 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10064 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10065 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10066 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10068 "mshflo.w %N1, %N2, %0"
10069 [(set_attr "type" "arith_media")])
10071 /* These are useful to expand ANDs and as combiner patterns. */
10072 (define_insn_and_split "mshfhi_l_di"
10073 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10074 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10076 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10077 (const_int -4294967296))))]
10080 mshfhi.l %N1, %N2, %0
10082 "TARGET_SHMEDIA && reload_completed
10083 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10084 [(set (match_dup 3) (match_dup 4))
10085 (set (match_dup 5) (match_dup 6))]
10088 operands[3] = gen_lowpart (SImode, operands[0]);
10089 operands[4] = gen_highpart (SImode, operands[1]);
10090 operands[5] = gen_highpart (SImode, operands[0]);
10091 operands[6] = gen_highpart (SImode, operands[2]);
10093 [(set_attr "type" "arith_media")])
10095 (define_insn "*mshfhi_l_di_rev"
10096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10097 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10098 (const_int -4294967296))
10099 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10102 "mshfhi.l %N2, %N1, %0"
10103 [(set_attr "type" "arith_media")])
10106 [(set (match_operand:DI 0 "arith_reg_dest" "")
10107 (ior:DI (zero_extend:DI (match_operand:SI 1
10108 "extend_reg_or_0_operand" ""))
10109 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10110 (const_int -4294967296))))
10111 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10116 emit_insn (gen_ashldi3_media (operands[3],
10117 simplify_gen_subreg (DImode, operands[1],
10120 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10124 (define_insn "mshflo_l_di"
10125 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10126 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10127 (const_int 4294967295))
10128 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10132 "mshflo.l %N1, %N2, %0"
10133 [(set_attr "type" "arith_media")])
10135 (define_insn "*mshflo_l_di_rev"
10136 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10137 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10139 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10140 (const_int 4294967295))))]
10143 "mshflo.l %N2, %N1, %0"
10144 [(set_attr "type" "arith_media")])
10146 ;; Combiner pattern for trampoline initialization.
10147 (define_insn_and_split "*double_shori"
10148 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10149 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10151 (match_operand:DI 2 "const_int_operand" "n")))]
10153 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10155 "rtx_equal_p (operands[0], operands[1])"
10159 HOST_WIDE_INT v = INTVAL (operands[2]);
10161 emit_insn (gen_shori_media (operands[0], operands[0],
10162 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10163 emit_insn (gen_shori_media (operands[0], operands[0],
10164 gen_int_mode (v, HImode)));
10169 (define_insn "*mshflo_l_di_x"
10170 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10171 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10173 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10177 "mshflo.l %N1, %N2, %0"
10178 [(set_attr "type" "arith_media")])
10180 (define_insn_and_split "concat_v2sf"
10181 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10182 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10183 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10184 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10188 mshflo.l %N1, %N2, %0
10191 "TARGET_SHMEDIA && reload_completed
10192 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10193 [(set (match_dup 3) (match_dup 1))
10194 (set (match_dup 4) (match_dup 2))]
10197 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10198 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10200 [(set_attr "type" "arith_media")])
10202 (define_insn "*mshflo_l_di_x_rev"
10203 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10204 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10206 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10209 "mshflo.l %N2, %N1, %0"
10210 [(set_attr "type" "arith_media")])
10212 (define_insn "ashlv2si3"
10213 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10214 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10215 (match_operand:DI 2 "arith_reg_operand" "r")))]
10217 "mshlld.l %1, %2, %0"
10218 [(set_attr "type" "arith_media")])
10220 (define_insn "ashlv4hi3"
10221 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10222 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10223 (match_operand:DI 2 "arith_reg_operand" "r")))]
10225 "mshlld.w %1, %2, %0"
10226 [(set_attr "type" "arith_media")])
10228 (define_insn "lshrv2si3"
10229 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10230 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10231 (match_operand:DI 2 "arith_reg_operand" "r")))]
10233 "mshlrd.l %1, %2, %0"
10234 [(set_attr "type" "arith_media")])
10236 (define_insn "lshrv4hi3"
10237 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10238 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10239 (match_operand:DI 2 "arith_reg_operand" "r")))]
10241 "mshlrd.w %1, %2, %0"
10242 [(set_attr "type" "arith_media")])
10244 (define_insn "subv2si3"
10245 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10246 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10247 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10249 "msub.l %N1, %2, %0"
10250 [(set_attr "type" "arith_media")])
10252 (define_insn "subv4hi3"
10253 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10254 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10255 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10257 "msub.w %N1, %2, %0"
10258 [(set_attr "type" "arith_media")])
10260 (define_insn "sssubv2si3"
10261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10262 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10263 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10265 "msubs.l %N1, %2, %0"
10266 [(set_attr "type" "mcmp_media")])
10268 (define_insn "ussubv8qi3"
10269 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10270 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10271 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10273 "msubs.ub %1, %2, %0"
10274 [(set_attr "type" "mcmp_media")])
10276 (define_insn "sssubv4hi3"
10277 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10278 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10279 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10281 "msubs.w %N1, %2, %0"
10282 [(set_attr "type" "mcmp_media")])
10284 ;; Floating Point Intrinsics
10286 (define_insn "fcosa_s"
10287 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10288 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10292 [(set_attr "type" "atrans_media")])
10294 (define_insn "fsina_s"
10295 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10296 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10300 [(set_attr "type" "atrans_media")])
10302 (define_insn "fipr"
10303 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10304 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10305 "fp_arith_reg_operand" "f")
10306 (match_operand:V4SF 2
10307 "fp_arith_reg_operand" "f"))
10308 (parallel [(const_int 0)]))
10309 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10310 (parallel [(const_int 1)])))
10311 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10312 (parallel [(const_int 2)]))
10313 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10314 (parallel [(const_int 3)])))))]
10317 [(set_attr "type" "fparith_media")])
10319 (define_insn "fsrra_s"
10320 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10321 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10325 [(set_attr "type" "atrans_media")])
10327 (define_insn "ftrv"
10328 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10332 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10333 (parallel [(const_int 0) (const_int 5)
10334 (const_int 10) (const_int 15)]))
10335 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10337 (vec_select:V4SF (match_dup 1)
10338 (parallel [(const_int 4) (const_int 9)
10339 (const_int 14) (const_int 3)]))
10340 (vec_select:V4SF (match_dup 2)
10341 (parallel [(const_int 1) (const_int 2)
10342 (const_int 3) (const_int 0)]))))
10345 (vec_select:V4SF (match_dup 1)
10346 (parallel [(const_int 8) (const_int 13)
10347 (const_int 2) (const_int 7)]))
10348 (vec_select:V4SF (match_dup 2)
10349 (parallel [(const_int 2) (const_int 3)
10350 (const_int 0) (const_int 1)])))
10352 (vec_select:V4SF (match_dup 1)
10353 (parallel [(const_int 12) (const_int 1)
10354 (const_int 6) (const_int 11)]))
10355 (vec_select:V4SF (match_dup 2)
10356 (parallel [(const_int 3) (const_int 0)
10357 (const_int 1) (const_int 2)]))))))]
10360 [(set_attr "type" "fparith_media")])
10363 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10364 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10368 [(set_attr "type" "arith_media")])
10370 (define_insn "nsbsi"
10371 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10373 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10377 [(set_attr "type" "arith_media")])
10379 (define_insn "nsbdi"
10380 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10382 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10386 [(set_attr "type" "arith_media")])
10388 (define_expand "ffsdi2"
10389 [(set (match_operand:DI 0 "arith_reg_dest" "")
10390 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10394 rtx scratch = gen_reg_rtx (DImode);
10397 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10398 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10399 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10400 emit_insn (gen_nsbdi (scratch, scratch));
10401 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10402 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10403 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10405 = gen_rtx_EXPR_LIST (REG_EQUAL,
10406 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10410 (define_expand "ffssi2"
10411 [(set (match_operand:SI 0 "arith_reg_dest" "")
10412 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10416 rtx scratch = gen_reg_rtx (SImode);
10417 rtx discratch = gen_reg_rtx (DImode);
10420 emit_insn (gen_adddi3 (discratch,
10421 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10423 emit_insn (gen_andcdi3 (discratch,
10424 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10426 emit_insn (gen_nsbsi (scratch, discratch));
10427 last = emit_insn (gen_subsi3 (operands[0],
10428 force_reg (SImode, GEN_INT (63)), scratch));
10430 = gen_rtx_EXPR_LIST (REG_EQUAL,
10431 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10435 (define_insn "byterev"
10436 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10437 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10438 (parallel [(const_int 7) (const_int 6) (const_int 5)
10439 (const_int 4) (const_int 3) (const_int 2)
10440 (const_int 1) (const_int 0)])))]
10443 [(set_attr "type" "arith_media")])
10445 ;; The following description models the
10446 ;; SH4 pipeline using the DFA based scheduler.
10447 ;; The DFA based description is better way to model
10448 ;; a superscalar pipeline as compared to function unit
10449 ;; reservation model.
10450 ;; 1. The function unit based model is oriented to describe at most one
10451 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10452 ;; pipeline units by same insn. This can be done using DFA based description.
10453 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10454 ;; 3. Writing all unit reservations for an instruction class is more natural description
10455 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10456 ;; old function unit based model.
10457 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10460 ;; Two automata are defined to reduce number of states
10461 ;; which a single large automaton will have.(Factoring)
10463 (define_automaton "inst_pipeline,fpu_pipe")
10465 ;; This unit is basically the decode unit of the processor.
10466 ;; Since SH4 is a dual issue machine,it is as if there are two
10467 ;; units so that any insn can be processed by either one
10468 ;; of the decoding unit.
10470 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10473 ;; The fixed point arithmetic calculator(?? EX Unit).
10475 (define_cpu_unit "int" "inst_pipeline")
10477 ;; f1_1 and f1_2 are floating point units.Actually there is
10478 ;; a f1 unit which can overlap with other f1 unit but
10479 ;; not another F1 unit.It is as though there were two
10482 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10484 ;; The floating point units (except FS - F2 always precedes it.)
10486 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10488 ;; This is basically the MA unit of SH4
10489 ;; used in LOAD/STORE pipeline.
10491 (define_cpu_unit "memory" "inst_pipeline")
10493 ;; However, there are LS group insns that don't use it, even ones that
10494 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10495 (define_cpu_unit "load_store" "inst_pipeline")
10497 ;; The address calculator used for branch instructions.
10498 ;; This will be reserved after "issue" of branch instructions
10499 ;; and this is to make sure that no two branch instructions
10500 ;; can be issued in parallel.
10502 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10504 ;; ----------------------------------------------------
10505 ;; This reservation is to simplify the dual issue description.
10507 (define_reservation "issue" "pipe_01|pipe_02")
10509 ;; This is to express the locking of D stage.
10510 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10512 (define_reservation "d_lock" "pipe_01+pipe_02")
10514 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10515 (define_reservation "F01" "F0+F1")
10517 ;; This is to simplify description where F1,F2,FS
10518 ;; are used simultaneously.
10520 (define_reservation "fpu" "F1+F2")
10522 ;; This is to highlight the fact that f1
10523 ;; cannot overlap with F1.
10525 (exclusion_set "f1_1,f1_2" "F1")
10527 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10529 ;; Although reg moves have a latency of zero
10530 ;; we need to highlight that they use D stage
10535 (define_insn_reservation "reg_mov" 0
10536 (and (eq_attr "pipe_model" "sh4")
10537 (eq_attr "type" "move"))
10542 (define_insn_reservation "freg_mov" 0
10543 (and (eq_attr "pipe_model" "sh4")
10544 (eq_attr "type" "fmove"))
10545 "issue+load_store")
10547 ;; We don't model all pipeline stages; we model the issue ('D') stage
10548 ;; inasmuch as we allow only two instructions to issue simultanously,
10549 ;; and CO instructions prevent any simultanous issue of another instruction.
10550 ;; (This uses pipe_01 and pipe_02).
10551 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10552 ;; Double issue of EX / BR insns is prevented by using the int unit /
10553 ;; pcr_addrcalc unit in the EX stage.
10554 ;; Double issue of BR / LS instructions is prevented by using the
10555 ;; pcr_addrcalc / load_store unit in the issue cycle.
10556 ;; Double issue of FE instructions is prevented by using F0 in the first
10557 ;; pipeline stage after the first D stage.
10558 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10559 ;; (except in the cases outlined above), nor to describe the FS stage after
10562 ;; Other MT group intructions(1 step operations)
10567 (define_insn_reservation "mt" 1
10568 (and (eq_attr "pipe_model" "sh4")
10569 (eq_attr "type" "mt_group"))
10572 ;; Fixed Point Arithmetic Instructions(1 step operations)
10577 (define_insn_reservation "sh4_simple_arith" 1
10578 (and (eq_attr "pipe_model" "sh4")
10579 (eq_attr "insn_class" "ex_group"))
10582 ;; Load and store instructions have no alignment peculiarities for the SH4,
10583 ;; but they use the load-store unit, which they share with the fmove type
10584 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10585 ;; Loads have a latency of two.
10586 ;; However, call insns can only paired with a preceding insn, and have
10587 ;; a delay slot, so that we want two more insns to be scheduled between the
10588 ;; load of the function address and the call. This is equivalent to a
10589 ;; latency of three.
10590 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10591 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10592 ;; We only do this for SImode loads of general registers, to make the work
10593 ;; for ADJUST_COST easier.
10595 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10600 (define_insn_reservation "sh4_load" 2
10601 (and (eq_attr "pipe_model" "sh4")
10602 (eq_attr "type" "load,pcload"))
10603 "issue+load_store,nothing,memory")
10605 ;; calls / sfuncs need an extra instruction for their delay slot.
10606 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10607 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10608 ;; count of a dynamic shift.
10609 (define_insn_reservation "sh4_load_si" 3
10610 (and (eq_attr "pipe_model" "sh4")
10611 (eq_attr "type" "load_si,pcload_si"))
10612 "issue+load_store,nothing,memory")
10614 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10616 ;; The load latency is upped to three higher if the dependent insn does
10617 ;; double precision computation. We want the 'default' latency to reflect
10618 ;; that increased latency because otherwise the insn priorities won't
10619 ;; allow proper scheduling.
10620 (define_insn_reservation "sh4_fload" 3
10621 (and (eq_attr "pipe_model" "sh4")
10622 (eq_attr "type" "fload,pcfload"))
10623 "issue+load_store,nothing,memory")
10625 ;; (define_bypass 2 "sh4_fload" "!")
10627 (define_insn_reservation "sh4_store" 1
10628 (and (eq_attr "pipe_model" "sh4")
10629 (eq_attr "type" "store"))
10630 "issue+load_store,nothing,memory")
10632 ;; Load Store instructions.
10637 (define_insn_reservation "sh4_gp_fpul" 1
10638 (and (eq_attr "pipe_model" "sh4")
10639 (eq_attr "type" "gp_fpul"))
10640 "issue+load_store")
10642 ;; Load Store instructions.
10647 (define_insn_reservation "sh4_fpul_gp" 3
10648 (and (eq_attr "pipe_model" "sh4")
10649 (eq_attr "type" "fpul_gp"))
10650 "issue+load_store")
10652 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10654 ;; Latency when taken: 2 (or 1)
10656 ;; The latency is 1 when displacement is 0.
10657 ;; We can't really do much with the latency, even if we could express it,
10658 ;; but the pairing restrictions are useful to take into account.
10659 ;; ??? If the branch is likely, we might want to fill the delay slot;
10660 ;; if the branch is likely, but not very likely, should we pretend to use
10661 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10663 (define_insn_reservation "sh4_branch" 1
10664 (and (eq_attr "pipe_model" "sh4")
10665 (eq_attr "type" "cbranch,jump"))
10666 "issue+pcr_addrcalc")
10668 ;; Branch Far (JMP,RTS,BRAF)
10672 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10673 ;; can't be distinguished from bra for the "jump" pattern.
10675 (define_insn_reservation "sh4_return" 3
10676 (and (eq_attr "pipe_model" "sh4")
10677 (eq_attr "type" "return,jump_ind"))
10684 ;; this instruction can be executed in any of the pipelines
10685 ;; and blocks the pipeline for next 4 stages.
10687 (define_insn_reservation "sh4_return_from_exp" 5
10688 (and (eq_attr "pipe_model" "sh4")
10689 (eq_attr "type" "rte"))
10697 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10698 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10699 (define_insn_reservation "ocbwb" 6
10700 (and (eq_attr "pipe_model" "sh4")
10701 (eq_attr "type" "cwb"))
10702 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10708 ;; The SX stage is blocked for last 2 cycles.
10709 ;; OTOH, the only time that has an effect for insns generated by the compiler
10710 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10711 ;; or when we are doing a function call - and we don't do inter-function
10712 ;; scheduling. For the function call case, it's really best that we end with
10713 ;; something that models an rts.
10715 (define_insn_reservation "sh4_lds_to_pr" 3
10716 (and (eq_attr "pipe_model" "sh4")
10717 (eq_attr "type" "prset") )
10720 ;; calls introduce a longisch delay that is likely to flush the pipelines
10721 ;; of the caller's instructions. Ordinary functions tend to end with a
10722 ;; load to restore a register (in the delay slot of rts), while sfuncs
10723 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10724 ;; since there are no instructions that contend for memory access early.
10725 ;; We could, of course, provide exact scheduling information for specific
10726 ;; sfuncs, if that should prove useful.
10728 (define_insn_reservation "sh4_call" 16
10729 (and (eq_attr "pipe_model" "sh4")
10730 (eq_attr "type" "call,sfunc"))
10737 ;; The SX unit is blocked for last 2 cycles.
10739 (define_insn_reservation "ldsmem_to_pr" 3
10740 (and (eq_attr "pipe_model" "sh4")
10741 (eq_attr "type" "pload"))
10748 ;; The SX unit in second and third cycles.
10750 (define_insn_reservation "sts_from_pr" 2
10751 (and (eq_attr "pipe_model" "sh4")
10752 (eq_attr "type" "prget"))
10760 (define_insn_reservation "sh4_prstore_mem" 2
10761 (and (eq_attr "pipe_model" "sh4")
10762 (eq_attr "type" "pstore"))
10763 "d_lock*2,nothing,memory")
10769 ;; F1 is blocked for last three cycles.
10771 (define_insn_reservation "fpscr_load" 4
10772 (and (eq_attr "pipe_model" "sh4")
10773 (eq_attr "type" "gp_fpscr"))
10774 "d_lock,nothing,F1*3")
10779 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10781 ;; F1 is blocked for last three cycles.
10783 (define_insn_reservation "fpscr_load_mem" 4
10784 (and (eq_attr "pipe_model" "sh4")
10785 (eq_attr "type" "mem_fpscr"))
10786 "d_lock,nothing,(F1+memory),F1*2")
10789 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10794 (define_insn_reservation "multi" 4
10795 (and (eq_attr "pipe_model" "sh4")
10796 (eq_attr "type" "smpy,dmpy"))
10797 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10799 ;; Fixed STS from MACL / MACH
10804 (define_insn_reservation "sh4_mac_gp" 3
10805 (and (eq_attr "pipe_model" "sh4")
10806 (eq_attr "type" "mac_gp"))
10810 ;; Single precision floating point computation FCMP/EQ,
10811 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10816 (define_insn_reservation "fp_arith" 3
10817 (and (eq_attr "pipe_model" "sh4")
10818 (eq_attr "type" "fp"))
10821 (define_insn_reservation "fp_arith_ftrc" 3
10822 (and (eq_attr "pipe_model" "sh4")
10823 (eq_attr "type" "ftrc_s"))
10826 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10828 ;; Single Precision FDIV/SQRT
10830 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10832 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10834 (define_insn_reservation "fp_div" 12
10835 (and (eq_attr "pipe_model" "sh4")
10836 (eq_attr "type" "fdiv"))
10837 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10839 ;; Double Precision floating point computation
10840 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10842 ;; Latency: (3,4)/5
10845 (define_insn_reservation "dp_float" 4
10846 (and (eq_attr "pipe_model" "sh4")
10847 (eq_attr "type" "dfp_conv"))
10848 "issue,F01,F1+F2,F2")
10850 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10852 ;; Latency: (7,8)/9
10855 (define_insn_reservation "fp_double_arith" 8
10856 (and (eq_attr "pipe_model" "sh4")
10857 (eq_attr "type" "dfp_arith"))
10858 "issue,F01,F1+F2,fpu*4,F2")
10860 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10865 (define_insn_reservation "fp_double_cmp" 3
10866 (and (eq_attr "pipe_model" "sh4")
10867 (eq_attr "type" "dfp_cmp"))
10868 "d_lock,(d_lock+F01),F1+F2,F2")
10870 ;; Double precision FDIV/SQRT
10872 ;; Latency: (24,25)/26
10875 (define_insn_reservation "dp_div" 25
10876 (and (eq_attr "pipe_model" "sh4")
10877 (eq_attr "type" "dfdiv"))
10878 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10881 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10882 ;; case, we'd get a d_lock instead of issue at the end.
10883 (define_insn_reservation "arith3" 3
10884 (and (eq_attr "pipe_model" "sh4")
10885 (eq_attr "type" "arith3"))
10886 "issue,d_lock+pcr_addrcalc,issue")
10888 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10889 (define_insn_reservation "arith3b" 2
10890 (and (eq_attr "pipe_model" "sh4")
10891 (eq_attr "type" "arith3"))
10892 "issue,d_lock+pcr_addrcalc")