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))])]
1344 rtx first = 0, last;
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 last = 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]);
1391 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1392 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1394 last = emit_insn (last);
1395 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1396 invariant code motion can move it. */
1397 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1398 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1402 (define_insn "divsi3_i1"
1403 [(set (match_operand:SI 0 "register_operand" "=z")
1404 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405 (clobber (reg:SI T_REG))
1406 (clobber (reg:SI PR_REG))
1407 (clobber (reg:SI R1_REG))
1408 (clobber (reg:SI R2_REG))
1409 (clobber (reg:SI R3_REG))
1410 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1411 "TARGET_SH1 && ! TARGET_SH4"
1413 [(set_attr "type" "sfunc")
1414 (set_attr "needs_delay_slot" "yes")])
1416 ; Since shmedia-nofpu code could be linked against shcompact code, and
1417 ; the sdivsi3 libcall has the same name, we must consider all registers
1418 ; clobbered that are in the union of the registers clobbered by the
1419 ; shmedia and the shcompact implementation. Note, if the shcompact
1420 ; implemenation actually used shcompact code, we'd need to clobber
1421 ; also r22, r23 and fr23.
1422 (define_insn "divsi3_i1_media"
1423 [(set (match_operand:SI 0 "register_operand" "=z")
1424 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1425 (clobber (reg:SI T_MEDIA_REG))
1426 (clobber (reg:SI PR_MEDIA_REG))
1427 (clobber (reg:SI R1_REG))
1428 (clobber (reg:SI R2_REG))
1429 (clobber (reg:SI R3_REG))
1430 (clobber (reg:SI R20_REG))
1431 (clobber (reg:SI R21_REG))
1432 (clobber (reg:DI TR0_REG))
1433 (clobber (reg:DI TR1_REG))
1434 (clobber (reg:DI TR2_REG))
1435 (use (match_operand:DI 1 "target_operand" "b"))]
1436 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1438 [(set_attr "type" "sfunc")])
1440 (define_expand "divsi3_i4_media"
1441 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1442 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1443 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1444 (set (match_operand:SI 0 "register_operand" "=r")
1445 (fix:SI (match_dup 5)))]
1446 "TARGET_SHMEDIA_FPU"
1449 operands[3] = gen_reg_rtx (DFmode);
1450 operands[4] = gen_reg_rtx (DFmode);
1451 operands[5] = gen_reg_rtx (DFmode);
1454 (define_insn "divsi3_i4"
1455 [(set (match_operand:SI 0 "register_operand" "=y")
1456 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1457 (clobber (reg:SI PR_REG))
1458 (clobber (reg:DF DR0_REG))
1459 (clobber (reg:DF DR2_REG))
1460 (use (reg:PSI FPSCR_REG))
1461 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1462 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1464 [(set_attr "type" "sfunc")
1465 (set_attr "fp_mode" "double")
1466 (set_attr "needs_delay_slot" "yes")])
1468 (define_insn "divsi3_i4_single"
1469 [(set (match_operand:SI 0 "register_operand" "=y")
1470 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471 (clobber (reg:SI PR_REG))
1472 (clobber (reg:DF DR0_REG))
1473 (clobber (reg:DF DR2_REG))
1474 (clobber (reg:SI R2_REG))
1475 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1478 [(set_attr "type" "sfunc")
1479 (set_attr "needs_delay_slot" "yes")])
1481 (define_expand "divsi3"
1482 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1483 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1484 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1485 (parallel [(set (match_operand:SI 0 "register_operand" "")
1486 (div:SI (reg:SI R4_REG)
1488 (clobber (reg:SI T_REG))
1489 (clobber (reg:SI PR_REG))
1490 (clobber (reg:SI R1_REG))
1491 (clobber (reg:SI R2_REG))
1492 (clobber (reg:SI R3_REG))
1493 (use (match_dup 3))])]
1497 rtx first = 0, last;
1499 operands[3] = gen_reg_rtx (Pmode);
1500 /* Emit the move of the address to a pseudo outside of the libcall. */
1501 if (TARGET_HARD_SH4 && TARGET_SH3E)
1503 emit_move_insn (operands[3],
1504 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1505 if (TARGET_FPU_SINGLE)
1506 last = gen_divsi3_i4_single (operands[0], operands[3]);
1508 last = gen_divsi3_i4 (operands[0], operands[3]);
1510 else if (TARGET_SHMEDIA_FPU)
1512 operands[1] = force_reg (SImode, operands[1]);
1513 operands[2] = force_reg (SImode, operands[2]);
1514 last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1517 else if (TARGET_SH5)
1519 emit_move_insn (operands[3],
1520 gen_rtx_SYMBOL_REF (Pmode,
1526 last = gen_divsi3_i1_media (operands[0],
1529 : gen_rtx_SUBREG (DImode, operands[3],
1531 else if (TARGET_FPU_ANY)
1532 last = gen_divsi3_i4_single (operands[0], operands[3]);
1534 last = gen_divsi3_i1 (operands[0], operands[3]);
1538 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1539 last = gen_divsi3_i1 (operands[0], operands[3]);
1543 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1544 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1546 last = emit_insn (last);
1547 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1548 invariant code motion can move it. */
1549 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1550 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1554 ;; -------------------------------------------------------------------------
1555 ;; Multiplication instructions
1556 ;; -------------------------------------------------------------------------
1558 (define_insn "umulhisi3_i"
1559 [(set (reg:SI MACL_REG)
1560 (mult:SI (zero_extend:SI
1561 (match_operand:HI 0 "arith_reg_operand" "r"))
1563 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1566 [(set_attr "type" "smpy")])
1568 (define_insn "mulhisi3_i"
1569 [(set (reg:SI MACL_REG)
1570 (mult:SI (sign_extend:SI
1571 (match_operand:HI 0 "arith_reg_operand" "r"))
1573 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1576 [(set_attr "type" "smpy")])
1578 (define_expand "mulhisi3"
1579 [(set (reg:SI MACL_REG)
1580 (mult:SI (sign_extend:SI
1581 (match_operand:HI 1 "arith_reg_operand" ""))
1583 (match_operand:HI 2 "arith_reg_operand" ""))))
1584 (set (match_operand:SI 0 "arith_reg_operand" "")
1591 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1592 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1593 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1594 invariant code motion can move it. */
1595 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1596 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1597 /* expand_binop can't find a suitable code in umul_widen_optab to
1598 make a REG_EQUAL note from, so make one here.
1599 See also smulsi3_highpart.
1600 ??? Alternatively, we could put this at the calling site of expand_binop,
1601 i.e. expand_expr. */
1603 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1608 (define_expand "umulhisi3"
1609 [(set (reg:SI MACL_REG)
1610 (mult:SI (zero_extend:SI
1611 (match_operand:HI 1 "arith_reg_operand" ""))
1613 (match_operand:HI 2 "arith_reg_operand" ""))))
1614 (set (match_operand:SI 0 "arith_reg_operand" "")
1621 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1622 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1623 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1624 invariant code motion can move it. */
1625 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1626 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1627 /* expand_binop can't find a suitable code in umul_widen_optab to
1628 make a REG_EQUAL note from, so make one here.
1629 See also smulsi3_highpart.
1630 ??? Alternatively, we could put this at the calling site of expand_binop,
1631 i.e. expand_expr. */
1633 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1638 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1639 ;; a call to a routine which clobbers known registers.
1642 [(set (match_operand:SI 1 "register_operand" "=z")
1643 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1644 (clobber (reg:SI MACL_REG))
1645 (clobber (reg:SI T_REG))
1646 (clobber (reg:SI PR_REG))
1647 (clobber (reg:SI R3_REG))
1648 (clobber (reg:SI R2_REG))
1649 (clobber (reg:SI R1_REG))
1650 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1653 [(set_attr "type" "sfunc")
1654 (set_attr "needs_delay_slot" "yes")])
1656 (define_expand "mulsi3_call"
1657 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1658 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1659 (parallel[(set (match_operand:SI 0 "register_operand" "")
1660 (mult:SI (reg:SI R4_REG)
1662 (clobber (reg:SI MACL_REG))
1663 (clobber (reg:SI T_REG))
1664 (clobber (reg:SI PR_REG))
1665 (clobber (reg:SI R3_REG))
1666 (clobber (reg:SI R2_REG))
1667 (clobber (reg:SI R1_REG))
1668 (use (match_operand:SI 3 "register_operand" ""))])]
1672 (define_insn "mul_l"
1673 [(set (reg:SI MACL_REG)
1674 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1675 (match_operand:SI 1 "arith_reg_operand" "r")))]
1678 [(set_attr "type" "dmpy")])
1680 (define_expand "mulsi3"
1681 [(set (reg:SI MACL_REG)
1682 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1683 (match_operand:SI 2 "arith_reg_operand" "")))
1684 (set (match_operand:SI 0 "arith_reg_operand" "")
1693 /* The address must be set outside the libcall,
1694 since it goes into a pseudo. */
1695 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1696 rtx addr = force_reg (SImode, sym);
1697 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1700 last = emit_insn (insns);
1704 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1706 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1707 /* consec_sets_giv can only recognize the first insn that sets a
1708 giv as the giv insn. So we must tag this also with a REG_EQUAL
1710 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1712 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1713 invariant code motion can move it. */
1714 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1715 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1719 (define_insn "mulsidi3_i"
1720 [(set (reg:SI MACH_REG)
1724 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1725 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1727 (set (reg:SI MACL_REG)
1728 (mult:SI (match_dup 0)
1732 [(set_attr "type" "dmpy")])
1734 (define_expand "mulsidi3"
1735 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1736 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1737 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1738 "TARGET_SH2 || TARGET_SHMEDIA"
1743 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1749 (define_insn "mulsidi3_media"
1750 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1751 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1752 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1755 [(set_attr "type" "dmpy_media")])
1757 (define_insn "mulsidi3_compact"
1758 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1761 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1762 (clobber (reg:SI MACH_REG))
1763 (clobber (reg:SI MACL_REG))]
1768 [(set (match_operand:DI 0 "arith_reg_operand" "")
1770 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1771 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1772 (clobber (reg:SI MACH_REG))
1773 (clobber (reg:SI MACL_REG))]
1778 rtx low_dst = gen_lowpart (SImode, operands[0]);
1779 rtx high_dst = gen_highpart (SImode, operands[0]);
1781 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1783 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1784 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1785 /* We need something to tag the possible REG_EQUAL notes on to. */
1786 emit_move_insn (operands[0], operands[0]);
1790 (define_insn "umulsidi3_i"
1791 [(set (reg:SI MACH_REG)
1795 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1796 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1798 (set (reg:SI MACL_REG)
1799 (mult:SI (match_dup 0)
1803 [(set_attr "type" "dmpy")])
1805 (define_expand "umulsidi3"
1806 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1807 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1808 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1809 "TARGET_SH2 || TARGET_SHMEDIA"
1814 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1820 (define_insn "umulsidi3_media"
1821 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1822 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1823 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1826 [(set_attr "type" "dmpy_media")])
1828 (define_insn "umulsidi3_compact"
1829 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1832 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1833 (clobber (reg:SI MACH_REG))
1834 (clobber (reg:SI MACL_REG))]
1839 [(set (match_operand:DI 0 "arith_reg_operand" "")
1840 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1842 (clobber (reg:SI MACH_REG))
1843 (clobber (reg:SI MACL_REG))]
1848 rtx low_dst = gen_lowpart (SImode, operands[0]);
1849 rtx high_dst = gen_highpart (SImode, operands[0]);
1851 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1853 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1854 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1855 /* We need something to tag the possible REG_EQUAL notes on to. */
1856 emit_move_insn (operands[0], operands[0]);
1860 (define_insn "smulsi3_highpart_i"
1861 [(set (reg:SI MACH_REG)
1865 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1866 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1868 (clobber (reg:SI MACL_REG))]
1871 [(set_attr "type" "dmpy")])
1873 (define_expand "smulsi3_highpart"
1875 [(set (reg:SI MACH_REG)
1879 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1880 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1882 (clobber (reg:SI MACL_REG))])
1883 (set (match_operand:SI 0 "arith_reg_operand" "")
1890 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1891 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1892 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1893 invariant code motion can move it. */
1894 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1895 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1896 /* expand_binop can't find a suitable code in mul_highpart_optab to
1897 make a REG_EQUAL note from, so make one here.
1898 See also {,u}mulhisi.
1899 ??? Alternatively, we could put this at the calling site of expand_binop,
1900 i.e. expand_mult_highpart. */
1902 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1907 (define_insn "umulsi3_highpart_i"
1908 [(set (reg:SI MACH_REG)
1912 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1913 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1915 (clobber (reg:SI MACL_REG))]
1918 [(set_attr "type" "dmpy")])
1920 (define_expand "umulsi3_highpart"
1922 [(set (reg:SI MACH_REG)
1926 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1927 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1929 (clobber (reg:SI MACL_REG))])
1930 (set (match_operand:SI 0 "arith_reg_operand" "")
1937 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1938 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1939 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1940 invariant code motion can move it. */
1941 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1942 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1946 ;; -------------------------------------------------------------------------
1947 ;; Logical operations
1948 ;; -------------------------------------------------------------------------
1950 (define_insn "*andsi3_compact"
1951 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1952 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1953 (match_operand:SI 2 "logical_operand" "r,L")))]
1956 [(set_attr "type" "arith")])
1958 ;; If the constant is 255, then emit an extu.b instruction instead of an
1959 ;; and, since that will give better code.
1961 (define_expand "andsi3"
1962 [(set (match_operand:SI 0 "arith_reg_operand" "")
1963 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1964 (match_operand:SI 2 "logical_operand" "")))]
1968 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1970 emit_insn (gen_zero_extendqisi2 (operands[0],
1971 gen_lowpart (QImode, operands[1])));
1976 (define_insn_and_split "anddi3"
1977 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1978 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1979 (match_operand:DI 2 "and_operand" "r,P,n")))]
1986 && ! logical_operand (operands[2], DImode)"
1990 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1991 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1993 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1996 [(set_attr "type" "arith_media")])
1998 (define_insn "andcdi3"
1999 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2000 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2001 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2004 [(set_attr "type" "arith_media")])
2006 (define_insn "iorsi3"
2007 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2008 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2009 (match_operand:SI 2 "logical_operand" "r,L")))]
2012 [(set_attr "type" "arith")])
2014 (define_insn "iordi3"
2015 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2016 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2017 (match_operand:DI 2 "logical_operand" "r,P")))]
2022 [(set_attr "type" "arith_media")])
2024 (define_insn "xorsi3"
2025 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2026 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2027 (match_operand:SI 2 "logical_operand" "L,r")))]
2030 [(set_attr "type" "arith")])
2032 (define_insn "xordi3"
2033 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2034 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2035 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2040 [(set_attr "type" "arith_media")])
2042 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2043 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2045 [(set (match_operand:DI 0 "arith_reg_operand" "")
2046 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2047 [(match_operand 1 "any_register_operand" "")
2048 (match_operand 2 "any_register_operand" "")])))]
2050 [(set (match_dup 5) (match_dup 4))
2051 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2054 enum machine_mode inmode = GET_MODE (operands[1]);
2055 int regno, offset = 0;
2057 if (GET_CODE (operands[0]) == SUBREG)
2059 offset = SUBREG_BYTE (operands[0]);
2060 operands[0] = SUBREG_REG (operands[0]);
2062 if (GET_CODE (operands[0]) != REG)
2064 if (! TARGET_LITTLE_ENDIAN)
2065 offset += 8 - GET_MODE_SIZE (inmode);
2066 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2069 ;; -------------------------------------------------------------------------
2070 ;; Shifts and rotates
2071 ;; -------------------------------------------------------------------------
2073 (define_expand "rotldi3"
2074 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2075 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2076 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2078 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2080 (define_insn "rotldi3_mextr"
2081 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2082 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2083 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2087 static char templ[16];
2089 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2090 8 - (int) (INTVAL (operands[2]) >> 3));
2093 [(set_attr "type" "arith_media")])
2095 (define_expand "rotrdi3"
2096 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2097 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2098 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2100 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2102 (define_insn "rotrdi3_mextr"
2103 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2104 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2105 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2109 static char templ[16];
2111 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2114 [(set_attr "type" "arith_media")])
2116 (define_insn "rotlsi3_1"
2117 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2118 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2121 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2124 [(set_attr "type" "arith")])
2126 (define_insn "rotlsi3_31"
2127 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2128 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130 (clobber (reg:SI T_REG))]
2133 [(set_attr "type" "arith")])
2135 (define_insn "rotlsi3_16"
2136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2141 [(set_attr "type" "arith")])
2143 (define_expand "rotlsi3"
2144 [(set (match_operand:SI 0 "arith_reg_operand" "")
2145 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2146 (match_operand:SI 2 "immediate_operand" "")))]
2150 static const char rot_tab[] = {
2151 000, 000, 000, 000, 000, 000, 010, 001,
2152 001, 001, 011, 013, 003, 003, 003, 003,
2153 003, 003, 003, 003, 003, 013, 012, 002,
2154 002, 002, 010, 000, 000, 000, 000, 000,
2159 if (GET_CODE (operands[2]) != CONST_INT)
2161 count = INTVAL (operands[2]);
2162 choice = rot_tab[count];
2163 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2169 emit_move_insn (operands[0], operands[1]);
2170 count -= (count & 16) * 2;
2173 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2180 parts[0] = gen_reg_rtx (SImode);
2181 parts[1] = gen_reg_rtx (SImode);
2182 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2183 parts[choice-1] = operands[1];
2184 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2185 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2186 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2187 count = (count & ~16) - 8;
2191 for (; count > 0; count--)
2192 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2193 for (; count < 0; count++)
2194 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2199 (define_insn "*rotlhi3_8"
2200 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2201 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2205 [(set_attr "type" "arith")])
2207 (define_expand "rotlhi3"
2208 [(set (match_operand:HI 0 "arith_reg_operand" "")
2209 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2210 (match_operand:HI 2 "immediate_operand" "")))]
2214 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2221 ;; This pattern is used by init_expmed for computing the costs of shift
2224 (define_insn_and_split "ashlsi3_std"
2225 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2226 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2227 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2228 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2230 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2231 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2239 && GET_CODE (operands[2]) == CONST_INT
2240 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2241 [(set (match_dup 3) (match_dup 2))
2243 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2244 (clobber (match_dup 4))])]
2245 "operands[4] = gen_rtx_SCRATCH (SImode);"
2246 [(set_attr "length" "*,*,*,4")
2247 (set_attr "type" "dyn_shift,arith,arith,arith")])
2249 (define_insn "ashlhi3_k"
2250 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2251 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2252 (match_operand:HI 2 "const_int_operand" "M,K")))]
2253 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2257 [(set_attr "type" "arith")])
2259 (define_insn "ashlsi3_n"
2260 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2261 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2262 (match_operand:SI 2 "const_int_operand" "n")))
2263 (clobber (reg:SI T_REG))]
2264 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2266 [(set (attr "length")
2267 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2269 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2271 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2273 (const_string "8")))
2274 (set_attr "type" "arith")])
2277 [(set (match_operand:SI 0 "arith_reg_operand" "")
2278 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2279 (match_operand:SI 2 "const_int_operand" "")))
2280 (clobber (reg:SI T_REG))]
2281 "TARGET_SH1 && reload_completed"
2282 [(use (reg:SI R0_REG))]
2285 gen_shifty_op (ASHIFT, operands);
2289 (define_insn "ashlsi3_media"
2290 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2291 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2292 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2297 [(set_attr "type" "arith_media")])
2299 (define_expand "ashlsi3"
2300 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2301 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2302 (match_operand:SI 2 "nonmemory_operand" "")))
2303 (clobber (reg:SI T_REG))])]
2309 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2312 if (GET_CODE (operands[2]) == CONST_INT
2313 && sh_dynamicalize_shift_p (operands[2]))
2314 operands[2] = force_reg (SImode, operands[2]);
2317 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2320 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2324 (define_insn "ashlhi3"
2325 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2326 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2327 (match_operand:HI 2 "const_int_operand" "n")))
2328 (clobber (reg:SI T_REG))]
2331 [(set (attr "length")
2332 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2334 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2336 (const_string "6")))
2337 (set_attr "type" "arith")])
2340 [(set (match_operand:HI 0 "arith_reg_operand" "")
2341 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2342 (match_operand:HI 2 "const_int_operand" "")))
2343 (clobber (reg:SI T_REG))]
2344 "TARGET_SH1 && reload_completed"
2345 [(use (reg:SI R0_REG))]
2348 gen_shifty_hi_op (ASHIFT, operands);
2353 ; arithmetic shift right
2356 (define_insn "ashrsi3_k"
2357 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2358 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2359 (match_operand:SI 2 "const_int_operand" "M")))
2360 (clobber (reg:SI T_REG))]
2361 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2363 [(set_attr "type" "arith")])
2365 ;; We can't do HImode right shifts correctly unless we start out with an
2366 ;; explicit zero / sign extension; doing that would result in worse overall
2367 ;; code, so just let the machine independent code widen the mode.
2368 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2371 ;; ??? This should be a define expand.
2373 (define_insn "ashrsi2_16"
2374 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2379 [(set_attr "length" "4")])
2382 [(set (match_operand:SI 0 "arith_reg_operand" "")
2383 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2386 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2387 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2388 "operands[2] = gen_lowpart (HImode, operands[0]);")
2390 ;; ??? This should be a define expand.
2392 (define_insn "ashrsi2_31"
2393 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2394 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2396 (clobber (reg:SI T_REG))]
2399 [(set_attr "length" "4")])
2402 [(set (match_operand:SI 0 "arith_reg_operand" "")
2403 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2405 (clobber (reg:SI T_REG))]
2410 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2411 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2415 (define_insn "ashlsi_c"
2416 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2417 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2419 (lt:SI (match_dup 1) (const_int 0)))]
2422 [(set_attr "type" "arith")])
2424 (define_insn "ashrsi3_d"
2425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2427 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2430 [(set_attr "type" "dyn_shift")])
2432 (define_insn "ashrsi3_n"
2433 [(set (reg:SI R4_REG)
2434 (ashiftrt:SI (reg:SI R4_REG)
2435 (match_operand:SI 0 "const_int_operand" "i")))
2436 (clobber (reg:SI T_REG))
2437 (clobber (reg:SI PR_REG))
2438 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2441 [(set_attr "type" "sfunc")
2442 (set_attr "needs_delay_slot" "yes")])
2444 (define_insn "ashrsi3_media"
2445 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2446 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2447 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2452 [(set_attr "type" "arith_media")])
2454 (define_expand "ashrsi3"
2455 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2456 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2457 (match_operand:SI 2 "nonmemory_operand" "")))
2458 (clobber (reg:SI T_REG))])]
2464 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2467 if (expand_ashiftrt (operands))
2473 ;; logical shift right
2475 (define_insn "lshrsi3_d"
2476 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2481 [(set_attr "type" "dyn_shift")])
2483 ;; Only the single bit shift clobbers the T bit.
2485 (define_insn "lshrsi3_m"
2486 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2487 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2488 (match_operand:SI 2 "const_int_operand" "M")))
2489 (clobber (reg:SI T_REG))]
2490 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2492 [(set_attr "type" "arith")])
2494 (define_insn "lshrsi3_k"
2495 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497 (match_operand:SI 2 "const_int_operand" "K")))]
2498 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2499 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2501 [(set_attr "type" "arith")])
2503 (define_insn "lshrsi3_n"
2504 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506 (match_operand:SI 2 "const_int_operand" "n")))
2507 (clobber (reg:SI T_REG))]
2508 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2510 [(set (attr "length")
2511 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2513 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2515 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2517 (const_string "8")))
2518 (set_attr "type" "arith")])
2521 [(set (match_operand:SI 0 "arith_reg_operand" "")
2522 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2523 (match_operand:SI 2 "const_int_operand" "")))
2524 (clobber (reg:SI T_REG))]
2525 "TARGET_SH1 && reload_completed"
2526 [(use (reg:SI R0_REG))]
2529 gen_shifty_op (LSHIFTRT, operands);
2533 (define_insn "lshrsi3_media"
2534 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2535 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2536 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2541 [(set_attr "type" "arith_media")])
2543 (define_expand "lshrsi3"
2544 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2545 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2546 (match_operand:SI 2 "nonmemory_operand" "")))
2547 (clobber (reg:SI T_REG))])]
2553 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2556 if (GET_CODE (operands[2]) == CONST_INT
2557 && sh_dynamicalize_shift_p (operands[2]))
2558 operands[2] = force_reg (SImode, operands[2]);
2559 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2561 rtx count = copy_to_mode_reg (SImode, operands[2]);
2562 emit_insn (gen_negsi2 (count, count));
2563 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2566 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2570 ;; ??? This should be a define expand.
2572 (define_insn "ashldi3_k"
2573 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2574 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2576 (clobber (reg:SI T_REG))]
2578 "shll %R0\;rotcl %S0"
2579 [(set_attr "length" "4")
2580 (set_attr "type" "arith")])
2582 (define_insn "ashldi3_media"
2583 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2584 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2585 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2590 [(set_attr "type" "arith_media")])
2592 (define_expand "ashldi3"
2593 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2594 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2595 (match_operand:DI 2 "immediate_operand" "")))
2596 (clobber (reg:SI T_REG))])]
2602 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2605 if (GET_CODE (operands[2]) != CONST_INT
2606 || INTVAL (operands[2]) != 1)
2610 ;; ??? This should be a define expand.
2612 (define_insn "lshrdi3_k"
2613 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2614 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2616 (clobber (reg:SI T_REG))]
2618 "shlr %S0\;rotcr %R0"
2619 [(set_attr "length" "4")
2620 (set_attr "type" "arith")])
2622 (define_insn "lshrdi3_media"
2623 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2624 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2625 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2630 [(set_attr "type" "arith_media")])
2632 (define_expand "lshrdi3"
2633 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2634 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2635 (match_operand:DI 2 "immediate_operand" "")))
2636 (clobber (reg:SI T_REG))])]
2642 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2645 if (GET_CODE (operands[2]) != CONST_INT
2646 || INTVAL (operands[2]) != 1)
2650 ;; ??? This should be a define expand.
2652 (define_insn "ashrdi3_k"
2653 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2654 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2656 (clobber (reg:SI T_REG))]
2658 "shar %S0\;rotcr %R0"
2659 [(set_attr "length" "4")
2660 (set_attr "type" "arith")])
2662 (define_insn "ashrdi3_media"
2663 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2664 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2665 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2670 [(set_attr "type" "arith_media")])
2672 (define_expand "ashrdi3"
2673 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2674 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2675 (match_operand:DI 2 "immediate_operand" "")))
2676 (clobber (reg:SI T_REG))])]
2682 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2685 if (GET_CODE (operands[2]) != CONST_INT
2686 || INTVAL (operands[2]) != 1)
2690 ;; combined left/right shift
2693 [(set (match_operand:SI 0 "register_operand" "")
2694 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695 (match_operand:SI 2 "const_int_operand" ""))
2696 (match_operand:SI 3 "const_int_operand" "")))]
2697 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2698 [(use (reg:SI R0_REG))]
2699 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2703 [(set (match_operand:SI 0 "register_operand" "")
2704 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2705 (match_operand:SI 2 "const_int_operand" ""))
2706 (match_operand:SI 3 "const_int_operand" "")))
2707 (clobber (reg:SI T_REG))]
2708 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2709 [(use (reg:SI R0_REG))]
2710 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2714 [(set (match_operand:SI 0 "register_operand" "=r")
2715 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2716 (match_operand:SI 2 "const_int_operand" "n"))
2717 (match_operand:SI 3 "const_int_operand" "n")))
2718 (clobber (reg:SI T_REG))]
2719 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2721 [(set (attr "length")
2722 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2724 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2726 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2728 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2730 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2732 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2734 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2735 (const_string "16")]
2736 (const_string "18")))
2737 (set_attr "type" "arith")])
2740 [(set (match_operand:SI 0 "register_operand" "=z")
2741 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2742 (match_operand:SI 2 "const_int_operand" "n"))
2743 (match_operand:SI 3 "const_int_operand" "n")))
2744 (clobber (reg:SI T_REG))]
2745 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2747 [(set (attr "length")
2748 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2750 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2752 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2754 (const_string "10")))
2755 (set_attr "type" "arith")])
2757 ;; shift left / and combination with a scratch register: The combine pass
2758 ;; does not accept the individual instructions, even though they are
2759 ;; cheap. But it needs a precise description so that it is usable after
2761 (define_insn "and_shl_scratch"
2762 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2766 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2767 (match_operand:SI 2 "const_int_operand" "N,n"))
2768 (match_operand:SI 3 "" "0,r"))
2769 (match_operand:SI 4 "const_int_operand" "n,n"))
2770 (match_operand:SI 5 "const_int_operand" "n,n")))
2771 (clobber (reg:SI T_REG))]
2774 [(set (attr "length")
2775 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2777 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2779 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2781 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2782 (const_string "10")]
2783 (const_string "12")))
2784 (set_attr "type" "arith")])
2787 [(set (match_operand:SI 0 "register_operand" "")
2791 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2792 (match_operand:SI 2 "const_int_operand" ""))
2793 (match_operand:SI 3 "register_operand" ""))
2794 (match_operand:SI 4 "const_int_operand" ""))
2795 (match_operand:SI 5 "const_int_operand" "")))
2796 (clobber (reg:SI T_REG))]
2798 [(use (reg:SI R0_REG))]
2801 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2803 if (INTVAL (operands[2]))
2805 gen_shifty_op (LSHIFTRT, operands);
2807 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2808 operands[2] = operands[4];
2809 gen_shifty_op (ASHIFT, operands);
2810 if (INTVAL (operands[5]))
2812 operands[2] = operands[5];
2813 gen_shifty_op (LSHIFTRT, operands);
2818 ;; signed left/right shift combination.
2820 [(set (match_operand:SI 0 "register_operand" "")
2822 (ashift:SI (match_operand:SI 1 "register_operand" "")
2823 (match_operand:SI 2 "const_int_operand" ""))
2824 (match_operand:SI 3 "const_int_operand" "")
2826 (clobber (reg:SI T_REG))]
2828 [(use (reg:SI R0_REG))]
2829 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2832 (define_insn "shl_sext_ext"
2833 [(set (match_operand:SI 0 "register_operand" "=r")
2835 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2836 (match_operand:SI 2 "const_int_operand" "n"))
2837 (match_operand:SI 3 "const_int_operand" "n")
2839 (clobber (reg:SI T_REG))]
2840 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2842 [(set (attr "length")
2843 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2845 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2847 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2849 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2851 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2853 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2855 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2857 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2858 (const_string "16")]
2859 (const_string "18")))
2860 (set_attr "type" "arith")])
2862 (define_insn "shl_sext_sub"
2863 [(set (match_operand:SI 0 "register_operand" "=z")
2865 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2866 (match_operand:SI 2 "const_int_operand" "n"))
2867 (match_operand:SI 3 "const_int_operand" "n")
2869 (clobber (reg:SI T_REG))]
2870 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2872 [(set (attr "length")
2873 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2875 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2877 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2879 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2880 (const_string "12")]
2881 (const_string "14")))
2882 (set_attr "type" "arith")])
2884 ;; These patterns are found in expansions of DImode shifts by 16, and
2885 ;; allow the xtrct instruction to be generated from C source.
2887 (define_insn "xtrct_left"
2888 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2891 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2895 [(set_attr "type" "arith")])
2897 (define_insn "xtrct_right"
2898 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2899 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2901 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2905 [(set_attr "type" "arith")])
2907 ;; -------------------------------------------------------------------------
2909 ;; -------------------------------------------------------------------------
2912 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913 (neg:SI (plus:SI (reg:SI T_REG)
2914 (match_operand:SI 1 "arith_reg_operand" "r"))))
2916 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2920 [(set_attr "type" "arith")])
2922 (define_insn "*negdi_media"
2923 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2924 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2927 [(set_attr "type" "arith_media")])
2929 (define_expand "negdi2"
2930 [(set (match_operand:DI 0 "arith_reg_operand" "")
2931 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2937 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2938 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2940 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2941 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2943 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2944 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2946 emit_insn (gen_clrt ());
2947 emit_insn (gen_negc (low_dst, low_src));
2948 emit_insn (gen_negc (high_dst, high_src));
2953 (define_insn "negsi2"
2954 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2955 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2958 [(set_attr "type" "arith")])
2960 (define_insn "one_cmplsi2"
2961 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2962 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2965 [(set_attr "type" "arith")])
2967 (define_expand "one_cmpldi2"
2968 [(set (match_operand:DI 0 "arith_reg_operand" "")
2969 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2971 "TARGET_SHMEDIA" "")
2973 ;; -------------------------------------------------------------------------
2974 ;; Zero extension instructions
2975 ;; -------------------------------------------------------------------------
2977 (define_insn "zero_extendsidi2"
2978 [(set (match_operand:DI 0 "register_operand" "=r")
2979 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2981 "addz.l %1, r63, %0"
2982 [(set_attr "type" "arith_media")])
2984 (define_insn "zero_extendhidi2"
2985 [(set (match_operand:DI 0 "register_operand" "=r,r")
2986 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2991 [(set_attr "type" "*,load_media")])
2994 [(set (match_operand:DI 0 "register_operand" "")
2995 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2996 "TARGET_SHMEDIA && reload_completed"
2997 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2998 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3001 if (GET_CODE (operands[1]) == TRUNCATE)
3002 operands[1] = XEXP (operands[1], 0);
3005 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3006 ;; reload the entrire truncate expression.
3007 (define_insn_and_split "*loaddi_trunc"
3008 [(set (match_operand 0 "int_gpr_dest" "=r")
3009 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3010 "TARGET_SHMEDIA && reload_completed"
3012 "TARGET_SHMEDIA && reload_completed"
3013 [(set (match_dup 0) (match_dup 1))]
3014 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3016 (define_insn "zero_extendqidi2"
3017 [(set (match_operand:DI 0 "register_operand" "=r,r")
3018 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3023 [(set_attr "type" "arith_media,load_media")])
3025 (define_expand "zero_extendhisi2"
3026 [(set (match_operand:SI 0 "arith_reg_operand" "")
3027 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3031 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3032 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3035 (define_insn "*zero_extendhisi2_compact"
3036 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3037 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3040 [(set_attr "type" "arith")])
3042 (define_insn "*zero_extendhisi2_media"
3043 [(set (match_operand:SI 0 "register_operand" "=r,r")
3044 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3049 [(set_attr "type" "arith_media,load_media")])
3052 [(set (match_operand:SI 0 "register_operand" "")
3053 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3054 "TARGET_SHMEDIA && reload_completed"
3055 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3056 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3059 if (GET_CODE (operands[1]) == TRUNCATE)
3060 operands[1] = XEXP (operands[1], 0);
3063 (define_expand "zero_extendqisi2"
3064 [(set (match_operand:SI 0 "arith_reg_operand" "")
3065 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3069 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3070 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3073 (define_insn "*zero_extendqisi2_compact"
3074 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3075 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3078 [(set_attr "type" "arith")])
3080 (define_insn "*zero_extendqisi2_media"
3081 [(set (match_operand:SI 0 "register_operand" "=r,r")
3082 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3087 [(set_attr "type" "arith_media,load_media")])
3089 (define_insn "zero_extendqihi2"
3090 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3091 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3094 [(set_attr "type" "arith")])
3096 ;; -------------------------------------------------------------------------
3097 ;; Sign extension instructions
3098 ;; -------------------------------------------------------------------------
3100 ;; ??? This should be a define expand.
3101 ;; ??? Or perhaps it should be dropped?
3103 ;; convert_move generates good code for SH[1-4].
3104 (define_insn "extendsidi2"
3105 [(set (match_operand:DI 0 "register_operand" "=r,r")
3106 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3111 [(set_attr "type" "arith_media,load_media")])
3113 (define_insn "extendhidi2"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r")
3115 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3120 [(set_attr "type" "*,load_media")])
3123 [(set (match_operand:DI 0 "register_operand" "")
3124 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3125 "TARGET_SHMEDIA && reload_completed"
3126 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3127 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3130 if (GET_CODE (operands[1]) == TRUNCATE)
3131 operands[1] = XEXP (operands[1], 0);
3134 (define_insn "extendqidi2"
3135 [(set (match_operand:DI 0 "register_operand" "=r,r")
3136 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3141 [(set_attr "type" "*,load_media")])
3144 [(set (match_operand:DI 0 "register_operand" "")
3145 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3146 "TARGET_SHMEDIA && reload_completed"
3147 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3148 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3151 if (GET_CODE (operands[1]) == TRUNCATE)
3152 operands[1] = XEXP (operands[1], 0);
3155 (define_expand "extendhisi2"
3156 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3157 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3161 (define_insn "*extendhisi2_compact"
3162 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3163 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3168 [(set_attr "type" "arith,load")])
3170 (define_insn "*extendhisi2_media"
3171 [(set (match_operand:SI 0 "register_operand" "=r,r")
3172 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3177 [(set_attr "type" "arith_media,load_media")])
3180 [(set (match_operand:SI 0 "register_operand" "")
3181 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3182 "TARGET_SHMEDIA && reload_completed"
3183 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3184 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3187 if (GET_CODE (operands[1]) == TRUNCATE)
3188 operands[1] = XEXP (operands[1], 0);
3191 (define_expand "extendqisi2"
3192 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3193 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3197 (define_insn "*extendqisi2_compact"
3198 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3199 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3204 [(set_attr "type" "arith,load")])
3206 (define_insn "*extendqisi2_media"
3207 [(set (match_operand:SI 0 "register_operand" "=r,r")
3208 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3213 [(set_attr "type" "arith_media,load_media")])
3216 [(set (match_operand:SI 0 "register_operand" "")
3217 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3218 "TARGET_SHMEDIA && reload_completed"
3219 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3220 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3223 if (GET_CODE (operands[1]) == TRUNCATE)
3224 operands[1] = XEXP (operands[1], 0);
3227 (define_insn "extendqihi2"
3228 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3229 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3234 [(set_attr "type" "arith,load")])
3236 /* It would seem useful to combine the truncXi patterns into the movXi
3237 patterns, but unary operators are ignored when matching constraints,
3238 so we need separate patterns. */
3239 (define_insn "truncdisi2"
3240 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3241 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3250 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3253 (define_insn "truncdihi2"
3254 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3255 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3258 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3260 [(set_attr "type" "arith_media,store_media")
3261 (set_attr "length" "8,4")])
3263 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3264 ; Because we use zero extension, we can't provide signed QImode compares
3265 ; using a simple compare or conditional banch insn.
3266 (define_insn "truncdiqi2"
3267 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3268 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3273 [(set_attr "type" "arith_media,store")])
3275 ;; -------------------------------------------------------------------------
3276 ;; Move instructions
3277 ;; -------------------------------------------------------------------------
3279 ;; define push and pop so it is easy for sh.c
3280 ;; We can't use push and pop on SHcompact because the stack must always
3281 ;; be 8-byte aligned.
3283 (define_expand "push"
3284 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3285 (match_operand:SI 0 "register_operand" "r,l,x"))]
3286 "TARGET_SH1 && ! TARGET_SH5"
3289 (define_expand "pop"
3290 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3291 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3292 "TARGET_SH1 && ! TARGET_SH5"
3295 (define_expand "push_e"
3296 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3297 (match_operand:SF 0 "" ""))
3298 (use (reg:PSI FPSCR_REG))
3299 (clobber (scratch:SI))])]
3300 "TARGET_SH1 && ! TARGET_SH5"
3303 (define_insn "push_fpul"
3304 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3305 "TARGET_SH3E && ! TARGET_SH5"
3307 [(set_attr "type" "store")
3308 (set_attr "late_fp_use" "yes")
3309 (set_attr "hit_stack" "yes")])
3311 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3313 (define_expand "push_4"
3314 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3315 (match_operand:DF 0 "" ""))
3316 (use (reg:PSI FPSCR_REG))
3317 (clobber (scratch:SI))])]
3318 "TARGET_SH1 && ! TARGET_SH5"
3321 (define_expand "pop_e"
3322 [(parallel [(set (match_operand:SF 0 "" "")
3323 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3324 (use (reg:PSI FPSCR_REG))
3325 (clobber (scratch:SI))])]
3326 "TARGET_SH1 && ! TARGET_SH5"
3329 (define_insn "pop_fpul"
3330 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3331 "TARGET_SH3E && ! TARGET_SH5"
3333 [(set_attr "type" "load")
3334 (set_attr "hit_stack" "yes")])
3336 (define_expand "pop_4"
3337 [(parallel [(set (match_operand:DF 0 "" "")
3338 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3339 (use (reg:PSI FPSCR_REG))
3340 (clobber (scratch:SI))])]
3341 "TARGET_SH1 && ! TARGET_SH5"
3344 ;; These two patterns can happen as the result of optimization, when
3345 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3346 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3349 [(set (reg:SI T_REG) (const_int 0))]
3354 [(set (reg:SI T_REG) (const_int 1))]
3358 ;; t/r must come after r/r, lest reload will try to reload stuff like
3359 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3360 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3361 (define_insn "movsi_i"
3362 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3363 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3366 && (register_operand (operands[0], SImode)
3367 || register_operand (operands[1], SImode))"
3384 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3385 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3387 ;; t/r must come after r/r, lest reload will try to reload stuff like
3388 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3389 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3390 ;; will require a reload.
3391 (define_insn "movsi_ie"
3392 [(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")
3393 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3395 && (register_operand (operands[0], SImode)
3396 || register_operand (operands[1], SImode))"
3417 ! move optimized away"
3418 [(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")
3419 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
3420 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3422 (define_insn "movsi_i_lowpart"
3423 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3424 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3426 && (register_operand (operands[0], SImode)
3427 || register_operand (operands[1], SImode))"
3437 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3439 (define_insn "*movsi_media"
3440 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3441 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3443 && (register_operand (operands[0], SImode)
3444 || register_operand (operands[1], SImode))"
3459 [(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")
3460 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3462 (define_insn "*movsi_media_nofpu"
3463 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3464 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3466 && (register_operand (operands[0], SImode)
3467 || register_operand (operands[1], SImode))"
3477 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3478 (set_attr "length" "4,4,8,4,4,4,4,12")])
3481 [(set (match_operand:SI 0 "arith_reg_operand" "")
3482 (match_operand:SI 1 "immediate_operand" ""))]
3483 "TARGET_SHMEDIA && reload_completed
3484 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3485 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3488 operands[2] = shallow_copy_rtx (operands[1]);
3489 PUT_MODE (operands[2], DImode);
3493 [(set (match_operand:SI 0 "register_operand" "")
3494 (match_operand:SI 1 "immediate_operand" ""))]
3495 "TARGET_SHMEDIA && reload_completed
3496 && ((GET_CODE (operands[1]) == CONST_INT
3497 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3498 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3499 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3501 (define_expand "movsi"
3502 [(set (match_operand:SI 0 "general_movdst_operand" "")
3503 (match_operand:SI 1 "general_movsrc_operand" ""))]
3505 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3507 (define_expand "ic_invalidate_line"
3508 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3509 (match_dup 1)] UNSPEC_ICACHE)
3510 (clobber (scratch:SI))])]
3511 "TARGET_HARD_SH4 || TARGET_SH5"
3516 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3519 else if (TARGET_SHCOMPACT)
3521 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3522 operands[1] = force_reg (Pmode, operands[1]);
3523 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3526 operands[0] = force_reg (Pmode, operands[0]);
3527 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3531 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3532 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3533 ;; the requirement *1*00 for associative address writes. The alignment of
3534 ;; %0 implies that its least significant bit is cleared,
3535 ;; thus we clear the V bit of a matching entry if there is one.
3536 (define_insn "ic_invalidate_line_i"
3537 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3538 (match_operand:SI 1 "register_operand" "r")]
3540 (clobber (match_scratch:SI 2 "=&r"))]
3542 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3543 [(set_attr "length" "8")
3544 (set_attr "type" "cwb")])
3546 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3547 ;; an add in the code that calculates the address.
3548 (define_insn "ic_invalidate_line_media"
3549 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3552 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3553 [(set_attr "length" "16")
3554 (set_attr "type" "invalidate_line_media")])
3556 (define_insn "ic_invalidate_line_compact"
3557 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3558 (match_operand:SI 1 "register_operand" "r")]
3560 (clobber (reg:SI PR_REG))]
3563 [(set_attr "type" "sfunc")
3564 (set_attr "needs_delay_slot" "yes")])
3566 (define_expand "initialize_trampoline"
3567 [(match_operand:SI 0 "" "")
3568 (match_operand:SI 1 "" "")
3569 (match_operand:SI 2 "" "")]
3575 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3576 tramp = gen_rtx_REG (SImode, R0_REG);
3577 emit_move_insn (tramp, operands[0]);
3578 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3579 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3581 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3585 (define_insn "initialize_trampoline_compact"
3586 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3587 (match_operand:SI 1 "register_operand" "r")
3588 (reg:SI R2_REG) (reg:SI R3_REG)]
3591 (clobber (reg:SI PR_REG))]
3594 [(set_attr "type" "sfunc")
3595 (set_attr "needs_delay_slot" "yes")])
3597 (define_insn "movqi_i"
3598 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3599 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3601 && (arith_reg_operand (operands[0], QImode)
3602 || arith_reg_operand (operands[1], QImode))"
3610 [(set_attr "type" "move,load,store,move,move,move")])
3612 (define_insn "*movqi_media"
3613 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3614 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3616 && (arith_reg_operand (operands[0], QImode)
3617 || arith_reg_operand (operands[1], QImode))"
3623 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3625 (define_expand "movqi"
3626 [(set (match_operand:QI 0 "general_operand" "")
3627 (match_operand:QI 1 "general_operand" ""))]
3629 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3631 (define_expand "reload_inqi"
3632 [(set (match_operand:SI 2 "" "=&r")
3633 (match_operand:QI 1 "inqhi_operand" ""))
3634 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3635 (truncate:HI (match_dup 3)))]
3639 rtx inner = XEXP (operands[1], 0);
3640 int regno = REGNO (inner);
3642 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3643 operands[1] = gen_rtx_REG (SImode, regno);
3644 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3647 (define_insn "movhi_i"
3648 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3649 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3651 && (arith_reg_operand (operands[0], HImode)
3652 || arith_reg_operand (operands[1], HImode))"
3662 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3664 (define_insn "*movhi_media"
3665 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3666 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3668 && (arith_reg_operand (operands[0], HImode)
3669 || arith_reg_operand (operands[1], HImode))"
3676 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3679 [(set (match_operand:HI 0 "register_operand" "")
3680 (match_operand:HI 1 "immediate_operand" ""))]
3681 "TARGET_SHMEDIA && reload_completed
3682 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3683 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3685 (define_expand "movhi"
3686 [(set (match_operand:HI 0 "general_movdst_operand" "")
3687 (match_operand:HI 1 "general_movsrc_operand" ""))]
3689 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3691 (define_expand "reload_inhi"
3692 [(set (match_operand:SI 2 "" "=&r")
3693 (match_operand:HI 1 "inqhi_operand" ""))
3694 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3695 (truncate:HI (match_dup 3)))]
3699 rtx inner = XEXP (operands[1], 0);
3700 int regno = REGNO (inner);
3702 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3703 operands[1] = gen_rtx_REG (SImode, regno);
3704 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3707 ;; ??? This should be a define expand.
3709 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3710 ;; compiled with -m2 -ml -O3 -funroll-loops
3712 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3713 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3715 && (arith_reg_operand (operands[0], DImode)
3716 || arith_reg_operand (operands[1], DImode))"
3717 "* return output_movedouble (insn, operands, DImode);"
3718 [(set_attr "length" "4")
3719 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3721 ;; If the output is a register and the input is memory or a register, we have
3722 ;; to be careful and see which word needs to be loaded first.
3725 [(set (match_operand:DI 0 "general_movdst_operand" "")
3726 (match_operand:DI 1 "general_movsrc_operand" ""))]
3727 "TARGET_SH1 && reload_completed"
3728 [(set (match_dup 2) (match_dup 3))
3729 (set (match_dup 4) (match_dup 5))]
3734 if ((GET_CODE (operands[0]) == MEM
3735 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3736 || (GET_CODE (operands[1]) == MEM
3737 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3740 if (GET_CODE (operands[0]) == REG)
3741 regno = REGNO (operands[0]);
3742 else if (GET_CODE (operands[0]) == SUBREG)
3743 regno = subreg_regno (operands[0]);
3744 else if (GET_CODE (operands[0]) == MEM)
3750 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3752 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3753 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3754 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3755 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3759 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3760 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3761 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3762 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3765 if (operands[2] == 0 || operands[3] == 0
3766 || operands[4] == 0 || operands[5] == 0)
3770 (define_insn "*movdi_media"
3771 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3772 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3774 && (register_operand (operands[0], DImode)
3775 || register_operand (operands[1], DImode))"
3790 [(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")
3791 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3793 (define_insn "*movdi_media_nofpu"
3794 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3795 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3797 && (register_operand (operands[0], DImode)
3798 || register_operand (operands[1], DImode))"
3808 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3809 (set_attr "length" "4,4,16,4,4,4,4,*")])
3812 [(set (match_operand:DI 0 "arith_reg_operand" "")
3813 (match_operand:DI 1 "immediate_operand" ""))]
3814 "TARGET_SHMEDIA && reload_completed
3815 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3816 [(set (match_dup 0) (match_dup 1))]
3821 if (TARGET_SHMEDIA64)
3822 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3824 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3826 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3832 (define_expand "movdi_const"
3833 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3834 (const:DI (sign_extend:DI
3837 (match_operand:DI 1 "immediate_operand" "s")
3840 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3848 (const_int 32)))))))))
3850 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3858 (const_int 16)))))))))
3860 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3866 (match_dup 1))))))))]
3867 "TARGET_SHMEDIA64 && reload_completed
3868 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3871 if (GET_CODE (operands[1]) == LABEL_REF
3872 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3873 LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3874 else if (GOTOFF_P (operands[1])
3875 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3876 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3878 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3881 (define_expand "movdi_const_32bit"
3882 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3883 (const:DI (sign_extend:DI
3886 (match_operand:DI 1 "immediate_operand" "s")
3889 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3895 (match_dup 1))))))))]
3896 "TARGET_SHMEDIA32 && reload_completed
3897 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3900 if (GET_CODE (operands[1]) == LABEL_REF
3901 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3902 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3903 else if (GOTOFF_P (operands[1])
3904 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3905 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3907 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3910 (define_expand "movdi_const_16bit"
3911 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3912 (const:DI (sign_extend:DI
3914 (match_operand:DI 1 "immediate_operand" "s")))))]
3915 "TARGET_SHMEDIA && flag_pic && reload_completed
3916 && GET_CODE (operands[1]) == SYMBOL_REF"
3920 [(set (match_operand:DI 0 "arith_reg_operand" "")
3921 (match_operand:DI 1 "immediate_operand" ""))]
3922 "TARGET_SHMEDIA && reload_completed
3923 && GET_CODE (operands[1]) == CONST_INT
3924 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3925 [(set (match_dup 0) (match_dup 2))
3929 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3930 unsigned HOST_WIDE_INT low = val;
3931 unsigned HOST_WIDE_INT high = val;
3932 unsigned HOST_WIDE_INT sign;
3933 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3935 /* Sign-extend the 16 least-significant bits. */
3940 /* Arithmetic shift right the word by 16 bits. */
3943 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3948 /* If we can't generate the constant with a two-insn movi / shori
3949 sequence, try some other strategies. */
3950 if (! CONST_OK_FOR_J (high))
3952 /* Try constant load / left shift. We know VAL != 0. */
3953 val2 = val ^ (val-1);
3956 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3958 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3959 || (! CONST_OK_FOR_J (high >> 16)
3960 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3962 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3963 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3964 GEN_INT (trailing_zeroes));
3968 /* Try constant load / right shift. */
3969 val2 = (val >> 15) + 1;
3970 if (val2 == (val2 & -val2))
3972 int shift = 49 - exact_log2 (val2);
3974 val2 = trunc_int_for_mode (val << shift, DImode);
3975 if (CONST_OK_FOR_J (val2))
3977 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3983 val2 = val & 0xffff;
3984 if ((val >> 16 & 0xffff) == val2
3985 && (val >> 32 & 0xffff) == val2
3986 && (val >> 48 & 0xffff) == val2)
3988 val2 = (HOST_WIDE_INT) val >> 48;
3989 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3990 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3993 /* Try movi / mshflo.l */
3994 val2 = (HOST_WIDE_INT) val >> 32;
3995 if (val2 == trunc_int_for_mode (val, SImode))
3997 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4001 /* Try movi / mshflo.l w/ r63. */
4002 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4003 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4005 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4011 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4014 operands[2] = GEN_INT (val2);
4018 [(set (match_operand:DI 0 "arith_reg_operand" "")
4019 (match_operand:DI 1 "immediate_operand" ""))]
4020 "TARGET_SHMEDIA && reload_completed
4021 && GET_CODE (operands[1]) == CONST_DOUBLE"
4022 [(set (match_dup 0) (match_dup 2))
4024 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4025 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4028 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4029 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4030 unsigned HOST_WIDE_INT val = low;
4031 unsigned HOST_WIDE_INT sign;
4033 /* Sign-extend the 16 least-significant bits. */
4037 operands[1] = GEN_INT (val);
4039 /* Arithmetic shift right the double-word by 16 bits. */
4041 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4044 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4048 /* This will only be true if high is a sign-extension of low, i.e.,
4049 it must be either 0 or (unsigned)-1, and be zero iff the
4050 most-significant bit of low is set. */
4051 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4052 operands[2] = GEN_INT (low);
4054 operands[2] = immed_double_const (low, high, DImode);
4057 (define_insn "shori_media"
4058 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4059 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4063 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4068 [(set_attr "type" "arith_media,*")])
4070 (define_expand "movdi"
4071 [(set (match_operand:DI 0 "general_movdst_operand" "")
4072 (match_operand:DI 1 "general_movsrc_operand" ""))]
4074 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4076 (define_insn "movdf_media"
4077 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4078 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4080 && (register_operand (operands[0], DFmode)
4081 || register_operand (operands[1], DFmode))"
4092 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4094 (define_insn "movdf_media_nofpu"
4095 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4096 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4098 && (register_operand (operands[0], DFmode)
4099 || register_operand (operands[1], DFmode))"
4105 [(set_attr "type" "arith_media,*,load_media,store_media")])
4108 [(set (match_operand:DF 0 "arith_reg_operand" "")
4109 (match_operand:DF 1 "immediate_operand" ""))]
4110 "TARGET_SHMEDIA && reload_completed"
4111 [(set (match_dup 3) (match_dup 2))]
4114 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4116 REAL_VALUE_TYPE value;
4118 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4119 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4121 if (HOST_BITS_PER_WIDE_INT >= 64)
4122 operands[2] = immed_double_const ((unsigned long) values[endian]
4123 | ((HOST_WIDE_INT) values[1 - endian]
4125 else if (HOST_BITS_PER_WIDE_INT == 32)
4126 operands[2] = immed_double_const (values[endian], values[1 - endian],
4131 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4134 ;; ??? This should be a define expand.
4136 (define_insn "movdf_k"
4137 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4138 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4140 && (! TARGET_SH4 || reload_completed
4141 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4142 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4143 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4144 && (arith_reg_operand (operands[0], DFmode)
4145 || arith_reg_operand (operands[1], DFmode))"
4146 "* return output_movedouble (insn, operands, DFmode);"
4147 [(set_attr "length" "4")
4148 (set_attr "type" "move,pcload,load,store")])
4150 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4151 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4152 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4153 ;; the d/m/c/X alternative, which is split later into single-precision
4154 ;; instructions. And when not optimizing, no splits are done before fixing
4155 ;; up pcloads, so we need usable length information for that.
4156 (define_insn "movdf_i4"
4157 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4158 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4159 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4160 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4162 && (arith_reg_operand (operands[0], DFmode)
4163 || arith_reg_operand (operands[1], DFmode))"
4175 [(set_attr_alternative "length"
4176 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4178 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4179 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4180 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4182 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4183 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4184 ;; increment or decrement r15 explicitly.
4186 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4187 (const_int 10) (const_int 8))
4189 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4190 (const_int 10) (const_int 8))])
4191 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4192 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4193 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4194 (const_string "double")
4195 (const_string "none")))])
4197 ;; Moving DFmode between fp/general registers through memory
4198 ;; (the top of the stack) is faster than moving through fpul even for
4199 ;; little endian. Because the type of an instruction is important for its
4200 ;; scheduling, it is beneficial to split these operations, rather than
4201 ;; emitting them in one single chunk, even if this will expose a stack
4202 ;; use that will prevent scheduling of other stack accesses beyond this
4205 [(set (match_operand:DF 0 "register_operand" "")
4206 (match_operand:DF 1 "register_operand" ""))
4207 (use (match_operand:PSI 2 "fpscr_operand" ""))
4208 (clobber (match_scratch:SI 3 "=X"))]
4209 "TARGET_SH4 && reload_completed
4210 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4216 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4218 emit_move_insn (stack_pointer_rtx,
4219 plus_constant (stack_pointer_rtx, -8));
4220 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4223 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4224 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4225 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4226 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4227 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4228 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4230 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4231 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4232 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4233 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4235 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4239 ;; local-alloc sometimes allocates scratch registers even when not required,
4240 ;; so we must be prepared to handle these.
4242 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4244 [(set (match_operand:DF 0 "general_movdst_operand" "")
4245 (match_operand:DF 1 "general_movsrc_operand" ""))
4246 (use (match_operand:PSI 2 "fpscr_operand" ""))
4247 (clobber (match_scratch:SI 3 ""))]
4250 && true_regnum (operands[0]) < 16
4251 && true_regnum (operands[1]) < 16"
4252 [(set (match_dup 0) (match_dup 1))]
4255 /* If this was a reg <-> mem operation with base + index reg addressing,
4256 we have to handle this in a special way. */
4257 rtx mem = operands[0];
4259 if (! memory_operand (mem, DFmode))
4264 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4265 mem = SUBREG_REG (mem);
4266 if (GET_CODE (mem) == MEM)
4268 rtx addr = XEXP (mem, 0);
4269 if (GET_CODE (addr) == PLUS
4270 && GET_CODE (XEXP (addr, 0)) == REG
4271 && GET_CODE (XEXP (addr, 1)) == REG)
4274 rtx reg0 = gen_rtx (REG, Pmode, 0);
4275 rtx regop = operands[store_p], word0 ,word1;
4277 if (GET_CODE (regop) == SUBREG)
4278 alter_subreg (®op);
4279 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4283 mem = copy_rtx (mem);
4284 PUT_MODE (mem, SImode);
4285 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4286 alter_subreg (&word0);
4287 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4288 alter_subreg (&word1);
4289 if (store_p || ! refers_to_regno_p (REGNO (word0),
4290 REGNO (word0) + 1, addr, 0))
4293 ? gen_movsi_ie (mem, word0)
4294 : gen_movsi_ie (word0, mem));
4295 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4296 mem = copy_rtx (mem);
4298 ? gen_movsi_ie (mem, word1)
4299 : gen_movsi_ie (word1, mem));
4300 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4304 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4305 emit_insn (gen_movsi_ie (word1, mem));
4306 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4307 mem = copy_rtx (mem);
4308 emit_insn (gen_movsi_ie (word0, mem));
4315 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4317 [(set (match_operand:DF 0 "register_operand" "")
4318 (match_operand:DF 1 "memory_operand" ""))
4319 (use (match_operand:PSI 2 "fpscr_operand" ""))
4320 (clobber (reg:SI R0_REG))]
4321 "TARGET_SH4 && reload_completed"
4322 [(parallel [(set (match_dup 0) (match_dup 1))
4324 (clobber (scratch:SI))])]
4327 (define_expand "reload_indf"
4328 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4329 (match_operand:DF 1 "immediate_operand" "FQ"))
4330 (use (reg:PSI FPSCR_REG))
4331 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4335 (define_expand "reload_outdf"
4336 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4337 (match_operand:DF 1 "register_operand" "af,r"))
4338 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4342 ;; Simplify no-op moves.
4344 [(set (match_operand:SF 0 "register_operand" "")
4345 (match_operand:SF 1 "register_operand" ""))
4346 (use (match_operand:PSI 2 "fpscr_operand" ""))
4347 (clobber (match_scratch:SI 3 "X"))]
4348 "TARGET_SH3E && reload_completed
4349 && true_regnum (operands[0]) == true_regnum (operands[1])"
4350 [(set (match_dup 0) (match_dup 0))]
4353 ;; fmovd substitute post-reload splits
4355 [(set (match_operand:DF 0 "register_operand" "")
4356 (match_operand:DF 1 "register_operand" ""))
4357 (use (match_operand:PSI 2 "fpscr_operand" ""))
4358 (clobber (match_scratch:SI 3 "X"))]
4359 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4360 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4361 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4365 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4366 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4367 gen_rtx (REG, SFmode, src), operands[2]));
4368 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4369 gen_rtx (REG, SFmode, src + 1), operands[2]));
4374 [(set (match_operand:DF 0 "register_operand" "")
4375 (mem:DF (match_operand:SI 1 "register_operand" "")))
4376 (use (match_operand:PSI 2 "fpscr_operand" ""))
4377 (clobber (match_scratch:SI 3 ""))]
4378 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4379 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4380 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4384 int regno = true_regnum (operands[0]);
4386 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4388 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4389 regno + !! TARGET_LITTLE_ENDIAN),
4390 mem2, operands[2]));
4391 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4392 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4393 regno + ! TARGET_LITTLE_ENDIAN),
4394 gen_rtx (MEM, SFmode, operands[1]),
4400 [(set (match_operand:DF 0 "register_operand" "")
4401 (match_operand:DF 1 "memory_operand" ""))
4402 (use (match_operand:PSI 2 "fpscr_operand" ""))
4403 (clobber (match_scratch:SI 3 ""))]
4404 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4405 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4409 int regno = true_regnum (operands[0]);
4410 rtx addr, insn, adjust = NULL_RTX;
4411 rtx mem2 = copy_rtx (operands[1]);
4412 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4413 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4415 PUT_MODE (mem2, SFmode);
4416 operands[1] = copy_rtx (mem2);
4417 addr = XEXP (mem2, 0);
4418 if (GET_CODE (addr) != POST_INC)
4420 /* If we have to modify the stack pointer, the value that we have
4421 read with post-increment might be modified by an interrupt,
4422 so write it back. */
4423 if (REGNO (addr) == STACK_POINTER_REGNUM)
4424 adjust = gen_push_e (reg0);
4426 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4427 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4429 addr = XEXP (addr, 0);
4430 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4431 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4432 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4436 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4441 [(set (match_operand:DF 0 "memory_operand" "")
4442 (match_operand:DF 1 "register_operand" ""))
4443 (use (match_operand:PSI 2 "fpscr_operand" ""))
4444 (clobber (match_scratch:SI 3 ""))]
4445 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4446 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4450 int regno = true_regnum (operands[1]);
4451 rtx insn, addr, adjust = NULL_RTX;
4453 operands[0] = copy_rtx (operands[0]);
4454 PUT_MODE (operands[0], SFmode);
4455 insn = emit_insn (gen_movsf_ie (operands[0],
4456 gen_rtx (REG, SFmode,
4457 regno + ! TARGET_LITTLE_ENDIAN),
4459 operands[0] = copy_rtx (operands[0]);
4460 addr = XEXP (operands[0], 0);
4461 if (GET_CODE (addr) != PRE_DEC)
4463 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4464 emit_insn_before (adjust, insn);
4465 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4467 addr = XEXP (addr, 0);
4469 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4470 insn = emit_insn (gen_movsf_ie (operands[0],
4471 gen_rtx (REG, SFmode,
4472 regno + !! TARGET_LITTLE_ENDIAN),
4474 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4478 ;; If the output is a register and the input is memory or a register, we have
4479 ;; to be careful and see which word needs to be loaded first.
4482 [(set (match_operand:DF 0 "general_movdst_operand" "")
4483 (match_operand:DF 1 "general_movsrc_operand" ""))]
4484 "TARGET_SH1 && reload_completed"
4485 [(set (match_dup 2) (match_dup 3))
4486 (set (match_dup 4) (match_dup 5))]
4491 if ((GET_CODE (operands[0]) == MEM
4492 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4493 || (GET_CODE (operands[1]) == MEM
4494 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4497 if (GET_CODE (operands[0]) == REG)
4498 regno = REGNO (operands[0]);
4499 else if (GET_CODE (operands[0]) == SUBREG)
4500 regno = subreg_regno (operands[0]);
4501 else if (GET_CODE (operands[0]) == MEM)
4507 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4509 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4510 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4511 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4512 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4516 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4517 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4518 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4519 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4522 if (operands[2] == 0 || operands[3] == 0
4523 || operands[4] == 0 || operands[5] == 0)
4527 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4528 ;; used only once, let combine add in the index again.
4531 [(set (match_operand:SI 0 "register_operand" "")
4532 (match_operand:SI 1 "" ""))
4533 (clobber (match_operand 2 "register_operand" ""))]
4534 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4535 [(use (reg:SI R0_REG))]
4538 rtx addr, reg, const_int;
4540 if (GET_CODE (operands[1]) != MEM)
4542 addr = XEXP (operands[1], 0);
4543 if (GET_CODE (addr) != PLUS)
4545 reg = XEXP (addr, 0);
4546 const_int = XEXP (addr, 1);
4547 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4548 && GET_CODE (const_int) == CONST_INT))
4550 emit_move_insn (operands[2], const_int);
4551 emit_move_insn (operands[0],
4552 change_address (operands[1], VOIDmode,
4553 gen_rtx_PLUS (SImode, reg, operands[2])));
4558 [(set (match_operand:SI 1 "" "")
4559 (match_operand:SI 0 "register_operand" ""))
4560 (clobber (match_operand 2 "register_operand" ""))]
4561 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4562 [(use (reg:SI R0_REG))]
4565 rtx addr, reg, const_int;
4567 if (GET_CODE (operands[1]) != MEM)
4569 addr = XEXP (operands[1], 0);
4570 if (GET_CODE (addr) != PLUS)
4572 reg = XEXP (addr, 0);
4573 const_int = XEXP (addr, 1);
4574 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4575 && GET_CODE (const_int) == CONST_INT))
4577 emit_move_insn (operands[2], const_int);
4578 emit_move_insn (change_address (operands[1], VOIDmode,
4579 gen_rtx_PLUS (SImode, reg, operands[2])),
4584 (define_expand "movdf"
4585 [(set (match_operand:DF 0 "general_movdst_operand" "")
4586 (match_operand:DF 1 "general_movsrc_operand" ""))]
4590 if (prepare_move_operands (operands, DFmode)) DONE;
4593 if (TARGET_SHMEDIA_FPU)
4594 emit_insn (gen_movdf_media (operands[0], operands[1]));
4596 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4601 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4606 ;;This is incompatible with the way gcc uses subregs.
4607 ;;(define_insn "movv2sf_i"
4608 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4609 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4610 ;; "TARGET_SHMEDIA_FPU
4611 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4612 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4616 ;; fst%M0.p %m0, %1"
4617 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4619 (define_insn_and_split "movv2sf_i"
4620 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4621 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4622 "TARGET_SHMEDIA_FPU"
4624 "TARGET_SHMEDIA_FPU && reload_completed"
4625 [(set (match_dup 0) (match_dup 1))]
4628 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4629 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4632 (define_expand "movv2sf"
4633 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4634 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4635 "TARGET_SHMEDIA_FPU"
4638 if (prepare_move_operands (operands, V2SFmode))
4642 (define_expand "addv2sf3"
4643 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4644 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4645 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4646 "TARGET_SHMEDIA_FPU"
4649 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4653 (define_expand "subv2sf3"
4654 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4655 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4656 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4657 "TARGET_SHMEDIA_FPU"
4660 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4664 (define_expand "mulv2sf3"
4665 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4666 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4667 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4668 "TARGET_SHMEDIA_FPU"
4671 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4675 (define_expand "divv2sf3"
4676 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4677 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4678 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4679 "TARGET_SHMEDIA_FPU"
4682 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4686 (define_insn_and_split "*movv4sf_i"
4687 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4688 (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4689 "TARGET_SHMEDIA_FPU"
4691 "&& reload_completed"
4697 for (i = 0; i < 4/2; i++)
4701 if (GET_CODE (operands[0]) == MEM)
4702 x = gen_rtx_MEM (V2SFmode,
4703 plus_constant (XEXP (operands[0], 0),
4704 i * GET_MODE_SIZE (V2SFmode)));
4706 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4708 if (GET_CODE (operands[1]) == MEM)
4709 y = gen_rtx_MEM (V2SFmode,
4710 plus_constant (XEXP (operands[1], 0),
4711 i * GET_MODE_SIZE (V2SFmode)));
4713 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4715 emit_insn (gen_movv2sf_i (x, y));
4720 [(set_attr "length" "8")])
4722 (define_expand "movv4sf"
4723 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4724 (match_operand:V4SF 1 "general_operand" ""))]
4725 "TARGET_SHMEDIA_FPU"
4728 if (prepare_move_operands (operands, V4SFmode))
4732 (define_insn_and_split "*movv16sf_i"
4733 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4734 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4735 "TARGET_SHMEDIA_FPU"
4737 "&& reload_completed"
4743 for (i = 0; i < 16/2; i++)
4747 if (GET_CODE (operands[0]) == MEM)
4748 x = gen_rtx_MEM (V2SFmode,
4749 plus_constant (XEXP (operands[0], 0),
4750 i * GET_MODE_SIZE (V2SFmode)));
4753 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4757 if (GET_CODE (operands[1]) == MEM)
4758 y = gen_rtx_MEM (V2SFmode,
4759 plus_constant (XEXP (operands[1], 0),
4760 i * GET_MODE_SIZE (V2SFmode)));
4763 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4767 emit_insn (gen_movv2sf_i (x, y));
4772 [(set_attr "length" "32")])
4774 (define_expand "movv16sf"
4775 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4776 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4777 "TARGET_SHMEDIA_FPU"
4780 if (prepare_move_operands (operands, V16SFmode))
4784 (define_insn "movsf_media"
4785 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4786 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4788 && (register_operand (operands[0], SFmode)
4789 || register_operand (operands[1], SFmode))"
4800 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4802 (define_insn "movsf_media_nofpu"
4803 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4804 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4806 && (register_operand (operands[0], SFmode)
4807 || register_operand (operands[1], SFmode))"
4813 [(set_attr "type" "arith_media,*,load_media,store_media")])
4816 [(set (match_operand:SF 0 "arith_reg_operand" "")
4817 (match_operand:SF 1 "immediate_operand" ""))]
4818 "TARGET_SHMEDIA && reload_completed
4819 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4820 [(set (match_dup 3) (match_dup 2))]
4824 REAL_VALUE_TYPE value;
4826 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4827 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4828 operands[2] = GEN_INT (values);
4830 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4833 (define_insn "movsf_i"
4834 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4835 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4838 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4839 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4840 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4841 && (arith_reg_operand (operands[0], SFmode)
4842 || arith_reg_operand (operands[1], SFmode))"
4851 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4853 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4854 ;; update_flow_info would not know where to put REG_EQUAL notes
4855 ;; when the destination changes mode.
4856 (define_insn "movsf_ie"
4857 [(set (match_operand:SF 0 "general_movdst_operand"
4858 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4859 (match_operand:SF 1 "general_movsrc_operand"
4860 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4861 (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"))
4862 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4865 && (arith_reg_operand (operands[0], SFmode)
4866 || arith_reg_operand (operands[1], SFmode)
4867 || arith_reg_operand (operands[3], SImode)
4868 || (fpul_operand (operands[0], SFmode)
4869 && memory_operand (operands[1], SFmode)
4870 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4871 || (fpul_operand (operands[1], SFmode)
4872 && memory_operand (operands[0], SFmode)
4873 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4893 ! move optimized away"
4894 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4895 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4896 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4897 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4898 (const_string "single")
4899 (const_string "none")))])
4902 [(set (match_operand:SF 0 "register_operand" "")
4903 (match_operand:SF 1 "register_operand" ""))
4904 (use (match_operand:PSI 2 "fpscr_operand" ""))
4905 (clobber (reg:SI FPUL_REG))]
4907 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4909 (clobber (scratch:SI))])
4910 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4912 (clobber (scratch:SI))])]
4915 (define_expand "movsf"
4916 [(set (match_operand:SF 0 "general_movdst_operand" "")
4917 (match_operand:SF 1 "general_movsrc_operand" ""))]
4921 if (prepare_move_operands (operands, SFmode))
4925 if (TARGET_SHMEDIA_FPU)
4926 emit_insn (gen_movsf_media (operands[0], operands[1]));
4928 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4933 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4938 (define_insn "mov_nop"
4939 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4942 [(set_attr "length" "0")
4943 (set_attr "type" "nil")])
4945 (define_expand "reload_insf"
4946 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4947 (match_operand:SF 1 "immediate_operand" "FQ"))
4948 (use (reg:PSI FPSCR_REG))
4949 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4953 (define_expand "reload_insi"
4954 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4955 (match_operand:SF 1 "immediate_operand" "FQ"))
4956 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4960 (define_insn "*movsi_y"
4961 [(set (match_operand:SI 0 "register_operand" "=y,y")
4962 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4963 (clobber (match_scratch:SI 2 "=&z,r"))]
4965 && (reload_in_progress || reload_completed)"
4967 [(set_attr "length" "4")
4968 (set_attr "type" "pcload,move")])
4971 [(set (match_operand:SI 0 "register_operand" "")
4972 (match_operand:SI 1 "immediate_operand" ""))
4973 (clobber (match_operand:SI 2 "register_operand" ""))]
4975 [(set (match_dup 2) (match_dup 1))
4976 (set (match_dup 0) (match_dup 2))]
4980 [(set (match_operand:SI 0 "register_operand" "")
4981 (match_operand:SI 1 "memory_operand" ""))
4982 (clobber (reg:SI R0_REG))]
4984 [(set (match_dup 0) (match_dup 1))]
4987 ;; ------------------------------------------------------------------------
4988 ;; Define the real conditional branch instructions.
4989 ;; ------------------------------------------------------------------------
4991 (define_insn "branch_true"
4992 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4993 (label_ref (match_operand 0 "" ""))
4996 "* return output_branch (1, insn, operands);"
4997 [(set_attr "type" "cbranch")])
4999 (define_insn "branch_false"
5000 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5001 (label_ref (match_operand 0 "" ""))
5004 "* return output_branch (0, insn, operands);"
5005 [(set_attr "type" "cbranch")])
5007 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5008 ;; which destination is too far away.
5009 ;; The const_int_operand is distinct for each branch target; it avoids
5010 ;; unwanted matches with redundant_insn.
5011 (define_insn "block_branch_redirect"
5012 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5015 [(set_attr "length" "0")])
5017 ;; This one has the additional purpose to record a possible scratch register
5018 ;; for the following branch.
5019 (define_insn "indirect_jump_scratch"
5020 [(set (match_operand:SI 0 "register_operand" "=r")
5021 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5024 [(set_attr "length" "0")])
5026 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5027 ;; being pulled into the delay slot of a condbranch that has been made to
5028 ;; jump around the unconditional jump because it was out of range.
5029 (define_insn "stuff_delay_slot"
5031 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5032 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5035 [(set_attr "length" "0")
5036 (set_attr "cond_delay_slot" "yes")])
5038 ;; Conditional branch insns
5040 (define_expand "beq_media"
5042 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5043 (match_operand:DI 2 "arith_operand" "r,O"))
5044 (label_ref:DI (match_operand 0 "" ""))
5049 (define_insn "*beq_media_i"
5051 (if_then_else (match_operator 3 "equality_comparison_operator"
5052 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5053 (match_operand:DI 2 "arith_operand" "r,O")])
5054 (match_operand:DI 0 "target_operand" "b,b")
5060 [(set_attr "type" "cbranch_media")])
5062 (define_expand "bne_media"
5064 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5065 (match_operand:DI 2 "arith_operand" "r,O"))
5066 (label_ref:DI (match_operand 0 "" ""))
5071 (define_expand "bgt_media"
5073 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5074 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5075 (label_ref:DI (match_operand 0 "" ""))
5080 (define_expand "bge_media"
5082 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5083 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5084 (label_ref:DI (match_operand 0 "" ""))
5089 (define_expand "bgtu_media"
5091 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5092 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5093 (label_ref:DI (match_operand 0 "" ""))
5098 (define_expand "bgeu_media"
5100 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5101 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5102 (label_ref:DI (match_operand 0 "" ""))
5107 (define_insn "*bgt_media_i"
5109 (if_then_else (match_operator 3 "greater_comparison_operator"
5110 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5111 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5112 (match_operand:DI 0 "target_operand" "b")
5115 "b%o3%' %N1, %N2, %0"
5116 [(set_attr "type" "cbranch_media")])
5118 ;; These are only needed to make invert_jump() happy.
5119 (define_insn "*blt_media_i"
5121 (if_then_else (match_operator 3 "less_comparison_operator"
5122 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5123 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5124 (match_operand:DI 0 "target_operand" "b")
5127 "b%o3%' %N2, %N1, %0"
5128 [(set_attr "type" "cbranch_media")])
5130 (define_expand "beq"
5132 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5133 (label_ref (match_operand 0 "" ""))
5140 if (GET_MODE (sh_compare_op0) != DImode)
5142 rtx tmp = gen_reg_rtx (DImode);
5144 emit_insn (gen_seq (tmp));
5145 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5149 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5150 emit_jump_insn (gen_beq_media (operands[0],
5151 sh_compare_op0, sh_compare_op1));
5155 from_compare (operands, EQ);
5158 (define_expand "bne"
5160 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5161 (label_ref (match_operand 0 "" ""))
5168 if (GET_MODE (sh_compare_op0) != DImode)
5170 rtx tmp = gen_reg_rtx (DImode);
5172 emit_insn (gen_seq (tmp));
5173 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5177 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5178 emit_jump_insn (gen_bne_media (operands[0],
5179 sh_compare_op0, sh_compare_op1));
5183 from_compare (operands, EQ);
5186 (define_expand "bgt"
5188 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5189 (label_ref (match_operand 0 "" ""))
5196 if (GET_MODE (sh_compare_op0) != DImode)
5198 rtx tmp = gen_reg_rtx (DImode);
5200 emit_insn (gen_sgt (tmp));
5201 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5205 if (sh_compare_op0 != const0_rtx)
5206 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5207 if (sh_compare_op1 != const0_rtx)
5208 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5209 emit_jump_insn (gen_bgt_media (operands[0],
5210 sh_compare_op0, sh_compare_op1));
5214 from_compare (operands, GT);
5217 (define_expand "blt"
5219 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5220 (label_ref (match_operand 0 "" ""))
5227 if (GET_MODE (sh_compare_op0) != DImode)
5229 rtx tmp = gen_reg_rtx (DImode);
5231 emit_insn (gen_slt (tmp));
5232 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5236 if (sh_compare_op0 != const0_rtx)
5237 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5238 if (sh_compare_op1 != const0_rtx)
5239 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5240 emit_jump_insn (gen_bgt_media (operands[0],
5241 sh_compare_op1, sh_compare_op0));
5245 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5247 rtx tmp = sh_compare_op0;
5248 sh_compare_op0 = sh_compare_op1;
5249 sh_compare_op1 = tmp;
5250 emit_insn (gen_bgt (operands[0]));
5253 from_compare (operands, GE);
5256 (define_expand "ble"
5258 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5259 (label_ref (match_operand 0 "" ""))
5266 if (GET_MODE (sh_compare_op0) != DImode)
5268 rtx tmp = gen_reg_rtx (DImode);
5270 emit_insn (gen_sle (tmp));
5271 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5275 if (sh_compare_op0 != const0_rtx)
5276 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5277 if (sh_compare_op1 != const0_rtx)
5278 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5279 emit_jump_insn (gen_bge_media (operands[0],
5280 sh_compare_op1, sh_compare_op0));
5286 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5288 rtx tmp = sh_compare_op0;
5289 sh_compare_op0 = sh_compare_op1;
5290 sh_compare_op1 = tmp;
5291 emit_insn (gen_bge (operands[0]));
5294 from_compare (operands, GT);
5297 (define_expand "bge"
5299 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5300 (label_ref (match_operand 0 "" ""))
5307 if (GET_MODE (sh_compare_op0) != DImode)
5309 rtx tmp = gen_reg_rtx (DImode);
5311 emit_insn (gen_sge (tmp));
5312 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5316 if (sh_compare_op0 != const0_rtx)
5317 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5318 if (sh_compare_op1 != const0_rtx)
5319 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5320 emit_jump_insn (gen_bge_media (operands[0],
5321 sh_compare_op0, sh_compare_op1));
5327 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5329 rtx tmp = sh_compare_op0;
5330 sh_compare_op0 = sh_compare_op1;
5331 sh_compare_op1 = tmp;
5332 emit_insn (gen_ble (operands[0]));
5335 from_compare (operands, GE);
5338 (define_expand "bgtu"
5340 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5341 (label_ref (match_operand 0 "" ""))
5348 if (sh_compare_op0 != const0_rtx)
5349 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5350 if (sh_compare_op1 != const0_rtx)
5351 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5352 emit_jump_insn (gen_bgtu_media (operands[0],
5353 sh_compare_op0, sh_compare_op1));
5357 from_compare (operands, GTU);
5360 (define_expand "bltu"
5362 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5363 (label_ref (match_operand 0 "" ""))
5370 if (sh_compare_op0 != const0_rtx)
5371 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5372 if (sh_compare_op1 != const0_rtx)
5373 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5374 emit_jump_insn (gen_bgtu_media (operands[0],
5375 sh_compare_op1, sh_compare_op0));
5379 from_compare (operands, GEU);
5382 (define_expand "bgeu"
5384 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5385 (label_ref (match_operand 0 "" ""))
5392 if (sh_compare_op0 != const0_rtx)
5393 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5394 if (sh_compare_op1 != const0_rtx)
5395 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5396 emit_jump_insn (gen_bgeu_media (operands[0],
5397 sh_compare_op0, sh_compare_op1));
5401 from_compare (operands, GEU);
5404 (define_expand "bleu"
5406 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5407 (label_ref (match_operand 0 "" ""))
5414 if (sh_compare_op0 != const0_rtx)
5415 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5416 if (sh_compare_op1 != const0_rtx)
5417 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5418 emit_jump_insn (gen_bgeu_media (operands[0],
5419 sh_compare_op1, sh_compare_op0));
5423 from_compare (operands, GTU);
5426 (define_expand "bunordered"
5427 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5429 (if_then_else (ne (match_dup 1) (const_int 0))
5430 (label_ref:DI (match_operand 0 "" ""))
5435 operands[1] = gen_reg_rtx (DImode);
5436 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5437 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5440 ;; ------------------------------------------------------------------------
5441 ;; Jump and linkage insns
5442 ;; ------------------------------------------------------------------------
5444 (define_insn "jump_compact"
5446 (label_ref (match_operand 0 "" "")))]
5450 /* The length is 16 if the delay slot is unfilled. */
5451 if (get_attr_length(insn) > 4)
5452 return output_far_jump(insn, operands[0]);
5454 return \"bra %l0%#\";
5456 [(set_attr "type" "jump")
5457 (set_attr "needs_delay_slot" "yes")])
5459 (define_insn "jump_media"
5461 (match_operand:DI 0 "target_operand" "b"))]
5464 [(set_attr "type" "jump_media")])
5466 (define_expand "jump"
5468 (label_ref (match_operand 0 "" "")))]
5473 emit_jump_insn (gen_jump_compact (operands[0]));
5474 else if (TARGET_SHMEDIA)
5476 if (reload_in_progress || reload_completed)
5478 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5484 (define_insn "force_mode_for_call"
5485 [(use (reg:PSI FPSCR_REG))]
5488 [(set_attr "length" "0")
5489 (set (attr "fp_mode")
5490 (if_then_else (eq_attr "fpu_single" "yes")
5491 (const_string "single") (const_string "double")))])
5493 (define_insn "calli"
5494 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5495 (match_operand 1 "" ""))
5496 (use (reg:PSI FPSCR_REG))
5497 (clobber (reg:SI PR_REG))]
5500 [(set_attr "type" "call")
5501 (set (attr "fp_mode")
5502 (if_then_else (eq_attr "fpu_single" "yes")
5503 (const_string "single") (const_string "double")))
5504 (set_attr "needs_delay_slot" "yes")])
5506 ;; This is a pc-rel call, using bsrf, for use with PIC.
5508 (define_insn "calli_pcrel"
5509 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5510 (match_operand 1 "" ""))
5511 (use (reg:PSI FPSCR_REG))
5512 (use (reg:SI PIC_REG))
5513 (use (match_operand 2 "" ""))
5514 (clobber (reg:SI PR_REG))]
5517 [(set_attr "type" "call")
5518 (set (attr "fp_mode")
5519 (if_then_else (eq_attr "fpu_single" "yes")
5520 (const_string "single") (const_string "double")))
5521 (set_attr "needs_delay_slot" "yes")])
5523 (define_insn_and_split "call_pcrel"
5524 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5525 (match_operand 1 "" ""))
5526 (use (reg:PSI FPSCR_REG))
5527 (use (reg:SI PIC_REG))
5528 (clobber (reg:SI PR_REG))
5529 (clobber (match_scratch:SI 2 "=r"))]
5536 rtx lab = PATTERN (gen_call_site ());
5538 if (SYMBOL_REF_FLAG (operands[0]))
5539 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5541 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5542 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5545 [(set_attr "type" "call")
5546 (set (attr "fp_mode")
5547 (if_then_else (eq_attr "fpu_single" "yes")
5548 (const_string "single") (const_string "double")))
5549 (set_attr "needs_delay_slot" "yes")])
5551 (define_insn "call_compact"
5552 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5553 (match_operand 1 "" ""))
5554 (match_operand 2 "immediate_operand" "n")
5555 (use (reg:SI R0_REG))
5556 (use (reg:SI R1_REG))
5557 (use (reg:PSI FPSCR_REG))
5558 (clobber (reg:SI PR_REG))]
5559 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5561 [(set_attr "type" "call")
5562 (set (attr "fp_mode")
5563 (if_then_else (eq_attr "fpu_single" "yes")
5564 (const_string "single") (const_string "double")))
5565 (set_attr "needs_delay_slot" "yes")])
5567 (define_insn "call_compact_rettramp"
5568 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5569 (match_operand 1 "" ""))
5570 (match_operand 2 "immediate_operand" "n")
5571 (use (reg:SI R0_REG))
5572 (use (reg:SI R1_REG))
5573 (use (reg:PSI FPSCR_REG))
5574 (clobber (reg:SI R10_REG))
5575 (clobber (reg:SI PR_REG))]
5576 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5578 [(set_attr "type" "call")
5579 (set (attr "fp_mode")
5580 (if_then_else (eq_attr "fpu_single" "yes")
5581 (const_string "single") (const_string "double")))
5582 (set_attr "needs_delay_slot" "yes")])
5584 (define_insn "call_media"
5585 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5586 (match_operand 1 "" ""))
5587 (clobber (reg:DI PR_MEDIA_REG))]
5590 [(set_attr "type" "jump_media")])
5592 (define_insn "call_valuei"
5593 [(set (match_operand 0 "" "=rf")
5594 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5595 (match_operand 2 "" "")))
5596 (use (reg:PSI FPSCR_REG))
5597 (clobber (reg:SI PR_REG))]
5600 [(set_attr "type" "call")
5601 (set (attr "fp_mode")
5602 (if_then_else (eq_attr "fpu_single" "yes")
5603 (const_string "single") (const_string "double")))
5604 (set_attr "needs_delay_slot" "yes")])
5606 (define_insn "call_valuei_pcrel"
5607 [(set (match_operand 0 "" "=rf")
5608 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5609 (match_operand 2 "" "")))
5610 (use (reg:PSI FPSCR_REG))
5611 (use (reg:SI PIC_REG))
5612 (use (match_operand 3 "" ""))
5613 (clobber (reg:SI PR_REG))]
5616 [(set_attr "type" "call")
5617 (set (attr "fp_mode")
5618 (if_then_else (eq_attr "fpu_single" "yes")
5619 (const_string "single") (const_string "double")))
5620 (set_attr "needs_delay_slot" "yes")])
5622 (define_insn_and_split "call_value_pcrel"
5623 [(set (match_operand 0 "" "=rf")
5624 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5625 (match_operand 2 "" "")))
5626 (use (reg:PSI FPSCR_REG))
5627 (use (reg:SI PIC_REG))
5628 (clobber (reg:SI PR_REG))
5629 (clobber (match_scratch:SI 3 "=r"))]
5636 rtx lab = PATTERN (gen_call_site ());
5638 if (SYMBOL_REF_FLAG (operands[1]))
5639 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5641 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5642 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5646 [(set_attr "type" "call")
5647 (set (attr "fp_mode")
5648 (if_then_else (eq_attr "fpu_single" "yes")
5649 (const_string "single") (const_string "double")))
5650 (set_attr "needs_delay_slot" "yes")])
5652 (define_insn "call_value_compact"
5653 [(set (match_operand 0 "" "=rf")
5654 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5655 (match_operand 2 "" "")))
5656 (match_operand 3 "immediate_operand" "n")
5657 (use (reg:SI R0_REG))
5658 (use (reg:SI R1_REG))
5659 (use (reg:PSI FPSCR_REG))
5660 (clobber (reg:SI PR_REG))]
5661 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5663 [(set_attr "type" "call")
5664 (set (attr "fp_mode")
5665 (if_then_else (eq_attr "fpu_single" "yes")
5666 (const_string "single") (const_string "double")))
5667 (set_attr "needs_delay_slot" "yes")])
5669 (define_insn "call_value_compact_rettramp"
5670 [(set (match_operand 0 "" "=rf")
5671 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5672 (match_operand 2 "" "")))
5673 (match_operand 3 "immediate_operand" "n")
5674 (use (reg:SI R0_REG))
5675 (use (reg:SI R1_REG))
5676 (use (reg:PSI FPSCR_REG))
5677 (clobber (reg:SI R10_REG))
5678 (clobber (reg:SI PR_REG))]
5679 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5681 [(set_attr "type" "call")
5682 (set (attr "fp_mode")
5683 (if_then_else (eq_attr "fpu_single" "yes")
5684 (const_string "single") (const_string "double")))
5685 (set_attr "needs_delay_slot" "yes")])
5687 (define_insn "call_value_media"
5688 [(set (match_operand 0 "" "=rf")
5689 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5690 (match_operand 2 "" "")))
5691 (clobber (reg:DI PR_MEDIA_REG))]
5694 [(set_attr "type" "jump_media")])
5696 (define_expand "call"
5697 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5698 (match_operand 1 "" ""))
5699 (match_operand 2 "" "")
5700 (use (reg:PSI FPSCR_REG))
5701 (clobber (reg:SI PR_REG))])]
5707 operands[0] = XEXP (operands[0], 0);
5708 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5710 if (! SYMBOL_REF_FLAG (operands[0]))
5712 rtx reg = gen_reg_rtx (Pmode);
5714 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5719 operands[0] = gen_sym2PIC (operands[0]);
5720 PUT_MODE (operands[0], Pmode);
5723 if (GET_MODE (operands[0]) == SImode)
5725 if (GET_CODE (operands[0]) == REG)
5726 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5727 else if (GET_CODE (operands[0]) == SUBREG)
5729 operands[0] = SUBREG_REG (operands[0]);
5730 if (GET_MODE (operands[0]) != DImode)
5731 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5735 operands[0] = shallow_copy_rtx (operands[0]);
5736 PUT_MODE (operands[0], DImode);
5739 if (! target_reg_operand (operands[0], DImode))
5740 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5741 emit_call_insn (gen_call_media (operands[0], operands[1]));
5744 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5746 rtx cookie_rtx = operands[2];
5747 long cookie = INTVAL (cookie_rtx);
5748 rtx func = XEXP (operands[0], 0);
5753 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5755 rtx reg = gen_reg_rtx (Pmode);
5757 emit_insn (gen_symGOTPLT2reg (reg, func));
5761 func = legitimize_pic_address (func, Pmode, 0);
5764 r0 = gen_rtx_REG (SImode, R0_REG);
5765 r1 = gen_rtx_REG (SImode, R1_REG);
5767 /* Since such a call function may use all call-clobbered
5768 registers, we force a mode switch earlier, so that we don't
5769 run out of registers when adjusting fpscr for the call. */
5770 emit_insn (gen_force_mode_for_call ());
5772 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5773 \"__GCC_shcompact_call_trampoline\");
5776 rtx reg = gen_reg_rtx (Pmode);
5778 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5781 operands[0] = force_reg (SImode, operands[0]);
5783 emit_move_insn (r0, func);
5784 emit_move_insn (r1, cookie_rtx);
5786 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5787 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5790 emit_call_insn (gen_call_compact (operands[0], operands[1],
5795 else if (TARGET_SHCOMPACT && flag_pic
5796 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5797 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5799 rtx reg = gen_reg_rtx (Pmode);
5801 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5802 XEXP (operands[0], 0) = reg;
5804 if (flag_pic && TARGET_SH2
5805 && GET_CODE (operands[0]) == MEM
5806 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5808 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5812 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5814 emit_call_insn (gen_calli (operands[0], operands[1]));
5818 (define_insn "call_pop_compact"
5819 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5820 (match_operand 1 "" ""))
5821 (match_operand 2 "immediate_operand" "n")
5822 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5823 (match_operand 3 "immediate_operand" "n")))
5824 (use (reg:SI R0_REG))
5825 (use (reg:SI R1_REG))
5826 (use (reg:PSI FPSCR_REG))
5827 (clobber (reg:SI PR_REG))]
5828 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5830 [(set_attr "type" "call")
5831 (set (attr "fp_mode")
5832 (if_then_else (eq_attr "fpu_single" "yes")
5833 (const_string "single") (const_string "double")))
5834 (set_attr "needs_delay_slot" "yes")])
5836 (define_insn "call_pop_compact_rettramp"
5837 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5838 (match_operand 1 "" ""))
5839 (match_operand 2 "immediate_operand" "n")
5840 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5841 (match_operand 3 "immediate_operand" "n")))
5842 (use (reg:SI R0_REG))
5843 (use (reg:SI R1_REG))
5844 (use (reg:PSI FPSCR_REG))
5845 (clobber (reg:SI R10_REG))
5846 (clobber (reg:SI PR_REG))]
5847 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5849 [(set_attr "type" "call")
5850 (set (attr "fp_mode")
5851 (if_then_else (eq_attr "fpu_single" "yes")
5852 (const_string "single") (const_string "double")))
5853 (set_attr "needs_delay_slot" "yes")])
5855 (define_expand "call_pop"
5856 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5857 (match_operand 1 "" ""))
5858 (match_operand 2 "" "")
5859 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5860 (match_operand 3 "" "")))])]
5864 if (operands[2] && INTVAL (operands[2]))
5866 rtx cookie_rtx = operands[2];
5867 long cookie = INTVAL (cookie_rtx);
5868 rtx func = XEXP (operands[0], 0);
5873 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5875 rtx reg = gen_reg_rtx (Pmode);
5877 emit_insn (gen_symGOTPLT2reg (reg, func));
5881 func = legitimize_pic_address (func, Pmode, 0);
5884 r0 = gen_rtx_REG (SImode, R0_REG);
5885 r1 = gen_rtx_REG (SImode, R1_REG);
5887 /* Since such a call function may use all call-clobbered
5888 registers, we force a mode switch earlier, so that we don't
5889 run out of registers when adjusting fpscr for the call. */
5890 emit_insn (gen_force_mode_for_call ());
5892 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5893 \"__GCC_shcompact_call_trampoline\");
5896 rtx reg = gen_reg_rtx (Pmode);
5898 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5901 operands[0] = force_reg (SImode, operands[0]);
5903 emit_move_insn (r0, func);
5904 emit_move_insn (r1, cookie_rtx);
5906 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5907 emit_call_insn (gen_call_pop_compact_rettramp
5908 (operands[0], operands[1], operands[2], operands[3]));
5910 emit_call_insn (gen_call_pop_compact
5911 (operands[0], operands[1], operands[2], operands[3]));
5919 (define_expand "call_value"
5920 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5921 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5922 (match_operand 2 "" "")))
5923 (match_operand 3 "" "")
5924 (use (reg:PSI FPSCR_REG))
5925 (clobber (reg:SI PR_REG))])]
5931 operands[1] = XEXP (operands[1], 0);
5932 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5934 if (! SYMBOL_REF_FLAG (operands[1]))
5936 rtx reg = gen_reg_rtx (Pmode);
5938 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5943 operands[1] = gen_sym2PIC (operands[1]);
5944 PUT_MODE (operands[1], Pmode);
5947 if (GET_MODE (operands[1]) == SImode)
5949 if (GET_CODE (operands[1]) == REG)
5950 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5951 else if (GET_CODE (operands[1]) == SUBREG)
5953 operands[1] = SUBREG_REG (operands[1]);
5954 if (GET_MODE (operands[1]) != DImode)
5955 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5959 operands[1] = shallow_copy_rtx (operands[1]);
5960 PUT_MODE (operands[1], DImode);
5963 if (! target_reg_operand (operands[1], DImode))
5964 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5965 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5969 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5971 rtx cookie_rtx = operands[3];
5972 long cookie = INTVAL (cookie_rtx);
5973 rtx func = XEXP (operands[1], 0);
5978 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5980 rtx reg = gen_reg_rtx (Pmode);
5982 emit_insn (gen_symGOTPLT2reg (reg, func));
5986 func = legitimize_pic_address (func, Pmode, 0);
5989 r0 = gen_rtx_REG (SImode, R0_REG);
5990 r1 = gen_rtx_REG (SImode, R1_REG);
5992 /* Since such a call function may use all call-clobbered
5993 registers, we force a mode switch earlier, so that we don't
5994 run out of registers when adjusting fpscr for the call. */
5995 emit_insn (gen_force_mode_for_call ());
5997 operands[1] = gen_rtx_SYMBOL_REF (SImode,
5998 \"__GCC_shcompact_call_trampoline\");
6001 rtx reg = gen_reg_rtx (Pmode);
6003 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6006 operands[1] = force_reg (SImode, operands[1]);
6008 emit_move_insn (r0, func);
6009 emit_move_insn (r1, cookie_rtx);
6011 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6012 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6017 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6018 operands[2], operands[3]));
6022 else if (TARGET_SHCOMPACT && flag_pic
6023 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6024 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6026 rtx reg = gen_reg_rtx (Pmode);
6028 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6029 XEXP (operands[1], 0) = reg;
6031 if (flag_pic && TARGET_SH2
6032 && GET_CODE (operands[1]) == MEM
6033 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6035 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6040 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6042 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6046 (define_insn "sibcalli"
6047 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6048 (match_operand 1 "" ""))
6049 (use (reg:PSI FPSCR_REG))
6053 [(set_attr "needs_delay_slot" "yes")
6054 (set (attr "fp_mode")
6055 (if_then_else (eq_attr "fpu_single" "yes")
6056 (const_string "single") (const_string "double")))
6057 (set_attr "type" "jump_ind")])
6059 (define_insn "sibcalli_pcrel"
6060 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6061 (match_operand 1 "" ""))
6062 (use (match_operand 2 "" ""))
6063 (use (reg:PSI FPSCR_REG))
6067 [(set_attr "needs_delay_slot" "yes")
6068 (set (attr "fp_mode")
6069 (if_then_else (eq_attr "fpu_single" "yes")
6070 (const_string "single") (const_string "double")))
6071 (set_attr "type" "jump_ind")])
6073 (define_insn_and_split "sibcall_pcrel"
6074 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6075 (match_operand 1 "" ""))
6076 (use (reg:PSI FPSCR_REG))
6077 (clobber (match_scratch:SI 2 "=k"))
6085 rtx lab = PATTERN (gen_call_site ());
6088 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6089 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6091 SIBLING_CALL_P (call_insn) = 1;
6094 [(set_attr "needs_delay_slot" "yes")
6095 (set (attr "fp_mode")
6096 (if_then_else (eq_attr "fpu_single" "yes")
6097 (const_string "single") (const_string "double")))
6098 (set_attr "type" "jump_ind")])
6100 (define_insn "sibcall_compact"
6101 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6102 (match_operand 1 "" ""))
6104 (use (match_operand:SI 2 "register_operand" "z,x"))
6105 (use (reg:SI R1_REG))
6106 (use (reg:PSI FPSCR_REG))
6107 ;; We want to make sure the `x' above will only match MACH_REG
6108 ;; because sibcall_epilogue may clobber MACL_REG.
6109 (clobber (reg:SI MACL_REG))]
6113 jmp @%0\\n sts %2, r0"
6114 [(set_attr "needs_delay_slot" "yes,no")
6115 (set_attr "length" "2,4")
6116 (set (attr "fp_mode") (const_string "single"))
6117 (set_attr "type" "jump_ind")])
6119 (define_insn "sibcall_media"
6120 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6121 (match_operand 1 "" ""))
6125 [(set_attr "type" "jump_media")])
6127 (define_expand "sibcall"
6129 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6130 (match_operand 1 "" ""))
6131 (match_operand 2 "" "")
6132 (use (reg:PSI FPSCR_REG))
6139 operands[0] = XEXP (operands[0], 0);
6140 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6142 if (! SYMBOL_REF_FLAG (operands[0]))
6144 rtx reg = gen_reg_rtx (Pmode);
6146 /* We must not use GOTPLT for sibcalls, because PIC_REG
6147 must be restored before the PLT code gets to run. */
6148 emit_insn (gen_symGOT2reg (reg, operands[0]));
6153 operands[0] = gen_sym2PIC (operands[0]);
6154 PUT_MODE (operands[0], Pmode);
6157 if (GET_MODE (operands[0]) == SImode)
6159 if (GET_CODE (operands[0]) == REG)
6160 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6161 else if (GET_CODE (operands[0]) == SUBREG)
6163 operands[0] = SUBREG_REG (operands[0]);
6164 if (GET_MODE (operands[0]) != DImode)
6165 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6169 operands[0] = shallow_copy_rtx (operands[0]);
6170 PUT_MODE (operands[0], DImode);
6173 if (! target_reg_operand (operands[0], DImode))
6174 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6175 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6178 else if (TARGET_SHCOMPACT && operands[2]
6179 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6181 rtx cookie_rtx = operands[2];
6182 long cookie = INTVAL (cookie_rtx);
6183 rtx func = XEXP (operands[0], 0);
6188 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6190 rtx reg = gen_reg_rtx (Pmode);
6192 emit_insn (gen_symGOT2reg (reg, func));
6196 func = legitimize_pic_address (func, Pmode, 0);
6199 /* FIXME: if we could tell whether all argument registers are
6200 already taken, we could decide whether to force the use of
6201 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6202 simple way to tell. We could use the CALL_COOKIE, but we
6203 can't currently tell a register used for regular argument
6204 passing from one that is unused. If we leave it up to reload
6205 to decide which register to use, it seems to always choose
6206 R0_REG, which leaves no available registers in SIBCALL_REGS
6207 to hold the address of the trampoline. */
6208 mach = gen_rtx_REG (SImode, MACH_REG);
6209 r1 = gen_rtx_REG (SImode, R1_REG);
6211 /* Since such a call function may use all call-clobbered
6212 registers, we force a mode switch earlier, so that we don't
6213 run out of registers when adjusting fpscr for the call. */
6214 emit_insn (gen_force_mode_for_call ());
6216 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6217 \"__GCC_shcompact_call_trampoline\");
6220 rtx reg = gen_reg_rtx (Pmode);
6222 emit_insn (gen_symGOT2reg (reg, operands[0]));
6225 operands[0] = force_reg (SImode, operands[0]);
6227 /* We don't need a return trampoline, since the callee will
6228 return directly to the upper caller. */
6229 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6231 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6232 cookie_rtx = GEN_INT (cookie);
6235 emit_move_insn (mach, func);
6236 emit_move_insn (r1, cookie_rtx);
6238 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6241 else if (TARGET_SHCOMPACT && flag_pic
6242 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6243 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6245 rtx reg = gen_reg_rtx (Pmode);
6247 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6248 XEXP (operands[0], 0) = reg;
6250 if (flag_pic && TARGET_SH2
6251 && GET_CODE (operands[0]) == MEM
6252 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6253 /* The PLT needs the PIC register, but the epilogue would have
6254 to restore it, so we can only use PC-relative PIC calls for
6255 static functions. */
6256 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6258 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6262 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6264 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6268 (define_expand "sibcall_value"
6269 [(set (match_operand 0 "" "")
6270 (call (match_operand 1 "" "")
6271 (match_operand 2 "" "")))
6272 (match_operand 3 "" "")]
6276 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6280 (define_insn "call_value_pop_compact"
6281 [(set (match_operand 0 "" "=rf")
6282 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6283 (match_operand 2 "" "")))
6284 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6285 (match_operand 4 "immediate_operand" "n")))
6286 (match_operand 3 "immediate_operand" "n")
6287 (use (reg:SI R0_REG))
6288 (use (reg:SI R1_REG))
6289 (use (reg:PSI FPSCR_REG))
6290 (clobber (reg:SI PR_REG))]
6291 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6293 [(set_attr "type" "call")
6294 (set (attr "fp_mode")
6295 (if_then_else (eq_attr "fpu_single" "yes")
6296 (const_string "single") (const_string "double")))
6297 (set_attr "needs_delay_slot" "yes")])
6299 (define_insn "call_value_pop_compact_rettramp"
6300 [(set (match_operand 0 "" "=rf")
6301 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6302 (match_operand 2 "" "")))
6303 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6304 (match_operand 4 "immediate_operand" "n")))
6305 (match_operand 3 "immediate_operand" "n")
6306 (use (reg:SI R0_REG))
6307 (use (reg:SI R1_REG))
6308 (use (reg:PSI FPSCR_REG))
6309 (clobber (reg:SI R10_REG))
6310 (clobber (reg:SI PR_REG))]
6311 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6313 [(set_attr "type" "call")
6314 (set (attr "fp_mode")
6315 (if_then_else (eq_attr "fpu_single" "yes")
6316 (const_string "single") (const_string "double")))
6317 (set_attr "needs_delay_slot" "yes")])
6319 (define_expand "call_value_pop"
6320 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6321 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6322 (match_operand 2 "" "")))
6323 (match_operand 3 "" "")
6324 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6325 (match_operand 4 "" "")))])]
6329 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6331 rtx cookie_rtx = operands[3];
6332 long cookie = INTVAL (cookie_rtx);
6333 rtx func = XEXP (operands[1], 0);
6338 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6340 rtx reg = gen_reg_rtx (Pmode);
6342 emit_insn (gen_symGOTPLT2reg (reg, func));
6346 func = legitimize_pic_address (func, Pmode, 0);
6349 r0 = gen_rtx_REG (SImode, R0_REG);
6350 r1 = gen_rtx_REG (SImode, R1_REG);
6352 /* Since such a call function may use all call-clobbered
6353 registers, we force a mode switch earlier, so that we don't
6354 run out of registers when adjusting fpscr for the call. */
6355 emit_insn (gen_force_mode_for_call ());
6357 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6358 \"__GCC_shcompact_call_trampoline\");
6361 rtx reg = gen_reg_rtx (Pmode);
6363 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6366 operands[1] = force_reg (SImode, operands[1]);
6368 emit_move_insn (r0, func);
6369 emit_move_insn (r1, cookie_rtx);
6371 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6372 emit_call_insn (gen_call_value_pop_compact_rettramp
6373 (operands[0], operands[1], operands[2],
6374 operands[3], operands[4]));
6376 emit_call_insn (gen_call_value_pop_compact
6377 (operands[0], operands[1], operands[2],
6378 operands[3], operands[4]));
6386 (define_expand "sibcall_epilogue"
6391 sh_expand_epilogue ();
6392 if (TARGET_SHCOMPACT)
6396 /* If epilogue clobbers r0, preserve it in macl. */
6397 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6398 if ((set = single_set (insn))
6399 && GET_CODE (SET_DEST (set)) == REG
6400 && REGNO (SET_DEST (set)) == R0_REG)
6402 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6403 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6406 /* We can't tell at this point whether the sibcall is a
6407 sibcall_compact and, if it is, whether it uses r0 or
6408 mach as operand 2, so let the instructions that
6409 preserve r0 be optimized away if r0 turns out to be
6411 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6412 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6414 i = emit_move_insn (r0, tmp);
6415 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6423 (define_insn "indirect_jump_compact"
6425 (match_operand:SI 0 "arith_reg_operand" "r"))]
6428 [(set_attr "needs_delay_slot" "yes")
6429 (set_attr "type" "jump_ind")])
6431 (define_expand "indirect_jump"
6433 (match_operand 0 "register_operand" ""))]
6437 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6438 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6441 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6442 ;; which can be present in structured code from indirect jumps which can not
6443 ;; be present in structured code. This allows -fprofile-arcs to work.
6445 ;; For SH1 processors.
6446 (define_insn "casesi_jump_1"
6448 (match_operand:SI 0 "register_operand" "r"))
6449 (use (label_ref (match_operand 1 "" "")))]
6452 [(set_attr "needs_delay_slot" "yes")
6453 (set_attr "type" "jump_ind")])
6455 ;; For all later processors.
6456 (define_insn "casesi_jump_2"
6457 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6458 (label_ref (match_operand 1 "" ""))))
6459 (use (label_ref (match_operand 2 "" "")))]
6461 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6463 [(set_attr "needs_delay_slot" "yes")
6464 (set_attr "type" "jump_ind")])
6466 (define_insn "casesi_jump_media"
6467 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6468 (use (label_ref (match_operand 1 "" "")))]
6471 [(set_attr "type" "jump_media")])
6473 ;; Call subroutine returning any type.
6474 ;; ??? This probably doesn't work.
6476 (define_expand "untyped_call"
6477 [(parallel [(call (match_operand 0 "" "")
6479 (match_operand 1 "" "")
6480 (match_operand 2 "" "")])]
6481 "TARGET_SH3E || TARGET_SHMEDIA"
6486 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6488 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6490 rtx set = XVECEXP (operands[2], 0, i);
6491 emit_move_insn (SET_DEST (set), SET_SRC (set));
6494 /* The optimizer does not know that the call sets the function value
6495 registers we stored in the result block. We avoid problems by
6496 claiming that all hard registers are used and clobbered at this
6498 emit_insn (gen_blockage ());
6503 ;; ------------------------------------------------------------------------
6505 ;; ------------------------------------------------------------------------
6508 [(set (reg:SI T_REG)
6509 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6510 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6513 [(set_attr "type" "arith")])
6520 ;; Load address of a label. This is only generated by the casesi expand,
6521 ;; and by machine_dependent_reorg (fixing up fp moves).
6522 ;; This must use unspec, because this only works for labels that are
6526 [(set (reg:SI R0_REG)
6527 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6530 [(set_attr "in_delay_slot" "no")
6531 (set_attr "type" "arith")])
6533 ;; machine_dependent_reorg() will make this a `mova'.
6534 (define_insn "mova_const"
6535 [(set (reg:SI R0_REG)
6536 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6539 [(set_attr "in_delay_slot" "no")
6540 (set_attr "type" "arith")])
6542 (define_expand "GOTaddr2picreg"
6543 [(set (reg:SI R0_REG)
6544 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6546 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6547 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6550 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6551 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6554 operands[1] = gen_datalabel_ref (operands[1]);
6558 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6559 rtx dipic = operands[0];
6560 rtx lab = PATTERN (gen_call_site ());
6563 equiv = operands[1];
6564 operands[1] = gen_rtx_MINUS (DImode,
6568 gen_rtx_MINUS (DImode,
6569 gen_rtx_CONST (DImode,
6572 operands[1] = gen_sym2PIC (operands[1]);
6573 PUT_MODE (operands[1], DImode);
6575 if (GET_MODE (dipic) != DImode)
6576 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6578 if (TARGET_SHMEDIA64)
6579 emit_insn (gen_movdi_const (dipic, operands[1]));
6581 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6583 emit_insn (gen_ptrel (tr, dipic, lab));
6585 if (GET_MODE (operands[0]) != GET_MODE (tr))
6586 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6588 insn = emit_move_insn (operands[0], tr);
6590 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6598 ;; When generating PIC, we must match label_refs especially, because
6599 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6600 ;; them to do, because they can't be loaded directly into
6601 ;; non-branch-target registers.
6603 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6604 (match_operand:DI 1 "" "T"))]
6605 "TARGET_SHMEDIA && flag_pic
6606 && EXTRA_CONSTRAINT_T (operands[1])"
6608 [(set_attr "type" "pt_media")
6609 (set_attr "length" "*")])
6612 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6613 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6614 UNSPEC_DATALABEL)))]
6615 "TARGET_SHMEDIA && flag_pic
6616 && EXTRA_CONSTRAINT_T (operands[1])"
6617 "ptb/u datalabel %1, %0"
6618 [(set_attr "type" "pt_media")
6619 (set_attr "length" "*")])
6621 (define_insn "ptrel"
6622 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6623 (plus:DI (match_operand:DI 1 "register_operand" "r")
6625 (match_operand:DI 2 "" "")]
6627 "%O2: ptrel/u %1, %0"
6628 [(set_attr "type" "ptabs_media")])
6630 (define_expand "builtin_setjmp_receiver"
6631 [(match_operand 0 "" "")]
6635 emit_insn (gen_GOTaddr2picreg ());
6639 (define_expand "call_site"
6640 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6644 static HOST_WIDE_INT i = 0;
6645 operands[0] = GEN_INT (i);
6649 (define_expand "sym_label2reg"
6650 [(set (match_operand:SI 0 "" "")
6653 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6656 (match_operand:SI 2 "" "")
6660 (define_expand "symGOT_load"
6661 [(set (match_dup 2) (match_operand 1 "" ""))
6662 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6663 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6669 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6670 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6674 rtx reg = operands[2];
6676 if (GET_MODE (reg) != DImode)
6677 reg = gen_rtx_SUBREG (DImode, reg, 0);
6680 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6682 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6685 emit_move_insn (operands[2], operands[1]);
6687 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6689 gen_rtx_REG (Pmode, PIC_REG)));
6691 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6693 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6700 (define_expand "sym2GOT"
6701 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6705 (define_expand "symGOT2reg"
6706 [(match_operand 0 "" "") (match_operand 1 "" "")]
6712 gotsym = gen_sym2GOT (operands[1]);
6713 PUT_MODE (gotsym, Pmode);
6714 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6716 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6721 (define_expand "sym2GOTPLT"
6722 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6726 (define_expand "symGOTPLT2reg"
6727 [(match_operand 0 "" "") (match_operand 1 "" "")]
6731 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6735 (define_expand "sym2GOTOFF"
6736 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6740 (define_expand "symGOTOFF2reg"
6741 [(match_operand 0 "" "") (match_operand 1 "" "")]
6745 rtx gotoffsym, insn;
6746 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6748 gotoffsym = gen_sym2GOTOFF (operands[1]);
6749 PUT_MODE (gotoffsym, Pmode);
6750 emit_move_insn (t, gotoffsym);
6751 insn = emit_move_insn (operands[0],
6752 gen_rtx_PLUS (Pmode, t,
6753 gen_rtx_REG (Pmode, PIC_REG)));
6755 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6761 (define_expand "symPLT_label2reg"
6762 [(set (match_operand:SI 0 "" "")
6765 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6769 (match_operand:SI 2 "" "")
6771 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6772 ;; Even though the PIC register is not really used by the call
6773 ;; sequence in which this is expanded, the PLT code assumes the PIC
6774 ;; register is set, so we must not skip its initialization. Since
6775 ;; we only use this expand as part of calling sequences, and never
6776 ;; to take the address of a function, this is the best point to
6777 ;; insert the (use). Using the PLT to take the address of a
6778 ;; function would be wrong, not only because the PLT entry could
6779 ;; then be called from a function that doesn't initialize the PIC
6780 ;; register to the proper GOT, but also because pointers to the
6781 ;; same function might not compare equal, should they be set by
6782 ;; different shared libraries.
6783 (use (reg:SI PIC_REG))]
6787 (define_expand "sym2PIC"
6788 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6792 ;; case instruction for switch statements.
6794 ;; Operand 0 is index
6795 ;; operand 1 is the minimum bound
6796 ;; operand 2 is the maximum bound - minimum bound + 1
6797 ;; operand 3 is CODE_LABEL for the table;
6798 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6800 (define_expand "casesi"
6801 [(match_operand:SI 0 "arith_reg_operand" "")
6802 (match_operand:SI 1 "arith_reg_operand" "")
6803 (match_operand:SI 2 "arith_reg_operand" "")
6804 (match_operand 3 "" "") (match_operand 4 "" "")]
6808 rtx reg = gen_reg_rtx (SImode);
6809 rtx reg2 = gen_reg_rtx (SImode);
6812 rtx reg = gen_reg_rtx (DImode);
6813 rtx reg2 = gen_reg_rtx (DImode);
6814 rtx reg3 = gen_reg_rtx (DImode);
6815 rtx reg4 = gen_reg_rtx (DImode);
6816 rtx reg5 = gen_reg_rtx (DImode);
6818 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6819 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6820 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6822 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6823 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6824 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6825 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6826 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6827 (DImode, operands[3])));
6828 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6829 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6830 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6834 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6835 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6836 /* If optimizing, casesi_worker depends on the mode of the instruction
6837 before label it 'uses' - operands[3]. */
6838 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6840 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6842 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6844 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6845 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6846 operands[3], but to lab. We will fix this up in
6847 machine_dependent_reorg. */
6852 (define_expand "casesi_0"
6853 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6854 (set (match_dup 4) (minus:SI (match_dup 4)
6855 (match_operand:SI 1 "arith_operand" "")))
6857 (gtu:SI (match_dup 4)
6858 (match_operand:SI 2 "arith_reg_operand" "")))
6860 (if_then_else (ne (reg:SI T_REG)
6862 (label_ref (match_operand 3 "" ""))
6867 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6868 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6869 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6871 (define_insn "casesi_worker_0"
6872 [(set (match_operand:SI 0 "register_operand" "=r,r")
6873 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6874 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6875 (clobber (match_scratch:SI 3 "=X,1"))
6876 (clobber (match_scratch:SI 4 "=&z,z"))]
6881 [(set (match_operand:SI 0 "register_operand" "")
6882 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6883 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6884 (clobber (match_scratch:SI 3 ""))
6885 (clobber (match_scratch:SI 4 ""))]
6886 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6887 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6888 (parallel [(set (match_dup 0)
6889 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6890 (label_ref (match_dup 2))] UNSPEC_CASESI))
6891 (clobber (match_dup 3))])
6892 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6893 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6896 [(set (match_operand:SI 0 "register_operand" "")
6897 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6898 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6899 (clobber (match_scratch:SI 3 ""))
6900 (clobber (match_scratch:SI 4 ""))]
6901 "TARGET_SH2 && reload_completed"
6902 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6903 (parallel [(set (match_dup 0)
6904 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6905 (label_ref (match_dup 2))] UNSPEC_CASESI))
6906 (clobber (match_dup 3))])]
6907 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6909 (define_insn "*casesi_worker"
6910 [(set (match_operand:SI 0 "register_operand" "=r,r")
6911 (unspec:SI [(reg:SI R0_REG)
6912 (match_operand:SI 1 "register_operand" "0,r")
6913 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6914 (clobber (match_scratch:SI 3 "=X,1"))]
6918 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6920 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6923 switch (GET_MODE (diff_vec))
6926 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6928 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6930 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6931 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6932 return \"mov.b @(r0,%1),%0\";
6937 [(set_attr "length" "4")])
6939 (define_insn "casesi_shift_media"
6940 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6941 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6942 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6947 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6949 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6952 switch (GET_MODE (diff_vec))
6955 return \"shlli %1, 2, %0\";
6957 return \"shlli %1, 1, %0\";
6959 if (rtx_equal_p (operands[0], operands[1]))
6961 return \"add %1, r63, %0\";
6966 [(set_attr "type" "arith_media")])
6968 (define_insn "casesi_load_media"
6969 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6970 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6971 (match_operand 2 "arith_reg_operand" "r")
6972 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6976 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6978 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6981 switch (GET_MODE (diff_vec))
6984 return \"ldx.l %1, %2, %0\";
6987 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6988 return \"ldx.uw %1, %2, %0\";
6990 return \"ldx.w %1, %2, %0\";
6992 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6993 return \"ldx.ub %1, %2, %0\";
6994 return \"ldx.b %1, %2, %0\";
6999 [(set_attr "type" "load_media")])
7001 (define_expand "return"
7003 "reload_completed && ! sh_need_epilogue ()"
7008 emit_jump_insn (gen_return_media ());
7012 if (TARGET_SHCOMPACT
7013 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7015 emit_jump_insn (gen_shcompact_return_tramp ());
7020 (define_insn "*return_i"
7022 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7023 && (current_function_args_info.call_cookie
7024 & CALL_COOKIE_RET_TRAMP (1)))
7025 && reload_completed"
7027 [(set_attr "type" "return")
7028 (set_attr "needs_delay_slot" "yes")])
7030 (define_expand "shcompact_return_tramp"
7033 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7036 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7037 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7038 \"__GCC_shcompact_return_trampoline\");
7041 emit_insn (gen_symGOTPLT2reg (reg, sym));
7043 emit_move_insn (reg, sym);
7045 emit_jump_insn (gen_shcompact_return_tramp_i ());
7049 (define_insn "shcompact_return_tramp_i"
7050 [(parallel [(return) (use (reg:SI R0_REG))])]
7052 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7054 [(set_attr "type" "jump_ind")
7055 (set_attr "needs_delay_slot" "yes")])
7057 (define_insn "return_media_i"
7058 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7059 "TARGET_SHMEDIA && reload_completed"
7061 [(set_attr "type" "jump_media")])
7063 (define_expand "return_media"
7065 "TARGET_SHMEDIA && reload_completed"
7068 int tr_regno = sh_media_register_for_return ();
7073 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7076 tr = gen_rtx_REG (DImode, tr_regno);
7077 emit_move_insn (tr, r18);
7080 tr = gen_rtx_REG (DImode, tr_regno);
7082 emit_jump_insn (gen_return_media_i (tr));
7086 (define_insn "shcompact_preserve_incoming_args"
7087 [(set (match_operand:SI 0 "register_operand" "+r")
7088 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7091 [(set_attr "length" "0")])
7093 (define_insn "shcompact_incoming_args"
7094 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7095 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7096 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7097 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7098 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7099 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7100 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7101 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7102 (set (mem:BLK (reg:SI MACL_REG))
7103 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7104 (use (reg:SI R0_REG))
7105 (clobber (reg:SI R0_REG))
7106 (clobber (reg:SI MACL_REG))
7107 (clobber (reg:SI MACH_REG))
7108 (clobber (reg:SI PR_REG))]
7111 [(set_attr "needs_delay_slot" "yes")])
7113 (define_insn "shmedia_save_restore_regs_compact"
7114 [(set (reg:SI SP_REG)
7115 (plus:SI (reg:SI SP_REG)
7116 (match_operand:SI 0 "immediate_operand" "i")))
7117 (use (reg:SI R0_REG))
7118 (clobber (reg:SI PR_REG))]
7120 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7121 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7123 [(set_attr "needs_delay_slot" "yes")])
7125 (define_expand "prologue"
7128 "sh_expand_prologue (); DONE;")
7130 (define_expand "epilogue"
7135 sh_expand_epilogue ();
7136 emit_jump_insn (gen_return ());
7140 (define_insn "blockage"
7141 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7144 [(set_attr "length" "0")])
7146 ;; ------------------------------------------------------------------------
7148 ;; ------------------------------------------------------------------------
7151 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7152 (eq:SI (reg:SI T_REG) (const_int 1)))]
7155 [(set_attr "type" "arith")])
7157 (define_expand "seq"
7158 [(set (match_operand:SI 0 "arith_reg_operand" "")
7165 if (GET_MODE (operands[0]) != DImode)
7166 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7167 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7168 if (sh_compare_op1 != const0_rtx)
7169 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7170 ? GET_MODE (sh_compare_op0)
7171 : GET_MODE (sh_compare_op1),
7174 switch (GET_MODE (sh_compare_op0))
7177 emit_insn (gen_cmpeqdi_media (operands[0],
7178 sh_compare_op0, sh_compare_op1));
7182 if (! TARGET_SHMEDIA_FPU)
7184 emit_insn (gen_cmpeqsf_media (operands[0],
7185 sh_compare_op0, sh_compare_op1));
7189 if (! TARGET_SHMEDIA_FPU)
7191 emit_insn (gen_cmpeqdf_media (operands[0],
7192 sh_compare_op0, sh_compare_op1));
7200 operands[1] = prepare_scc_operands (EQ);
7203 (define_expand "slt"
7204 [(set (match_operand:SI 0 "arith_reg_operand" "")
7211 if (GET_MODE (operands[0]) != DImode)
7212 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7213 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7214 if (sh_compare_op1 != const0_rtx)
7215 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7216 ? GET_MODE (sh_compare_op0)
7217 : GET_MODE (sh_compare_op1),
7220 switch (GET_MODE (sh_compare_op0))
7223 emit_insn (gen_cmpgtdi_media (operands[0],
7224 sh_compare_op1, sh_compare_op0));
7228 if (! TARGET_SHMEDIA_FPU)
7230 emit_insn (gen_cmpgtsf_media (operands[0],
7231 sh_compare_op1, sh_compare_op0));
7235 if (! TARGET_SHMEDIA_FPU)
7237 emit_insn (gen_cmpgtdf_media (operands[0],
7238 sh_compare_op1, sh_compare_op0));
7246 operands[1] = prepare_scc_operands (LT);
7249 (define_expand "sle"
7250 [(match_operand:SI 0 "arith_reg_operand" "")]
7254 rtx tmp = sh_compare_op0;
7258 if (GET_MODE (operands[0]) != DImode)
7259 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7260 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7261 if (sh_compare_op1 != const0_rtx)
7262 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7263 ? GET_MODE (sh_compare_op0)
7264 : GET_MODE (sh_compare_op1),
7267 switch (GET_MODE (sh_compare_op0))
7271 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7273 emit_insn (gen_cmpgtdi_media (tmp,
7274 sh_compare_op0, sh_compare_op1));
7275 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7280 if (! TARGET_SHMEDIA_FPU)
7282 emit_insn (gen_cmpgesf_media (operands[0],
7283 sh_compare_op1, sh_compare_op0));
7287 if (! TARGET_SHMEDIA_FPU)
7289 emit_insn (gen_cmpgedf_media (operands[0],
7290 sh_compare_op1, sh_compare_op0));
7299 sh_compare_op0 = sh_compare_op1;
7300 sh_compare_op1 = tmp;
7301 emit_insn (gen_sge (operands[0]));
7305 (define_expand "sgt"
7306 [(set (match_operand:SI 0 "arith_reg_operand" "")
7313 if (GET_MODE (operands[0]) != DImode)
7314 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7315 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7316 if (sh_compare_op1 != const0_rtx)
7317 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7318 ? GET_MODE (sh_compare_op0)
7319 : GET_MODE (sh_compare_op1),
7322 switch (GET_MODE (sh_compare_op0))
7325 emit_insn (gen_cmpgtdi_media (operands[0],
7326 sh_compare_op0, sh_compare_op1));
7330 if (! TARGET_SHMEDIA_FPU)
7332 emit_insn (gen_cmpgtsf_media (operands[0],
7333 sh_compare_op0, sh_compare_op1));
7337 if (! TARGET_SHMEDIA_FPU)
7339 emit_insn (gen_cmpgtdf_media (operands[0],
7340 sh_compare_op0, sh_compare_op1));
7348 operands[1] = prepare_scc_operands (GT);
7351 (define_expand "sge"
7352 [(set (match_operand:SI 0 "arith_reg_operand" "")
7359 if (GET_MODE (operands[0]) != DImode)
7360 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7361 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7362 if (sh_compare_op1 != const0_rtx)
7363 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7364 ? GET_MODE (sh_compare_op0)
7365 : GET_MODE (sh_compare_op1),
7368 switch (GET_MODE (sh_compare_op0))
7372 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7374 emit_insn (gen_cmpgtdi_media (tmp,
7375 sh_compare_op1, sh_compare_op0));
7376 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7381 if (! TARGET_SHMEDIA_FPU)
7383 emit_insn (gen_cmpgesf_media (operands[0],
7384 sh_compare_op0, sh_compare_op1));
7388 if (! TARGET_SHMEDIA_FPU)
7390 emit_insn (gen_cmpgedf_media (operands[0],
7391 sh_compare_op0, sh_compare_op1));
7400 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7404 rtx lab = gen_label_rtx ();
7405 prepare_scc_operands (EQ);
7406 emit_jump_insn (gen_branch_true (lab));
7407 prepare_scc_operands (GT);
7409 emit_insn (gen_movt (operands[0]));
7412 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7415 operands[1] = prepare_scc_operands (GE);
7418 (define_expand "sgtu"
7419 [(set (match_operand:SI 0 "arith_reg_operand" "")
7426 if (GET_MODE (operands[0]) != DImode)
7427 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7428 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7429 if (sh_compare_op1 != const0_rtx)
7430 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7431 ? GET_MODE (sh_compare_op0)
7432 : GET_MODE (sh_compare_op1),
7435 emit_insn (gen_cmpgtudi_media (operands[0],
7436 sh_compare_op0, sh_compare_op1));
7439 operands[1] = prepare_scc_operands (GTU);
7442 (define_expand "sltu"
7443 [(set (match_operand:SI 0 "arith_reg_operand" "")
7450 if (GET_MODE (operands[0]) != DImode)
7451 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7452 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7453 if (sh_compare_op1 != const0_rtx)
7454 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7455 ? GET_MODE (sh_compare_op0)
7456 : GET_MODE (sh_compare_op1),
7459 emit_insn (gen_cmpgtudi_media (operands[0],
7460 sh_compare_op1, sh_compare_op0));
7463 operands[1] = prepare_scc_operands (LTU);
7466 (define_expand "sleu"
7467 [(set (match_operand:SI 0 "arith_reg_operand" "")
7476 if (GET_MODE (operands[0]) != DImode)
7477 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7478 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7479 if (sh_compare_op1 != const0_rtx)
7480 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7481 ? GET_MODE (sh_compare_op0)
7482 : GET_MODE (sh_compare_op1),
7485 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7487 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7488 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7492 operands[1] = prepare_scc_operands (LEU);
7495 (define_expand "sgeu"
7496 [(set (match_operand:SI 0 "arith_reg_operand" "")
7505 if (GET_MODE (operands[0]) != DImode)
7506 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7507 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7508 if (sh_compare_op1 != const0_rtx)
7509 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7510 ? GET_MODE (sh_compare_op0)
7511 : GET_MODE (sh_compare_op1),
7514 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7516 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7517 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7522 operands[1] = prepare_scc_operands (GEU);
7525 ;; sne moves the complement of the T reg to DEST like this:
7529 ;; This is better than xoring compare result with 1 because it does
7530 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7533 (define_expand "sne"
7534 [(set (match_dup 2) (const_int -1))
7535 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7536 (neg:SI (plus:SI (match_dup 1)
7539 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7548 if (GET_MODE (operands[0]) != DImode)
7549 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7551 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7554 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7555 if (sh_compare_op1 != const0_rtx)
7556 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7557 ? GET_MODE (sh_compare_op0)
7558 : GET_MODE (sh_compare_op1),
7561 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7563 emit_insn (gen_seq (tmp));
7564 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7569 operands[1] = prepare_scc_operands (EQ);
7570 operands[2] = gen_reg_rtx (SImode);
7573 (define_expand "sunordered"
7574 [(set (match_operand:DI 0 "arith_reg_operand" "")
7575 (unordered:DI (match_dup 1) (match_dup 2)))]
7576 "TARGET_SHMEDIA_FPU"
7579 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7580 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7583 ;; Use the same trick for FP sle / sge
7584 (define_expand "movnegt"
7585 [(set (match_dup 2) (const_int -1))
7586 (parallel [(set (match_operand 0 "" "")
7587 (neg:SI (plus:SI (match_dup 1)
7590 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7593 "operands[2] = gen_reg_rtx (SImode);")
7595 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7596 ;; This prevents a regression that occurred when we switched from xor to
7600 [(set (match_operand:SI 0 "arith_reg_operand" "")
7601 (plus:SI (reg:SI T_REG)
7604 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7605 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7608 ;; -------------------------------------------------------------------------
7609 ;; Instructions to cope with inline literal tables
7610 ;; -------------------------------------------------------------------------
7612 ; 2 byte integer in line
7614 (define_insn "consttable_2"
7615 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7616 (match_operand 1 "" "")]
7621 if (operands[1] != const0_rtx)
7622 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7625 [(set_attr "length" "2")
7626 (set_attr "in_delay_slot" "no")])
7628 ; 4 byte integer in line
7630 (define_insn "consttable_4"
7631 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7632 (match_operand 1 "" "")]
7637 if (operands[1] != const0_rtx)
7638 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7641 [(set_attr "length" "4")
7642 (set_attr "in_delay_slot" "no")])
7644 ; 8 byte integer in line
7646 (define_insn "consttable_8"
7647 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7648 (match_operand 1 "" "")]
7653 if (operands[1] != const0_rtx)
7654 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7657 [(set_attr "length" "8")
7658 (set_attr "in_delay_slot" "no")])
7660 ; 4 byte floating point
7662 (define_insn "consttable_sf"
7663 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7664 (match_operand 1 "" "")]
7669 if (operands[1] != const0_rtx)
7672 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7673 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7677 [(set_attr "length" "4")
7678 (set_attr "in_delay_slot" "no")])
7680 ; 8 byte floating point
7682 (define_insn "consttable_df"
7683 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7684 (match_operand 1 "" "")]
7689 if (operands[1] != const0_rtx)
7692 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7693 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7697 [(set_attr "length" "8")
7698 (set_attr "in_delay_slot" "no")])
7700 ;; Alignment is needed for some constant tables; it may also be added for
7701 ;; Instructions at the start of loops, or after unconditional branches.
7702 ;; ??? We would get more accurate lengths if we did instruction
7703 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7704 ;; here is too conservative.
7706 ; align to a two byte boundary
7708 (define_expand "align_2"
7709 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7713 ; align to a four byte boundary
7714 ;; align_4 and align_log are instructions for the starts of loops, or
7715 ;; after unconditional branches, which may take up extra room.
7717 (define_expand "align_4"
7718 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7722 ; align to a cache line boundary
7724 (define_insn "align_log"
7725 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7728 [(set_attr "length" "0")
7729 (set_attr "in_delay_slot" "no")])
7731 ; emitted at the end of the literal table, used to emit the
7732 ; 32bit branch labels if needed.
7734 (define_insn "consttable_end"
7735 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7737 "* return output_jump_label_table ();"
7738 [(set_attr "in_delay_slot" "no")])
7740 ; emitted at the end of the window in the literal table.
7742 (define_insn "consttable_window_end"
7743 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7746 [(set_attr "length" "0")
7747 (set_attr "in_delay_slot" "no")])
7749 ;; -------------------------------------------------------------------------
7751 ;; -------------------------------------------------------------------------
7753 ;; String/block move insn.
7755 (define_expand "movstrsi"
7756 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7757 (mem:BLK (match_operand:BLK 1 "" "")))
7758 (use (match_operand:SI 2 "nonmemory_operand" ""))
7759 (use (match_operand:SI 3 "immediate_operand" ""))
7760 (clobber (reg:SI PR_REG))
7761 (clobber (reg:SI R4_REG))
7762 (clobber (reg:SI R5_REG))
7763 (clobber (reg:SI R0_REG))])]
7764 "TARGET_SH1 && ! TARGET_SH5"
7767 if(expand_block_move (operands))
7772 (define_insn "block_move_real"
7773 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7774 (mem:BLK (reg:SI R5_REG)))
7775 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7776 (clobber (reg:SI PR_REG))
7777 (clobber (reg:SI R0_REG))])]
7778 "TARGET_SH1 && ! TARGET_HARD_SH4"
7780 [(set_attr "type" "sfunc")
7781 (set_attr "needs_delay_slot" "yes")])
7783 (define_insn "block_lump_real"
7784 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7785 (mem:BLK (reg:SI R5_REG)))
7786 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7787 (use (reg:SI R6_REG))
7788 (clobber (reg:SI PR_REG))
7789 (clobber (reg:SI T_REG))
7790 (clobber (reg:SI R4_REG))
7791 (clobber (reg:SI R5_REG))
7792 (clobber (reg:SI R6_REG))
7793 (clobber (reg:SI R0_REG))])]
7794 "TARGET_SH1 && ! TARGET_HARD_SH4"
7796 [(set_attr "type" "sfunc")
7797 (set_attr "needs_delay_slot" "yes")])
7799 (define_insn "block_move_real_i4"
7800 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7801 (mem:BLK (reg:SI R5_REG)))
7802 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7803 (clobber (reg:SI PR_REG))
7804 (clobber (reg:SI R0_REG))
7805 (clobber (reg:SI R1_REG))
7806 (clobber (reg:SI R2_REG))])]
7809 [(set_attr "type" "sfunc")
7810 (set_attr "needs_delay_slot" "yes")])
7812 (define_insn "block_lump_real_i4"
7813 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7814 (mem:BLK (reg:SI R5_REG)))
7815 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7816 (use (reg:SI R6_REG))
7817 (clobber (reg:SI PR_REG))
7818 (clobber (reg:SI T_REG))
7819 (clobber (reg:SI R4_REG))
7820 (clobber (reg:SI R5_REG))
7821 (clobber (reg:SI R6_REG))
7822 (clobber (reg:SI R0_REG))
7823 (clobber (reg:SI R1_REG))
7824 (clobber (reg:SI R2_REG))
7825 (clobber (reg:SI R3_REG))])]
7828 [(set_attr "type" "sfunc")
7829 (set_attr "needs_delay_slot" "yes")])
7831 ;; -------------------------------------------------------------------------
7832 ;; Floating point instructions.
7833 ;; -------------------------------------------------------------------------
7835 ;; ??? All patterns should have a type attribute.
7837 (define_expand "fpu_switch0"
7838 [(set (match_operand:SI 0 "" "") (match_dup 2))
7839 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7843 operands[1] = get_fpscr_rtx ();
7844 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7846 operands[2] = legitimize_pic_address (operands[2], SImode,
7847 no_new_pseudos ? operands[0] : 0);
7850 (define_expand "fpu_switch1"
7851 [(set (match_operand:SI 0 "" "") (match_dup 2))
7852 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7853 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7857 operands[1] = get_fpscr_rtx ();
7858 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7860 operands[2] = legitimize_pic_address (operands[2], SImode,
7861 no_new_pseudos ? operands[0] : 0);
7862 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7865 (define_expand "movpsi"
7866 [(set (match_operand:PSI 0 "register_operand" "")
7867 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7871 ;; The c / m alternative is a fake to guide reload to load directly into
7872 ;; fpscr, since reload doesn't know how to use post-increment.
7873 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7874 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7875 ;; predicate after reload.
7876 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7877 ;; like a mac -> gpr move.
7878 (define_insn "fpu_switch"
7879 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7880 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7882 && (! reload_completed
7883 || true_regnum (operands[0]) != FPSCR_REG
7884 || GET_CODE (operands[1]) != MEM
7885 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7887 ! precision stays the same
7895 [(set_attr "length" "0,2,2,4,2,2,2,2")
7896 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
7899 [(set (reg:PSI FPSCR_REG)
7900 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7901 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7902 [(set (match_dup 0) (match_dup 0))]
7905 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7906 gen_rtx (MEM, PSImode,
7907 gen_rtx (POST_INC, Pmode,
7909 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7913 [(set (reg:PSI FPSCR_REG)
7914 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7916 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7919 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7920 gen_rtx (MEM, PSImode,
7921 gen_rtx (POST_INC, Pmode,
7923 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7926 ;; ??? This uses the fp unit, but has no type indicating that.
7927 ;; If we did that, this would either give a bogus latency or introduce
7928 ;; a bogus FIFO constraint.
7929 ;; Since this insn is currently only used for prologues/epilogues,
7930 ;; it is probably best to claim no function unit, which matches the
7932 (define_insn "toggle_sz"
7933 [(set (reg:PSI FPSCR_REG)
7934 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7938 (define_expand "addsf3"
7939 [(set (match_operand:SF 0 "arith_reg_operand" "")
7940 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7941 (match_operand:SF 2 "arith_reg_operand" "")))]
7942 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7947 expand_sf_binop (&gen_addsf3_i, operands);
7952 (define_insn "*addsf3_media"
7953 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7954 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7955 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7956 "TARGET_SHMEDIA_FPU"
7958 [(set_attr "type" "fparith_media")])
7960 (define_insn_and_split "unary_sf_op"
7961 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7966 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7967 (match_operator:SF 2 "unary_float_operator"
7968 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7969 (parallel [(match_operand 4
7970 "const_int_operand" "n")]))]))
7971 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7972 "TARGET_SHMEDIA_FPU"
7974 "TARGET_SHMEDIA_FPU && reload_completed"
7975 [(set (match_dup 5) (match_dup 6))]
7978 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7979 rtx op1 = gen_rtx_REG (SFmode,
7980 (true_regnum (operands[1])
7981 + (INTVAL (operands[4]) ^ endian)));
7983 operands[7] = gen_rtx_REG (SFmode,
7984 (true_regnum (operands[0])
7985 + (INTVAL (operands[3]) ^ endian)));
7986 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7988 [(set_attr "type" "fparith_media")])
7990 (define_insn_and_split "binary_sf_op"
7991 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7996 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
7997 (match_operator:SF 3 "binary_float_operator"
7998 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7999 (parallel [(match_operand 5
8000 "const_int_operand" "n")]))
8001 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8002 (parallel [(match_operand 6
8003 "const_int_operand" "n")]))]))
8004 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8005 "TARGET_SHMEDIA_FPU"
8007 "TARGET_SHMEDIA_FPU && reload_completed"
8008 [(set (match_dup 7) (match_dup 8))]
8011 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8012 rtx op1 = gen_rtx_REG (SFmode,
8013 (true_regnum (operands[1])
8014 + (INTVAL (operands[5]) ^ endian)));
8015 rtx op2 = gen_rtx_REG (SFmode,
8016 (true_regnum (operands[2])
8017 + (INTVAL (operands[6]) ^ endian)));
8019 operands[7] = gen_rtx_REG (SFmode,
8020 (true_regnum (operands[0])
8021 + (INTVAL (operands[4]) ^ endian)));
8022 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8024 [(set_attr "type" "fparith_media")])
8026 (define_insn "addsf3_i"
8027 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8028 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8029 (match_operand:SF 2 "arith_reg_operand" "f")))
8030 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8033 [(set_attr "type" "fp")
8034 (set_attr "fp_mode" "single")])
8036 (define_expand "subsf3"
8037 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8038 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8039 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8040 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8045 expand_sf_binop (&gen_subsf3_i, operands);
8050 (define_insn "*subsf3_media"
8051 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8052 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8053 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8054 "TARGET_SHMEDIA_FPU"
8056 [(set_attr "type" "fparith_media")])
8058 (define_insn "subsf3_i"
8059 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8060 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8061 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8062 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8065 [(set_attr "type" "fp")
8066 (set_attr "fp_mode" "single")])
8068 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8069 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8070 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8071 ;; SH3E, we use a separate insn for SH3E mulsf3.
8073 (define_expand "mulsf3"
8074 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8075 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8076 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8077 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8081 expand_sf_binop (&gen_mulsf3_i4, operands);
8082 else if (TARGET_SH3E)
8083 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8084 if (! TARGET_SHMEDIA)
8088 (define_insn "*mulsf3_media"
8089 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8090 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8091 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8092 "TARGET_SHMEDIA_FPU"
8094 [(set_attr "type" "fparith_media")])
8096 (define_insn "mulsf3_i4"
8097 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8098 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8099 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8100 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8103 [(set_attr "type" "fp")
8104 (set_attr "fp_mode" "single")])
8106 (define_insn "mulsf3_ie"
8107 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8108 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8109 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8110 "TARGET_SH3E && ! TARGET_SH4"
8112 [(set_attr "type" "fp")])
8114 (define_insn "*mac_media"
8115 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8116 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8117 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8118 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8119 "TARGET_SHMEDIA_FPU"
8121 [(set_attr "type" "fparith_media")])
8123 (define_insn "*macsf3"
8124 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8125 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8126 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8127 (match_operand:SF 3 "arith_reg_operand" "0")))
8128 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8129 "TARGET_SH3E && ! TARGET_SH4"
8131 [(set_attr "type" "fp")
8132 (set_attr "fp_mode" "single")])
8134 (define_expand "divsf3"
8135 [(set (match_operand:SF 0 "arith_reg_operand" "")
8136 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8137 (match_operand:SF 2 "arith_reg_operand" "")))]
8138 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8143 expand_sf_binop (&gen_divsf3_i, operands);
8148 (define_insn "*divsf3_media"
8149 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8150 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8151 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8152 "TARGET_SHMEDIA_FPU"
8154 [(set_attr "type" "fdiv_media")])
8156 (define_insn "divsf3_i"
8157 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8158 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8159 (match_operand:SF 2 "arith_reg_operand" "f")))
8160 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8163 [(set_attr "type" "fdiv")
8164 (set_attr "fp_mode" "single")])
8166 (define_insn "floatdisf2"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8169 "TARGET_SHMEDIA_FPU"
8171 [(set_attr "type" "fpconv_media")])
8173 (define_expand "floatsisf2"
8174 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8175 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8176 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8181 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8186 (define_insn "*floatsisf2_media"
8187 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8188 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8189 "TARGET_SHMEDIA_FPU"
8191 [(set_attr "type" "fpconv_media")])
8193 (define_insn "floatsisf2_i4"
8194 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8195 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8196 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8199 [(set_attr "type" "fp")
8200 (set_attr "fp_mode" "single")])
8202 (define_insn "*floatsisf2_ie"
8203 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8204 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8205 "TARGET_SH3E && ! TARGET_SH4"
8207 [(set_attr "type" "fp")])
8209 (define_insn "fix_truncsfdi2"
8210 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8211 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8212 "TARGET_SHMEDIA_FPU"
8214 [(set_attr "type" "fpconv_media")])
8216 (define_expand "fix_truncsfsi2"
8217 [(set (match_operand:SI 0 "fpul_operand" "=y")
8218 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8219 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8224 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8229 (define_insn "*fix_truncsfsi2_media"
8230 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8231 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8232 "TARGET_SHMEDIA_FPU"
8234 [(set_attr "type" "fpconv_media")])
8236 (define_insn "fix_truncsfsi2_i4"
8237 [(set (match_operand:SI 0 "fpul_operand" "=y")
8238 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8239 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8242 [(set_attr "type" "ftrc_s")
8243 (set_attr "fp_mode" "single")])
8245 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8246 ;; fix_truncsfsi2_i4.
8247 ;; (define_insn "fix_truncsfsi2_i4_2"
8248 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8249 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8250 ;; (use (reg:PSI FPSCR_REG))
8251 ;; (clobber (reg:SI FPUL_REG))]
8254 ;; [(set_attr "length" "4")
8255 ;; (set_attr "fp_mode" "single")])
8258 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8259 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8260 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8261 ;; (clobber (reg:SI FPUL_REG))]
8263 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8264 ;; (use (match_dup 2))])
8265 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8267 (define_insn "*fixsfsi"
8268 [(set (match_operand:SI 0 "fpul_operand" "=y")
8269 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8270 "TARGET_SH3E && ! TARGET_SH4"
8272 [(set_attr "type" "fp")])
8274 (define_insn "cmpgtsf_t"
8275 [(set (reg:SI T_REG)
8276 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8277 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8278 "TARGET_SH3E && ! TARGET_SH4"
8280 [(set_attr "type" "fp")
8281 (set_attr "fp_mode" "single")])
8283 (define_insn "cmpeqsf_t"
8284 [(set (reg:SI T_REG)
8285 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8286 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8287 "TARGET_SH3E && ! TARGET_SH4"
8289 [(set_attr "type" "fp")
8290 (set_attr "fp_mode" "single")])
8292 (define_insn "ieee_ccmpeqsf_t"
8293 [(set (reg:SI T_REG)
8294 (ior:SI (reg:SI T_REG)
8295 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8296 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8297 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8298 "* return output_ieee_ccmpeq (insn, operands);"
8299 [(set_attr "length" "4")])
8302 (define_insn "cmpgtsf_t_i4"
8303 [(set (reg:SI T_REG)
8304 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8305 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8306 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8309 [(set_attr "type" "fp")
8310 (set_attr "fp_mode" "single")])
8312 (define_insn "cmpeqsf_t_i4"
8313 [(set (reg:SI T_REG)
8314 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8315 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8316 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8319 [(set_attr "type" "fp")
8320 (set_attr "fp_mode" "single")])
8322 (define_insn "*ieee_ccmpeqsf_t_4"
8323 [(set (reg:SI T_REG)
8324 (ior:SI (reg:SI T_REG)
8325 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8326 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8327 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8328 "TARGET_IEEE && TARGET_SH4"
8329 "* return output_ieee_ccmpeq (insn, operands);"
8330 [(set_attr "length" "4")
8331 (set_attr "fp_mode" "single")])
8333 (define_insn "cmpeqsf_media"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8335 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8336 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8337 "TARGET_SHMEDIA_FPU"
8338 "fcmpeq.s %1, %2, %0"
8339 [(set_attr "type" "fcmp_media")])
8341 (define_insn "cmpgtsf_media"
8342 [(set (match_operand:DI 0 "register_operand" "=r")
8343 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8344 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8345 "TARGET_SHMEDIA_FPU"
8346 "fcmpgt.s %1, %2, %0"
8347 [(set_attr "type" "fcmp_media")])
8349 (define_insn "cmpgesf_media"
8350 [(set (match_operand:DI 0 "register_operand" "=r")
8351 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8352 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8353 "TARGET_SHMEDIA_FPU"
8354 "fcmpge.s %1, %2, %0"
8355 [(set_attr "type" "fcmp_media")])
8357 (define_insn "cmpunsf_media"
8358 [(set (match_operand:DI 0 "register_operand" "=r")
8359 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8360 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8361 "TARGET_SHMEDIA_FPU"
8362 "fcmpun.s %1, %2, %0"
8363 [(set_attr "type" "fcmp_media")])
8365 (define_expand "cmpsf"
8366 [(set (reg:SI T_REG)
8367 (compare (match_operand:SF 0 "arith_operand" "")
8368 (match_operand:SF 1 "arith_operand" "")))]
8369 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8372 sh_compare_op0 = operands[0];
8373 sh_compare_op1 = operands[1];
8377 (define_expand "negsf2"
8378 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8379 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8380 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8385 expand_sf_unop (&gen_negsf2_i, operands);
8390 (define_insn "*negsf2_media"
8391 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8392 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8393 "TARGET_SHMEDIA_FPU"
8395 [(set_attr "type" "fmove_media")])
8397 (define_insn "negsf2_i"
8398 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8399 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8400 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8403 [(set_attr "type" "fmove")
8404 (set_attr "fp_mode" "single")])
8406 (define_expand "sqrtsf2"
8407 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8408 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8409 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8414 expand_sf_unop (&gen_sqrtsf2_i, operands);
8419 (define_insn "*sqrtsf2_media"
8420 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8421 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8422 "TARGET_SHMEDIA_FPU"
8424 [(set_attr "type" "fdiv_media")])
8426 (define_insn "sqrtsf2_i"
8427 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8429 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8432 [(set_attr "type" "fdiv")
8433 (set_attr "fp_mode" "single")])
8435 (define_expand "abssf2"
8436 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8437 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8438 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8443 expand_sf_unop (&gen_abssf2_i, operands);
8448 (define_insn "*abssf2_media"
8449 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8450 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8451 "TARGET_SHMEDIA_FPU"
8453 [(set_attr "type" "fmove_media")])
8455 (define_insn "abssf2_i"
8456 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8457 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8458 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8461 [(set_attr "type" "fmove")
8462 (set_attr "fp_mode" "single")])
8464 (define_expand "adddf3"
8465 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8466 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8467 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8468 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8473 expand_df_binop (&gen_adddf3_i, operands);
8478 (define_insn "*adddf3_media"
8479 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8480 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8481 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8482 "TARGET_SHMEDIA_FPU"
8484 [(set_attr "type" "dfparith_media")])
8486 (define_insn "adddf3_i"
8487 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8488 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8489 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8490 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8493 [(set_attr "type" "dfp_arith")
8494 (set_attr "fp_mode" "double")])
8496 (define_expand "subdf3"
8497 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8498 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8499 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8500 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8505 expand_df_binop (&gen_subdf3_i, operands);
8510 (define_insn "*subdf3_media"
8511 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8512 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8513 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8514 "TARGET_SHMEDIA_FPU"
8516 [(set_attr "type" "dfparith_media")])
8518 (define_insn "subdf3_i"
8519 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8520 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8521 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8522 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8525 [(set_attr "type" "dfp_arith")
8526 (set_attr "fp_mode" "double")])
8528 (define_expand "muldf3"
8529 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8530 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8531 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8532 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8537 expand_df_binop (&gen_muldf3_i, operands);
8542 (define_insn "*muldf3_media"
8543 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8544 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8545 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8546 "TARGET_SHMEDIA_FPU"
8548 [(set_attr "type" "dfmul_media")])
8550 (define_insn "muldf3_i"
8551 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8552 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8553 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8554 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8557 [(set_attr "type" "dfp_arith")
8558 (set_attr "fp_mode" "double")])
8560 (define_expand "divdf3"
8561 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8562 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8563 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8564 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8569 expand_df_binop (&gen_divdf3_i, operands);
8574 (define_insn "*divdf3_media"
8575 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8576 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8577 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8578 "TARGET_SHMEDIA_FPU"
8580 [(set_attr "type" "dfdiv_media")])
8582 (define_insn "divdf3_i"
8583 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8584 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8585 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8586 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8589 [(set_attr "type" "dfdiv")
8590 (set_attr "fp_mode" "double")])
8592 (define_insn "floatdidf2"
8593 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8594 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8595 "TARGET_SHMEDIA_FPU"
8597 [(set_attr "type" "dfpconv_media")])
8599 (define_expand "floatsidf2"
8600 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8601 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8602 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8607 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8613 (define_insn "*floatsidf2_media"
8614 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8615 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8616 "TARGET_SHMEDIA_FPU"
8618 [(set_attr "type" "dfpconv_media")])
8620 (define_insn "floatsidf2_i"
8621 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8622 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8623 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8626 [(set_attr "type" "dfp_conv")
8627 (set_attr "fp_mode" "double")])
8629 (define_insn "fix_truncdfdi2"
8630 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8631 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8632 "TARGET_SHMEDIA_FPU"
8634 [(set_attr "type" "dfpconv_media")])
8636 (define_expand "fix_truncdfsi2"
8637 [(set (match_operand:SI 0 "fpul_operand" "")
8638 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8639 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8644 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8650 (define_insn "*fix_truncdfsi2_media"
8651 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8652 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8653 "TARGET_SHMEDIA_FPU"
8655 [(set_attr "type" "dfpconv_media")])
8657 (define_insn "fix_truncdfsi2_i"
8658 [(set (match_operand:SI 0 "fpul_operand" "=y")
8659 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8660 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8663 [(set_attr "type" "dfp_conv")
8664 (set_attr "dfp_comp" "no")
8665 (set_attr "fp_mode" "double")])
8667 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8668 ;; fix_truncdfsi2_i.
8669 ;; (define_insn "fix_truncdfsi2_i4"
8670 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8671 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8672 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8673 ;; (clobber (reg:SI FPUL_REG))]
8676 ;; [(set_attr "length" "4")
8677 ;; (set_attr "fp_mode" "double")])
8680 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8681 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8682 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8683 ;; (clobber (reg:SI FPUL_REG))]
8685 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8686 ;; (use (match_dup 2))])
8687 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8689 (define_insn "cmpgtdf_t"
8690 [(set (reg:SI T_REG)
8691 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8692 (match_operand:DF 1 "arith_reg_operand" "f")))
8693 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8696 [(set_attr "type" "dfp_cmp")
8697 (set_attr "fp_mode" "double")])
8699 (define_insn "cmpeqdf_t"
8700 [(set (reg:SI T_REG)
8701 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8702 (match_operand:DF 1 "arith_reg_operand" "f")))
8703 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8706 [(set_attr "type" "dfp_cmp")
8707 (set_attr "fp_mode" "double")])
8709 (define_insn "*ieee_ccmpeqdf_t"
8710 [(set (reg:SI T_REG)
8711 (ior:SI (reg:SI T_REG)
8712 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8713 (match_operand:DF 1 "arith_reg_operand" "f"))))
8714 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8715 "TARGET_IEEE && TARGET_SH4"
8716 "* return output_ieee_ccmpeq (insn, operands);"
8717 [(set_attr "length" "4")
8718 (set_attr "fp_mode" "double")])
8720 (define_insn "cmpeqdf_media"
8721 [(set (match_operand:DI 0 "register_operand" "=r")
8722 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8723 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8724 "TARGET_SHMEDIA_FPU"
8726 [(set_attr "type" "fcmp_media")])
8728 (define_insn "cmpgtdf_media"
8729 [(set (match_operand:DI 0 "register_operand" "=r")
8730 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8731 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8732 "TARGET_SHMEDIA_FPU"
8734 [(set_attr "type" "fcmp_media")])
8736 (define_insn "cmpgedf_media"
8737 [(set (match_operand:DI 0 "register_operand" "=r")
8738 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8739 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8740 "TARGET_SHMEDIA_FPU"
8742 [(set_attr "type" "fcmp_media")])
8744 (define_insn "cmpundf_media"
8745 [(set (match_operand:DI 0 "register_operand" "=r")
8746 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8747 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8748 "TARGET_SHMEDIA_FPU"
8750 [(set_attr "type" "fcmp_media")])
8752 (define_expand "cmpdf"
8753 [(set (reg:SI T_REG)
8754 (compare (match_operand:DF 0 "arith_operand" "")
8755 (match_operand:DF 1 "arith_operand" "")))]
8756 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8759 sh_compare_op0 = operands[0];
8760 sh_compare_op1 = operands[1];
8764 (define_expand "negdf2"
8765 [(set (match_operand:DF 0 "arith_reg_operand" "")
8766 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8767 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8772 expand_df_unop (&gen_negdf2_i, operands);
8777 (define_insn "*negdf2_media"
8778 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8779 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8780 "TARGET_SHMEDIA_FPU"
8782 [(set_attr "type" "fmove_media")])
8784 (define_insn "negdf2_i"
8785 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8786 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8787 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8790 [(set_attr "type" "fmove")
8791 (set_attr "fp_mode" "double")])
8793 (define_expand "sqrtdf2"
8794 [(set (match_operand:DF 0 "arith_reg_operand" "")
8795 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8796 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8801 expand_df_unop (&gen_sqrtdf2_i, operands);
8806 (define_insn "*sqrtdf2_media"
8807 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8808 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8809 "TARGET_SHMEDIA_FPU"
8811 [(set_attr "type" "dfdiv_media")])
8813 (define_insn "sqrtdf2_i"
8814 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8815 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8816 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8819 [(set_attr "type" "dfdiv")
8820 (set_attr "fp_mode" "double")])
8822 (define_expand "absdf2"
8823 [(set (match_operand:DF 0 "arith_reg_operand" "")
8824 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8825 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8830 expand_df_unop (&gen_absdf2_i, operands);
8835 (define_insn "*absdf2_media"
8836 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8837 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8838 "TARGET_SHMEDIA_FPU"
8840 [(set_attr "type" "fmove_media")])
8842 (define_insn "absdf2_i"
8843 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8844 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8845 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8848 [(set_attr "type" "fmove")
8849 (set_attr "fp_mode" "double")])
8851 (define_expand "extendsfdf2"
8852 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8853 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8854 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8859 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8865 (define_insn "*extendsfdf2_media"
8866 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8867 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8868 "TARGET_SHMEDIA_FPU"
8870 [(set_attr "type" "dfpconv_media")])
8872 (define_insn "extendsfdf2_i4"
8873 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8874 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8875 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8878 [(set_attr "type" "fp")
8879 (set_attr "fp_mode" "double")])
8881 (define_expand "truncdfsf2"
8882 [(set (match_operand:SF 0 "fpul_operand" "")
8883 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8884 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8889 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8895 (define_insn "*truncdfsf2_media"
8896 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8897 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8898 "TARGET_SHMEDIA_FPU"
8900 [(set_attr "type" "dfpconv_media")])
8902 (define_insn "truncdfsf2_i4"
8903 [(set (match_operand:SF 0 "fpul_operand" "=y")
8904 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8905 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8908 [(set_attr "type" "fp")
8909 (set_attr "fp_mode" "double")])
8911 ;; Bit field extract patterns. These give better code for packed bitfields,
8912 ;; because they allow auto-increment addresses to be generated.
8914 (define_expand "insv"
8915 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8916 (match_operand:SI 1 "immediate_operand" "")
8917 (match_operand:SI 2 "immediate_operand" ""))
8918 (match_operand:SI 3 "general_operand" ""))]
8919 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8922 rtx addr_target, orig_address, shift_reg, qi_val;
8923 HOST_WIDE_INT bitsize, size, v;
8924 rtx x = operands[3];
8926 /* ??? expmed doesn't care for non-register predicates. */
8927 if (! memory_operand (operands[0], VOIDmode)
8928 || ! immediate_operand (operands[1], VOIDmode)
8929 || ! immediate_operand (operands[2], VOIDmode)
8930 || ! general_operand (x, VOIDmode))
8932 /* If this isn't a 16 / 24 / 32 bit field, or if
8933 it doesn't start on a byte boundary, then fail. */
8934 bitsize = INTVAL (operands[1]);
8935 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8936 || (INTVAL (operands[2]) % 8) != 0)
8940 orig_address = XEXP (operands[0], 0);
8941 shift_reg = gen_reg_rtx (SImode);
8942 if (GET_CODE (x) == CONST_INT)
8945 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8949 emit_insn (gen_movsi (shift_reg, operands[3]));
8950 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8952 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8954 operands[0] = replace_equiv_address (operands[0], addr_target);
8955 emit_insn (gen_movqi (operands[0], qi_val));
8959 if (GET_CODE (x) == CONST_INT)
8961 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8964 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8965 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8967 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8968 emit_insn (gen_movqi (operands[0], qi_val));
8974 ;; -------------------------------------------------------------------------
8976 ;; -------------------------------------------------------------------------
8978 ;; This matches cases where a stack pointer increment at the start of the
8979 ;; epilogue combines with a stack slot read loading the return value.
8982 [(set (match_operand:SI 0 "arith_reg_operand" "")
8983 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8984 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8985 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8988 ;; See the comment on the dt combiner pattern above.
8991 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8992 (plus:SI (match_dup 0)
8995 (eq:SI (match_dup 0)
9000 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9001 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9002 ;; reload when the constant is too large for a reg+offset address.
9004 ;; ??? We would get much better code if this was done in reload. This would
9005 ;; require modifying find_reloads_address to recognize that if the constant
9006 ;; is out-of-range for an immediate add, then we get better code by reloading
9007 ;; the constant into a register than by reloading the sum into a register,
9008 ;; since the former is one instruction shorter if the address does not need
9009 ;; to be offsettable. Unfortunately this does not work, because there is
9010 ;; only one register, r0, that can be used as an index register. This register
9011 ;; is also the function return value register. So, if we try to force reload
9012 ;; to use double-reg addresses, then we end up with some instructions that
9013 ;; need to use r0 twice. The only way to fix this is to change the calling
9014 ;; convention so that r0 is not used to return values.
9017 [(set (match_operand:SI 0 "register_operand" "=r")
9018 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9019 (set (mem:SI (match_dup 0))
9020 (match_operand:SI 2 "general_movsrc_operand" ""))]
9021 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9022 "mov.l %2,@(%0,%1)")
9025 [(set (match_operand:SI 0 "register_operand" "=r")
9026 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9027 (set (match_operand:SI 2 "general_movdst_operand" "")
9028 (mem:SI (match_dup 0)))]
9029 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9030 "mov.l @(%0,%1),%2")
9033 [(set (match_operand:SI 0 "register_operand" "=r")
9034 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9035 (set (mem:HI (match_dup 0))
9036 (match_operand:HI 2 "general_movsrc_operand" ""))]
9037 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9038 "mov.w %2,@(%0,%1)")
9041 [(set (match_operand:SI 0 "register_operand" "=r")
9042 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9043 (set (match_operand:HI 2 "general_movdst_operand" "")
9044 (mem:HI (match_dup 0)))]
9045 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9046 "mov.w @(%0,%1),%2")
9049 [(set (match_operand:SI 0 "register_operand" "=r")
9050 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9051 (set (mem:QI (match_dup 0))
9052 (match_operand:QI 2 "general_movsrc_operand" ""))]
9053 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9054 "mov.b %2,@(%0,%1)")
9057 [(set (match_operand:SI 0 "register_operand" "=r")
9058 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9059 (set (match_operand:QI 2 "general_movdst_operand" "")
9060 (mem:QI (match_dup 0)))]
9061 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9062 "mov.b @(%0,%1),%2")
9065 [(set (match_operand:SI 0 "register_operand" "=r")
9066 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9067 (set (mem:SF (match_dup 0))
9068 (match_operand:SF 2 "general_movsrc_operand" ""))]
9069 "TARGET_SH1 && REGNO (operands[0]) == 0
9070 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9071 || (GET_CODE (operands[2]) == SUBREG
9072 && REGNO (SUBREG_REG (operands[2])) < 16))
9073 && reg_unused_after (operands[0], insn)"
9074 "mov.l %2,@(%0,%1)")
9077 [(set (match_operand:SI 0 "register_operand" "=r")
9078 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9079 (set (match_operand:SF 2 "general_movdst_operand" "")
9081 (mem:SF (match_dup 0)))]
9082 "TARGET_SH1 && REGNO (operands[0]) == 0
9083 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9084 || (GET_CODE (operands[2]) == SUBREG
9085 && REGNO (SUBREG_REG (operands[2])) < 16))
9086 && reg_unused_after (operands[0], insn)"
9087 "mov.l @(%0,%1),%2")
9090 [(set (match_operand:SI 0 "register_operand" "=r")
9091 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9092 (set (mem:SF (match_dup 0))
9093 (match_operand:SF 2 "general_movsrc_operand" ""))]
9094 "TARGET_SH3E && REGNO (operands[0]) == 0
9095 && ((GET_CODE (operands[2]) == REG
9096 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9097 || (GET_CODE (operands[2]) == SUBREG
9098 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9099 && reg_unused_after (operands[0], insn)"
9100 "fmov{.s|} %2,@(%0,%1)")
9103 [(set (match_operand:SI 0 "register_operand" "=r")
9104 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9105 (set (match_operand:SF 2 "general_movdst_operand" "")
9107 (mem:SF (match_dup 0)))]
9108 "TARGET_SH3E && REGNO (operands[0]) == 0
9109 && ((GET_CODE (operands[2]) == REG
9110 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9111 || (GET_CODE (operands[2]) == SUBREG
9112 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9113 && reg_unused_after (operands[0], insn)"
9114 "fmov{.s|} @(%0,%1),%2")
9116 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9117 (define_insn "sp_switch_1"
9124 xoperands[0] = sp_switch;
9125 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9126 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9127 return \"mov r0,r15\";
9129 [(set_attr "length" "10")])
9131 ;; Switch back to the original stack for interrupt functions with the
9132 ;; sp_switch attribute. */
9133 (define_insn "sp_switch_2"
9136 "mov.l @r15+,r15\;mov.l @r15+,r0"
9137 [(set_attr "length" "4")])
9139 ;; Integer vector moves
9141 (define_expand "movv8qi"
9142 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9143 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9145 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9147 (define_insn "movv8qi_i"
9148 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9149 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9151 && (register_operand (operands[0], V8QImode)
9152 || register_operand (operands[1], V8QImode))"
9159 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9160 (set_attr "length" "4,4,16,4,4")])
9163 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9164 (subreg:V8QI (const_int 0) 0))]
9167 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9168 (const_int 0) (const_int 0) (const_int 0)
9169 (const_int 0) (const_int 0)]))])
9172 [(set (match_operand 0 "arith_reg_dest" "")
9173 (match_operand 1 "sh_rep_vec" ""))]
9174 "TARGET_SHMEDIA && reload_completed
9175 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9176 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9177 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9178 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9179 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9180 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9181 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9182 [(set (match_dup 0) (match_dup 1))
9186 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9187 rtx elt1 = XVECEXP (operands[1], 0, 1);
9190 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9194 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9195 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9197 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9198 operands[1] = XVECEXP (operands[1], 0, 0);
9201 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9202 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9203 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9204 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9207 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9209 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9215 [(set (match_operand 0 "arith_reg_dest" "")
9216 (match_operand 1 "sh_const_vec" ""))]
9217 "TARGET_SHMEDIA && reload_completed
9218 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9219 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9220 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9221 [(set (match_dup 0) (match_dup 1))]
9224 rtx v = operands[1];
9225 enum machine_mode new_mode
9226 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9228 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9230 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9233 (define_expand "movv2hi"
9234 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9235 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9237 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9239 (define_insn "movv2hi_i"
9240 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9241 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9243 && (register_operand (operands[0], V2HImode)
9244 || register_operand (operands[1], V2HImode))"
9251 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9252 (set_attr "length" "4,4,16,4,4")])
9254 (define_expand "movv4hi"
9255 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9256 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9258 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9260 (define_insn "movv4hi_i"
9261 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9262 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9264 && (register_operand (operands[0], V4HImode)
9265 || register_operand (operands[1], V4HImode))"
9272 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9273 (set_attr "length" "4,4,16,4,4")])
9275 (define_expand "movv2si"
9276 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9277 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9279 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9281 (define_insn "movv2si_i"
9282 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9283 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9285 && (register_operand (operands[0], V2SImode)
9286 || register_operand (operands[1], V2SImode))"
9293 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9294 (set_attr "length" "4,4,16,4,4")])
9296 ;; Multimedia Intrinsics
9298 (define_insn "absv2si2"
9299 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9300 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9303 [(set_attr "type" "mcmp_media")])
9305 (define_insn "absv4hi2"
9306 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9307 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9310 [(set_attr "type" "mcmp_media")])
9312 (define_insn "addv2si3"
9313 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9314 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9315 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9318 [(set_attr "type" "arith_media")])
9320 (define_insn "addv4hi3"
9321 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9322 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9323 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9326 [(set_attr "type" "arith_media")])
9328 (define_insn "ssaddv2si3"
9329 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9330 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9331 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9333 "madds.l %1, %2, %0"
9334 [(set_attr "type" "mcmp_media")])
9336 (define_insn "usaddv8qi3"
9337 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9338 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9339 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9341 "madds.ub %1, %2, %0"
9342 [(set_attr "type" "mcmp_media")])
9344 (define_insn "ssaddv4hi3"
9345 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9346 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9347 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9349 "madds.w %1, %2, %0"
9350 [(set_attr "type" "mcmp_media")])
9352 (define_insn "negcmpeqv8qi"
9353 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9354 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9355 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9357 "mcmpeq.b %N1, %N2, %0"
9358 [(set_attr "type" "mcmp_media")])
9360 (define_insn "negcmpeqv2si"
9361 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9362 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9363 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9365 "mcmpeq.l %N1, %N2, %0"
9366 [(set_attr "type" "mcmp_media")])
9368 (define_insn "negcmpeqv4hi"
9369 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9370 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9371 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9373 "mcmpeq.w %N1, %N2, %0"
9374 [(set_attr "type" "mcmp_media")])
9376 (define_insn "negcmpgtuv8qi"
9377 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9378 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9379 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9381 "mcmpgt.ub %N1, %N2, %0"
9382 [(set_attr "type" "mcmp_media")])
9384 (define_insn "negcmpgtv2si"
9385 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9386 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9387 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9389 "mcmpgt.l %N1, %N2, %0"
9390 [(set_attr "type" "mcmp_media")])
9392 (define_insn "negcmpgtv4hi"
9393 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9394 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9395 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9397 "mcmpgt.w %N1, %N2, %0"
9398 [(set_attr "type" "mcmp_media")])
9401 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9402 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9403 (match_operand:DI 2 "arith_reg_operand" "r"))
9404 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9405 (not:DI (match_dup 2)))))]
9408 [(set_attr "type" "arith_media")])
9410 (define_insn "mcnvs_lw"
9411 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9413 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9414 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9416 "mcnvs.lw %N1, %N2, %0"
9417 [(set_attr "type" "mcmp_media")])
9419 (define_insn "mcnvs_wb"
9420 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9422 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9423 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9425 "mcnvs.wb %N1, %N2, %0"
9426 [(set_attr "type" "mcmp_media")])
9428 (define_insn "mcnvs_wub"
9429 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9431 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9432 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9434 "mcnvs.wub %N1, %N2, %0"
9435 [(set_attr "type" "mcmp_media")])
9437 (define_insn "mextr_rl"
9438 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9439 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9440 (match_operand:HI 3 "mextr_bit_offset" "i"))
9441 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9442 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9443 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9446 static char templ[16];
9448 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9449 (int) INTVAL (operands[3]) >> 3);
9452 [(set_attr "type" "arith_media")])
9454 (define_insn "*mextr_lr"
9455 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9456 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9457 (match_operand:HI 3 "mextr_bit_offset" "i"))
9458 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9459 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9460 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9463 static char templ[16];
9465 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9466 (int) INTVAL (operands[4]) >> 3);
9469 [(set_attr "type" "arith_media")])
9471 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9472 ; vector then varies depending on endianness.
9473 (define_expand "mextr1"
9474 [(match_operand:DI 0 "arith_reg_dest" "")
9475 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9476 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9480 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9481 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9485 (define_expand "mextr2"
9486 [(match_operand:DI 0 "arith_reg_dest" "")
9487 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9488 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9492 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9493 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9497 (define_expand "mextr3"
9498 [(match_operand:DI 0 "arith_reg_dest" "")
9499 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9500 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9504 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9505 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9509 (define_expand "mextr4"
9510 [(match_operand:DI 0 "arith_reg_dest" "")
9511 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9512 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9516 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9517 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9521 (define_expand "mextr5"
9522 [(match_operand:DI 0 "arith_reg_dest" "")
9523 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9524 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9528 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9529 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9533 (define_expand "mextr6"
9534 [(match_operand:DI 0 "arith_reg_dest" "")
9535 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9536 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9540 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9541 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9545 (define_expand "mextr7"
9546 [(match_operand:DI 0 "arith_reg_dest" "")
9547 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9548 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9552 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9553 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9557 (define_expand "mmacfx_wl"
9558 [(match_operand:V2SI 0 "arith_reg_dest" "")
9559 (match_operand:V2HI 1 "extend_reg_operand" "")
9560 (match_operand:V2HI 2 "extend_reg_operand" "")
9561 (match_operand:V2SI 3 "arith_reg_operand" "")]
9565 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9566 operands[1], operands[2]));
9570 (define_insn "mmacfx_wl_i"
9571 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9573 (match_operand:V2SI 1 "arith_reg_operand" "0")
9578 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9579 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9582 "mmacfx.wl %2, %3, %0"
9583 [(set_attr "type" "mac_media")])
9585 (define_expand "mmacnfx_wl"
9586 [(match_operand:V2SI 0 "arith_reg_dest" "")
9587 (match_operand:V2HI 1 "extend_reg_operand" "")
9588 (match_operand:V2HI 2 "extend_reg_operand" "")
9589 (match_operand:V2SI 3 "arith_reg_operand" "")]
9593 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9594 operands[1], operands[2]));
9598 (define_insn "mmacnfx_wl_i"
9599 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9601 (match_operand:V2SI 1 "arith_reg_operand" "0")
9606 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9607 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9610 "mmacnfx.wl %2, %3, %0"
9611 [(set_attr "type" "mac_media")])
9613 (define_insn "mulv2si3"
9614 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9615 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9616 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9619 [(set_attr "type" "d2mpy_media")])
9621 (define_insn "mulv4hi3"
9622 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9623 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9624 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9627 [(set_attr "type" "dmpy_media")])
9629 (define_insn "mmulfx_l"
9630 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9634 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9635 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9638 "mmulfx.l %1, %2, %0"
9639 [(set_attr "type" "d2mpy_media")])
9641 (define_insn "mmulfx_w"
9642 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9646 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9647 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9650 "mmulfx.w %1, %2, %0"
9651 [(set_attr "type" "dmpy_media")])
9653 (define_insn "mmulfxrp_w"
9654 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9659 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9660 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9664 "mmulfxrp.w %1, %2, %0"
9665 [(set_attr "type" "dmpy_media")])
9667 (define_expand "mmulhi_wl"
9668 [(match_operand:V2SI 0 "arith_reg_dest" "")
9669 (match_operand:V4HI 1 "arith_reg_operand" "")
9670 (match_operand:V4HI 2 "arith_reg_operand" "")]
9674 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9675 (operands[0], operands[1], operands[2]));
9679 (define_expand "mmullo_wl"
9680 [(match_operand:V2SI 0 "arith_reg_dest" "")
9681 (match_operand:V4HI 1 "arith_reg_operand" "")
9682 (match_operand:V4HI 2 "arith_reg_operand" "")]
9686 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9687 (operands[0], operands[1], operands[2]));
9691 (define_insn "mmul23_wl"
9692 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9695 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9696 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9697 (parallel [(const_int 2) (const_int 3)])))]
9699 "* return (TARGET_LITTLE_ENDIAN
9700 ? \"mmulhi.wl %1, %2, %0\"
9701 : \"mmullo.wl %1, %2, %0\");"
9702 [(set_attr "type" "dmpy_media")])
9704 (define_insn "mmul01_wl"
9705 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9708 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9709 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9710 (parallel [(const_int 0) (const_int 1)])))]
9712 "* return (TARGET_LITTLE_ENDIAN
9713 ? \"mmullo.wl %1, %2, %0\"
9714 : \"mmulhi.wl %1, %2, %0\");"
9715 [(set_attr "type" "dmpy_media")])
9717 (define_expand "mmulsum_wq"
9718 [(match_operand:DI 0 "arith_reg_dest" "")
9719 (match_operand:V4HI 1 "arith_reg_operand" "")
9720 (match_operand:V4HI 2 "arith_reg_operand" "")
9721 (match_operand:DI 3 "arith_reg_operand" "")]
9725 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9726 operands[1], operands[2]));
9730 (define_insn "mmulsum_wq_i"
9731 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9732 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9737 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9738 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9739 (parallel [(const_int 0)]))
9740 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9741 (sign_extend:V4DI (match_dup 3)))
9742 (parallel [(const_int 1)])))
9744 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9745 (sign_extend:V4DI (match_dup 3)))
9746 (parallel [(const_int 2)]))
9747 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9748 (sign_extend:V4DI (match_dup 3)))
9749 (parallel [(const_int 3)]))))))]
9751 "mmulsum.wq %2, %3, %0"
9752 [(set_attr "type" "mac_media")])
9754 (define_expand "mperm_w"
9755 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9756 (match_operand:V4HI 1 "arith_reg_operand" "r")
9757 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9761 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9762 (operands[0], operands[1], operands[2]));
9766 ; This use of vec_select isn't exactly correct according to rtl.texi
9767 ; (because not constant), but it seems a straightforward extension.
9768 (define_insn "mperm_w_little"
9769 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9771 (match_operand:V4HI 1 "arith_reg_operand" "r")
9773 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9774 (const_int 2) (const_int 0))
9775 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9776 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9777 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9778 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9779 "mperm.w %1, %N2, %0"
9780 [(set_attr "type" "arith_media")])
9782 (define_insn "mperm_w_big"
9783 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9785 (match_operand:V4HI 1 "arith_reg_operand" "r")
9787 [(zero_extract:QI (not:QI (match_operand:QI 2
9788 "extend_reg_or_0_operand" "rU"))
9789 (const_int 2) (const_int 0))
9790 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9791 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9792 (zero_extract:QI (not:QI (match_dup 2))
9793 (const_int 2) (const_int 6))])))]
9794 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9795 "mperm.w %1, %N2, %0"
9796 [(set_attr "type" "arith_media")])
9798 (define_insn "mperm_w0"
9799 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9800 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9801 "trunc_hi_operand" "r"))))]
9803 "mperm.w %1, r63, %0"
9804 [(set_attr "type" "arith_media")])
9806 (define_expand "msad_ubq"
9807 [(match_operand:DI 0 "arith_reg_dest" "")
9808 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9809 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9810 (match_operand:DI 3 "arith_reg_operand" "")]
9814 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9815 operands[1], operands[2]));
9819 (define_insn "msad_ubq_i"
9820 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9825 (match_operand:DI 1 "arith_reg_operand" "0")
9826 (abs:DI (vec_select:DI
9829 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9831 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9832 (parallel [(const_int 0)]))))
9833 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9834 (zero_extend:V8DI (match_dup 3)))
9835 (parallel [(const_int 1)]))))
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 2)])))
9840 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9841 (zero_extend:V8DI (match_dup 3)))
9842 (parallel [(const_int 3)])))))
9845 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9846 (zero_extend:V8DI (match_dup 3)))
9847 (parallel [(const_int 4)])))
9848 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9849 (zero_extend:V8DI (match_dup 3)))
9850 (parallel [(const_int 5)]))))
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 6)])))
9855 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9856 (zero_extend:V8DI (match_dup 3)))
9857 (parallel [(const_int 7)])))))))]
9859 "msad.ubq %N2, %N3, %0"
9860 [(set_attr "type" "mac_media")])
9862 (define_insn "mshalds_l"
9863 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9866 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9867 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9870 "mshalds.l %1, %2, %0"
9871 [(set_attr "type" "mcmp_media")])
9873 (define_insn "mshalds_w"
9874 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9877 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9878 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9881 "mshalds.w %1, %2, %0"
9882 [(set_attr "type" "mcmp_media")])
9884 (define_insn "ashrv2si3"
9885 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9886 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9887 (match_operand:DI 2 "arith_reg_operand" "r")))]
9889 "mshard.l %1, %2, %0"
9890 [(set_attr "type" "arith_media")])
9892 (define_insn "ashrv4hi3"
9893 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9894 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9895 (match_operand:DI 2 "arith_reg_operand" "r")))]
9897 "mshard.w %1, %2, %0"
9898 [(set_attr "type" "arith_media")])
9900 (define_insn "mshards_q"
9901 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9903 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9904 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9906 "mshards.q %1, %N2, %0"
9907 [(set_attr "type" "mcmp_media")])
9909 (define_expand "mshfhi_b"
9910 [(match_operand:V8QI 0 "arith_reg_dest" "")
9911 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9912 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9916 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9917 (operands[0], operands[1], operands[2]));
9921 (define_expand "mshflo_b"
9922 [(match_operand:V8QI 0 "arith_reg_dest" "")
9923 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9924 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9928 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9929 (operands[0], operands[1], operands[2]));
9933 (define_insn "mshf4_b"
9935 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9937 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9938 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9939 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9940 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9942 "* return (TARGET_LITTLE_ENDIAN
9943 ? \"mshfhi.b %N1, %N2, %0\"
9944 : \"mshflo.b %N1, %N2, %0\");"
9945 [(set_attr "type" "arith_media")])
9947 (define_insn "mshf0_b"
9949 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9951 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9952 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9953 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9954 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9956 "* return (TARGET_LITTLE_ENDIAN
9957 ? \"mshflo.b %N1, %N2, %0\"
9958 : \"mshfhi.b %N1, %N2, %0\");"
9959 [(set_attr "type" "arith_media")])
9961 (define_expand "mshfhi_l"
9962 [(match_operand:V2SI 0 "arith_reg_dest" "")
9963 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9964 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9968 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9969 (operands[0], operands[1], operands[2]));
9973 (define_expand "mshflo_l"
9974 [(match_operand:V2SI 0 "arith_reg_dest" "")
9975 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9976 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9980 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9981 (operands[0], operands[1], operands[2]));
9985 (define_insn "mshf4_l"
9986 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9988 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9989 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9990 (parallel [(const_int 1) (const_int 3)])))]
9992 "* return (TARGET_LITTLE_ENDIAN
9993 ? \"mshfhi.l %N1, %N2, %0\"
9994 : \"mshflo.l %N1, %N2, %0\");"
9995 [(set_attr "type" "arith_media")])
9997 (define_insn "mshf0_l"
9998 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10000 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10001 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10002 (parallel [(const_int 0) (const_int 2)])))]
10004 "* return (TARGET_LITTLE_ENDIAN
10005 ? \"mshflo.l %N1, %N2, %0\"
10006 : \"mshfhi.l %N1, %N2, %0\");"
10007 [(set_attr "type" "arith_media")])
10009 (define_expand "mshfhi_w"
10010 [(match_operand:V4HI 0 "arith_reg_dest" "")
10011 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10012 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10016 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10017 (operands[0], operands[1], operands[2]));
10021 (define_expand "mshflo_w"
10022 [(match_operand:V4HI 0 "arith_reg_dest" "")
10023 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10024 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10028 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10029 (operands[0], operands[1], operands[2]));
10033 (define_insn "mshf4_w"
10034 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10037 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10038 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10040 "* return (TARGET_LITTLE_ENDIAN
10041 ? \"mshfhi.w %N1, %N2, %0\"
10042 : \"mshflo.w %N1, %N2, %0\");"
10043 [(set_attr "type" "arith_media")])
10045 (define_insn "mshf0_w"
10046 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10048 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10049 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10050 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10052 "* return (TARGET_LITTLE_ENDIAN
10053 ? \"mshflo.w %N1, %N2, %0\"
10054 : \"mshfhi.w %N1, %N2, %0\");"
10055 [(set_attr "type" "arith_media")])
10057 (define_insn "mshflo_w_x"
10058 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10060 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10061 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10062 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10064 "mshflo.w %N1, %N2, %0"
10065 [(set_attr "type" "arith_media")])
10067 /* These are useful to expand ANDs and as combiner patterns. */
10068 (define_insn_and_split "mshfhi_l_di"
10069 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10070 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10072 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10073 (const_int -4294967296))))]
10076 mshfhi.l %N1, %N2, %0
10078 "TARGET_SHMEDIA && reload_completed
10079 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10080 [(set (match_dup 3) (match_dup 4))
10081 (set (match_dup 5) (match_dup 6))]
10084 operands[3] = gen_lowpart (SImode, operands[0]);
10085 operands[4] = gen_highpart (SImode, operands[1]);
10086 operands[5] = gen_highpart (SImode, operands[0]);
10087 operands[6] = gen_highpart (SImode, operands[2]);
10089 [(set_attr "type" "arith_media")])
10091 (define_insn "*mshfhi_l_di_rev"
10092 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10093 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10094 (const_int -4294967296))
10095 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10098 "mshfhi.l %N2, %N1, %0"
10099 [(set_attr "type" "arith_media")])
10102 [(set (match_operand:DI 0 "arith_reg_dest" "")
10103 (ior:DI (zero_extend:DI (match_operand:SI 1
10104 "extend_reg_or_0_operand" ""))
10105 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10106 (const_int -4294967296))))
10107 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10112 emit_insn (gen_ashldi3_media (operands[3],
10113 simplify_gen_subreg (DImode, operands[1],
10116 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10120 (define_insn "mshflo_l_di"
10121 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10122 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10123 (const_int 4294967295))
10124 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10128 "mshflo.l %N1, %N2, %0"
10129 [(set_attr "type" "arith_media")])
10131 (define_insn "*mshflo_l_di_rev"
10132 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10133 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10135 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10136 (const_int 4294967295))))]
10139 "mshflo.l %N2, %N1, %0"
10140 [(set_attr "type" "arith_media")])
10142 ;; Combiner pattern for trampoline initialization.
10143 (define_insn_and_split "*double_shori"
10144 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10147 (match_operand:DI 2 "const_int_operand" "n")))]
10149 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10151 "rtx_equal_p (operands[0], operands[1])"
10155 HOST_WIDE_INT v = INTVAL (operands[2]);
10157 emit_insn (gen_shori_media (operands[0], operands[0],
10158 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10159 emit_insn (gen_shori_media (operands[0], operands[0],
10160 gen_int_mode (v, HImode)));
10165 (define_insn "*mshflo_l_di_x"
10166 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10167 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10169 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10173 "mshflo.l %N1, %N2, %0"
10174 [(set_attr "type" "arith_media")])
10176 (define_insn_and_split "concat_v2sf"
10177 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10178 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10179 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10180 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10184 mshflo.l %N1, %N2, %0
10187 "TARGET_SHMEDIA && reload_completed
10188 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10189 [(set (match_dup 3) (match_dup 1))
10190 (set (match_dup 4) (match_dup 2))]
10193 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10194 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10196 [(set_attr "type" "arith_media")])
10198 (define_insn "*mshflo_l_di_x_rev"
10199 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10200 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10202 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10205 "mshflo.l %N2, %N1, %0"
10206 [(set_attr "type" "arith_media")])
10208 (define_insn "ashlv2si3"
10209 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10210 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10211 (match_operand:DI 2 "arith_reg_operand" "r")))]
10213 "mshlld.l %1, %2, %0"
10214 [(set_attr "type" "arith_media")])
10216 (define_insn "ashlv4hi3"
10217 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10218 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10219 (match_operand:DI 2 "arith_reg_operand" "r")))]
10221 "mshlld.w %1, %2, %0"
10222 [(set_attr "type" "arith_media")])
10224 (define_insn "lshrv2si3"
10225 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10226 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10227 (match_operand:DI 2 "arith_reg_operand" "r")))]
10229 "mshlrd.l %1, %2, %0"
10230 [(set_attr "type" "arith_media")])
10232 (define_insn "lshrv4hi3"
10233 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10234 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10235 (match_operand:DI 2 "arith_reg_operand" "r")))]
10237 "mshlrd.w %1, %2, %0"
10238 [(set_attr "type" "arith_media")])
10240 (define_insn "subv2si3"
10241 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10242 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10243 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10245 "msub.l %N1, %2, %0"
10246 [(set_attr "type" "arith_media")])
10248 (define_insn "subv4hi3"
10249 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10250 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10251 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10253 "msub.w %N1, %2, %0"
10254 [(set_attr "type" "arith_media")])
10256 (define_insn "sssubv2si3"
10257 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10258 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10259 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10261 "msubs.l %N1, %2, %0"
10262 [(set_attr "type" "mcmp_media")])
10264 (define_insn "ussubv8qi3"
10265 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10266 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10267 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10269 "msubs.ub %1, %2, %0"
10270 [(set_attr "type" "mcmp_media")])
10272 (define_insn "sssubv4hi3"
10273 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10274 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10275 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10277 "msubs.w %N1, %2, %0"
10278 [(set_attr "type" "mcmp_media")])
10280 ;; Floating Point Intrinsics
10282 (define_insn "fcosa_s"
10283 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10284 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10288 [(set_attr "type" "atrans_media")])
10290 (define_insn "fsina_s"
10291 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10292 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10296 [(set_attr "type" "atrans_media")])
10298 (define_insn "fipr"
10299 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10300 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10301 "fp_arith_reg_operand" "f")
10302 (match_operand:V4SF 2
10303 "fp_arith_reg_operand" "f"))
10304 (parallel [(const_int 0)]))
10305 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10306 (parallel [(const_int 1)])))
10307 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10308 (parallel [(const_int 2)]))
10309 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10310 (parallel [(const_int 3)])))))]
10313 [(set_attr "type" "fparith_media")])
10315 (define_insn "fsrra_s"
10316 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10317 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10321 [(set_attr "type" "atrans_media")])
10323 (define_insn "ftrv"
10324 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10328 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10329 (parallel [(const_int 0) (const_int 5)
10330 (const_int 10) (const_int 15)]))
10331 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10333 (vec_select:V4SF (match_dup 1)
10334 (parallel [(const_int 4) (const_int 9)
10335 (const_int 14) (const_int 3)]))
10336 (vec_select:V4SF (match_dup 2)
10337 (parallel [(const_int 1) (const_int 2)
10338 (const_int 3) (const_int 0)]))))
10341 (vec_select:V4SF (match_dup 1)
10342 (parallel [(const_int 8) (const_int 13)
10343 (const_int 2) (const_int 7)]))
10344 (vec_select:V4SF (match_dup 2)
10345 (parallel [(const_int 2) (const_int 3)
10346 (const_int 0) (const_int 1)])))
10348 (vec_select:V4SF (match_dup 1)
10349 (parallel [(const_int 12) (const_int 1)
10350 (const_int 6) (const_int 11)]))
10351 (vec_select:V4SF (match_dup 2)
10352 (parallel [(const_int 3) (const_int 0)
10353 (const_int 1) (const_int 2)]))))))]
10356 [(set_attr "type" "fparith_media")])
10359 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10360 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10364 [(set_attr "type" "arith_media")])
10366 (define_insn "nsbsi"
10367 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10369 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10373 [(set_attr "type" "arith_media")])
10375 (define_insn "nsbdi"
10376 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10378 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10382 [(set_attr "type" "arith_media")])
10384 (define_expand "ffsdi2"
10385 [(set (match_operand:DI 0 "arith_reg_dest" "")
10386 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10390 rtx scratch = gen_reg_rtx (DImode);
10393 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10394 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10395 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10396 emit_insn (gen_nsbdi (scratch, scratch));
10397 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10398 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10399 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10401 = gen_rtx_EXPR_LIST (REG_EQUAL,
10402 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10406 (define_expand "ffssi2"
10407 [(set (match_operand:SI 0 "arith_reg_dest" "")
10408 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10412 rtx scratch = gen_reg_rtx (SImode);
10413 rtx discratch = gen_reg_rtx (DImode);
10416 emit_insn (gen_adddi3 (discratch,
10417 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10419 emit_insn (gen_andcdi3 (discratch,
10420 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10422 emit_insn (gen_nsbsi (scratch, discratch));
10423 last = emit_insn (gen_subsi3 (operands[0],
10424 force_reg (SImode, GEN_INT (63)), scratch));
10426 = gen_rtx_EXPR_LIST (REG_EQUAL,
10427 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10431 (define_insn "byterev"
10432 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10433 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10434 (parallel [(const_int 7) (const_int 6) (const_int 5)
10435 (const_int 4) (const_int 3) (const_int 2)
10436 (const_int 1) (const_int 0)])))]
10439 [(set_attr "type" "arith_media")])
10441 ;; The following description models the
10442 ;; SH4 pipeline using the DFA based scheduler.
10443 ;; The DFA based description is better way to model
10444 ;; a superscalar pipeline as compared to function unit
10445 ;; reservation model.
10446 ;; 1. The function unit based model is oriented to describe at most one
10447 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10448 ;; pipeline units by same insn. This can be done using DFA based description.
10449 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10450 ;; 3. Writing all unit reservations for an instruction class is more natural description
10451 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10452 ;; old function unit based model.
10453 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10456 ;; Two automata are defined to reduce number of states
10457 ;; which a single large automaton will have.(Factoring)
10459 (define_automaton "inst_pipeline,fpu_pipe")
10461 ;; This unit is basically the decode unit of the processor.
10462 ;; Since SH4 is a dual issue machine,it is as if there are two
10463 ;; units so that any insn can be processed by either one
10464 ;; of the decoding unit.
10466 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10469 ;; The fixed point arithmetic calculator(?? EX Unit).
10471 (define_cpu_unit "int" "inst_pipeline")
10473 ;; f1_1 and f1_2 are floating point units.Actually there is
10474 ;; a f1 unit which can overlap with other f1 unit but
10475 ;; not another F1 unit.It is as though there were two
10478 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10480 ;; The floating point units (except FS - F2 always precedes it.)
10482 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10484 ;; This is basically the MA unit of SH4
10485 ;; used in LOAD/STORE pipeline.
10487 (define_cpu_unit "memory" "inst_pipeline")
10489 ;; However, there are LS group insns that don't use it, even ones that
10490 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10491 (define_cpu_unit "load_store" "inst_pipeline")
10493 ;; The address calculator used for branch instructions.
10494 ;; This will be reserved after "issue" of branch instructions
10495 ;; and this is to make sure that no two branch instructions
10496 ;; can be issued in parallel.
10498 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10500 ;; ----------------------------------------------------
10501 ;; This reservation is to simplify the dual issue description.
10503 (define_reservation "issue" "pipe_01|pipe_02")
10505 ;; This is to express the locking of D stage.
10506 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10508 (define_reservation "d_lock" "pipe_01+pipe_02")
10510 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10511 (define_reservation "F01" "F0+F1")
10513 ;; This is to simplify description where F1,F2,FS
10514 ;; are used simultaneously.
10516 (define_reservation "fpu" "F1+F2")
10518 ;; This is to highlight the fact that f1
10519 ;; cannot overlap with F1.
10521 (exclusion_set "f1_1,f1_2" "F1")
10523 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10525 ;; Although reg moves have a latency of zero
10526 ;; we need to highlight that they use D stage
10531 (define_insn_reservation "reg_mov" 0
10532 (and (eq_attr "pipe_model" "sh4")
10533 (eq_attr "type" "move"))
10538 (define_insn_reservation "freg_mov" 0
10539 (and (eq_attr "pipe_model" "sh4")
10540 (eq_attr "type" "fmove"))
10541 "issue+load_store")
10543 ;; We don't model all pipeline stages; we model the issue ('D') stage
10544 ;; inasmuch as we allow only two instructions to issue simultanously,
10545 ;; and CO instructions prevent any simultanous issue of another instruction.
10546 ;; (This uses pipe_01 and pipe_02).
10547 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10548 ;; Double issue of EX / BR insns is prevented by using the int unit /
10549 ;; pcr_addrcalc unit in the EX stage.
10550 ;; Double issue of BR / LS instructions is prevented by using the
10551 ;; pcr_addrcalc / load_store unit in the issue cycle.
10552 ;; Double issue of FE instructions is prevented by using F0 in the first
10553 ;; pipeline stage after the first D stage.
10554 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10555 ;; (except in the cases outlined above), nor to describe the FS stage after
10558 ;; Other MT group intructions(1 step operations)
10563 (define_insn_reservation "mt" 1
10564 (and (eq_attr "pipe_model" "sh4")
10565 (eq_attr "type" "mt_group"))
10568 ;; Fixed Point Arithmetic Instructions(1 step operations)
10573 (define_insn_reservation "sh4_simple_arith" 1
10574 (and (eq_attr "pipe_model" "sh4")
10575 (eq_attr "insn_class" "ex_group"))
10578 ;; Load and store instructions have no alignment peculiarities for the SH4,
10579 ;; but they use the load-store unit, which they share with the fmove type
10580 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10581 ;; Loads have a latency of two.
10582 ;; However, call insns can only paired with a preceding insn, and have
10583 ;; a delay slot, so that we want two more insns to be scheduled between the
10584 ;; load of the function address and the call. This is equivalent to a
10585 ;; latency of three.
10586 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10587 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10588 ;; We only do this for SImode loads of general registers, to make the work
10589 ;; for ADJUST_COST easier.
10591 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10596 (define_insn_reservation "sh4_load" 2
10597 (and (eq_attr "pipe_model" "sh4")
10598 (eq_attr "type" "load,pcload"))
10599 "issue+load_store,nothing,memory")
10601 ;; calls / sfuncs need an extra instruction for their delay slot.
10602 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10603 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10604 ;; count of a dynamic shift.
10605 (define_insn_reservation "sh4_load_si" 3
10606 (and (eq_attr "pipe_model" "sh4")
10607 (eq_attr "type" "load_si,pcload_si"))
10608 "issue+load_store,nothing,memory")
10610 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10612 ;; The load latency is upped to three higher if the dependent insn does
10613 ;; double precision computation. We want the 'default' latency to reflect
10614 ;; that increased latency because otherwise the insn priorities won't
10615 ;; allow proper scheduling.
10616 (define_insn_reservation "sh4_fload" 3
10617 (and (eq_attr "pipe_model" "sh4")
10618 (eq_attr "type" "fload,pcfload"))
10619 "issue+load_store,nothing,memory")
10621 ;; (define_bypass 2 "sh4_fload" "!")
10623 (define_insn_reservation "sh4_store" 1
10624 (and (eq_attr "pipe_model" "sh4")
10625 (eq_attr "type" "store"))
10626 "issue+load_store,nothing,memory")
10628 ;; Load Store instructions.
10633 (define_insn_reservation "sh4_gp_fpul" 1
10634 (and (eq_attr "pipe_model" "sh4")
10635 (eq_attr "type" "gp_fpul"))
10636 "issue+load_store")
10638 ;; Load Store instructions.
10643 (define_insn_reservation "sh4_fpul_gp" 3
10644 (and (eq_attr "pipe_model" "sh4")
10645 (eq_attr "type" "fpul_gp"))
10646 "issue+load_store")
10648 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10650 ;; Latency when taken: 2 (or 1)
10652 ;; The latency is 1 when displacement is 0.
10653 ;; We can't really do much with the latency, even if we could express it,
10654 ;; but the pairing restrictions are useful to take into account.
10655 ;; ??? If the branch is likely, we might want to fill the delay slot;
10656 ;; if the branch is likely, but not very likely, should we pretend to use
10657 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10659 (define_insn_reservation "sh4_branch" 1
10660 (and (eq_attr "pipe_model" "sh4")
10661 (eq_attr "type" "cbranch,jump"))
10662 "issue+pcr_addrcalc")
10664 ;; Branch Far (JMP,RTS,BRAF)
10668 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10669 ;; can't be distinguished from bra for the "jump" pattern.
10671 (define_insn_reservation "sh4_return" 3
10672 (and (eq_attr "pipe_model" "sh4")
10673 (eq_attr "type" "return,jump_ind"))
10680 ;; this instruction can be executed in any of the pipelines
10681 ;; and blocks the pipeline for next 4 stages.
10683 (define_insn_reservation "sh4_return_from_exp" 5
10684 (and (eq_attr "pipe_model" "sh4")
10685 (eq_attr "type" "rte"))
10693 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10694 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10695 (define_insn_reservation "ocbwb" 6
10696 (and (eq_attr "pipe_model" "sh4")
10697 (eq_attr "type" "cwb"))
10698 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10704 ;; The SX stage is blocked for last 2 cycles.
10705 ;; OTOH, the only time that has an effect for insns generated by the compiler
10706 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10707 ;; or when we are doing a function call - and we don't do inter-function
10708 ;; scheduling. For the function call case, it's really best that we end with
10709 ;; something that models an rts.
10711 (define_insn_reservation "sh4_lds_to_pr" 3
10712 (and (eq_attr "pipe_model" "sh4")
10713 (eq_attr "type" "prset") )
10716 ;; calls introduce a longisch delay that is likely to flush the pipelines
10717 ;; of the caller's instructions. Ordinary functions tend to end with a
10718 ;; load to restore a register (in the delay slot of rts), while sfuncs
10719 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10720 ;; since there are no instructions that contend for memory access early.
10721 ;; We could, of course, provide exact scheduling information for specific
10722 ;; sfuncs, if that should prove useful.
10724 (define_insn_reservation "sh4_call" 16
10725 (and (eq_attr "pipe_model" "sh4")
10726 (eq_attr "type" "call,sfunc"))
10733 ;; The SX unit is blocked for last 2 cycles.
10735 (define_insn_reservation "ldsmem_to_pr" 3
10736 (and (eq_attr "pipe_model" "sh4")
10737 (eq_attr "type" "pload"))
10744 ;; The SX unit in second and third cycles.
10746 (define_insn_reservation "sts_from_pr" 2
10747 (and (eq_attr "pipe_model" "sh4")
10748 (eq_attr "type" "prget"))
10756 (define_insn_reservation "sh4_prstore_mem" 2
10757 (and (eq_attr "pipe_model" "sh4")
10758 (eq_attr "type" "pstore"))
10759 "d_lock*2,nothing,memory")
10765 ;; F1 is blocked for last three cycles.
10767 (define_insn_reservation "fpscr_load" 4
10768 (and (eq_attr "pipe_model" "sh4")
10769 (eq_attr "type" "gp_fpscr"))
10770 "d_lock,nothing,F1*3")
10775 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10777 ;; F1 is blocked for last three cycles.
10779 (define_insn_reservation "fpscr_load_mem" 4
10780 (and (eq_attr "pipe_model" "sh4")
10781 (eq_attr "type" "mem_fpscr"))
10782 "d_lock,nothing,(F1+memory),F1*2")
10785 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10790 (define_insn_reservation "multi" 4
10791 (and (eq_attr "pipe_model" "sh4")
10792 (eq_attr "type" "smpy,dmpy"))
10793 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10795 ;; Fixed STS from MACL / MACH
10800 (define_insn_reservation "sh4_mac_gp" 3
10801 (and (eq_attr "pipe_model" "sh4")
10802 (eq_attr "type" "mac_gp"))
10806 ;; Single precision floating point computation FCMP/EQ,
10807 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10812 (define_insn_reservation "fp_arith" 3
10813 (and (eq_attr "pipe_model" "sh4")
10814 (eq_attr "type" "fp"))
10817 (define_insn_reservation "fp_arith_ftrc" 3
10818 (and (eq_attr "pipe_model" "sh4")
10819 (eq_attr "type" "ftrc_s"))
10822 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10824 ;; Single Precision FDIV/SQRT
10826 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10828 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10830 (define_insn_reservation "fp_div" 12
10831 (and (eq_attr "pipe_model" "sh4")
10832 (eq_attr "type" "fdiv"))
10833 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10835 ;; Double Precision floating point computation
10836 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10838 ;; Latency: (3,4)/5
10841 (define_insn_reservation "dp_float" 4
10842 (and (eq_attr "pipe_model" "sh4")
10843 (eq_attr "type" "dfp_conv"))
10844 "issue,F01,F1+F2,F2")
10846 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10848 ;; Latency: (7,8)/9
10851 (define_insn_reservation "fp_double_arith" 8
10852 (and (eq_attr "pipe_model" "sh4")
10853 (eq_attr "type" "dfp_arith"))
10854 "issue,F01,F1+F2,fpu*4,F2")
10856 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10861 (define_insn_reservation "fp_double_cmp" 3
10862 (and (eq_attr "pipe_model" "sh4")
10863 (eq_attr "type" "dfp_cmp"))
10864 "d_lock,(d_lock+F01),F1+F2,F2")
10866 ;; Double precision FDIV/SQRT
10868 ;; Latency: (24,25)/26
10871 (define_insn_reservation "dp_div" 25
10872 (and (eq_attr "pipe_model" "sh4")
10873 (eq_attr "type" "dfdiv"))
10874 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10877 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10878 ;; case, we'd get a d_lock instead of issue at the end.
10879 (define_insn_reservation "arith3" 3
10880 (and (eq_attr "pipe_model" "sh4")
10881 (eq_attr "type" "arith3"))
10882 "issue,d_lock+pcr_addrcalc,issue")
10884 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10885 (define_insn_reservation "arith3b" 2
10886 (and (eq_attr "pipe_model" "sh4")
10887 (eq_attr "type" "arith3"))
10888 "issue,d_lock+pcr_addrcalc")