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 ;; -------------------------------------------------------------------------
2043 ;; Shifts and rotates
2044 ;; -------------------------------------------------------------------------
2046 (define_expand "rotldi3"
2047 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2048 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2049 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2051 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2053 (define_insn "rotldi3_mextr"
2054 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2055 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2056 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2060 static char templ[16];
2062 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2063 8 - (int) (INTVAL (operands[2]) >> 3));
2066 [(set_attr "type" "arith_media")])
2068 (define_expand "rotrdi3"
2069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2070 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2071 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2073 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2075 (define_insn "rotrdi3_mextr"
2076 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2077 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2078 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2082 static char templ[16];
2084 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2087 [(set_attr "type" "arith_media")])
2089 (define_insn "rotlsi3_1"
2090 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2094 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2097 [(set_attr "type" "arith")])
2099 (define_insn "rotlsi3_31"
2100 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2101 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2103 (clobber (reg:SI T_REG))]
2106 [(set_attr "type" "arith")])
2108 (define_insn "rotlsi3_16"
2109 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2110 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2114 [(set_attr "type" "arith")])
2116 (define_expand "rotlsi3"
2117 [(set (match_operand:SI 0 "arith_reg_operand" "")
2118 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2119 (match_operand:SI 2 "immediate_operand" "")))]
2123 static const char rot_tab[] = {
2124 000, 000, 000, 000, 000, 000, 010, 001,
2125 001, 001, 011, 013, 003, 003, 003, 003,
2126 003, 003, 003, 003, 003, 013, 012, 002,
2127 002, 002, 010, 000, 000, 000, 000, 000,
2132 if (GET_CODE (operands[2]) != CONST_INT)
2134 count = INTVAL (operands[2]);
2135 choice = rot_tab[count];
2136 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2142 emit_move_insn (operands[0], operands[1]);
2143 count -= (count & 16) * 2;
2146 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2153 parts[0] = gen_reg_rtx (SImode);
2154 parts[1] = gen_reg_rtx (SImode);
2155 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2156 parts[choice-1] = operands[1];
2157 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2158 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2159 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2160 count = (count & ~16) - 8;
2164 for (; count > 0; count--)
2165 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2166 for (; count < 0; count++)
2167 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2172 (define_insn "*rotlhi3_8"
2173 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2174 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2178 [(set_attr "type" "arith")])
2180 (define_expand "rotlhi3"
2181 [(set (match_operand:HI 0 "arith_reg_operand" "")
2182 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2183 (match_operand:HI 2 "immediate_operand" "")))]
2187 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2194 ;; This pattern is used by init_expmed for computing the costs of shift
2197 (define_insn_and_split "ashlsi3_std"
2198 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2199 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2200 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2201 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2203 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2204 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2212 && GET_CODE (operands[2]) == CONST_INT
2213 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2214 [(set (match_dup 3) (match_dup 2))
2216 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2217 (clobber (match_dup 4))])]
2218 "operands[4] = gen_rtx_SCRATCH (SImode);"
2219 [(set_attr "length" "*,*,*,4")
2220 (set_attr "type" "dyn_shift,arith,arith,arith")])
2222 (define_insn "ashlhi3_k"
2223 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2224 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2225 (match_operand:HI 2 "const_int_operand" "M,K")))]
2226 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2230 [(set_attr "type" "arith")])
2232 (define_insn "ashlsi3_n"
2233 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2234 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2235 (match_operand:SI 2 "const_int_operand" "n")))
2236 (clobber (reg:SI T_REG))]
2237 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2239 [(set (attr "length")
2240 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2242 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2244 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2246 (const_string "8")))
2247 (set_attr "type" "arith")])
2250 [(set (match_operand:SI 0 "arith_reg_operand" "")
2251 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2252 (match_operand:SI 2 "const_int_operand" "")))
2253 (clobber (reg:SI T_REG))]
2254 "TARGET_SH1 && reload_completed"
2255 [(use (reg:SI R0_REG))]
2258 gen_shifty_op (ASHIFT, operands);
2262 (define_insn "ashlsi3_media"
2263 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2264 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2265 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2270 [(set_attr "type" "arith_media")])
2272 (define_expand "ashlsi3"
2273 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2274 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2275 (match_operand:SI 2 "nonmemory_operand" "")))
2276 (clobber (reg:SI T_REG))])]
2282 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2285 if (GET_CODE (operands[2]) == CONST_INT
2286 && sh_dynamicalize_shift_p (operands[2]))
2287 operands[2] = force_reg (SImode, operands[2]);
2290 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2293 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2297 (define_insn "ashlhi3"
2298 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2299 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2300 (match_operand:HI 2 "const_int_operand" "n")))
2301 (clobber (reg:SI T_REG))]
2304 [(set (attr "length")
2305 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2307 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2309 (const_string "6")))
2310 (set_attr "type" "arith")])
2313 [(set (match_operand:HI 0 "arith_reg_operand" "")
2314 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2315 (match_operand:HI 2 "const_int_operand" "")))
2316 (clobber (reg:SI T_REG))]
2317 "TARGET_SH1 && reload_completed"
2318 [(use (reg:SI R0_REG))]
2321 gen_shifty_hi_op (ASHIFT, operands);
2326 ; arithmetic shift right
2329 (define_insn "ashrsi3_k"
2330 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2331 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2332 (match_operand:SI 2 "const_int_operand" "M")))
2333 (clobber (reg:SI T_REG))]
2334 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2336 [(set_attr "type" "arith")])
2338 ;; We can't do HImode right shifts correctly unless we start out with an
2339 ;; explicit zero / sign extension; doing that would result in worse overall
2340 ;; code, so just let the machine independent code widen the mode.
2341 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2344 ;; ??? This should be a define expand.
2346 (define_insn "ashrsi2_16"
2347 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2348 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2352 [(set_attr "length" "4")])
2355 [(set (match_operand:SI 0 "arith_reg_operand" "")
2356 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2359 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2360 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2361 "operands[2] = gen_lowpart (HImode, operands[0]);")
2363 ;; ??? This should be a define expand.
2365 (define_insn "ashrsi2_31"
2366 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2369 (clobber (reg:SI T_REG))]
2372 [(set_attr "length" "4")])
2375 [(set (match_operand:SI 0 "arith_reg_operand" "")
2376 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2378 (clobber (reg:SI T_REG))]
2383 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2384 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2388 (define_insn "ashlsi_c"
2389 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2390 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2392 (lt:SI (match_dup 1) (const_int 0)))]
2395 [(set_attr "type" "arith")])
2397 (define_insn "ashrsi3_d"
2398 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2399 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2400 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2403 [(set_attr "type" "dyn_shift")])
2405 (define_insn "ashrsi3_n"
2406 [(set (reg:SI R4_REG)
2407 (ashiftrt:SI (reg:SI R4_REG)
2408 (match_operand:SI 0 "const_int_operand" "i")))
2409 (clobber (reg:SI T_REG))
2410 (clobber (reg:SI PR_REG))
2411 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2414 [(set_attr "type" "sfunc")
2415 (set_attr "needs_delay_slot" "yes")])
2417 (define_insn "ashrsi3_media"
2418 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2419 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2420 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2425 [(set_attr "type" "arith_media")])
2427 (define_expand "ashrsi3"
2428 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2429 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2430 (match_operand:SI 2 "nonmemory_operand" "")))
2431 (clobber (reg:SI T_REG))])]
2437 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2440 if (expand_ashiftrt (operands))
2446 ;; logical shift right
2448 (define_insn "lshrsi3_d"
2449 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2450 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2451 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2454 [(set_attr "type" "dyn_shift")])
2456 ;; Only the single bit shift clobbers the T bit.
2458 (define_insn "lshrsi3_m"
2459 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2460 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2461 (match_operand:SI 2 "const_int_operand" "M")))
2462 (clobber (reg:SI T_REG))]
2463 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2465 [(set_attr "type" "arith")])
2467 (define_insn "lshrsi3_k"
2468 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2469 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2470 (match_operand:SI 2 "const_int_operand" "K")))]
2471 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2472 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2474 [(set_attr "type" "arith")])
2476 (define_insn "lshrsi3_n"
2477 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2479 (match_operand:SI 2 "const_int_operand" "n")))
2480 (clobber (reg:SI T_REG))]
2481 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2483 [(set (attr "length")
2484 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2486 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2488 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2490 (const_string "8")))
2491 (set_attr "type" "arith")])
2494 [(set (match_operand:SI 0 "arith_reg_operand" "")
2495 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2496 (match_operand:SI 2 "const_int_operand" "")))
2497 (clobber (reg:SI T_REG))]
2498 "TARGET_SH1 && reload_completed"
2499 [(use (reg:SI R0_REG))]
2502 gen_shifty_op (LSHIFTRT, operands);
2506 (define_insn "lshrsi3_media"
2507 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2508 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2509 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2514 [(set_attr "type" "arith_media")])
2516 (define_expand "lshrsi3"
2517 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2518 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2519 (match_operand:SI 2 "nonmemory_operand" "")))
2520 (clobber (reg:SI T_REG))])]
2526 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2529 if (GET_CODE (operands[2]) == CONST_INT
2530 && sh_dynamicalize_shift_p (operands[2]))
2531 operands[2] = force_reg (SImode, operands[2]);
2532 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2534 rtx count = copy_to_mode_reg (SImode, operands[2]);
2535 emit_insn (gen_negsi2 (count, count));
2536 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2539 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2543 ;; ??? This should be a define expand.
2545 (define_insn "ashldi3_k"
2546 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2547 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2549 (clobber (reg:SI T_REG))]
2551 "shll %R0\;rotcl %S0"
2552 [(set_attr "length" "4")
2553 (set_attr "type" "arith")])
2555 (define_insn "ashldi3_media"
2556 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2557 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2558 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2563 [(set_attr "type" "arith_media")])
2565 (define_expand "ashldi3"
2566 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2567 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2568 (match_operand:DI 2 "immediate_operand" "")))
2569 (clobber (reg:SI T_REG))])]
2575 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2578 if (GET_CODE (operands[2]) != CONST_INT
2579 || INTVAL (operands[2]) != 1)
2583 ;; ??? This should be a define expand.
2585 (define_insn "lshrdi3_k"
2586 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2587 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2589 (clobber (reg:SI T_REG))]
2591 "shlr %S0\;rotcr %R0"
2592 [(set_attr "length" "4")
2593 (set_attr "type" "arith")])
2595 (define_insn "lshrdi3_media"
2596 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2597 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2598 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2603 [(set_attr "type" "arith_media")])
2605 (define_expand "lshrdi3"
2606 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2607 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2608 (match_operand:DI 2 "immediate_operand" "")))
2609 (clobber (reg:SI T_REG))])]
2615 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2618 if (GET_CODE (operands[2]) != CONST_INT
2619 || INTVAL (operands[2]) != 1)
2623 ;; ??? This should be a define expand.
2625 (define_insn "ashrdi3_k"
2626 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2627 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2629 (clobber (reg:SI T_REG))]
2631 "shar %S0\;rotcr %R0"
2632 [(set_attr "length" "4")
2633 (set_attr "type" "arith")])
2635 (define_insn "ashrdi3_media"
2636 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2637 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2638 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2643 [(set_attr "type" "arith_media")])
2645 (define_expand "ashrdi3"
2646 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2647 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2648 (match_operand:DI 2 "immediate_operand" "")))
2649 (clobber (reg:SI T_REG))])]
2655 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2658 if (GET_CODE (operands[2]) != CONST_INT
2659 || INTVAL (operands[2]) != 1)
2663 ;; combined left/right shift
2666 [(set (match_operand:SI 0 "register_operand" "")
2667 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2668 (match_operand:SI 2 "const_int_operand" ""))
2669 (match_operand:SI 3 "const_int_operand" "")))]
2670 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2671 [(use (reg:SI R0_REG))]
2672 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2676 [(set (match_operand:SI 0 "register_operand" "")
2677 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2678 (match_operand:SI 2 "const_int_operand" ""))
2679 (match_operand:SI 3 "const_int_operand" "")))
2680 (clobber (reg:SI T_REG))]
2681 "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2682 [(use (reg:SI R0_REG))]
2683 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2687 [(set (match_operand:SI 0 "register_operand" "=r")
2688 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2689 (match_operand:SI 2 "const_int_operand" "n"))
2690 (match_operand:SI 3 "const_int_operand" "n")))
2691 (clobber (reg:SI T_REG))]
2692 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2694 [(set (attr "length")
2695 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2697 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2699 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2701 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2703 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2705 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2707 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2708 (const_string "16")]
2709 (const_string "18")))
2710 (set_attr "type" "arith")])
2713 [(set (match_operand:SI 0 "register_operand" "=z")
2714 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2715 (match_operand:SI 2 "const_int_operand" "n"))
2716 (match_operand:SI 3 "const_int_operand" "n")))
2717 (clobber (reg:SI T_REG))]
2718 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2720 [(set (attr "length")
2721 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2723 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2727 (const_string "10")))
2728 (set_attr "type" "arith")])
2730 ;; shift left / and combination with a scratch register: The combine pass
2731 ;; does not accept the individual instructions, even though they are
2732 ;; cheap. But it needs a precise description so that it is usable after
2734 (define_insn "and_shl_scratch"
2735 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2739 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2740 (match_operand:SI 2 "const_int_operand" "N,n"))
2741 (match_operand:SI 3 "" "0,r"))
2742 (match_operand:SI 4 "const_int_operand" "n,n"))
2743 (match_operand:SI 5 "const_int_operand" "n,n")))
2744 (clobber (reg:SI T_REG))]
2747 [(set (attr "length")
2748 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2750 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2752 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2754 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2755 (const_string "10")]
2756 (const_string "12")))
2757 (set_attr "type" "arith")])
2760 [(set (match_operand:SI 0 "register_operand" "")
2764 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2765 (match_operand:SI 2 "const_int_operand" ""))
2766 (match_operand:SI 3 "register_operand" ""))
2767 (match_operand:SI 4 "const_int_operand" ""))
2768 (match_operand:SI 5 "const_int_operand" "")))
2769 (clobber (reg:SI T_REG))]
2771 [(use (reg:SI R0_REG))]
2774 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2776 if (INTVAL (operands[2]))
2778 gen_shifty_op (LSHIFTRT, operands);
2780 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2781 operands[2] = operands[4];
2782 gen_shifty_op (ASHIFT, operands);
2783 if (INTVAL (operands[5]))
2785 operands[2] = operands[5];
2786 gen_shifty_op (LSHIFTRT, operands);
2791 ;; signed left/right shift combination.
2793 [(set (match_operand:SI 0 "register_operand" "")
2795 (ashift:SI (match_operand:SI 1 "register_operand" "")
2796 (match_operand:SI 2 "const_int_operand" ""))
2797 (match_operand:SI 3 "const_int_operand" "")
2799 (clobber (reg:SI T_REG))]
2801 [(use (reg:SI R0_REG))]
2802 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2805 (define_insn "shl_sext_ext"
2806 [(set (match_operand:SI 0 "register_operand" "=r")
2808 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2809 (match_operand:SI 2 "const_int_operand" "n"))
2810 (match_operand:SI 3 "const_int_operand" "n")
2812 (clobber (reg:SI T_REG))]
2813 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2815 [(set (attr "length")
2816 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2818 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2820 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2822 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2824 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2826 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2828 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2830 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2831 (const_string "16")]
2832 (const_string "18")))
2833 (set_attr "type" "arith")])
2835 (define_insn "shl_sext_sub"
2836 [(set (match_operand:SI 0 "register_operand" "=z")
2838 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2839 (match_operand:SI 2 "const_int_operand" "n"))
2840 (match_operand:SI 3 "const_int_operand" "n")
2842 (clobber (reg:SI T_REG))]
2843 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2845 [(set (attr "length")
2846 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2853 (const_string "12")]
2854 (const_string "14")))
2855 (set_attr "type" "arith")])
2857 ;; These patterns are found in expansions of DImode shifts by 16, and
2858 ;; allow the xtrct instruction to be generated from C source.
2860 (define_insn "xtrct_left"
2861 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2862 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2864 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2868 [(set_attr "type" "arith")])
2870 (define_insn "xtrct_right"
2871 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2872 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2874 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2878 [(set_attr "type" "arith")])
2880 ;; -------------------------------------------------------------------------
2882 ;; -------------------------------------------------------------------------
2885 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2886 (neg:SI (plus:SI (reg:SI T_REG)
2887 (match_operand:SI 1 "arith_reg_operand" "r"))))
2889 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2893 [(set_attr "type" "arith")])
2895 (define_insn "*negdi_media"
2896 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2897 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2900 [(set_attr "type" "arith_media")])
2902 (define_expand "negdi2"
2903 [(set (match_operand:DI 0 "arith_reg_operand" "")
2904 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2910 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2911 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2913 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2914 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2916 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2917 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2919 emit_insn (gen_clrt ());
2920 emit_insn (gen_negc (low_dst, low_src));
2921 emit_insn (gen_negc (high_dst, high_src));
2926 (define_insn "negsi2"
2927 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2928 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2931 [(set_attr "type" "arith")])
2933 (define_insn "one_cmplsi2"
2934 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2935 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2938 [(set_attr "type" "arith")])
2940 (define_expand "one_cmpldi2"
2941 [(set (match_operand:DI 0 "arith_reg_operand" "")
2942 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2944 "TARGET_SHMEDIA" "")
2946 ;; -------------------------------------------------------------------------
2947 ;; Zero extension instructions
2948 ;; -------------------------------------------------------------------------
2950 (define_insn "zero_extendsidi2"
2951 [(set (match_operand:DI 0 "register_operand" "=r")
2952 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2954 "addz.l %1, r63, %0"
2955 [(set_attr "type" "arith_media")])
2957 (define_insn "zero_extendhidi2"
2958 [(set (match_operand:DI 0 "register_operand" "=r,r")
2959 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2964 [(set_attr "type" "*,load_media")])
2967 [(set (match_operand:DI 0 "register_operand" "")
2968 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2969 "TARGET_SHMEDIA && reload_completed"
2970 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2971 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2974 if (GET_CODE (operands[1]) == TRUNCATE)
2975 operands[1] = XEXP (operands[1], 0);
2978 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
2979 ;; reload the entrire truncate expression.
2980 (define_insn_and_split "*loaddi_trunc"
2981 [(set (match_operand 0 "int_gpr_dest" "=r")
2982 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2983 "TARGET_SHMEDIA && reload_completed"
2985 "TARGET_SHMEDIA && reload_completed"
2986 [(set (match_dup 0) (match_dup 1))]
2987 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
2989 (define_insn "zero_extendqidi2"
2990 [(set (match_operand:DI 0 "register_operand" "=r,r")
2991 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
2996 [(set_attr "type" "arith_media,load_media")])
2998 (define_expand "zero_extendhisi2"
2999 [(set (match_operand:SI 0 "arith_reg_operand" "")
3000 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3004 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3005 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3008 (define_insn "*zero_extendhisi2_compact"
3009 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3010 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3013 [(set_attr "type" "arith")])
3015 (define_insn "*zero_extendhisi2_media"
3016 [(set (match_operand:SI 0 "register_operand" "=r,r")
3017 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3022 [(set_attr "type" "arith_media,load_media")])
3025 [(set (match_operand:SI 0 "register_operand" "")
3026 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3027 "TARGET_SHMEDIA && reload_completed"
3028 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3029 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3032 if (GET_CODE (operands[1]) == TRUNCATE)
3033 operands[1] = XEXP (operands[1], 0);
3036 (define_expand "zero_extendqisi2"
3037 [(set (match_operand:SI 0 "arith_reg_operand" "")
3038 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3042 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3043 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3046 (define_insn "*zero_extendqisi2_compact"
3047 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3048 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3051 [(set_attr "type" "arith")])
3053 (define_insn "*zero_extendqisi2_media"
3054 [(set (match_operand:SI 0 "register_operand" "=r,r")
3055 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3060 [(set_attr "type" "arith_media,load_media")])
3062 (define_insn "zero_extendqihi2"
3063 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3064 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3067 [(set_attr "type" "arith")])
3069 ;; -------------------------------------------------------------------------
3070 ;; Sign extension instructions
3071 ;; -------------------------------------------------------------------------
3073 ;; ??? This should be a define expand.
3074 ;; ??? Or perhaps it should be dropped?
3076 ;; convert_move generates good code for SH[1-4].
3077 (define_insn "extendsidi2"
3078 [(set (match_operand:DI 0 "register_operand" "=r,r")
3079 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3084 [(set_attr "type" "arith_media,load_media")])
3086 (define_insn "extendhidi2"
3087 [(set (match_operand:DI 0 "register_operand" "=r,r")
3088 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3093 [(set_attr "type" "*,load_media")])
3096 [(set (match_operand:DI 0 "register_operand" "")
3097 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3098 "TARGET_SHMEDIA && reload_completed"
3099 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3100 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3103 if (GET_CODE (operands[1]) == TRUNCATE)
3104 operands[1] = XEXP (operands[1], 0);
3107 (define_insn "extendqidi2"
3108 [(set (match_operand:DI 0 "register_operand" "=r,r")
3109 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3114 [(set_attr "type" "*,load_media")])
3117 [(set (match_operand:DI 0 "register_operand" "")
3118 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3119 "TARGET_SHMEDIA && reload_completed"
3120 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3121 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3124 if (GET_CODE (operands[1]) == TRUNCATE)
3125 operands[1] = XEXP (operands[1], 0);
3128 (define_expand "extendhisi2"
3129 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3130 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3134 (define_insn "*extendhisi2_compact"
3135 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3136 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3141 [(set_attr "type" "arith,load")])
3143 (define_insn "*extendhisi2_media"
3144 [(set (match_operand:SI 0 "register_operand" "=r,r")
3145 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3150 [(set_attr "type" "arith_media,load_media")])
3153 [(set (match_operand:SI 0 "register_operand" "")
3154 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3155 "TARGET_SHMEDIA && reload_completed"
3156 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3157 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3160 if (GET_CODE (operands[1]) == TRUNCATE)
3161 operands[1] = XEXP (operands[1], 0);
3164 (define_expand "extendqisi2"
3165 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3166 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3170 (define_insn "*extendqisi2_compact"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3177 [(set_attr "type" "arith,load")])
3179 (define_insn "*extendqisi2_media"
3180 [(set (match_operand:SI 0 "register_operand" "=r,r")
3181 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3186 [(set_attr "type" "arith_media,load_media")])
3189 [(set (match_operand:SI 0 "register_operand" "")
3190 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3191 "TARGET_SHMEDIA && reload_completed"
3192 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3193 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3196 if (GET_CODE (operands[1]) == TRUNCATE)
3197 operands[1] = XEXP (operands[1], 0);
3200 (define_insn "extendqihi2"
3201 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3202 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3207 [(set_attr "type" "arith,load")])
3209 /* It would seem useful to combine the truncXi patterns into the movXi
3210 patterns, but unary operators are ignored when matching constraints,
3211 so we need separate patterns. */
3212 (define_insn "truncdisi2"
3213 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3214 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3223 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3226 (define_insn "truncdihi2"
3227 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3228 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3231 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3233 [(set_attr "type" "arith_media,store_media")
3234 (set_attr "length" "8,4")])
3236 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3237 ; Because we use zero extension, we can't provide signed QImode compares
3238 ; using a simple compare or conditional banch insn.
3239 (define_insn "truncdiqi2"
3240 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3241 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3246 [(set_attr "type" "arith_media,store")])
3248 ;; -------------------------------------------------------------------------
3249 ;; Move instructions
3250 ;; -------------------------------------------------------------------------
3252 ;; define push and pop so it is easy for sh.c
3253 ;; We can't use push and pop on SHcompact because the stack must always
3254 ;; be 8-byte aligned.
3256 (define_expand "push"
3257 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3258 (match_operand:SI 0 "register_operand" "r,l,x"))]
3259 "TARGET_SH1 && ! TARGET_SH5"
3262 (define_expand "pop"
3263 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3264 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3265 "TARGET_SH1 && ! TARGET_SH5"
3268 (define_expand "push_e"
3269 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3270 (match_operand:SF 0 "" ""))
3271 (use (reg:PSI FPSCR_REG))
3272 (clobber (scratch:SI))])]
3273 "TARGET_SH1 && ! TARGET_SH5"
3276 (define_insn "push_fpul"
3277 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3278 "TARGET_SH3E && ! TARGET_SH5"
3280 [(set_attr "type" "store")
3281 (set_attr "late_fp_use" "yes")
3282 (set_attr "hit_stack" "yes")])
3284 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3286 (define_expand "push_4"
3287 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3288 (match_operand:DF 0 "" ""))
3289 (use (reg:PSI FPSCR_REG))
3290 (clobber (scratch:SI))])]
3291 "TARGET_SH1 && ! TARGET_SH5"
3294 (define_expand "pop_e"
3295 [(parallel [(set (match_operand:SF 0 "" "")
3296 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3297 (use (reg:PSI FPSCR_REG))
3298 (clobber (scratch:SI))])]
3299 "TARGET_SH1 && ! TARGET_SH5"
3302 (define_insn "pop_fpul"
3303 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3304 "TARGET_SH3E && ! TARGET_SH5"
3306 [(set_attr "type" "load")
3307 (set_attr "hit_stack" "yes")])
3309 (define_expand "pop_4"
3310 [(parallel [(set (match_operand:DF 0 "" "")
3311 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3312 (use (reg:PSI FPSCR_REG))
3313 (clobber (scratch:SI))])]
3314 "TARGET_SH1 && ! TARGET_SH5"
3317 ;; These two patterns can happen as the result of optimization, when
3318 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3319 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3322 [(set (reg:SI T_REG) (const_int 0))]
3327 [(set (reg:SI T_REG) (const_int 1))]
3331 ;; t/r must come after r/r, lest reload will try to reload stuff like
3332 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3333 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3334 (define_insn "movsi_i"
3335 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3336 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3339 && (register_operand (operands[0], SImode)
3340 || register_operand (operands[1], SImode))"
3357 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3358 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3360 ;; t/r must come after r/r, lest reload will try to reload stuff like
3361 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3362 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3363 ;; will require a reload.
3364 (define_insn "movsi_ie"
3365 [(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")
3366 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3368 && (register_operand (operands[0], SImode)
3369 || register_operand (operands[1], SImode))"
3390 ! move optimized away"
3391 [(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")
3392 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
3393 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3395 (define_insn "movsi_i_lowpart"
3396 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3397 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3399 && (register_operand (operands[0], SImode)
3400 || register_operand (operands[1], SImode))"
3410 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3412 (define_insn "*movsi_media"
3413 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3414 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3416 && (register_operand (operands[0], SImode)
3417 || register_operand (operands[1], SImode))"
3432 [(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")
3433 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3435 (define_insn "*movsi_media_nofpu"
3436 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3437 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3439 && (register_operand (operands[0], SImode)
3440 || register_operand (operands[1], SImode))"
3450 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3451 (set_attr "length" "4,4,8,4,4,4,4,12")])
3454 [(set (match_operand:SI 0 "arith_reg_operand" "")
3455 (match_operand:SI 1 "immediate_operand" ""))]
3456 "TARGET_SHMEDIA && reload_completed
3457 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3458 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3461 operands[2] = shallow_copy_rtx (operands[1]);
3462 PUT_MODE (operands[2], DImode);
3466 [(set (match_operand:SI 0 "register_operand" "")
3467 (match_operand:SI 1 "immediate_operand" ""))]
3468 "TARGET_SHMEDIA && reload_completed
3469 && ((GET_CODE (operands[1]) == CONST_INT
3470 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3471 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3472 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3474 (define_expand "movsi"
3475 [(set (match_operand:SI 0 "general_movdst_operand" "")
3476 (match_operand:SI 1 "general_movsrc_operand" ""))]
3478 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3480 (define_expand "ic_invalidate_line"
3481 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3482 (match_dup 1)] UNSPEC_ICACHE)
3483 (clobber (scratch:SI))])]
3484 "TARGET_HARD_SH4 || TARGET_SH5"
3489 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3492 else if (TARGET_SHCOMPACT)
3494 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3495 operands[1] = force_reg (Pmode, operands[1]);
3496 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3499 operands[0] = force_reg (Pmode, operands[0]);
3500 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3504 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3505 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3506 ;; the requirement *1*00 for associative address writes. The alignment of
3507 ;; %0 implies that its least significant bit is cleared,
3508 ;; thus we clear the V bit of a matching entry if there is one.
3509 (define_insn "ic_invalidate_line_i"
3510 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3511 (match_operand:SI 1 "register_operand" "r")]
3513 (clobber (match_scratch:SI 2 "=&r"))]
3515 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3516 [(set_attr "length" "8")
3517 (set_attr "type" "cwb")])
3519 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3520 ;; an add in the code that calculates the address.
3521 (define_insn "ic_invalidate_line_media"
3522 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3525 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3526 [(set_attr "length" "16")
3527 (set_attr "type" "invalidate_line_media")])
3529 (define_insn "ic_invalidate_line_compact"
3530 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3531 (match_operand:SI 1 "register_operand" "r")]
3533 (clobber (reg:SI PR_REG))]
3536 [(set_attr "type" "sfunc")
3537 (set_attr "needs_delay_slot" "yes")])
3539 (define_expand "initialize_trampoline"
3540 [(match_operand:SI 0 "" "")
3541 (match_operand:SI 1 "" "")
3542 (match_operand:SI 2 "" "")]
3548 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3549 tramp = gen_rtx_REG (SImode, R0_REG);
3550 emit_move_insn (tramp, operands[0]);
3551 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3552 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3554 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3558 (define_insn "initialize_trampoline_compact"
3559 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3560 (match_operand:SI 1 "register_operand" "r")
3561 (reg:SI R2_REG) (reg:SI R3_REG)]
3564 (clobber (reg:SI PR_REG))]
3567 [(set_attr "type" "sfunc")
3568 (set_attr "needs_delay_slot" "yes")])
3570 (define_insn "movqi_i"
3571 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3572 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3574 && (arith_reg_operand (operands[0], QImode)
3575 || arith_reg_operand (operands[1], QImode))"
3583 [(set_attr "type" "move,load,store,move,move,move")])
3585 (define_insn "*movqi_media"
3586 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3587 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3589 && (arith_reg_operand (operands[0], QImode)
3590 || arith_reg_operand (operands[1], QImode))"
3596 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3598 (define_expand "movqi"
3599 [(set (match_operand:QI 0 "general_operand" "")
3600 (match_operand:QI 1 "general_operand" ""))]
3602 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3604 (define_expand "reload_inqi"
3605 [(set (match_operand:SI 2 "" "=&r")
3606 (match_operand:QI 1 "inqhi_operand" ""))
3607 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3608 (truncate:HI (match_dup 3)))]
3612 rtx inner = XEXP (operands[1], 0);
3613 int regno = REGNO (inner);
3615 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3616 operands[1] = gen_rtx_REG (SImode, regno);
3617 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3620 (define_insn "movhi_i"
3621 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3622 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3624 && (arith_reg_operand (operands[0], HImode)
3625 || arith_reg_operand (operands[1], HImode))"
3635 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3637 (define_insn "*movhi_media"
3638 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3639 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3641 && (arith_reg_operand (operands[0], HImode)
3642 || arith_reg_operand (operands[1], HImode))"
3649 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3652 [(set (match_operand:HI 0 "register_operand" "")
3653 (match_operand:HI 1 "immediate_operand" ""))]
3654 "TARGET_SHMEDIA && reload_completed
3655 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3656 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3658 (define_expand "movhi"
3659 [(set (match_operand:HI 0 "general_movdst_operand" "")
3660 (match_operand:HI 1 "general_movsrc_operand" ""))]
3662 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3664 (define_expand "reload_inhi"
3665 [(set (match_operand:SI 2 "" "=&r")
3666 (match_operand:HI 1 "inqhi_operand" ""))
3667 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3668 (truncate:HI (match_dup 3)))]
3672 rtx inner = XEXP (operands[1], 0);
3673 int regno = REGNO (inner);
3675 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3676 operands[1] = gen_rtx_REG (SImode, regno);
3677 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3680 ;; ??? This should be a define expand.
3682 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3683 ;; compiled with -m2 -ml -O3 -funroll-loops
3685 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3686 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3688 && (arith_reg_operand (operands[0], DImode)
3689 || arith_reg_operand (operands[1], DImode))"
3690 "* return output_movedouble (insn, operands, DImode);"
3691 [(set_attr "length" "4")
3692 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3694 ;; If the output is a register and the input is memory or a register, we have
3695 ;; to be careful and see which word needs to be loaded first.
3698 [(set (match_operand:DI 0 "general_movdst_operand" "")
3699 (match_operand:DI 1 "general_movsrc_operand" ""))]
3700 "TARGET_SH1 && reload_completed"
3701 [(set (match_dup 2) (match_dup 3))
3702 (set (match_dup 4) (match_dup 5))]
3707 if ((GET_CODE (operands[0]) == MEM
3708 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3709 || (GET_CODE (operands[1]) == MEM
3710 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3713 if (GET_CODE (operands[0]) == REG)
3714 regno = REGNO (operands[0]);
3715 else if (GET_CODE (operands[0]) == SUBREG)
3716 regno = subreg_regno (operands[0]);
3717 else if (GET_CODE (operands[0]) == MEM)
3723 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3725 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3726 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3727 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3728 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3732 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3733 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3734 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3735 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3738 if (operands[2] == 0 || operands[3] == 0
3739 || operands[4] == 0 || operands[5] == 0)
3743 (define_insn "*movdi_media"
3744 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3745 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3747 && (register_operand (operands[0], DImode)
3748 || register_operand (operands[1], DImode))"
3763 [(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")
3764 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3766 (define_insn "*movdi_media_nofpu"
3767 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3768 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3770 && (register_operand (operands[0], DImode)
3771 || register_operand (operands[1], DImode))"
3781 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3782 (set_attr "length" "4,4,16,4,4,4,4,*")])
3785 [(set (match_operand:DI 0 "arith_reg_operand" "")
3786 (match_operand:DI 1 "immediate_operand" ""))]
3787 "TARGET_SHMEDIA && reload_completed
3788 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3789 [(set (match_dup 0) (match_dup 1))]
3794 if (TARGET_SHMEDIA64)
3795 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3797 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3799 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3805 (define_expand "movdi_const"
3806 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3807 (const:DI (sign_extend:DI
3810 (match_operand:DI 1 "immediate_operand" "s")
3813 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3821 (const_int 32)))))))))
3823 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3831 (const_int 16)))))))))
3833 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3839 (match_dup 1))))))))]
3840 "TARGET_SHMEDIA64 && reload_completed
3841 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3844 if (GET_CODE (operands[1]) == LABEL_REF
3845 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3846 LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3847 else if (GOTOFF_P (operands[1])
3848 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3849 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3851 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3854 (define_expand "movdi_const_32bit"
3855 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3856 (const:DI (sign_extend:DI
3859 (match_operand:DI 1 "immediate_operand" "s")
3862 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3868 (match_dup 1))))))))]
3869 "TARGET_SHMEDIA32 && reload_completed
3870 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3873 if (GET_CODE (operands[1]) == LABEL_REF
3874 && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3875 LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3876 else if (GOTOFF_P (operands[1])
3877 && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3878 && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3880 LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3883 (define_expand "movdi_const_16bit"
3884 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3885 (const:DI (sign_extend:DI
3887 (match_operand:DI 1 "immediate_operand" "s")))))]
3888 "TARGET_SHMEDIA && flag_pic && reload_completed
3889 && GET_CODE (operands[1]) == SYMBOL_REF"
3893 [(set (match_operand:DI 0 "arith_reg_operand" "")
3894 (match_operand:DI 1 "immediate_operand" ""))]
3895 "TARGET_SHMEDIA && reload_completed
3896 && GET_CODE (operands[1]) == CONST_INT
3897 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3898 [(set (match_dup 0) (match_dup 2))
3902 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3903 unsigned HOST_WIDE_INT low = val;
3904 unsigned HOST_WIDE_INT high = val;
3905 unsigned HOST_WIDE_INT sign;
3906 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3908 /* Sign-extend the 16 least-significant bits. */
3913 /* Arithmetic shift right the word by 16 bits. */
3916 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3921 /* If we can't generate the constant with a two-insn movi / shori
3922 sequence, try some other strategies. */
3923 if (! CONST_OK_FOR_J (high))
3925 /* Try constant load / left shift. We know VAL != 0. */
3926 val2 = val ^ (val-1);
3929 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3931 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3932 || (! CONST_OK_FOR_J (high >> 16)
3933 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3935 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3936 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3937 GEN_INT (trailing_zeroes));
3941 /* Try constant load / right shift. */
3942 val2 = (val >> 15) + 1;
3943 if (val2 == (val2 & -val2))
3945 int shift = 49 - exact_log2 (val2);
3947 val2 = trunc_int_for_mode (val << shift, DImode);
3948 if (CONST_OK_FOR_J (val2))
3950 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3956 val2 = val & 0xffff;
3957 if ((val >> 16 & 0xffff) == val2
3958 && (val >> 32 & 0xffff) == val2
3959 && (val >> 48 & 0xffff) == val2)
3961 val2 = (HOST_WIDE_INT) val >> 48;
3962 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3963 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3966 /* Try movi / mshflo.l */
3967 val2 = (HOST_WIDE_INT) val >> 32;
3968 if (val2 == trunc_int_for_mode (val, SImode))
3970 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3974 /* Try movi / mshflo.l w/ r63. */
3975 val2 = val + ((HOST_WIDE_INT) -1 << 32);
3976 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
3978 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3984 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3987 operands[2] = GEN_INT (val2);
3991 [(set (match_operand:DI 0 "arith_reg_operand" "")
3992 (match_operand:DI 1 "immediate_operand" ""))]
3993 "TARGET_SHMEDIA && reload_completed
3994 && GET_CODE (operands[1]) == CONST_DOUBLE"
3995 [(set (match_dup 0) (match_dup 2))
3997 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3998 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4001 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4002 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4003 unsigned HOST_WIDE_INT val = low;
4004 unsigned HOST_WIDE_INT sign;
4006 /* Sign-extend the 16 least-significant bits. */
4010 operands[1] = GEN_INT (val);
4012 /* Arithmetic shift right the double-word by 16 bits. */
4014 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4017 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4021 /* This will only be true if high is a sign-extension of low, i.e.,
4022 it must be either 0 or (unsigned)-1, and be zero iff the
4023 most-significant bit of low is set. */
4024 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4025 operands[2] = GEN_INT (low);
4027 operands[2] = immed_double_const (low, high, DImode);
4030 (define_insn "shori_media"
4031 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4032 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4036 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4041 [(set_attr "type" "arith_media,*")])
4043 (define_expand "movdi"
4044 [(set (match_operand:DI 0 "general_movdst_operand" "")
4045 (match_operand:DI 1 "general_movsrc_operand" ""))]
4047 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4049 (define_insn "movdf_media"
4050 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4051 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4053 && (register_operand (operands[0], DFmode)
4054 || register_operand (operands[1], DFmode))"
4065 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4067 (define_insn "movdf_media_nofpu"
4068 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4069 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4071 && (register_operand (operands[0], DFmode)
4072 || register_operand (operands[1], DFmode))"
4078 [(set_attr "type" "arith_media,*,load_media,store_media")])
4081 [(set (match_operand:DF 0 "arith_reg_operand" "")
4082 (match_operand:DF 1 "immediate_operand" ""))]
4083 "TARGET_SHMEDIA && reload_completed"
4084 [(set (match_dup 3) (match_dup 2))]
4087 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4089 REAL_VALUE_TYPE value;
4091 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4092 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4094 if (HOST_BITS_PER_WIDE_INT >= 64)
4095 operands[2] = immed_double_const ((unsigned long) values[endian]
4096 | ((HOST_WIDE_INT) values[1 - endian]
4098 else if (HOST_BITS_PER_WIDE_INT == 32)
4099 operands[2] = immed_double_const (values[endian], values[1 - endian],
4104 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4107 ;; ??? This should be a define expand.
4109 (define_insn "movdf_k"
4110 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4111 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4113 && (! TARGET_SH4 || reload_completed
4114 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4115 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4116 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4117 && (arith_reg_operand (operands[0], DFmode)
4118 || arith_reg_operand (operands[1], DFmode))"
4119 "* return output_movedouble (insn, operands, DFmode);"
4120 [(set_attr "length" "4")
4121 (set_attr "type" "move,pcload,load,store")])
4123 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4124 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4125 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4126 ;; the d/m/c/X alternative, which is split later into single-precision
4127 ;; instructions. And when not optimizing, no splits are done before fixing
4128 ;; up pcloads, so we need usable length information for that.
4129 (define_insn "movdf_i4"
4130 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4131 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4132 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4133 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4135 && (arith_reg_operand (operands[0], DFmode)
4136 || arith_reg_operand (operands[1], DFmode))"
4148 [(set_attr_alternative "length"
4149 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4151 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4152 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4153 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4155 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4156 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4157 ;; increment or decrement r15 explicitly.
4159 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4160 (const_int 10) (const_int 8))
4162 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4163 (const_int 10) (const_int 8))])
4164 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4165 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4166 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4167 (const_string "double")
4168 (const_string "none")))])
4170 ;; Moving DFmode between fp/general registers through memory
4171 ;; (the top of the stack) is faster than moving through fpul even for
4172 ;; little endian. Because the type of an instruction is important for its
4173 ;; scheduling, it is beneficial to split these operations, rather than
4174 ;; emitting them in one single chunk, even if this will expose a stack
4175 ;; use that will prevent scheduling of other stack accesses beyond this
4178 [(set (match_operand:DF 0 "register_operand" "")
4179 (match_operand:DF 1 "register_operand" ""))
4180 (use (match_operand:PSI 2 "fpscr_operand" ""))
4181 (clobber (match_scratch:SI 3 "=X"))]
4182 "TARGET_SH4 && reload_completed
4183 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4189 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4191 emit_move_insn (stack_pointer_rtx,
4192 plus_constant (stack_pointer_rtx, -8));
4193 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4196 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4197 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4198 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4199 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4200 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4201 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4203 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4204 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4205 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4206 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4208 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4212 ;; local-alloc sometimes allocates scratch registers even when not required,
4213 ;; so we must be prepared to handle these.
4215 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4217 [(set (match_operand:DF 0 "general_movdst_operand" "")
4218 (match_operand:DF 1 "general_movsrc_operand" ""))
4219 (use (match_operand:PSI 2 "fpscr_operand" ""))
4220 (clobber (match_scratch:SI 3 ""))]
4223 && true_regnum (operands[0]) < 16
4224 && true_regnum (operands[1]) < 16"
4225 [(set (match_dup 0) (match_dup 1))]
4228 /* If this was a reg <-> mem operation with base + index reg addressing,
4229 we have to handle this in a special way. */
4230 rtx mem = operands[0];
4232 if (! memory_operand (mem, DFmode))
4237 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4238 mem = SUBREG_REG (mem);
4239 if (GET_CODE (mem) == MEM)
4241 rtx addr = XEXP (mem, 0);
4242 if (GET_CODE (addr) == PLUS
4243 && GET_CODE (XEXP (addr, 0)) == REG
4244 && GET_CODE (XEXP (addr, 1)) == REG)
4247 rtx reg0 = gen_rtx (REG, Pmode, 0);
4248 rtx regop = operands[store_p], word0 ,word1;
4250 if (GET_CODE (regop) == SUBREG)
4251 alter_subreg (®op);
4252 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4256 mem = copy_rtx (mem);
4257 PUT_MODE (mem, SImode);
4258 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4259 alter_subreg (&word0);
4260 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4261 alter_subreg (&word1);
4262 if (store_p || ! refers_to_regno_p (REGNO (word0),
4263 REGNO (word0) + 1, addr, 0))
4266 ? gen_movsi_ie (mem, word0)
4267 : gen_movsi_ie (word0, mem));
4268 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4269 mem = copy_rtx (mem);
4271 ? gen_movsi_ie (mem, word1)
4272 : gen_movsi_ie (word1, mem));
4273 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4277 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4278 emit_insn (gen_movsi_ie (word1, mem));
4279 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4280 mem = copy_rtx (mem);
4281 emit_insn (gen_movsi_ie (word0, mem));
4288 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4290 [(set (match_operand:DF 0 "register_operand" "")
4291 (match_operand:DF 1 "memory_operand" ""))
4292 (use (match_operand:PSI 2 "fpscr_operand" ""))
4293 (clobber (reg:SI R0_REG))]
4294 "TARGET_SH4 && reload_completed"
4295 [(parallel [(set (match_dup 0) (match_dup 1))
4297 (clobber (scratch:SI))])]
4300 (define_expand "reload_indf"
4301 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4302 (match_operand:DF 1 "immediate_operand" "FQ"))
4303 (use (reg:PSI FPSCR_REG))
4304 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4308 (define_expand "reload_outdf"
4309 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4310 (match_operand:DF 1 "register_operand" "af,r"))
4311 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4315 ;; Simplify no-op moves.
4317 [(set (match_operand:SF 0 "register_operand" "")
4318 (match_operand:SF 1 "register_operand" ""))
4319 (use (match_operand:PSI 2 "fpscr_operand" ""))
4320 (clobber (match_scratch:SI 3 "X"))]
4321 "TARGET_SH3E && reload_completed
4322 && true_regnum (operands[0]) == true_regnum (operands[1])"
4323 [(set (match_dup 0) (match_dup 0))]
4326 ;; fmovd substitute post-reload splits
4328 [(set (match_operand:DF 0 "register_operand" "")
4329 (match_operand:DF 1 "register_operand" ""))
4330 (use (match_operand:PSI 2 "fpscr_operand" ""))
4331 (clobber (match_scratch:SI 3 "X"))]
4332 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4333 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4334 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4338 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4339 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4340 gen_rtx (REG, SFmode, src), operands[2]));
4341 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4342 gen_rtx (REG, SFmode, src + 1), operands[2]));
4347 [(set (match_operand:DF 0 "register_operand" "")
4348 (mem:DF (match_operand:SI 1 "register_operand" "")))
4349 (use (match_operand:PSI 2 "fpscr_operand" ""))
4350 (clobber (match_scratch:SI 3 ""))]
4351 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4352 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4353 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4357 int regno = true_regnum (operands[0]);
4359 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4361 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4362 regno + !! TARGET_LITTLE_ENDIAN),
4363 mem2, operands[2]));
4364 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4365 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4366 regno + ! TARGET_LITTLE_ENDIAN),
4367 gen_rtx (MEM, SFmode, operands[1]),
4373 [(set (match_operand:DF 0 "register_operand" "")
4374 (match_operand:DF 1 "memory_operand" ""))
4375 (use (match_operand:PSI 2 "fpscr_operand" ""))
4376 (clobber (match_scratch:SI 3 ""))]
4377 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4378 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4382 int regno = true_regnum (operands[0]);
4383 rtx addr, insn, adjust = NULL_RTX;
4384 rtx mem2 = copy_rtx (operands[1]);
4385 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4386 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4388 PUT_MODE (mem2, SFmode);
4389 operands[1] = copy_rtx (mem2);
4390 addr = XEXP (mem2, 0);
4391 if (GET_CODE (addr) != POST_INC)
4393 /* If we have to modify the stack pointer, the value that we have
4394 read with post-increment might be modified by an interrupt,
4395 so write it back. */
4396 if (REGNO (addr) == STACK_POINTER_REGNUM)
4397 adjust = gen_push_e (reg0);
4399 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4400 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4402 addr = XEXP (addr, 0);
4403 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4404 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4405 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4409 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4414 [(set (match_operand:DF 0 "memory_operand" "")
4415 (match_operand:DF 1 "register_operand" ""))
4416 (use (match_operand:PSI 2 "fpscr_operand" ""))
4417 (clobber (match_scratch:SI 3 ""))]
4418 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4419 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4423 int regno = true_regnum (operands[1]);
4424 rtx insn, addr, adjust = NULL_RTX;
4426 operands[0] = copy_rtx (operands[0]);
4427 PUT_MODE (operands[0], SFmode);
4428 insn = emit_insn (gen_movsf_ie (operands[0],
4429 gen_rtx (REG, SFmode,
4430 regno + ! TARGET_LITTLE_ENDIAN),
4432 operands[0] = copy_rtx (operands[0]);
4433 addr = XEXP (operands[0], 0);
4434 if (GET_CODE (addr) != PRE_DEC)
4436 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4437 emit_insn_before (adjust, insn);
4438 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4440 addr = XEXP (addr, 0);
4442 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4443 insn = emit_insn (gen_movsf_ie (operands[0],
4444 gen_rtx (REG, SFmode,
4445 regno + !! TARGET_LITTLE_ENDIAN),
4447 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4451 ;; If the output is a register and the input is memory or a register, we have
4452 ;; to be careful and see which word needs to be loaded first.
4455 [(set (match_operand:DF 0 "general_movdst_operand" "")
4456 (match_operand:DF 1 "general_movsrc_operand" ""))]
4457 "TARGET_SH1 && reload_completed"
4458 [(set (match_dup 2) (match_dup 3))
4459 (set (match_dup 4) (match_dup 5))]
4464 if ((GET_CODE (operands[0]) == MEM
4465 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4466 || (GET_CODE (operands[1]) == MEM
4467 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4470 if (GET_CODE (operands[0]) == REG)
4471 regno = REGNO (operands[0]);
4472 else if (GET_CODE (operands[0]) == SUBREG)
4473 regno = subreg_regno (operands[0]);
4474 else if (GET_CODE (operands[0]) == MEM)
4480 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4482 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4483 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4484 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4485 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4489 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4490 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4491 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4492 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4495 if (operands[2] == 0 || operands[3] == 0
4496 || operands[4] == 0 || operands[5] == 0)
4500 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4501 ;; used only once, let combine add in the index again.
4504 [(set (match_operand:SI 0 "register_operand" "")
4505 (match_operand:SI 1 "" ""))
4506 (clobber (match_operand 2 "register_operand" ""))]
4507 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4508 [(use (reg:SI R0_REG))]
4511 rtx addr, reg, const_int;
4513 if (GET_CODE (operands[1]) != MEM)
4515 addr = XEXP (operands[1], 0);
4516 if (GET_CODE (addr) != PLUS)
4518 reg = XEXP (addr, 0);
4519 const_int = XEXP (addr, 1);
4520 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4521 && GET_CODE (const_int) == CONST_INT))
4523 emit_move_insn (operands[2], const_int);
4524 emit_move_insn (operands[0],
4525 change_address (operands[1], VOIDmode,
4526 gen_rtx_PLUS (SImode, reg, operands[2])));
4531 [(set (match_operand:SI 1 "" "")
4532 (match_operand:SI 0 "register_operand" ""))
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 (change_address (operands[1], VOIDmode,
4552 gen_rtx_PLUS (SImode, reg, operands[2])),
4557 (define_expand "movdf"
4558 [(set (match_operand:DF 0 "general_movdst_operand" "")
4559 (match_operand:DF 1 "general_movsrc_operand" ""))]
4563 if (prepare_move_operands (operands, DFmode)) DONE;
4566 if (TARGET_SHMEDIA_FPU)
4567 emit_insn (gen_movdf_media (operands[0], operands[1]));
4569 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4574 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4579 ;;This is incompatible with the way gcc uses subregs.
4580 ;;(define_insn "movv2sf_i"
4581 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4582 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4583 ;; "TARGET_SHMEDIA_FPU
4584 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4585 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4589 ;; fst%M0.p %m0, %1"
4590 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4592 (define_insn_and_split "movv2sf_i"
4593 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4594 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4595 "TARGET_SHMEDIA_FPU"
4597 "TARGET_SHMEDIA_FPU && reload_completed"
4598 [(set (match_dup 0) (match_dup 1))]
4601 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4602 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4605 (define_expand "movv2sf"
4606 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4607 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4608 "TARGET_SHMEDIA_FPU"
4611 if (prepare_move_operands (operands, V2SFmode))
4615 (define_expand "addv2sf3"
4616 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4617 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4618 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4619 "TARGET_SHMEDIA_FPU"
4622 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4626 (define_expand "subv2sf3"
4627 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4628 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4629 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4630 "TARGET_SHMEDIA_FPU"
4633 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4637 (define_expand "mulv2sf3"
4638 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4639 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4640 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4641 "TARGET_SHMEDIA_FPU"
4644 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4648 (define_expand "divv2sf3"
4649 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4650 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4651 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4652 "TARGET_SHMEDIA_FPU"
4655 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4659 (define_insn_and_split "*movv4sf_i"
4660 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4661 (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4662 "TARGET_SHMEDIA_FPU"
4664 "&& reload_completed"
4670 for (i = 0; i < 4/2; i++)
4674 if (GET_CODE (operands[0]) == MEM)
4675 x = gen_rtx_MEM (V2SFmode,
4676 plus_constant (XEXP (operands[0], 0),
4677 i * GET_MODE_SIZE (V2SFmode)));
4679 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4681 if (GET_CODE (operands[1]) == MEM)
4682 y = gen_rtx_MEM (V2SFmode,
4683 plus_constant (XEXP (operands[1], 0),
4684 i * GET_MODE_SIZE (V2SFmode)));
4686 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4688 emit_insn (gen_movv2sf_i (x, y));
4693 [(set_attr "length" "8")])
4695 (define_expand "movv4sf"
4696 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4697 (match_operand:V4SF 1 "general_operand" ""))]
4698 "TARGET_SHMEDIA_FPU"
4701 if (prepare_move_operands (operands, V4SFmode))
4705 (define_insn_and_split "*movv16sf_i"
4706 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4707 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4708 "TARGET_SHMEDIA_FPU"
4710 "&& reload_completed"
4716 for (i = 0; i < 16/2; i++)
4720 if (GET_CODE (operands[0]) == MEM)
4721 x = gen_rtx_MEM (V2SFmode,
4722 plus_constant (XEXP (operands[0], 0),
4723 i * GET_MODE_SIZE (V2SFmode)));
4726 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4730 if (GET_CODE (operands[1]) == MEM)
4731 y = gen_rtx_MEM (V2SFmode,
4732 plus_constant (XEXP (operands[1], 0),
4733 i * GET_MODE_SIZE (V2SFmode)));
4736 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4740 emit_insn (gen_movv2sf_i (x, y));
4745 [(set_attr "length" "32")])
4747 (define_expand "movv16sf"
4748 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4749 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4750 "TARGET_SHMEDIA_FPU"
4753 if (prepare_move_operands (operands, V16SFmode))
4757 (define_insn "movsf_media"
4758 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4759 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4761 && (register_operand (operands[0], SFmode)
4762 || register_operand (operands[1], SFmode))"
4773 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4775 (define_insn "movsf_media_nofpu"
4776 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4777 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4779 && (register_operand (operands[0], SFmode)
4780 || register_operand (operands[1], SFmode))"
4786 [(set_attr "type" "arith_media,*,load_media,store_media")])
4789 [(set (match_operand:SF 0 "arith_reg_operand" "")
4790 (match_operand:SF 1 "immediate_operand" ""))]
4791 "TARGET_SHMEDIA && reload_completed
4792 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4793 [(set (match_dup 3) (match_dup 2))]
4797 REAL_VALUE_TYPE value;
4799 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4800 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4801 operands[2] = GEN_INT (values);
4803 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4806 (define_insn "movsf_i"
4807 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4808 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4811 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4812 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4813 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4814 && (arith_reg_operand (operands[0], SFmode)
4815 || arith_reg_operand (operands[1], SFmode))"
4824 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4826 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4827 ;; update_flow_info would not know where to put REG_EQUAL notes
4828 ;; when the destination changes mode.
4829 (define_insn "movsf_ie"
4830 [(set (match_operand:SF 0 "general_movdst_operand"
4831 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4832 (match_operand:SF 1 "general_movsrc_operand"
4833 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4834 (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"))
4835 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4838 && (arith_reg_operand (operands[0], SFmode)
4839 || arith_reg_operand (operands[1], SFmode)
4840 || arith_reg_operand (operands[3], SImode)
4841 || (fpul_operand (operands[0], SFmode)
4842 && memory_operand (operands[1], SFmode)
4843 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4844 || (fpul_operand (operands[1], SFmode)
4845 && memory_operand (operands[0], SFmode)
4846 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4866 ! move optimized away"
4867 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4868 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4869 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4870 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4871 (const_string "single")
4872 (const_string "none")))])
4875 [(set (match_operand:SF 0 "register_operand" "")
4876 (match_operand:SF 1 "register_operand" ""))
4877 (use (match_operand:PSI 2 "fpscr_operand" ""))
4878 (clobber (reg:SI FPUL_REG))]
4880 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4882 (clobber (scratch:SI))])
4883 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4885 (clobber (scratch:SI))])]
4888 (define_expand "movsf"
4889 [(set (match_operand:SF 0 "general_movdst_operand" "")
4890 (match_operand:SF 1 "general_movsrc_operand" ""))]
4894 if (prepare_move_operands (operands, SFmode))
4898 if (TARGET_SHMEDIA_FPU)
4899 emit_insn (gen_movsf_media (operands[0], operands[1]));
4901 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4906 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4911 (define_insn "mov_nop"
4912 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4915 [(set_attr "length" "0")
4916 (set_attr "type" "nil")])
4918 (define_expand "reload_insf"
4919 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4920 (match_operand:SF 1 "immediate_operand" "FQ"))
4921 (use (reg:PSI FPSCR_REG))
4922 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4926 (define_expand "reload_insi"
4927 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4928 (match_operand:SF 1 "immediate_operand" "FQ"))
4929 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4933 (define_insn "*movsi_y"
4934 [(set (match_operand:SI 0 "register_operand" "=y,y")
4935 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4936 (clobber (match_scratch:SI 2 "=&z,r"))]
4938 && (reload_in_progress || reload_completed)"
4940 [(set_attr "length" "4")
4941 (set_attr "type" "pcload,move")])
4944 [(set (match_operand:SI 0 "register_operand" "")
4945 (match_operand:SI 1 "immediate_operand" ""))
4946 (clobber (match_operand:SI 2 "register_operand" ""))]
4948 [(set (match_dup 2) (match_dup 1))
4949 (set (match_dup 0) (match_dup 2))]
4953 [(set (match_operand:SI 0 "register_operand" "")
4954 (match_operand:SI 1 "memory_operand" ""))
4955 (clobber (reg:SI R0_REG))]
4957 [(set (match_dup 0) (match_dup 1))]
4960 ;; ------------------------------------------------------------------------
4961 ;; Define the real conditional branch instructions.
4962 ;; ------------------------------------------------------------------------
4964 (define_insn "branch_true"
4965 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4966 (label_ref (match_operand 0 "" ""))
4969 "* return output_branch (1, insn, operands);"
4970 [(set_attr "type" "cbranch")])
4972 (define_insn "branch_false"
4973 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4974 (label_ref (match_operand 0 "" ""))
4977 "* return output_branch (0, insn, operands);"
4978 [(set_attr "type" "cbranch")])
4980 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4981 ;; which destination is too far away.
4982 ;; The const_int_operand is distinct for each branch target; it avoids
4983 ;; unwanted matches with redundant_insn.
4984 (define_insn "block_branch_redirect"
4985 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4988 [(set_attr "length" "0")])
4990 ;; This one has the additional purpose to record a possible scratch register
4991 ;; for the following branch.
4992 (define_insn "indirect_jump_scratch"
4993 [(set (match_operand:SI 0 "register_operand" "=r")
4994 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
4997 [(set_attr "length" "0")])
4999 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5000 ;; being pulled into the delay slot of a condbranch that has been made to
5001 ;; jump around the unconditional jump because it was out of range.
5002 (define_insn "stuff_delay_slot"
5004 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5005 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5008 [(set_attr "length" "0")
5009 (set_attr "cond_delay_slot" "yes")])
5011 ;; Conditional branch insns
5013 (define_expand "beq_media"
5015 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5016 (match_operand:DI 2 "arith_operand" "r,O"))
5017 (label_ref:DI (match_operand 0 "" ""))
5022 (define_insn "*beq_media_i"
5024 (if_then_else (match_operator 3 "equality_comparison_operator"
5025 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5026 (match_operand:DI 2 "arith_operand" "r,O")])
5027 (match_operand:DI 0 "target_operand" "b,b")
5033 [(set_attr "type" "cbranch_media")])
5035 (define_expand "bne_media"
5037 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5038 (match_operand:DI 2 "arith_operand" "r,O"))
5039 (label_ref:DI (match_operand 0 "" ""))
5044 (define_expand "bgt_media"
5046 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5047 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5048 (label_ref:DI (match_operand 0 "" ""))
5053 (define_expand "bge_media"
5055 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5056 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5057 (label_ref:DI (match_operand 0 "" ""))
5062 (define_expand "bgtu_media"
5064 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5065 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5066 (label_ref:DI (match_operand 0 "" ""))
5071 (define_expand "bgeu_media"
5073 (if_then_else (geu (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_insn "*bgt_media_i"
5082 (if_then_else (match_operator 3 "greater_comparison_operator"
5083 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5084 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5085 (match_operand:DI 0 "target_operand" "b")
5088 "b%o3%' %N1, %N2, %0"
5089 [(set_attr "type" "cbranch_media")])
5091 ;; These are only needed to make invert_jump() happy.
5092 (define_insn "*blt_media_i"
5094 (if_then_else (match_operator 3 "less_comparison_operator"
5095 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5096 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5097 (match_operand:DI 0 "target_operand" "b")
5100 "b%o3%' %N2, %N1, %0"
5101 [(set_attr "type" "cbranch_media")])
5103 (define_expand "beq"
5105 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5106 (label_ref (match_operand 0 "" ""))
5113 if (GET_MODE (sh_compare_op0) != DImode)
5115 rtx tmp = gen_reg_rtx (DImode);
5117 emit_insn (gen_seq (tmp));
5118 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5122 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5123 emit_jump_insn (gen_beq_media (operands[0],
5124 sh_compare_op0, sh_compare_op1));
5128 from_compare (operands, EQ);
5131 (define_expand "bne"
5133 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5134 (label_ref (match_operand 0 "" ""))
5141 if (GET_MODE (sh_compare_op0) != DImode)
5143 rtx tmp = gen_reg_rtx (DImode);
5145 emit_insn (gen_seq (tmp));
5146 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5150 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5151 emit_jump_insn (gen_bne_media (operands[0],
5152 sh_compare_op0, sh_compare_op1));
5156 from_compare (operands, EQ);
5159 (define_expand "bgt"
5161 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5162 (label_ref (match_operand 0 "" ""))
5169 if (GET_MODE (sh_compare_op0) != DImode)
5171 rtx tmp = gen_reg_rtx (DImode);
5173 emit_insn (gen_sgt (tmp));
5174 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5178 if (sh_compare_op0 != const0_rtx)
5179 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5180 if (sh_compare_op1 != const0_rtx)
5181 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5182 emit_jump_insn (gen_bgt_media (operands[0],
5183 sh_compare_op0, sh_compare_op1));
5187 from_compare (operands, GT);
5190 (define_expand "blt"
5192 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5193 (label_ref (match_operand 0 "" ""))
5200 if (GET_MODE (sh_compare_op0) != DImode)
5202 rtx tmp = gen_reg_rtx (DImode);
5204 emit_insn (gen_slt (tmp));
5205 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5209 if (sh_compare_op0 != const0_rtx)
5210 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5211 if (sh_compare_op1 != const0_rtx)
5212 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5213 emit_jump_insn (gen_bgt_media (operands[0],
5214 sh_compare_op1, sh_compare_op0));
5218 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5220 rtx tmp = sh_compare_op0;
5221 sh_compare_op0 = sh_compare_op1;
5222 sh_compare_op1 = tmp;
5223 emit_insn (gen_bgt (operands[0]));
5226 from_compare (operands, GE);
5229 (define_expand "ble"
5231 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5232 (label_ref (match_operand 0 "" ""))
5239 if (GET_MODE (sh_compare_op0) != DImode)
5241 rtx tmp = gen_reg_rtx (DImode);
5243 emit_insn (gen_sle (tmp));
5244 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5248 if (sh_compare_op0 != const0_rtx)
5249 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5250 if (sh_compare_op1 != const0_rtx)
5251 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5252 emit_jump_insn (gen_bge_media (operands[0],
5253 sh_compare_op1, sh_compare_op0));
5259 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5261 rtx tmp = sh_compare_op0;
5262 sh_compare_op0 = sh_compare_op1;
5263 sh_compare_op1 = tmp;
5264 emit_insn (gen_bge (operands[0]));
5267 from_compare (operands, GT);
5270 (define_expand "bge"
5272 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5273 (label_ref (match_operand 0 "" ""))
5280 if (GET_MODE (sh_compare_op0) != DImode)
5282 rtx tmp = gen_reg_rtx (DImode);
5284 emit_insn (gen_sge (tmp));
5285 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5289 if (sh_compare_op0 != const0_rtx)
5290 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5291 if (sh_compare_op1 != const0_rtx)
5292 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5293 emit_jump_insn (gen_bge_media (operands[0],
5294 sh_compare_op0, sh_compare_op1));
5300 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5302 rtx tmp = sh_compare_op0;
5303 sh_compare_op0 = sh_compare_op1;
5304 sh_compare_op1 = tmp;
5305 emit_insn (gen_ble (operands[0]));
5308 from_compare (operands, GE);
5311 (define_expand "bgtu"
5313 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5314 (label_ref (match_operand 0 "" ""))
5321 if (sh_compare_op0 != const0_rtx)
5322 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5323 if (sh_compare_op1 != const0_rtx)
5324 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5325 emit_jump_insn (gen_bgtu_media (operands[0],
5326 sh_compare_op0, sh_compare_op1));
5330 from_compare (operands, GTU);
5333 (define_expand "bltu"
5335 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5336 (label_ref (match_operand 0 "" ""))
5343 if (sh_compare_op0 != const0_rtx)
5344 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5345 if (sh_compare_op1 != const0_rtx)
5346 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5347 emit_jump_insn (gen_bgtu_media (operands[0],
5348 sh_compare_op1, sh_compare_op0));
5352 from_compare (operands, GEU);
5355 (define_expand "bgeu"
5357 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5358 (label_ref (match_operand 0 "" ""))
5365 if (sh_compare_op0 != const0_rtx)
5366 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5367 if (sh_compare_op1 != const0_rtx)
5368 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5369 emit_jump_insn (gen_bgeu_media (operands[0],
5370 sh_compare_op0, sh_compare_op1));
5374 from_compare (operands, GEU);
5377 (define_expand "bleu"
5379 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5380 (label_ref (match_operand 0 "" ""))
5387 if (sh_compare_op0 != const0_rtx)
5388 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5389 if (sh_compare_op1 != const0_rtx)
5390 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5391 emit_jump_insn (gen_bgeu_media (operands[0],
5392 sh_compare_op1, sh_compare_op0));
5396 from_compare (operands, GTU);
5399 (define_expand "bunordered"
5400 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5402 (if_then_else (ne (match_dup 1) (const_int 0))
5403 (label_ref:DI (match_operand 0 "" ""))
5408 operands[1] = gen_reg_rtx (DImode);
5409 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5410 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5413 ;; ------------------------------------------------------------------------
5414 ;; Jump and linkage insns
5415 ;; ------------------------------------------------------------------------
5417 (define_insn "jump_compact"
5419 (label_ref (match_operand 0 "" "")))]
5423 /* The length is 16 if the delay slot is unfilled. */
5424 if (get_attr_length(insn) > 4)
5425 return output_far_jump(insn, operands[0]);
5427 return \"bra %l0%#\";
5429 [(set_attr "type" "jump")
5430 (set_attr "needs_delay_slot" "yes")])
5432 (define_insn "jump_media"
5434 (match_operand:DI 0 "target_operand" "b"))]
5437 [(set_attr "type" "jump_media")])
5439 (define_expand "jump"
5441 (label_ref (match_operand 0 "" "")))]
5446 emit_jump_insn (gen_jump_compact (operands[0]));
5447 else if (TARGET_SHMEDIA)
5449 if (reload_in_progress || reload_completed)
5451 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5457 (define_insn "force_mode_for_call"
5458 [(use (reg:PSI FPSCR_REG))]
5461 [(set_attr "length" "0")
5462 (set (attr "fp_mode")
5463 (if_then_else (eq_attr "fpu_single" "yes")
5464 (const_string "single") (const_string "double")))])
5466 (define_insn "calli"
5467 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5468 (match_operand 1 "" ""))
5469 (use (reg:PSI FPSCR_REG))
5470 (clobber (reg:SI PR_REG))]
5473 [(set_attr "type" "call")
5474 (set (attr "fp_mode")
5475 (if_then_else (eq_attr "fpu_single" "yes")
5476 (const_string "single") (const_string "double")))
5477 (set_attr "needs_delay_slot" "yes")])
5479 ;; This is a pc-rel call, using bsrf, for use with PIC.
5481 (define_insn "calli_pcrel"
5482 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5483 (match_operand 1 "" ""))
5484 (use (reg:PSI FPSCR_REG))
5485 (use (reg:SI PIC_REG))
5486 (use (match_operand 2 "" ""))
5487 (clobber (reg:SI PR_REG))]
5490 [(set_attr "type" "call")
5491 (set (attr "fp_mode")
5492 (if_then_else (eq_attr "fpu_single" "yes")
5493 (const_string "single") (const_string "double")))
5494 (set_attr "needs_delay_slot" "yes")])
5496 (define_insn_and_split "call_pcrel"
5497 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5498 (match_operand 1 "" ""))
5499 (use (reg:PSI FPSCR_REG))
5500 (use (reg:SI PIC_REG))
5501 (clobber (reg:SI PR_REG))
5502 (clobber (match_scratch:SI 2 "=r"))]
5509 rtx lab = PATTERN (gen_call_site ());
5511 if (SYMBOL_REF_FLAG (operands[0]))
5512 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5514 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5515 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5518 [(set_attr "type" "call")
5519 (set (attr "fp_mode")
5520 (if_then_else (eq_attr "fpu_single" "yes")
5521 (const_string "single") (const_string "double")))
5522 (set_attr "needs_delay_slot" "yes")])
5524 (define_insn "call_compact"
5525 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5526 (match_operand 1 "" ""))
5527 (match_operand 2 "immediate_operand" "n")
5528 (use (reg:SI R0_REG))
5529 (use (reg:SI R1_REG))
5530 (use (reg:PSI FPSCR_REG))
5531 (clobber (reg:SI PR_REG))]
5532 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5534 [(set_attr "type" "call")
5535 (set (attr "fp_mode")
5536 (if_then_else (eq_attr "fpu_single" "yes")
5537 (const_string "single") (const_string "double")))
5538 (set_attr "needs_delay_slot" "yes")])
5540 (define_insn "call_compact_rettramp"
5541 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5542 (match_operand 1 "" ""))
5543 (match_operand 2 "immediate_operand" "n")
5544 (use (reg:SI R0_REG))
5545 (use (reg:SI R1_REG))
5546 (use (reg:PSI FPSCR_REG))
5547 (clobber (reg:SI R10_REG))
5548 (clobber (reg:SI PR_REG))]
5549 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5551 [(set_attr "type" "call")
5552 (set (attr "fp_mode")
5553 (if_then_else (eq_attr "fpu_single" "yes")
5554 (const_string "single") (const_string "double")))
5555 (set_attr "needs_delay_slot" "yes")])
5557 (define_insn "call_media"
5558 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5559 (match_operand 1 "" ""))
5560 (clobber (reg:DI PR_MEDIA_REG))]
5563 [(set_attr "type" "jump_media")])
5565 (define_insn "call_valuei"
5566 [(set (match_operand 0 "" "=rf")
5567 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5568 (match_operand 2 "" "")))
5569 (use (reg:PSI FPSCR_REG))
5570 (clobber (reg:SI PR_REG))]
5573 [(set_attr "type" "call")
5574 (set (attr "fp_mode")
5575 (if_then_else (eq_attr "fpu_single" "yes")
5576 (const_string "single") (const_string "double")))
5577 (set_attr "needs_delay_slot" "yes")])
5579 (define_insn "call_valuei_pcrel"
5580 [(set (match_operand 0 "" "=rf")
5581 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5582 (match_operand 2 "" "")))
5583 (use (reg:PSI FPSCR_REG))
5584 (use (reg:SI PIC_REG))
5585 (use (match_operand 3 "" ""))
5586 (clobber (reg:SI PR_REG))]
5589 [(set_attr "type" "call")
5590 (set (attr "fp_mode")
5591 (if_then_else (eq_attr "fpu_single" "yes")
5592 (const_string "single") (const_string "double")))
5593 (set_attr "needs_delay_slot" "yes")])
5595 (define_insn_and_split "call_value_pcrel"
5596 [(set (match_operand 0 "" "=rf")
5597 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5598 (match_operand 2 "" "")))
5599 (use (reg:PSI FPSCR_REG))
5600 (use (reg:SI PIC_REG))
5601 (clobber (reg:SI PR_REG))
5602 (clobber (match_scratch:SI 3 "=r"))]
5609 rtx lab = PATTERN (gen_call_site ());
5611 if (SYMBOL_REF_FLAG (operands[1]))
5612 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5614 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5615 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5619 [(set_attr "type" "call")
5620 (set (attr "fp_mode")
5621 (if_then_else (eq_attr "fpu_single" "yes")
5622 (const_string "single") (const_string "double")))
5623 (set_attr "needs_delay_slot" "yes")])
5625 (define_insn "call_value_compact"
5626 [(set (match_operand 0 "" "=rf")
5627 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5628 (match_operand 2 "" "")))
5629 (match_operand 3 "immediate_operand" "n")
5630 (use (reg:SI R0_REG))
5631 (use (reg:SI R1_REG))
5632 (use (reg:PSI FPSCR_REG))
5633 (clobber (reg:SI PR_REG))]
5634 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5636 [(set_attr "type" "call")
5637 (set (attr "fp_mode")
5638 (if_then_else (eq_attr "fpu_single" "yes")
5639 (const_string "single") (const_string "double")))
5640 (set_attr "needs_delay_slot" "yes")])
5642 (define_insn "call_value_compact_rettramp"
5643 [(set (match_operand 0 "" "=rf")
5644 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5645 (match_operand 2 "" "")))
5646 (match_operand 3 "immediate_operand" "n")
5647 (use (reg:SI R0_REG))
5648 (use (reg:SI R1_REG))
5649 (use (reg:PSI FPSCR_REG))
5650 (clobber (reg:SI R10_REG))
5651 (clobber (reg:SI PR_REG))]
5652 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5654 [(set_attr "type" "call")
5655 (set (attr "fp_mode")
5656 (if_then_else (eq_attr "fpu_single" "yes")
5657 (const_string "single") (const_string "double")))
5658 (set_attr "needs_delay_slot" "yes")])
5660 (define_insn "call_value_media"
5661 [(set (match_operand 0 "" "=rf")
5662 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5663 (match_operand 2 "" "")))
5664 (clobber (reg:DI PR_MEDIA_REG))]
5667 [(set_attr "type" "jump_media")])
5669 (define_expand "call"
5670 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5671 (match_operand 1 "" ""))
5672 (match_operand 2 "" "")
5673 (use (reg:PSI FPSCR_REG))
5674 (clobber (reg:SI PR_REG))])]
5680 operands[0] = XEXP (operands[0], 0);
5681 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5683 if (! SYMBOL_REF_FLAG (operands[0]))
5685 rtx reg = gen_reg_rtx (Pmode);
5687 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5692 operands[0] = gen_sym2PIC (operands[0]);
5693 PUT_MODE (operands[0], Pmode);
5696 if (GET_MODE (operands[0]) == SImode)
5698 if (GET_CODE (operands[0]) == REG)
5699 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5700 else if (GET_CODE (operands[0]) == SUBREG)
5702 operands[0] = SUBREG_REG (operands[0]);
5703 if (GET_MODE (operands[0]) != DImode)
5704 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5708 operands[0] = shallow_copy_rtx (operands[0]);
5709 PUT_MODE (operands[0], DImode);
5712 if (! target_reg_operand (operands[0], DImode))
5713 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5714 emit_call_insn (gen_call_media (operands[0], operands[1]));
5717 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5719 rtx cookie_rtx = operands[2];
5720 long cookie = INTVAL (cookie_rtx);
5721 rtx func = XEXP (operands[0], 0);
5726 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5728 rtx reg = gen_reg_rtx (Pmode);
5730 emit_insn (gen_symGOTPLT2reg (reg, func));
5734 func = legitimize_pic_address (func, Pmode, 0);
5737 r0 = gen_rtx_REG (SImode, R0_REG);
5738 r1 = gen_rtx_REG (SImode, R1_REG);
5740 /* Since such a call function may use all call-clobbered
5741 registers, we force a mode switch earlier, so that we don't
5742 run out of registers when adjusting fpscr for the call. */
5743 emit_insn (gen_force_mode_for_call ());
5745 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5746 \"__GCC_shcompact_call_trampoline\");
5749 rtx reg = gen_reg_rtx (Pmode);
5751 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5754 operands[0] = force_reg (SImode, operands[0]);
5756 emit_move_insn (r0, func);
5757 emit_move_insn (r1, cookie_rtx);
5759 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5760 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5763 emit_call_insn (gen_call_compact (operands[0], operands[1],
5768 else if (TARGET_SHCOMPACT && flag_pic
5769 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5770 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5772 rtx reg = gen_reg_rtx (Pmode);
5774 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5775 XEXP (operands[0], 0) = reg;
5777 if (flag_pic && TARGET_SH2
5778 && GET_CODE (operands[0]) == MEM
5779 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5781 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5785 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5787 emit_call_insn (gen_calli (operands[0], operands[1]));
5791 (define_insn "call_pop_compact"
5792 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5793 (match_operand 1 "" ""))
5794 (match_operand 2 "immediate_operand" "n")
5795 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5796 (match_operand 3 "immediate_operand" "n")))
5797 (use (reg:SI R0_REG))
5798 (use (reg:SI R1_REG))
5799 (use (reg:PSI FPSCR_REG))
5800 (clobber (reg:SI PR_REG))]
5801 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5803 [(set_attr "type" "call")
5804 (set (attr "fp_mode")
5805 (if_then_else (eq_attr "fpu_single" "yes")
5806 (const_string "single") (const_string "double")))
5807 (set_attr "needs_delay_slot" "yes")])
5809 (define_insn "call_pop_compact_rettramp"
5810 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5811 (match_operand 1 "" ""))
5812 (match_operand 2 "immediate_operand" "n")
5813 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5814 (match_operand 3 "immediate_operand" "n")))
5815 (use (reg:SI R0_REG))
5816 (use (reg:SI R1_REG))
5817 (use (reg:PSI FPSCR_REG))
5818 (clobber (reg:SI R10_REG))
5819 (clobber (reg:SI PR_REG))]
5820 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5822 [(set_attr "type" "call")
5823 (set (attr "fp_mode")
5824 (if_then_else (eq_attr "fpu_single" "yes")
5825 (const_string "single") (const_string "double")))
5826 (set_attr "needs_delay_slot" "yes")])
5828 (define_expand "call_pop"
5829 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5830 (match_operand 1 "" ""))
5831 (match_operand 2 "" "")
5832 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5833 (match_operand 3 "" "")))])]
5837 if (operands[2] && INTVAL (operands[2]))
5839 rtx cookie_rtx = operands[2];
5840 long cookie = INTVAL (cookie_rtx);
5841 rtx func = XEXP (operands[0], 0);
5846 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5848 rtx reg = gen_reg_rtx (Pmode);
5850 emit_insn (gen_symGOTPLT2reg (reg, func));
5854 func = legitimize_pic_address (func, Pmode, 0);
5857 r0 = gen_rtx_REG (SImode, R0_REG);
5858 r1 = gen_rtx_REG (SImode, R1_REG);
5860 /* Since such a call function may use all call-clobbered
5861 registers, we force a mode switch earlier, so that we don't
5862 run out of registers when adjusting fpscr for the call. */
5863 emit_insn (gen_force_mode_for_call ());
5865 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5866 \"__GCC_shcompact_call_trampoline\");
5869 rtx reg = gen_reg_rtx (Pmode);
5871 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5874 operands[0] = force_reg (SImode, operands[0]);
5876 emit_move_insn (r0, func);
5877 emit_move_insn (r1, cookie_rtx);
5879 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5880 emit_call_insn (gen_call_pop_compact_rettramp
5881 (operands[0], operands[1], operands[2], operands[3]));
5883 emit_call_insn (gen_call_pop_compact
5884 (operands[0], operands[1], operands[2], operands[3]));
5892 (define_expand "call_value"
5893 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5894 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5895 (match_operand 2 "" "")))
5896 (match_operand 3 "" "")
5897 (use (reg:PSI FPSCR_REG))
5898 (clobber (reg:SI PR_REG))])]
5904 operands[1] = XEXP (operands[1], 0);
5905 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5907 if (! SYMBOL_REF_FLAG (operands[1]))
5909 rtx reg = gen_reg_rtx (Pmode);
5911 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5916 operands[1] = gen_sym2PIC (operands[1]);
5917 PUT_MODE (operands[1], Pmode);
5920 if (GET_MODE (operands[1]) == SImode)
5922 if (GET_CODE (operands[1]) == REG)
5923 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5924 else if (GET_CODE (operands[1]) == SUBREG)
5926 operands[1] = SUBREG_REG (operands[1]);
5927 if (GET_MODE (operands[1]) != DImode)
5928 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5932 operands[1] = shallow_copy_rtx (operands[1]);
5933 PUT_MODE (operands[1], DImode);
5936 if (! target_reg_operand (operands[1], DImode))
5937 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5938 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5942 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5944 rtx cookie_rtx = operands[3];
5945 long cookie = INTVAL (cookie_rtx);
5946 rtx func = XEXP (operands[1], 0);
5951 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5953 rtx reg = gen_reg_rtx (Pmode);
5955 emit_insn (gen_symGOTPLT2reg (reg, func));
5959 func = legitimize_pic_address (func, Pmode, 0);
5962 r0 = gen_rtx_REG (SImode, R0_REG);
5963 r1 = gen_rtx_REG (SImode, R1_REG);
5965 /* Since such a call function may use all call-clobbered
5966 registers, we force a mode switch earlier, so that we don't
5967 run out of registers when adjusting fpscr for the call. */
5968 emit_insn (gen_force_mode_for_call ());
5970 operands[1] = gen_rtx_SYMBOL_REF (SImode,
5971 \"__GCC_shcompact_call_trampoline\");
5974 rtx reg = gen_reg_rtx (Pmode);
5976 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5979 operands[1] = force_reg (SImode, operands[1]);
5981 emit_move_insn (r0, func);
5982 emit_move_insn (r1, cookie_rtx);
5984 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5985 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
5990 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
5991 operands[2], operands[3]));
5995 else if (TARGET_SHCOMPACT && flag_pic
5996 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
5997 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
5999 rtx reg = gen_reg_rtx (Pmode);
6001 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6002 XEXP (operands[1], 0) = reg;
6004 if (flag_pic && TARGET_SH2
6005 && GET_CODE (operands[1]) == MEM
6006 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6008 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6013 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6015 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6019 (define_insn "sibcalli"
6020 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6021 (match_operand 1 "" ""))
6022 (use (reg:PSI FPSCR_REG))
6026 [(set_attr "needs_delay_slot" "yes")
6027 (set (attr "fp_mode")
6028 (if_then_else (eq_attr "fpu_single" "yes")
6029 (const_string "single") (const_string "double")))
6030 (set_attr "type" "jump_ind")])
6032 (define_insn "sibcalli_pcrel"
6033 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6034 (match_operand 1 "" ""))
6035 (use (match_operand 2 "" ""))
6036 (use (reg:PSI FPSCR_REG))
6040 [(set_attr "needs_delay_slot" "yes")
6041 (set (attr "fp_mode")
6042 (if_then_else (eq_attr "fpu_single" "yes")
6043 (const_string "single") (const_string "double")))
6044 (set_attr "type" "jump_ind")])
6046 (define_insn_and_split "sibcall_pcrel"
6047 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6048 (match_operand 1 "" ""))
6049 (use (reg:PSI FPSCR_REG))
6050 (clobber (match_scratch:SI 2 "=k"))
6058 rtx lab = PATTERN (gen_call_site ());
6061 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6062 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6064 SIBLING_CALL_P (call_insn) = 1;
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 "sibcall_compact"
6074 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6075 (match_operand 1 "" ""))
6077 (use (match_operand:SI 2 "register_operand" "z,x"))
6078 (use (reg:SI R1_REG))
6079 (use (reg:PSI FPSCR_REG))
6080 ;; We want to make sure the `x' above will only match MACH_REG
6081 ;; because sibcall_epilogue may clobber MACL_REG.
6082 (clobber (reg:SI MACL_REG))]
6086 jmp @%0\\n sts %2, r0"
6087 [(set_attr "needs_delay_slot" "yes,no")
6088 (set_attr "length" "2,4")
6089 (set (attr "fp_mode") (const_string "single"))
6090 (set_attr "type" "jump_ind")])
6092 (define_insn "sibcall_media"
6093 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6094 (match_operand 1 "" ""))
6098 [(set_attr "type" "jump_media")])
6100 (define_expand "sibcall"
6102 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6103 (match_operand 1 "" ""))
6104 (match_operand 2 "" "")
6105 (use (reg:PSI FPSCR_REG))
6112 operands[0] = XEXP (operands[0], 0);
6113 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6115 if (! SYMBOL_REF_FLAG (operands[0]))
6117 rtx reg = gen_reg_rtx (Pmode);
6119 /* We must not use GOTPLT for sibcalls, because PIC_REG
6120 must be restored before the PLT code gets to run. */
6121 emit_insn (gen_symGOT2reg (reg, operands[0]));
6126 operands[0] = gen_sym2PIC (operands[0]);
6127 PUT_MODE (operands[0], Pmode);
6130 if (GET_MODE (operands[0]) == SImode)
6132 if (GET_CODE (operands[0]) == REG)
6133 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6134 else if (GET_CODE (operands[0]) == SUBREG)
6136 operands[0] = SUBREG_REG (operands[0]);
6137 if (GET_MODE (operands[0]) != DImode)
6138 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6142 operands[0] = shallow_copy_rtx (operands[0]);
6143 PUT_MODE (operands[0], DImode);
6146 if (! target_reg_operand (operands[0], DImode))
6147 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6148 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6151 else if (TARGET_SHCOMPACT && operands[2]
6152 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6154 rtx cookie_rtx = operands[2];
6155 long cookie = INTVAL (cookie_rtx);
6156 rtx func = XEXP (operands[0], 0);
6161 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6163 rtx reg = gen_reg_rtx (Pmode);
6165 emit_insn (gen_symGOT2reg (reg, func));
6169 func = legitimize_pic_address (func, Pmode, 0);
6172 /* FIXME: if we could tell whether all argument registers are
6173 already taken, we could decide whether to force the use of
6174 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6175 simple way to tell. We could use the CALL_COOKIE, but we
6176 can't currently tell a register used for regular argument
6177 passing from one that is unused. If we leave it up to reload
6178 to decide which register to use, it seems to always choose
6179 R0_REG, which leaves no available registers in SIBCALL_REGS
6180 to hold the address of the trampoline. */
6181 mach = gen_rtx_REG (SImode, MACH_REG);
6182 r1 = gen_rtx_REG (SImode, R1_REG);
6184 /* Since such a call function may use all call-clobbered
6185 registers, we force a mode switch earlier, so that we don't
6186 run out of registers when adjusting fpscr for the call. */
6187 emit_insn (gen_force_mode_for_call ());
6189 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6190 \"__GCC_shcompact_call_trampoline\");
6193 rtx reg = gen_reg_rtx (Pmode);
6195 emit_insn (gen_symGOT2reg (reg, operands[0]));
6198 operands[0] = force_reg (SImode, operands[0]);
6200 /* We don't need a return trampoline, since the callee will
6201 return directly to the upper caller. */
6202 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6204 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6205 cookie_rtx = GEN_INT (cookie);
6208 emit_move_insn (mach, func);
6209 emit_move_insn (r1, cookie_rtx);
6211 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6214 else if (TARGET_SHCOMPACT && flag_pic
6215 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6216 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6218 rtx reg = gen_reg_rtx (Pmode);
6220 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6221 XEXP (operands[0], 0) = reg;
6223 if (flag_pic && TARGET_SH2
6224 && GET_CODE (operands[0]) == MEM
6225 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6226 /* The PLT needs the PIC register, but the epilogue would have
6227 to restore it, so we can only use PC-relative PIC calls for
6228 static functions. */
6229 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6231 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6235 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6237 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6241 (define_expand "sibcall_value"
6242 [(set (match_operand 0 "" "")
6243 (call (match_operand 1 "" "")
6244 (match_operand 2 "" "")))
6245 (match_operand 3 "" "")]
6249 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6253 (define_insn "call_value_pop_compact"
6254 [(set (match_operand 0 "" "=rf")
6255 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6256 (match_operand 2 "" "")))
6257 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6258 (match_operand 4 "immediate_operand" "n")))
6259 (match_operand 3 "immediate_operand" "n")
6260 (use (reg:SI R0_REG))
6261 (use (reg:SI R1_REG))
6262 (use (reg:PSI FPSCR_REG))
6263 (clobber (reg:SI PR_REG))]
6264 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6266 [(set_attr "type" "call")
6267 (set (attr "fp_mode")
6268 (if_then_else (eq_attr "fpu_single" "yes")
6269 (const_string "single") (const_string "double")))
6270 (set_attr "needs_delay_slot" "yes")])
6272 (define_insn "call_value_pop_compact_rettramp"
6273 [(set (match_operand 0 "" "=rf")
6274 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6275 (match_operand 2 "" "")))
6276 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6277 (match_operand 4 "immediate_operand" "n")))
6278 (match_operand 3 "immediate_operand" "n")
6279 (use (reg:SI R0_REG))
6280 (use (reg:SI R1_REG))
6281 (use (reg:PSI FPSCR_REG))
6282 (clobber (reg:SI R10_REG))
6283 (clobber (reg:SI PR_REG))]
6284 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6286 [(set_attr "type" "call")
6287 (set (attr "fp_mode")
6288 (if_then_else (eq_attr "fpu_single" "yes")
6289 (const_string "single") (const_string "double")))
6290 (set_attr "needs_delay_slot" "yes")])
6292 (define_expand "call_value_pop"
6293 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6294 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6295 (match_operand 2 "" "")))
6296 (match_operand 3 "" "")
6297 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6298 (match_operand 4 "" "")))])]
6302 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6304 rtx cookie_rtx = operands[3];
6305 long cookie = INTVAL (cookie_rtx);
6306 rtx func = XEXP (operands[1], 0);
6311 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6313 rtx reg = gen_reg_rtx (Pmode);
6315 emit_insn (gen_symGOTPLT2reg (reg, func));
6319 func = legitimize_pic_address (func, Pmode, 0);
6322 r0 = gen_rtx_REG (SImode, R0_REG);
6323 r1 = gen_rtx_REG (SImode, R1_REG);
6325 /* Since such a call function may use all call-clobbered
6326 registers, we force a mode switch earlier, so that we don't
6327 run out of registers when adjusting fpscr for the call. */
6328 emit_insn (gen_force_mode_for_call ());
6330 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6331 \"__GCC_shcompact_call_trampoline\");
6334 rtx reg = gen_reg_rtx (Pmode);
6336 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6339 operands[1] = force_reg (SImode, operands[1]);
6341 emit_move_insn (r0, func);
6342 emit_move_insn (r1, cookie_rtx);
6344 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6345 emit_call_insn (gen_call_value_pop_compact_rettramp
6346 (operands[0], operands[1], operands[2],
6347 operands[3], operands[4]));
6349 emit_call_insn (gen_call_value_pop_compact
6350 (operands[0], operands[1], operands[2],
6351 operands[3], operands[4]));
6359 (define_expand "sibcall_epilogue"
6364 sh_expand_epilogue ();
6365 if (TARGET_SHCOMPACT)
6369 /* If epilogue clobbers r0, preserve it in macl. */
6370 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6371 if ((set = single_set (insn))
6372 && GET_CODE (SET_DEST (set)) == REG
6373 && REGNO (SET_DEST (set)) == R0_REG)
6375 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6376 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6379 /* We can't tell at this point whether the sibcall is a
6380 sibcall_compact and, if it is, whether it uses r0 or
6381 mach as operand 2, so let the instructions that
6382 preserve r0 be optimized away if r0 turns out to be
6384 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6385 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6387 i = emit_move_insn (r0, tmp);
6388 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6396 (define_insn "indirect_jump_compact"
6398 (match_operand:SI 0 "arith_reg_operand" "r"))]
6401 [(set_attr "needs_delay_slot" "yes")
6402 (set_attr "type" "jump_ind")])
6404 (define_expand "indirect_jump"
6406 (match_operand 0 "register_operand" ""))]
6410 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6411 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6414 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6415 ;; which can be present in structured code from indirect jumps which can not
6416 ;; be present in structured code. This allows -fprofile-arcs to work.
6418 ;; For SH1 processors.
6419 (define_insn "casesi_jump_1"
6421 (match_operand:SI 0 "register_operand" "r"))
6422 (use (label_ref (match_operand 1 "" "")))]
6425 [(set_attr "needs_delay_slot" "yes")
6426 (set_attr "type" "jump_ind")])
6428 ;; For all later processors.
6429 (define_insn "casesi_jump_2"
6430 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6431 (label_ref (match_operand 1 "" ""))))
6432 (use (label_ref (match_operand 2 "" "")))]
6434 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6436 [(set_attr "needs_delay_slot" "yes")
6437 (set_attr "type" "jump_ind")])
6439 (define_insn "casesi_jump_media"
6440 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6441 (use (label_ref (match_operand 1 "" "")))]
6444 [(set_attr "type" "jump_media")])
6446 ;; Call subroutine returning any type.
6447 ;; ??? This probably doesn't work.
6449 (define_expand "untyped_call"
6450 [(parallel [(call (match_operand 0 "" "")
6452 (match_operand 1 "" "")
6453 (match_operand 2 "" "")])]
6454 "TARGET_SH3E || TARGET_SHMEDIA"
6459 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6461 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6463 rtx set = XVECEXP (operands[2], 0, i);
6464 emit_move_insn (SET_DEST (set), SET_SRC (set));
6467 /* The optimizer does not know that the call sets the function value
6468 registers we stored in the result block. We avoid problems by
6469 claiming that all hard registers are used and clobbered at this
6471 emit_insn (gen_blockage ());
6476 ;; ------------------------------------------------------------------------
6478 ;; ------------------------------------------------------------------------
6481 [(set (reg:SI T_REG)
6482 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6483 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6486 [(set_attr "type" "arith")])
6493 ;; Load address of a label. This is only generated by the casesi expand,
6494 ;; and by machine_dependent_reorg (fixing up fp moves).
6495 ;; This must use unspec, because this only works for labels that are
6499 [(set (reg:SI R0_REG)
6500 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6503 [(set_attr "in_delay_slot" "no")
6504 (set_attr "type" "arith")])
6506 ;; machine_dependent_reorg() will make this a `mova'.
6507 (define_insn "mova_const"
6508 [(set (reg:SI R0_REG)
6509 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6512 [(set_attr "in_delay_slot" "no")
6513 (set_attr "type" "arith")])
6515 (define_expand "GOTaddr2picreg"
6516 [(set (reg:SI R0_REG)
6517 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6519 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6520 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6523 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6524 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6527 operands[1] = gen_datalabel_ref (operands[1]);
6531 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6532 rtx dipic = operands[0];
6533 rtx lab = PATTERN (gen_call_site ());
6536 equiv = operands[1];
6537 operands[1] = gen_rtx_MINUS (DImode,
6541 gen_rtx_MINUS (DImode,
6542 gen_rtx_CONST (DImode,
6545 operands[1] = gen_sym2PIC (operands[1]);
6546 PUT_MODE (operands[1], DImode);
6548 if (GET_MODE (dipic) != DImode)
6549 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6551 if (TARGET_SHMEDIA64)
6552 emit_insn (gen_movdi_const (dipic, operands[1]));
6554 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6556 emit_insn (gen_ptrel (tr, dipic, lab));
6558 if (GET_MODE (operands[0]) != GET_MODE (tr))
6559 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6561 insn = emit_move_insn (operands[0], tr);
6563 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6571 ;; When generating PIC, we must match label_refs especially, because
6572 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6573 ;; them to do, because they can't be loaded directly into
6574 ;; non-branch-target registers.
6576 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6577 (match_operand:DI 1 "" "T"))]
6578 "TARGET_SHMEDIA && flag_pic
6579 && EXTRA_CONSTRAINT_T (operands[1])"
6581 [(set_attr "type" "pt_media")
6582 (set_attr "length" "*")])
6585 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6586 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6587 UNSPEC_DATALABEL)))]
6588 "TARGET_SHMEDIA && flag_pic
6589 && EXTRA_CONSTRAINT_T (operands[1])"
6590 "ptb/u datalabel %1, %0"
6591 [(set_attr "type" "pt_media")
6592 (set_attr "length" "*")])
6594 (define_insn "ptrel"
6595 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6596 (plus:DI (match_operand:DI 1 "register_operand" "r")
6598 (match_operand:DI 2 "" "")]
6600 "%O2: ptrel/u %1, %0"
6601 [(set_attr "type" "ptabs_media")])
6603 (define_expand "builtin_setjmp_receiver"
6604 [(match_operand 0 "" "")]
6608 emit_insn (gen_GOTaddr2picreg ());
6612 (define_expand "call_site"
6613 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6617 static HOST_WIDE_INT i = 0;
6618 operands[0] = GEN_INT (i);
6622 (define_expand "sym_label2reg"
6623 [(set (match_operand:SI 0 "" "")
6626 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6629 (match_operand:SI 2 "" "")
6633 (define_expand "symGOT_load"
6634 [(set (match_dup 2) (match_operand 1 "" ""))
6635 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6636 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6642 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6643 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6647 rtx reg = operands[2];
6649 if (GET_MODE (reg) != DImode)
6650 reg = gen_rtx_SUBREG (DImode, reg, 0);
6653 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6655 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6658 emit_move_insn (operands[2], operands[1]);
6660 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6662 gen_rtx_REG (Pmode, PIC_REG)));
6664 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6666 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6673 (define_expand "sym2GOT"
6674 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6678 (define_expand "symGOT2reg"
6679 [(match_operand 0 "" "") (match_operand 1 "" "")]
6685 gotsym = gen_sym2GOT (operands[1]);
6686 PUT_MODE (gotsym, Pmode);
6687 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6689 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6694 (define_expand "sym2GOTPLT"
6695 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6699 (define_expand "symGOTPLT2reg"
6700 [(match_operand 0 "" "") (match_operand 1 "" "")]
6704 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6708 (define_expand "sym2GOTOFF"
6709 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6713 (define_expand "symGOTOFF2reg"
6714 [(match_operand 0 "" "") (match_operand 1 "" "")]
6718 rtx gotoffsym, insn;
6719 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6721 gotoffsym = gen_sym2GOTOFF (operands[1]);
6722 PUT_MODE (gotoffsym, Pmode);
6723 emit_move_insn (t, gotoffsym);
6724 insn = emit_move_insn (operands[0],
6725 gen_rtx_PLUS (Pmode, t,
6726 gen_rtx_REG (Pmode, PIC_REG)));
6728 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6734 (define_expand "symPLT_label2reg"
6735 [(set (match_operand:SI 0 "" "")
6738 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6742 (match_operand:SI 2 "" "")
6744 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6745 ;; Even though the PIC register is not really used by the call
6746 ;; sequence in which this is expanded, the PLT code assumes the PIC
6747 ;; register is set, so we must not skip its initialization. Since
6748 ;; we only use this expand as part of calling sequences, and never
6749 ;; to take the address of a function, this is the best point to
6750 ;; insert the (use). Using the PLT to take the address of a
6751 ;; function would be wrong, not only because the PLT entry could
6752 ;; then be called from a function that doesn't initialize the PIC
6753 ;; register to the proper GOT, but also because pointers to the
6754 ;; same function might not compare equal, should they be set by
6755 ;; different shared libraries.
6756 (use (reg:SI PIC_REG))]
6760 (define_expand "sym2PIC"
6761 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6765 ;; case instruction for switch statements.
6767 ;; Operand 0 is index
6768 ;; operand 1 is the minimum bound
6769 ;; operand 2 is the maximum bound - minimum bound + 1
6770 ;; operand 3 is CODE_LABEL for the table;
6771 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6773 (define_expand "casesi"
6774 [(match_operand:SI 0 "arith_reg_operand" "")
6775 (match_operand:SI 1 "arith_reg_operand" "")
6776 (match_operand:SI 2 "arith_reg_operand" "")
6777 (match_operand 3 "" "") (match_operand 4 "" "")]
6781 rtx reg = gen_reg_rtx (SImode);
6782 rtx reg2 = gen_reg_rtx (SImode);
6785 rtx reg = gen_reg_rtx (DImode);
6786 rtx reg2 = gen_reg_rtx (DImode);
6787 rtx reg3 = gen_reg_rtx (DImode);
6788 rtx reg4 = gen_reg_rtx (DImode);
6789 rtx reg5 = gen_reg_rtx (DImode);
6791 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6792 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6793 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6795 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6796 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6797 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6798 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6799 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6800 (DImode, operands[3])));
6801 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6802 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6803 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6807 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6808 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6809 /* If optimizing, casesi_worker depends on the mode of the instruction
6810 before label it 'uses' - operands[3]. */
6811 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6813 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6815 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6817 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6818 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6819 operands[3], but to lab. We will fix this up in
6820 machine_dependent_reorg. */
6825 (define_expand "casesi_0"
6826 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6827 (set (match_dup 4) (minus:SI (match_dup 4)
6828 (match_operand:SI 1 "arith_operand" "")))
6830 (gtu:SI (match_dup 4)
6831 (match_operand:SI 2 "arith_reg_operand" "")))
6833 (if_then_else (ne (reg:SI T_REG)
6835 (label_ref (match_operand 3 "" ""))
6840 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6841 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6842 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6844 (define_insn "casesi_worker_0"
6845 [(set (match_operand:SI 0 "register_operand" "=r,r")
6846 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6847 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6848 (clobber (match_scratch:SI 3 "=X,1"))
6849 (clobber (match_scratch:SI 4 "=&z,z"))]
6854 [(set (match_operand:SI 0 "register_operand" "")
6855 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6856 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6857 (clobber (match_scratch:SI 3 ""))
6858 (clobber (match_scratch:SI 4 ""))]
6859 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6860 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6861 (parallel [(set (match_dup 0)
6862 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6863 (label_ref (match_dup 2))] UNSPEC_CASESI))
6864 (clobber (match_dup 3))])
6865 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6866 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6869 [(set (match_operand:SI 0 "register_operand" "")
6870 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6871 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6872 (clobber (match_scratch:SI 3 ""))
6873 (clobber (match_scratch:SI 4 ""))]
6874 "TARGET_SH2 && reload_completed"
6875 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6876 (parallel [(set (match_dup 0)
6877 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6878 (label_ref (match_dup 2))] UNSPEC_CASESI))
6879 (clobber (match_dup 3))])]
6880 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6882 (define_insn "*casesi_worker"
6883 [(set (match_operand:SI 0 "register_operand" "=r,r")
6884 (unspec:SI [(reg:SI R0_REG)
6885 (match_operand:SI 1 "register_operand" "0,r")
6886 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6887 (clobber (match_scratch:SI 3 "=X,1"))]
6891 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6893 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6896 switch (GET_MODE (diff_vec))
6899 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6901 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6903 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6904 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6905 return \"mov.b @(r0,%1),%0\";
6910 [(set_attr "length" "4")])
6912 (define_insn "casesi_shift_media"
6913 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6914 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6915 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6920 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6922 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6925 switch (GET_MODE (diff_vec))
6928 return \"shlli %1, 2, %0\";
6930 return \"shlli %1, 1, %0\";
6932 if (rtx_equal_p (operands[0], operands[1]))
6934 return \"add %1, r63, %0\";
6939 [(set_attr "type" "arith_media")])
6941 (define_insn "casesi_load_media"
6942 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6943 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6944 (match_operand 2 "arith_reg_operand" "r")
6945 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6949 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6951 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6954 switch (GET_MODE (diff_vec))
6957 return \"ldx.l %1, %2, %0\";
6960 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6961 return \"ldx.uw %1, %2, %0\";
6963 return \"ldx.w %1, %2, %0\";
6965 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6966 return \"ldx.ub %1, %2, %0\";
6967 return \"ldx.b %1, %2, %0\";
6972 [(set_attr "type" "load_media")])
6974 (define_expand "return"
6976 "reload_completed && ! sh_need_epilogue ()"
6981 emit_jump_insn (gen_return_media ());
6985 if (TARGET_SHCOMPACT
6986 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
6988 emit_jump_insn (gen_shcompact_return_tramp ());
6993 (define_insn "*return_i"
6995 "TARGET_SH1 && ! (TARGET_SHCOMPACT
6996 && (current_function_args_info.call_cookie
6997 & CALL_COOKIE_RET_TRAMP (1)))
6998 && reload_completed"
7000 [(set_attr "type" "return")
7001 (set_attr "needs_delay_slot" "yes")])
7003 (define_expand "shcompact_return_tramp"
7006 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7009 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7010 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7011 \"__GCC_shcompact_return_trampoline\");
7014 emit_insn (gen_symGOTPLT2reg (reg, sym));
7016 emit_move_insn (reg, sym);
7018 emit_jump_insn (gen_shcompact_return_tramp_i ());
7022 (define_insn "shcompact_return_tramp_i"
7023 [(parallel [(return) (use (reg:SI R0_REG))])]
7025 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7027 [(set_attr "type" "jump_ind")
7028 (set_attr "needs_delay_slot" "yes")])
7030 (define_insn "return_media_i"
7031 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7032 "TARGET_SHMEDIA && reload_completed"
7034 [(set_attr "type" "jump_media")])
7036 (define_expand "return_media"
7038 "TARGET_SHMEDIA && reload_completed"
7041 int tr_regno = sh_media_register_for_return ();
7046 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7049 tr = gen_rtx_REG (DImode, tr_regno);
7050 emit_move_insn (tr, r18);
7053 tr = gen_rtx_REG (DImode, tr_regno);
7055 emit_jump_insn (gen_return_media_i (tr));
7059 (define_insn "shcompact_preserve_incoming_args"
7060 [(set (match_operand:SI 0 "register_operand" "+r")
7061 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7064 [(set_attr "length" "0")])
7066 (define_insn "shcompact_incoming_args"
7067 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7068 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7069 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7070 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7071 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7072 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7073 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7074 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7075 (set (mem:BLK (reg:SI MACL_REG))
7076 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7077 (use (reg:SI R0_REG))
7078 (clobber (reg:SI R0_REG))
7079 (clobber (reg:SI MACL_REG))
7080 (clobber (reg:SI MACH_REG))
7081 (clobber (reg:SI PR_REG))]
7084 [(set_attr "needs_delay_slot" "yes")])
7086 (define_insn "shmedia_save_restore_regs_compact"
7087 [(set (reg:SI SP_REG)
7088 (plus:SI (reg:SI SP_REG)
7089 (match_operand:SI 0 "immediate_operand" "i")))
7090 (use (reg:SI R0_REG))
7091 (clobber (reg:SI PR_REG))]
7093 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7094 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7096 [(set_attr "needs_delay_slot" "yes")])
7098 (define_expand "prologue"
7101 "sh_expand_prologue (); DONE;")
7103 (define_expand "epilogue"
7108 sh_expand_epilogue ();
7109 emit_jump_insn (gen_return ());
7113 (define_insn "blockage"
7114 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7117 [(set_attr "length" "0")])
7119 ;; ------------------------------------------------------------------------
7121 ;; ------------------------------------------------------------------------
7124 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7125 (eq:SI (reg:SI T_REG) (const_int 1)))]
7128 [(set_attr "type" "arith")])
7130 (define_expand "seq"
7131 [(set (match_operand:SI 0 "arith_reg_operand" "")
7138 if (GET_MODE (operands[0]) != DImode)
7139 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7140 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7141 if (sh_compare_op1 != const0_rtx)
7142 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7143 ? GET_MODE (sh_compare_op0)
7144 : GET_MODE (sh_compare_op1),
7147 switch (GET_MODE (sh_compare_op0))
7150 emit_insn (gen_cmpeqdi_media (operands[0],
7151 sh_compare_op0, sh_compare_op1));
7155 if (! TARGET_SHMEDIA_FPU)
7157 emit_insn (gen_cmpeqsf_media (operands[0],
7158 sh_compare_op0, sh_compare_op1));
7162 if (! TARGET_SHMEDIA_FPU)
7164 emit_insn (gen_cmpeqdf_media (operands[0],
7165 sh_compare_op0, sh_compare_op1));
7173 operands[1] = prepare_scc_operands (EQ);
7176 (define_expand "slt"
7177 [(set (match_operand:SI 0 "arith_reg_operand" "")
7184 if (GET_MODE (operands[0]) != DImode)
7185 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7186 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7187 if (sh_compare_op1 != const0_rtx)
7188 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7189 ? GET_MODE (sh_compare_op0)
7190 : GET_MODE (sh_compare_op1),
7193 switch (GET_MODE (sh_compare_op0))
7196 emit_insn (gen_cmpgtdi_media (operands[0],
7197 sh_compare_op1, sh_compare_op0));
7201 if (! TARGET_SHMEDIA_FPU)
7203 emit_insn (gen_cmpgtsf_media (operands[0],
7204 sh_compare_op1, sh_compare_op0));
7208 if (! TARGET_SHMEDIA_FPU)
7210 emit_insn (gen_cmpgtdf_media (operands[0],
7211 sh_compare_op1, sh_compare_op0));
7219 operands[1] = prepare_scc_operands (LT);
7222 (define_expand "sle"
7223 [(match_operand:SI 0 "arith_reg_operand" "")]
7227 rtx tmp = sh_compare_op0;
7231 if (GET_MODE (operands[0]) != DImode)
7232 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7233 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7234 if (sh_compare_op1 != const0_rtx)
7235 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7236 ? GET_MODE (sh_compare_op0)
7237 : GET_MODE (sh_compare_op1),
7240 switch (GET_MODE (sh_compare_op0))
7244 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7246 emit_insn (gen_cmpgtdi_media (tmp,
7247 sh_compare_op0, sh_compare_op1));
7248 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7253 if (! TARGET_SHMEDIA_FPU)
7255 emit_insn (gen_cmpgesf_media (operands[0],
7256 sh_compare_op1, sh_compare_op0));
7260 if (! TARGET_SHMEDIA_FPU)
7262 emit_insn (gen_cmpgedf_media (operands[0],
7263 sh_compare_op1, sh_compare_op0));
7272 sh_compare_op0 = sh_compare_op1;
7273 sh_compare_op1 = tmp;
7274 emit_insn (gen_sge (operands[0]));
7278 (define_expand "sgt"
7279 [(set (match_operand:SI 0 "arith_reg_operand" "")
7286 if (GET_MODE (operands[0]) != DImode)
7287 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7288 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7289 if (sh_compare_op1 != const0_rtx)
7290 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7291 ? GET_MODE (sh_compare_op0)
7292 : GET_MODE (sh_compare_op1),
7295 switch (GET_MODE (sh_compare_op0))
7298 emit_insn (gen_cmpgtdi_media (operands[0],
7299 sh_compare_op0, sh_compare_op1));
7303 if (! TARGET_SHMEDIA_FPU)
7305 emit_insn (gen_cmpgtsf_media (operands[0],
7306 sh_compare_op0, sh_compare_op1));
7310 if (! TARGET_SHMEDIA_FPU)
7312 emit_insn (gen_cmpgtdf_media (operands[0],
7313 sh_compare_op0, sh_compare_op1));
7321 operands[1] = prepare_scc_operands (GT);
7324 (define_expand "sge"
7325 [(set (match_operand:SI 0 "arith_reg_operand" "")
7332 if (GET_MODE (operands[0]) != DImode)
7333 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7334 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7335 if (sh_compare_op1 != const0_rtx)
7336 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7337 ? GET_MODE (sh_compare_op0)
7338 : GET_MODE (sh_compare_op1),
7341 switch (GET_MODE (sh_compare_op0))
7345 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7347 emit_insn (gen_cmpgtdi_media (tmp,
7348 sh_compare_op1, sh_compare_op0));
7349 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7354 if (! TARGET_SHMEDIA_FPU)
7356 emit_insn (gen_cmpgesf_media (operands[0],
7357 sh_compare_op0, sh_compare_op1));
7361 if (! TARGET_SHMEDIA_FPU)
7363 emit_insn (gen_cmpgedf_media (operands[0],
7364 sh_compare_op0, sh_compare_op1));
7373 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7377 rtx lab = gen_label_rtx ();
7378 prepare_scc_operands (EQ);
7379 emit_jump_insn (gen_branch_true (lab));
7380 prepare_scc_operands (GT);
7382 emit_insn (gen_movt (operands[0]));
7385 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7388 operands[1] = prepare_scc_operands (GE);
7391 (define_expand "sgtu"
7392 [(set (match_operand:SI 0 "arith_reg_operand" "")
7399 if (GET_MODE (operands[0]) != DImode)
7400 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7401 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7402 if (sh_compare_op1 != const0_rtx)
7403 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7404 ? GET_MODE (sh_compare_op0)
7405 : GET_MODE (sh_compare_op1),
7408 emit_insn (gen_cmpgtudi_media (operands[0],
7409 sh_compare_op0, sh_compare_op1));
7412 operands[1] = prepare_scc_operands (GTU);
7415 (define_expand "sltu"
7416 [(set (match_operand:SI 0 "arith_reg_operand" "")
7423 if (GET_MODE (operands[0]) != DImode)
7424 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7425 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7426 if (sh_compare_op1 != const0_rtx)
7427 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7428 ? GET_MODE (sh_compare_op0)
7429 : GET_MODE (sh_compare_op1),
7432 emit_insn (gen_cmpgtudi_media (operands[0],
7433 sh_compare_op1, sh_compare_op0));
7436 operands[1] = prepare_scc_operands (LTU);
7439 (define_expand "sleu"
7440 [(set (match_operand:SI 0 "arith_reg_operand" "")
7449 if (GET_MODE (operands[0]) != DImode)
7450 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7451 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7452 if (sh_compare_op1 != const0_rtx)
7453 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7454 ? GET_MODE (sh_compare_op0)
7455 : GET_MODE (sh_compare_op1),
7458 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7460 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7461 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7465 operands[1] = prepare_scc_operands (LEU);
7468 (define_expand "sgeu"
7469 [(set (match_operand:SI 0 "arith_reg_operand" "")
7478 if (GET_MODE (operands[0]) != DImode)
7479 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7480 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7481 if (sh_compare_op1 != const0_rtx)
7482 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7483 ? GET_MODE (sh_compare_op0)
7484 : GET_MODE (sh_compare_op1),
7487 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7489 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7490 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7495 operands[1] = prepare_scc_operands (GEU);
7498 ;; sne moves the complement of the T reg to DEST like this:
7502 ;; This is better than xoring compare result with 1 because it does
7503 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7506 (define_expand "sne"
7507 [(set (match_dup 2) (const_int -1))
7508 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7509 (neg:SI (plus:SI (match_dup 1)
7512 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7521 if (GET_MODE (operands[0]) != DImode)
7522 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7524 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7527 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7528 if (sh_compare_op1 != const0_rtx)
7529 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7530 ? GET_MODE (sh_compare_op0)
7531 : GET_MODE (sh_compare_op1),
7534 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7536 emit_insn (gen_seq (tmp));
7537 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7542 operands[1] = prepare_scc_operands (EQ);
7543 operands[2] = gen_reg_rtx (SImode);
7546 (define_expand "sunordered"
7547 [(set (match_operand:DI 0 "arith_reg_operand" "")
7548 (unordered:DI (match_dup 1) (match_dup 2)))]
7549 "TARGET_SHMEDIA_FPU"
7552 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7553 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7556 ;; Use the same trick for FP sle / sge
7557 (define_expand "movnegt"
7558 [(set (match_dup 2) (const_int -1))
7559 (parallel [(set (match_operand 0 "" "")
7560 (neg:SI (plus:SI (match_dup 1)
7563 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7566 "operands[2] = gen_reg_rtx (SImode);")
7568 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7569 ;; This prevents a regression that occurred when we switched from xor to
7573 [(set (match_operand:SI 0 "arith_reg_operand" "")
7574 (plus:SI (reg:SI T_REG)
7577 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7578 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7581 ;; -------------------------------------------------------------------------
7582 ;; Instructions to cope with inline literal tables
7583 ;; -------------------------------------------------------------------------
7585 ; 2 byte integer in line
7587 (define_insn "consttable_2"
7588 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7589 (match_operand 1 "" "")]
7594 if (operands[1] != const0_rtx)
7595 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7598 [(set_attr "length" "2")
7599 (set_attr "in_delay_slot" "no")])
7601 ; 4 byte integer in line
7603 (define_insn "consttable_4"
7604 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7605 (match_operand 1 "" "")]
7610 if (operands[1] != const0_rtx)
7611 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7614 [(set_attr "length" "4")
7615 (set_attr "in_delay_slot" "no")])
7617 ; 8 byte integer in line
7619 (define_insn "consttable_8"
7620 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7621 (match_operand 1 "" "")]
7626 if (operands[1] != const0_rtx)
7627 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7630 [(set_attr "length" "8")
7631 (set_attr "in_delay_slot" "no")])
7633 ; 4 byte floating point
7635 (define_insn "consttable_sf"
7636 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7637 (match_operand 1 "" "")]
7642 if (operands[1] != const0_rtx)
7645 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7646 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7650 [(set_attr "length" "4")
7651 (set_attr "in_delay_slot" "no")])
7653 ; 8 byte floating point
7655 (define_insn "consttable_df"
7656 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7657 (match_operand 1 "" "")]
7662 if (operands[1] != const0_rtx)
7665 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7666 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7670 [(set_attr "length" "8")
7671 (set_attr "in_delay_slot" "no")])
7673 ;; Alignment is needed for some constant tables; it may also be added for
7674 ;; Instructions at the start of loops, or after unconditional branches.
7675 ;; ??? We would get more accurate lengths if we did instruction
7676 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7677 ;; here is too conservative.
7679 ; align to a two byte boundary
7681 (define_expand "align_2"
7682 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7686 ; align to a four byte boundary
7687 ;; align_4 and align_log are instructions for the starts of loops, or
7688 ;; after unconditional branches, which may take up extra room.
7690 (define_expand "align_4"
7691 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7695 ; align to a cache line boundary
7697 (define_insn "align_log"
7698 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7701 [(set_attr "length" "0")
7702 (set_attr "in_delay_slot" "no")])
7704 ; emitted at the end of the literal table, used to emit the
7705 ; 32bit branch labels if needed.
7707 (define_insn "consttable_end"
7708 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7710 "* return output_jump_label_table ();"
7711 [(set_attr "in_delay_slot" "no")])
7713 ; emitted at the end of the window in the literal table.
7715 (define_insn "consttable_window_end"
7716 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7719 [(set_attr "length" "0")
7720 (set_attr "in_delay_slot" "no")])
7722 ;; -------------------------------------------------------------------------
7724 ;; -------------------------------------------------------------------------
7726 ;; String/block move insn.
7728 (define_expand "movstrsi"
7729 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7730 (mem:BLK (match_operand:BLK 1 "" "")))
7731 (use (match_operand:SI 2 "nonmemory_operand" ""))
7732 (use (match_operand:SI 3 "immediate_operand" ""))
7733 (clobber (reg:SI PR_REG))
7734 (clobber (reg:SI R4_REG))
7735 (clobber (reg:SI R5_REG))
7736 (clobber (reg:SI R0_REG))])]
7737 "TARGET_SH1 && ! TARGET_SH5"
7740 if(expand_block_move (operands))
7745 (define_insn "block_move_real"
7746 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7747 (mem:BLK (reg:SI R5_REG)))
7748 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7749 (clobber (reg:SI PR_REG))
7750 (clobber (reg:SI R0_REG))])]
7751 "TARGET_SH1 && ! TARGET_HARD_SH4"
7753 [(set_attr "type" "sfunc")
7754 (set_attr "needs_delay_slot" "yes")])
7756 (define_insn "block_lump_real"
7757 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7758 (mem:BLK (reg:SI R5_REG)))
7759 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7760 (use (reg:SI R6_REG))
7761 (clobber (reg:SI PR_REG))
7762 (clobber (reg:SI T_REG))
7763 (clobber (reg:SI R4_REG))
7764 (clobber (reg:SI R5_REG))
7765 (clobber (reg:SI R6_REG))
7766 (clobber (reg:SI R0_REG))])]
7767 "TARGET_SH1 && ! TARGET_HARD_SH4"
7769 [(set_attr "type" "sfunc")
7770 (set_attr "needs_delay_slot" "yes")])
7772 (define_insn "block_move_real_i4"
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 (clobber (reg:SI R1_REG))
7779 (clobber (reg:SI R2_REG))])]
7782 [(set_attr "type" "sfunc")
7783 (set_attr "needs_delay_slot" "yes")])
7785 (define_insn "block_lump_real_i4"
7786 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7787 (mem:BLK (reg:SI R5_REG)))
7788 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7789 (use (reg:SI R6_REG))
7790 (clobber (reg:SI PR_REG))
7791 (clobber (reg:SI T_REG))
7792 (clobber (reg:SI R4_REG))
7793 (clobber (reg:SI R5_REG))
7794 (clobber (reg:SI R6_REG))
7795 (clobber (reg:SI R0_REG))
7796 (clobber (reg:SI R1_REG))
7797 (clobber (reg:SI R2_REG))
7798 (clobber (reg:SI R3_REG))])]
7801 [(set_attr "type" "sfunc")
7802 (set_attr "needs_delay_slot" "yes")])
7804 ;; -------------------------------------------------------------------------
7805 ;; Floating point instructions.
7806 ;; -------------------------------------------------------------------------
7808 ;; ??? All patterns should have a type attribute.
7810 (define_expand "fpu_switch0"
7811 [(set (match_operand:SI 0 "" "") (match_dup 2))
7812 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7816 operands[1] = get_fpscr_rtx ();
7817 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7819 operands[2] = legitimize_pic_address (operands[2], SImode,
7820 no_new_pseudos ? operands[0] : 0);
7823 (define_expand "fpu_switch1"
7824 [(set (match_operand:SI 0 "" "") (match_dup 2))
7825 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7826 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7830 operands[1] = get_fpscr_rtx ();
7831 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7833 operands[2] = legitimize_pic_address (operands[2], SImode,
7834 no_new_pseudos ? operands[0] : 0);
7835 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7838 (define_expand "movpsi"
7839 [(set (match_operand:PSI 0 "register_operand" "")
7840 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7844 ;; The c / m alternative is a fake to guide reload to load directly into
7845 ;; fpscr, since reload doesn't know how to use post-increment.
7846 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7847 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7848 ;; predicate after reload.
7849 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7850 ;; like a mac -> gpr move.
7851 (define_insn "fpu_switch"
7852 [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7853 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7855 && (! reload_completed
7856 || true_regnum (operands[0]) != FPSCR_REG
7857 || GET_CODE (operands[1]) != MEM
7858 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7860 ! precision stays the same
7868 [(set_attr "length" "0,2,2,4,2,2,2,2")
7869 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
7872 [(set (reg:PSI FPSCR_REG)
7873 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7874 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7875 [(set (match_dup 0) (match_dup 0))]
7878 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7879 gen_rtx (MEM, PSImode,
7880 gen_rtx (POST_INC, Pmode,
7882 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7886 [(set (reg:PSI FPSCR_REG)
7887 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7889 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7892 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7893 gen_rtx (MEM, PSImode,
7894 gen_rtx (POST_INC, Pmode,
7896 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7899 ;; ??? This uses the fp unit, but has no type indicating that.
7900 ;; If we did that, this would either give a bogus latency or introduce
7901 ;; a bogus FIFO constraint.
7902 ;; Since this insn is currently only used for prologues/epilogues,
7903 ;; it is probably best to claim no function unit, which matches the
7905 (define_insn "toggle_sz"
7906 [(set (reg:PSI FPSCR_REG)
7907 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7911 (define_expand "addsf3"
7912 [(set (match_operand:SF 0 "arith_reg_operand" "")
7913 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7914 (match_operand:SF 2 "arith_reg_operand" "")))]
7915 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7920 expand_sf_binop (&gen_addsf3_i, operands);
7925 (define_insn "*addsf3_media"
7926 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7927 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7928 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7929 "TARGET_SHMEDIA_FPU"
7931 [(set_attr "type" "fparith_media")])
7933 (define_insn_and_split "unary_sf_op"
7934 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7939 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7940 (match_operator:SF 2 "unary_float_operator"
7941 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7942 (parallel [(match_operand 4
7943 "const_int_operand" "n")]))]))
7944 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7945 "TARGET_SHMEDIA_FPU"
7947 "TARGET_SHMEDIA_FPU && reload_completed"
7948 [(set (match_dup 5) (match_dup 6))]
7951 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7952 rtx op1 = gen_rtx_REG (SFmode,
7953 (true_regnum (operands[1])
7954 + (INTVAL (operands[4]) ^ endian)));
7956 operands[7] = gen_rtx_REG (SFmode,
7957 (true_regnum (operands[0])
7958 + (INTVAL (operands[3]) ^ endian)));
7959 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7961 [(set_attr "type" "fparith_media")])
7963 (define_insn_and_split "binary_sf_op"
7964 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7969 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
7970 (match_operator:SF 3 "binary_float_operator"
7971 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7972 (parallel [(match_operand 5
7973 "const_int_operand" "n")]))
7974 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
7975 (parallel [(match_operand 6
7976 "const_int_operand" "n")]))]))
7977 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
7978 "TARGET_SHMEDIA_FPU"
7980 "TARGET_SHMEDIA_FPU && reload_completed"
7981 [(set (match_dup 7) (match_dup 8))]
7984 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7985 rtx op1 = gen_rtx_REG (SFmode,
7986 (true_regnum (operands[1])
7987 + (INTVAL (operands[5]) ^ endian)));
7988 rtx op2 = gen_rtx_REG (SFmode,
7989 (true_regnum (operands[2])
7990 + (INTVAL (operands[6]) ^ endian)));
7992 operands[7] = gen_rtx_REG (SFmode,
7993 (true_regnum (operands[0])
7994 + (INTVAL (operands[4]) ^ endian)));
7995 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
7997 [(set_attr "type" "fparith_media")])
7999 (define_insn "addsf3_i"
8000 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8001 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8002 (match_operand:SF 2 "arith_reg_operand" "f")))
8003 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8006 [(set_attr "type" "fp")
8007 (set_attr "fp_mode" "single")])
8009 (define_expand "subsf3"
8010 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8011 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8012 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8013 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8018 expand_sf_binop (&gen_subsf3_i, operands);
8023 (define_insn "*subsf3_media"
8024 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8025 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8026 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8027 "TARGET_SHMEDIA_FPU"
8029 [(set_attr "type" "fparith_media")])
8031 (define_insn "subsf3_i"
8032 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8033 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8034 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8035 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8038 [(set_attr "type" "fp")
8039 (set_attr "fp_mode" "single")])
8041 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8042 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8043 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8044 ;; SH3E, we use a separate insn for SH3E mulsf3.
8046 (define_expand "mulsf3"
8047 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8048 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8049 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8050 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8054 expand_sf_binop (&gen_mulsf3_i4, operands);
8055 else if (TARGET_SH3E)
8056 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8057 if (! TARGET_SHMEDIA)
8061 (define_insn "*mulsf3_media"
8062 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8063 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8064 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8065 "TARGET_SHMEDIA_FPU"
8067 [(set_attr "type" "fparith_media")])
8069 (define_insn "mulsf3_i4"
8070 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8071 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8072 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8073 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8076 [(set_attr "type" "fp")
8077 (set_attr "fp_mode" "single")])
8079 (define_insn "mulsf3_ie"
8080 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8081 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8082 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8083 "TARGET_SH3E && ! TARGET_SH4"
8085 [(set_attr "type" "fp")])
8087 (define_insn "*mac_media"
8088 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8089 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8090 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8091 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8092 "TARGET_SHMEDIA_FPU"
8094 [(set_attr "type" "fparith_media")])
8096 (define_insn "*macsf3"
8097 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8098 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8099 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8100 (match_operand:SF 3 "arith_reg_operand" "0")))
8101 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8102 "TARGET_SH3E && ! TARGET_SH4"
8104 [(set_attr "type" "fp")
8105 (set_attr "fp_mode" "single")])
8107 (define_expand "divsf3"
8108 [(set (match_operand:SF 0 "arith_reg_operand" "")
8109 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8110 (match_operand:SF 2 "arith_reg_operand" "")))]
8111 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8116 expand_sf_binop (&gen_divsf3_i, operands);
8121 (define_insn "*divsf3_media"
8122 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8123 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8124 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8125 "TARGET_SHMEDIA_FPU"
8127 [(set_attr "type" "fdiv_media")])
8129 (define_insn "divsf3_i"
8130 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8131 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8132 (match_operand:SF 2 "arith_reg_operand" "f")))
8133 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8136 [(set_attr "type" "fdiv")
8137 (set_attr "fp_mode" "single")])
8139 (define_insn "floatdisf2"
8140 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8141 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8142 "TARGET_SHMEDIA_FPU"
8144 [(set_attr "type" "fpconv_media")])
8146 (define_expand "floatsisf2"
8147 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8148 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8149 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8154 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8159 (define_insn "*floatsisf2_media"
8160 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8161 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8162 "TARGET_SHMEDIA_FPU"
8164 [(set_attr "type" "fpconv_media")])
8166 (define_insn "floatsisf2_i4"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8169 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8172 [(set_attr "type" "fp")
8173 (set_attr "fp_mode" "single")])
8175 (define_insn "*floatsisf2_ie"
8176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8178 "TARGET_SH3E && ! TARGET_SH4"
8180 [(set_attr "type" "fp")])
8182 (define_insn "fix_truncsfdi2"
8183 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8184 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8185 "TARGET_SHMEDIA_FPU"
8187 [(set_attr "type" "fpconv_media")])
8189 (define_expand "fix_truncsfsi2"
8190 [(set (match_operand:SI 0 "fpul_operand" "=y")
8191 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8192 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8197 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8202 (define_insn "*fix_truncsfsi2_media"
8203 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8204 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8205 "TARGET_SHMEDIA_FPU"
8207 [(set_attr "type" "fpconv_media")])
8209 (define_insn "fix_truncsfsi2_i4"
8210 [(set (match_operand:SI 0 "fpul_operand" "=y")
8211 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8212 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8215 [(set_attr "type" "ftrc_s")
8216 (set_attr "fp_mode" "single")])
8218 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8219 ;; fix_truncsfsi2_i4.
8220 ;; (define_insn "fix_truncsfsi2_i4_2"
8221 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8222 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8223 ;; (use (reg:PSI FPSCR_REG))
8224 ;; (clobber (reg:SI FPUL_REG))]
8227 ;; [(set_attr "length" "4")
8228 ;; (set_attr "fp_mode" "single")])
8231 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8232 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8233 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8234 ;; (clobber (reg:SI FPUL_REG))]
8236 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8237 ;; (use (match_dup 2))])
8238 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8240 (define_insn "*fixsfsi"
8241 [(set (match_operand:SI 0 "fpul_operand" "=y")
8242 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8243 "TARGET_SH3E && ! TARGET_SH4"
8245 [(set_attr "type" "fp")])
8247 (define_insn "cmpgtsf_t"
8248 [(set (reg:SI T_REG)
8249 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8250 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8251 "TARGET_SH3E && ! TARGET_SH4"
8253 [(set_attr "type" "fp")
8254 (set_attr "fp_mode" "single")])
8256 (define_insn "cmpeqsf_t"
8257 [(set (reg:SI T_REG)
8258 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8259 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8260 "TARGET_SH3E && ! TARGET_SH4"
8262 [(set_attr "type" "fp")
8263 (set_attr "fp_mode" "single")])
8265 (define_insn "ieee_ccmpeqsf_t"
8266 [(set (reg:SI T_REG)
8267 (ior:SI (reg:SI T_REG)
8268 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8269 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8270 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8271 "* return output_ieee_ccmpeq (insn, operands);"
8272 [(set_attr "length" "4")])
8275 (define_insn "cmpgtsf_t_i4"
8276 [(set (reg:SI T_REG)
8277 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8278 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8279 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8282 [(set_attr "type" "fp")
8283 (set_attr "fp_mode" "single")])
8285 (define_insn "cmpeqsf_t_i4"
8286 [(set (reg:SI T_REG)
8287 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8288 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8289 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8292 [(set_attr "type" "fp")
8293 (set_attr "fp_mode" "single")])
8295 (define_insn "*ieee_ccmpeqsf_t_4"
8296 [(set (reg:SI T_REG)
8297 (ior:SI (reg:SI T_REG)
8298 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8299 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8300 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8301 "TARGET_IEEE && TARGET_SH4"
8302 "* return output_ieee_ccmpeq (insn, operands);"
8303 [(set_attr "length" "4")
8304 (set_attr "fp_mode" "single")])
8306 (define_insn "cmpeqsf_media"
8307 [(set (match_operand:DI 0 "register_operand" "=r")
8308 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8309 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8310 "TARGET_SHMEDIA_FPU"
8311 "fcmpeq.s %1, %2, %0"
8312 [(set_attr "type" "fcmp_media")])
8314 (define_insn "cmpgtsf_media"
8315 [(set (match_operand:DI 0 "register_operand" "=r")
8316 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8317 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8318 "TARGET_SHMEDIA_FPU"
8319 "fcmpgt.s %1, %2, %0"
8320 [(set_attr "type" "fcmp_media")])
8322 (define_insn "cmpgesf_media"
8323 [(set (match_operand:DI 0 "register_operand" "=r")
8324 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8325 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8326 "TARGET_SHMEDIA_FPU"
8327 "fcmpge.s %1, %2, %0"
8328 [(set_attr "type" "fcmp_media")])
8330 (define_insn "cmpunsf_media"
8331 [(set (match_operand:DI 0 "register_operand" "=r")
8332 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8333 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8334 "TARGET_SHMEDIA_FPU"
8335 "fcmpun.s %1, %2, %0"
8336 [(set_attr "type" "fcmp_media")])
8338 (define_expand "cmpsf"
8339 [(set (reg:SI T_REG)
8340 (compare (match_operand:SF 0 "arith_operand" "")
8341 (match_operand:SF 1 "arith_operand" "")))]
8342 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8345 sh_compare_op0 = operands[0];
8346 sh_compare_op1 = operands[1];
8350 (define_expand "negsf2"
8351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8352 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8353 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8358 expand_sf_unop (&gen_negsf2_i, operands);
8363 (define_insn "*negsf2_media"
8364 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8365 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8366 "TARGET_SHMEDIA_FPU"
8368 [(set_attr "type" "fmove_media")])
8370 (define_insn "negsf2_i"
8371 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8372 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8373 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8376 [(set_attr "type" "fmove")
8377 (set_attr "fp_mode" "single")])
8379 (define_expand "sqrtsf2"
8380 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8381 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8382 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8387 expand_sf_unop (&gen_sqrtsf2_i, operands);
8392 (define_insn "*sqrtsf2_media"
8393 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8394 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8395 "TARGET_SHMEDIA_FPU"
8397 [(set_attr "type" "fdiv_media")])
8399 (define_insn "sqrtsf2_i"
8400 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8402 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8405 [(set_attr "type" "fdiv")
8406 (set_attr "fp_mode" "single")])
8408 (define_expand "abssf2"
8409 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8410 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8411 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8416 expand_sf_unop (&gen_abssf2_i, operands);
8421 (define_insn "*abssf2_media"
8422 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8423 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8424 "TARGET_SHMEDIA_FPU"
8426 [(set_attr "type" "fmove_media")])
8428 (define_insn "abssf2_i"
8429 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8430 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8431 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8434 [(set_attr "type" "fmove")
8435 (set_attr "fp_mode" "single")])
8437 (define_expand "adddf3"
8438 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8439 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8440 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8441 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8446 expand_df_binop (&gen_adddf3_i, operands);
8451 (define_insn "*adddf3_media"
8452 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8453 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8454 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8455 "TARGET_SHMEDIA_FPU"
8457 [(set_attr "type" "dfparith_media")])
8459 (define_insn "adddf3_i"
8460 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8461 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8462 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8463 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8466 [(set_attr "type" "dfp_arith")
8467 (set_attr "fp_mode" "double")])
8469 (define_expand "subdf3"
8470 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8471 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8472 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8473 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8478 expand_df_binop (&gen_subdf3_i, operands);
8483 (define_insn "*subdf3_media"
8484 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8485 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8486 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8487 "TARGET_SHMEDIA_FPU"
8489 [(set_attr "type" "dfparith_media")])
8491 (define_insn "subdf3_i"
8492 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8493 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8494 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8495 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8498 [(set_attr "type" "dfp_arith")
8499 (set_attr "fp_mode" "double")])
8501 (define_expand "muldf3"
8502 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8503 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8504 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8505 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8510 expand_df_binop (&gen_muldf3_i, operands);
8515 (define_insn "*muldf3_media"
8516 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8517 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8518 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8519 "TARGET_SHMEDIA_FPU"
8521 [(set_attr "type" "dfmul_media")])
8523 (define_insn "muldf3_i"
8524 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8525 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8526 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8527 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8530 [(set_attr "type" "dfp_arith")
8531 (set_attr "fp_mode" "double")])
8533 (define_expand "divdf3"
8534 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8535 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8536 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8537 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8542 expand_df_binop (&gen_divdf3_i, operands);
8547 (define_insn "*divdf3_media"
8548 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8549 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8550 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8551 "TARGET_SHMEDIA_FPU"
8553 [(set_attr "type" "dfdiv_media")])
8555 (define_insn "divdf3_i"
8556 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8557 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8558 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8559 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8562 [(set_attr "type" "dfdiv")
8563 (set_attr "fp_mode" "double")])
8565 (define_insn "floatdidf2"
8566 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8567 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8568 "TARGET_SHMEDIA_FPU"
8570 [(set_attr "type" "dfpconv_media")])
8572 (define_expand "floatsidf2"
8573 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8574 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8575 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8580 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8586 (define_insn "*floatsidf2_media"
8587 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8588 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8589 "TARGET_SHMEDIA_FPU"
8591 [(set_attr "type" "dfpconv_media")])
8593 (define_insn "floatsidf2_i"
8594 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8595 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8596 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8599 [(set_attr "type" "dfp_conv")
8600 (set_attr "fp_mode" "double")])
8602 (define_insn "fix_truncdfdi2"
8603 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8604 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8605 "TARGET_SHMEDIA_FPU"
8607 [(set_attr "type" "dfpconv_media")])
8609 (define_expand "fix_truncdfsi2"
8610 [(set (match_operand:SI 0 "fpul_operand" "")
8611 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8612 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8617 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8623 (define_insn "*fix_truncdfsi2_media"
8624 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8625 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8626 "TARGET_SHMEDIA_FPU"
8628 [(set_attr "type" "dfpconv_media")])
8630 (define_insn "fix_truncdfsi2_i"
8631 [(set (match_operand:SI 0 "fpul_operand" "=y")
8632 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8633 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8636 [(set_attr "type" "dfp_conv")
8637 (set_attr "dfp_comp" "no")
8638 (set_attr "fp_mode" "double")])
8640 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8641 ;; fix_truncdfsi2_i.
8642 ;; (define_insn "fix_truncdfsi2_i4"
8643 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8644 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8645 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8646 ;; (clobber (reg:SI FPUL_REG))]
8649 ;; [(set_attr "length" "4")
8650 ;; (set_attr "fp_mode" "double")])
8653 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8654 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8655 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8656 ;; (clobber (reg:SI FPUL_REG))]
8658 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8659 ;; (use (match_dup 2))])
8660 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8662 (define_insn "cmpgtdf_t"
8663 [(set (reg:SI T_REG)
8664 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8665 (match_operand:DF 1 "arith_reg_operand" "f")))
8666 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8669 [(set_attr "type" "dfp_cmp")
8670 (set_attr "fp_mode" "double")])
8672 (define_insn "cmpeqdf_t"
8673 [(set (reg:SI T_REG)
8674 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8675 (match_operand:DF 1 "arith_reg_operand" "f")))
8676 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8679 [(set_attr "type" "dfp_cmp")
8680 (set_attr "fp_mode" "double")])
8682 (define_insn "*ieee_ccmpeqdf_t"
8683 [(set (reg:SI T_REG)
8684 (ior:SI (reg:SI T_REG)
8685 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8686 (match_operand:DF 1 "arith_reg_operand" "f"))))
8687 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8688 "TARGET_IEEE && TARGET_SH4"
8689 "* return output_ieee_ccmpeq (insn, operands);"
8690 [(set_attr "length" "4")
8691 (set_attr "fp_mode" "double")])
8693 (define_insn "cmpeqdf_media"
8694 [(set (match_operand:DI 0 "register_operand" "=r")
8695 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8696 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8697 "TARGET_SHMEDIA_FPU"
8699 [(set_attr "type" "fcmp_media")])
8701 (define_insn "cmpgtdf_media"
8702 [(set (match_operand:DI 0 "register_operand" "=r")
8703 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8704 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8705 "TARGET_SHMEDIA_FPU"
8707 [(set_attr "type" "fcmp_media")])
8709 (define_insn "cmpgedf_media"
8710 [(set (match_operand:DI 0 "register_operand" "=r")
8711 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8712 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8713 "TARGET_SHMEDIA_FPU"
8715 [(set_attr "type" "fcmp_media")])
8717 (define_insn "cmpundf_media"
8718 [(set (match_operand:DI 0 "register_operand" "=r")
8719 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8720 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8721 "TARGET_SHMEDIA_FPU"
8723 [(set_attr "type" "fcmp_media")])
8725 (define_expand "cmpdf"
8726 [(set (reg:SI T_REG)
8727 (compare (match_operand:DF 0 "arith_operand" "")
8728 (match_operand:DF 1 "arith_operand" "")))]
8729 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8732 sh_compare_op0 = operands[0];
8733 sh_compare_op1 = operands[1];
8737 (define_expand "negdf2"
8738 [(set (match_operand:DF 0 "arith_reg_operand" "")
8739 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8740 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8745 expand_df_unop (&gen_negdf2_i, operands);
8750 (define_insn "*negdf2_media"
8751 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8752 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8753 "TARGET_SHMEDIA_FPU"
8755 [(set_attr "type" "fmove_media")])
8757 (define_insn "negdf2_i"
8758 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8759 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8760 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8763 [(set_attr "type" "fmove")
8764 (set_attr "fp_mode" "double")])
8766 (define_expand "sqrtdf2"
8767 [(set (match_operand:DF 0 "arith_reg_operand" "")
8768 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8769 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8774 expand_df_unop (&gen_sqrtdf2_i, operands);
8779 (define_insn "*sqrtdf2_media"
8780 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8781 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8782 "TARGET_SHMEDIA_FPU"
8784 [(set_attr "type" "dfdiv_media")])
8786 (define_insn "sqrtdf2_i"
8787 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8788 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8789 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8792 [(set_attr "type" "dfdiv")
8793 (set_attr "fp_mode" "double")])
8795 (define_expand "absdf2"
8796 [(set (match_operand:DF 0 "arith_reg_operand" "")
8797 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8798 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8803 expand_df_unop (&gen_absdf2_i, operands);
8808 (define_insn "*absdf2_media"
8809 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8810 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8811 "TARGET_SHMEDIA_FPU"
8813 [(set_attr "type" "fmove_media")])
8815 (define_insn "absdf2_i"
8816 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8817 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8818 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8821 [(set_attr "type" "fmove")
8822 (set_attr "fp_mode" "double")])
8824 (define_expand "extendsfdf2"
8825 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8826 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8827 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8832 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8838 (define_insn "*extendsfdf2_media"
8839 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8840 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8841 "TARGET_SHMEDIA_FPU"
8843 [(set_attr "type" "dfpconv_media")])
8845 (define_insn "extendsfdf2_i4"
8846 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8847 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8848 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8851 [(set_attr "type" "fp")
8852 (set_attr "fp_mode" "double")])
8854 (define_expand "truncdfsf2"
8855 [(set (match_operand:SF 0 "fpul_operand" "")
8856 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8857 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8862 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8868 (define_insn "*truncdfsf2_media"
8869 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8870 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8871 "TARGET_SHMEDIA_FPU"
8873 [(set_attr "type" "dfpconv_media")])
8875 (define_insn "truncdfsf2_i4"
8876 [(set (match_operand:SF 0 "fpul_operand" "=y")
8877 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8878 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8881 [(set_attr "type" "fp")
8882 (set_attr "fp_mode" "double")])
8884 ;; Bit field extract patterns. These give better code for packed bitfields,
8885 ;; because they allow auto-increment addresses to be generated.
8887 (define_expand "insv"
8888 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8889 (match_operand:SI 1 "immediate_operand" "")
8890 (match_operand:SI 2 "immediate_operand" ""))
8891 (match_operand:SI 3 "general_operand" ""))]
8892 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8895 rtx addr_target, orig_address, shift_reg, qi_val;
8896 HOST_WIDE_INT bitsize, size, v;
8897 rtx x = operands[3];
8899 /* ??? expmed doesn't care for non-register predicates. */
8900 if (! memory_operand (operands[0], VOIDmode)
8901 || ! immediate_operand (operands[1], VOIDmode)
8902 || ! immediate_operand (operands[2], VOIDmode)
8903 || ! general_operand (x, VOIDmode))
8905 /* If this isn't a 16 / 24 / 32 bit field, or if
8906 it doesn't start on a byte boundary, then fail. */
8907 bitsize = INTVAL (operands[1]);
8908 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8909 || (INTVAL (operands[2]) % 8) != 0)
8913 orig_address = XEXP (operands[0], 0);
8914 shift_reg = gen_reg_rtx (SImode);
8915 if (GET_CODE (x) == CONST_INT)
8918 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8922 emit_insn (gen_movsi (shift_reg, operands[3]));
8923 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8925 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8927 operands[0] = replace_equiv_address (operands[0], addr_target);
8928 emit_insn (gen_movqi (operands[0], qi_val));
8932 if (GET_CODE (x) == CONST_INT)
8934 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8937 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8938 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8940 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8941 emit_insn (gen_movqi (operands[0], qi_val));
8947 ;; -------------------------------------------------------------------------
8949 ;; -------------------------------------------------------------------------
8951 ;; This matches cases where a stack pointer increment at the start of the
8952 ;; epilogue combines with a stack slot read loading the return value.
8955 [(set (match_operand:SI 0 "arith_reg_operand" "")
8956 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8957 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8958 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8961 ;; See the comment on the dt combiner pattern above.
8964 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8965 (plus:SI (match_dup 0)
8968 (eq:SI (match_dup 0)
8973 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
8974 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
8975 ;; reload when the constant is too large for a reg+offset address.
8977 ;; ??? We would get much better code if this was done in reload. This would
8978 ;; require modifying find_reloads_address to recognize that if the constant
8979 ;; is out-of-range for an immediate add, then we get better code by reloading
8980 ;; the constant into a register than by reloading the sum into a register,
8981 ;; since the former is one instruction shorter if the address does not need
8982 ;; to be offsettable. Unfortunately this does not work, because there is
8983 ;; only one register, r0, that can be used as an index register. This register
8984 ;; is also the function return value register. So, if we try to force reload
8985 ;; to use double-reg addresses, then we end up with some instructions that
8986 ;; need to use r0 twice. The only way to fix this is to change the calling
8987 ;; convention so that r0 is not used to return values.
8990 [(set (match_operand:SI 0 "register_operand" "=r")
8991 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8992 (set (mem:SI (match_dup 0))
8993 (match_operand:SI 2 "general_movsrc_operand" ""))]
8994 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8995 "mov.l %2,@(%0,%1)")
8998 [(set (match_operand:SI 0 "register_operand" "=r")
8999 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9000 (set (match_operand:SI 2 "general_movdst_operand" "")
9001 (mem:SI (match_dup 0)))]
9002 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9003 "mov.l @(%0,%1),%2")
9006 [(set (match_operand:SI 0 "register_operand" "=r")
9007 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9008 (set (mem:HI (match_dup 0))
9009 (match_operand:HI 2 "general_movsrc_operand" ""))]
9010 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9011 "mov.w %2,@(%0,%1)")
9014 [(set (match_operand:SI 0 "register_operand" "=r")
9015 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9016 (set (match_operand:HI 2 "general_movdst_operand" "")
9017 (mem:HI (match_dup 0)))]
9018 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9019 "mov.w @(%0,%1),%2")
9022 [(set (match_operand:SI 0 "register_operand" "=r")
9023 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9024 (set (mem:QI (match_dup 0))
9025 (match_operand:QI 2 "general_movsrc_operand" ""))]
9026 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9027 "mov.b %2,@(%0,%1)")
9030 [(set (match_operand:SI 0 "register_operand" "=r")
9031 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9032 (set (match_operand:QI 2 "general_movdst_operand" "")
9033 (mem:QI (match_dup 0)))]
9034 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9035 "mov.b @(%0,%1),%2")
9038 [(set (match_operand:SI 0 "register_operand" "=r")
9039 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9040 (set (mem:SF (match_dup 0))
9041 (match_operand:SF 2 "general_movsrc_operand" ""))]
9042 "TARGET_SH1 && REGNO (operands[0]) == 0
9043 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9044 || (GET_CODE (operands[2]) == SUBREG
9045 && REGNO (SUBREG_REG (operands[2])) < 16))
9046 && reg_unused_after (operands[0], insn)"
9047 "mov.l %2,@(%0,%1)")
9050 [(set (match_operand:SI 0 "register_operand" "=r")
9051 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9052 (set (match_operand:SF 2 "general_movdst_operand" "")
9054 (mem:SF (match_dup 0)))]
9055 "TARGET_SH1 && REGNO (operands[0]) == 0
9056 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9057 || (GET_CODE (operands[2]) == SUBREG
9058 && REGNO (SUBREG_REG (operands[2])) < 16))
9059 && reg_unused_after (operands[0], insn)"
9060 "mov.l @(%0,%1),%2")
9063 [(set (match_operand:SI 0 "register_operand" "=r")
9064 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9065 (set (mem:SF (match_dup 0))
9066 (match_operand:SF 2 "general_movsrc_operand" ""))]
9067 "TARGET_SH3E && REGNO (operands[0]) == 0
9068 && ((GET_CODE (operands[2]) == REG
9069 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9070 || (GET_CODE (operands[2]) == SUBREG
9071 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9072 && reg_unused_after (operands[0], insn)"
9073 "fmov{.s|} %2,@(%0,%1)")
9076 [(set (match_operand:SI 0 "register_operand" "=r")
9077 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9078 (set (match_operand:SF 2 "general_movdst_operand" "")
9080 (mem:SF (match_dup 0)))]
9081 "TARGET_SH3E && REGNO (operands[0]) == 0
9082 && ((GET_CODE (operands[2]) == REG
9083 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9084 || (GET_CODE (operands[2]) == SUBREG
9085 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9086 && reg_unused_after (operands[0], insn)"
9087 "fmov{.s|} @(%0,%1),%2")
9089 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9090 (define_insn "sp_switch_1"
9097 xoperands[0] = sp_switch;
9098 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9099 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9100 return \"mov r0,r15\";
9102 [(set_attr "length" "10")])
9104 ;; Switch back to the original stack for interrupt functions with the
9105 ;; sp_switch attribute. */
9106 (define_insn "sp_switch_2"
9109 "mov.l @r15+,r15\;mov.l @r15+,r0"
9110 [(set_attr "length" "4")])
9112 ;; Integer vector moves
9114 (define_expand "movv8qi"
9115 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9116 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9118 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9120 (define_insn "movv8qi_i"
9121 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9122 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9124 && (register_operand (operands[0], V8QImode)
9125 || register_operand (operands[1], V8QImode))"
9132 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9133 (set_attr "length" "4,4,16,4,4")])
9136 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9137 (subreg:V8QI (const_int 0) 0))]
9140 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9141 (const_int 0) (const_int 0) (const_int 0)
9142 (const_int 0) (const_int 0)]))])
9145 [(set (match_operand 0 "arith_reg_dest" "")
9146 (match_operand 1 "sh_rep_vec" ""))]
9147 "TARGET_SHMEDIA && reload_completed
9148 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9149 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9150 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9151 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9152 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9153 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9154 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9155 [(set (match_dup 0) (match_dup 1))
9159 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9160 rtx elt1 = XVECEXP (operands[1], 0, 1);
9163 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9167 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9168 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9170 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9171 operands[1] = XVECEXP (operands[1], 0, 0);
9174 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9175 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9176 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9177 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9180 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9182 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9188 [(set (match_operand 0 "arith_reg_dest" "")
9189 (match_operand 1 "sh_const_vec" ""))]
9190 "TARGET_SHMEDIA && reload_completed
9191 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9192 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9193 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9194 [(set (match_dup 0) (match_dup 1))]
9197 rtx v = operands[1];
9198 enum machine_mode new_mode
9199 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9201 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9203 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9206 (define_expand "movv2hi"
9207 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9208 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9210 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9212 (define_insn "movv2hi_i"
9213 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9214 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9216 && (register_operand (operands[0], V2HImode)
9217 || register_operand (operands[1], V2HImode))"
9224 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9225 (set_attr "length" "4,4,16,4,4")])
9227 (define_expand "movv4hi"
9228 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9229 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9231 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9233 (define_insn "movv4hi_i"
9234 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9235 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9237 && (register_operand (operands[0], V4HImode)
9238 || register_operand (operands[1], V4HImode))"
9245 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9246 (set_attr "length" "4,4,16,4,4")])
9248 (define_expand "movv2si"
9249 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9250 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9252 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9254 (define_insn "movv2si_i"
9255 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9256 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9258 && (register_operand (operands[0], V2SImode)
9259 || register_operand (operands[1], V2SImode))"
9266 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9267 (set_attr "length" "4,4,16,4,4")])
9269 ;; Multimedia Intrinsics
9271 (define_insn "absv2si2"
9272 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9273 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9276 [(set_attr "type" "mcmp_media")])
9278 (define_insn "absv4hi2"
9279 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9280 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9283 [(set_attr "type" "mcmp_media")])
9285 (define_insn "addv2si3"
9286 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9287 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9288 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9291 [(set_attr "type" "arith_media")])
9293 (define_insn "addv4hi3"
9294 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9295 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9296 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9299 [(set_attr "type" "arith_media")])
9301 (define_insn "ssaddv2si3"
9302 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9303 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9304 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9306 "madds.l %1, %2, %0"
9307 [(set_attr "type" "mcmp_media")])
9309 (define_insn "usaddv8qi3"
9310 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9311 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9312 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9314 "madds.ub %1, %2, %0"
9315 [(set_attr "type" "mcmp_media")])
9317 (define_insn "ssaddv4hi3"
9318 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9319 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9320 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9322 "madds.w %1, %2, %0"
9323 [(set_attr "type" "mcmp_media")])
9325 (define_insn "negcmpeqv8qi"
9326 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9327 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9328 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9330 "mcmpeq.b %N1, %N2, %0"
9331 [(set_attr "type" "mcmp_media")])
9333 (define_insn "negcmpeqv2si"
9334 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9335 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9336 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9338 "mcmpeq.l %N1, %N2, %0"
9339 [(set_attr "type" "mcmp_media")])
9341 (define_insn "negcmpeqv4hi"
9342 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9343 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9344 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9346 "mcmpeq.w %N1, %N2, %0"
9347 [(set_attr "type" "mcmp_media")])
9349 (define_insn "negcmpgtuv8qi"
9350 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9351 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9352 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9354 "mcmpgt.ub %N1, %N2, %0"
9355 [(set_attr "type" "mcmp_media")])
9357 (define_insn "negcmpgtv2si"
9358 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9359 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9360 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9362 "mcmpgt.l %N1, %N2, %0"
9363 [(set_attr "type" "mcmp_media")])
9365 (define_insn "negcmpgtv4hi"
9366 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9367 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9368 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9370 "mcmpgt.w %N1, %N2, %0"
9371 [(set_attr "type" "mcmp_media")])
9374 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9375 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9376 (match_operand:DI 2 "arith_reg_operand" "r"))
9377 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9378 (not:DI (match_dup 2)))))]
9381 [(set_attr "type" "arith_media")])
9383 (define_insn "mcnvs_lw"
9384 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9386 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9387 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9389 "mcnvs.lw %N1, %N2, %0"
9390 [(set_attr "type" "mcmp_media")])
9392 (define_insn "mcnvs_wb"
9393 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9395 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9396 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9398 "mcnvs.wb %N1, %N2, %0"
9399 [(set_attr "type" "mcmp_media")])
9401 (define_insn "mcnvs_wub"
9402 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9404 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9405 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9407 "mcnvs.wub %N1, %N2, %0"
9408 [(set_attr "type" "mcmp_media")])
9410 (define_insn "mextr_rl"
9411 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9412 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9413 (match_operand:HI 3 "mextr_bit_offset" "i"))
9414 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9415 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9416 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9419 static char templ[16];
9421 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9422 (int) INTVAL (operands[3]) >> 3);
9425 [(set_attr "type" "arith_media")])
9427 (define_insn "*mextr_lr"
9428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9429 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9430 (match_operand:HI 3 "mextr_bit_offset" "i"))
9431 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9432 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9433 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9436 static char templ[16];
9438 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9439 (int) INTVAL (operands[4]) >> 3);
9442 [(set_attr "type" "arith_media")])
9444 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9445 ; vector then varies depending on endianness.
9446 (define_expand "mextr1"
9447 [(match_operand:DI 0 "arith_reg_dest" "")
9448 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9449 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9453 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9454 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9458 (define_expand "mextr2"
9459 [(match_operand:DI 0 "arith_reg_dest" "")
9460 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9461 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9465 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9466 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9470 (define_expand "mextr3"
9471 [(match_operand:DI 0 "arith_reg_dest" "")
9472 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9473 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9477 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9478 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9482 (define_expand "mextr4"
9483 [(match_operand:DI 0 "arith_reg_dest" "")
9484 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9485 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9489 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9490 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9494 (define_expand "mextr5"
9495 [(match_operand:DI 0 "arith_reg_dest" "")
9496 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9497 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9501 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9502 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9506 (define_expand "mextr6"
9507 [(match_operand:DI 0 "arith_reg_dest" "")
9508 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9509 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9513 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9514 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9518 (define_expand "mextr7"
9519 [(match_operand:DI 0 "arith_reg_dest" "")
9520 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9521 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9525 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9526 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9530 (define_expand "mmacfx_wl"
9531 [(match_operand:V2SI 0 "arith_reg_dest" "")
9532 (match_operand:V2HI 1 "extend_reg_operand" "")
9533 (match_operand:V2HI 2 "extend_reg_operand" "")
9534 (match_operand:V2SI 3 "arith_reg_operand" "")]
9538 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9539 operands[1], operands[2]));
9543 (define_insn "mmacfx_wl_i"
9544 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9546 (match_operand:V2SI 1 "arith_reg_operand" "0")
9551 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9552 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9555 "mmacfx.wl %2, %3, %0"
9556 [(set_attr "type" "mac_media")])
9558 (define_expand "mmacnfx_wl"
9559 [(match_operand:V2SI 0 "arith_reg_dest" "")
9560 (match_operand:V2HI 1 "extend_reg_operand" "")
9561 (match_operand:V2HI 2 "extend_reg_operand" "")
9562 (match_operand:V2SI 3 "arith_reg_operand" "")]
9566 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9567 operands[1], operands[2]));
9571 (define_insn "mmacnfx_wl_i"
9572 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9574 (match_operand:V2SI 1 "arith_reg_operand" "0")
9579 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9580 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9583 "mmacnfx.wl %2, %3, %0"
9584 [(set_attr "type" "mac_media")])
9586 (define_insn "mulv2si3"
9587 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9588 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9589 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9592 [(set_attr "type" "d2mpy_media")])
9594 (define_insn "mulv4hi3"
9595 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9596 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9597 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9600 [(set_attr "type" "dmpy_media")])
9602 (define_insn "mmulfx_l"
9603 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9607 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9608 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9611 "mmulfx.l %1, %2, %0"
9612 [(set_attr "type" "d2mpy_media")])
9614 (define_insn "mmulfx_w"
9615 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9619 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9620 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9623 "mmulfx.w %1, %2, %0"
9624 [(set_attr "type" "dmpy_media")])
9626 (define_insn "mmulfxrp_w"
9627 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9632 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9633 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9637 "mmulfxrp.w %1, %2, %0"
9638 [(set_attr "type" "dmpy_media")])
9640 (define_expand "mmulhi_wl"
9641 [(match_operand:V2SI 0 "arith_reg_dest" "")
9642 (match_operand:V4HI 1 "arith_reg_operand" "")
9643 (match_operand:V4HI 2 "arith_reg_operand" "")]
9647 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9648 (operands[0], operands[1], operands[2]));
9652 (define_expand "mmullo_wl"
9653 [(match_operand:V2SI 0 "arith_reg_dest" "")
9654 (match_operand:V4HI 1 "arith_reg_operand" "")
9655 (match_operand:V4HI 2 "arith_reg_operand" "")]
9659 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9660 (operands[0], operands[1], operands[2]));
9664 (define_insn "mmul23_wl"
9665 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9668 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9669 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9670 (parallel [(const_int 2) (const_int 3)])))]
9672 "* return (TARGET_LITTLE_ENDIAN
9673 ? \"mmulhi.wl %1, %2, %0\"
9674 : \"mmullo.wl %1, %2, %0\");"
9675 [(set_attr "type" "dmpy_media")])
9677 (define_insn "mmul01_wl"
9678 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9681 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9682 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9683 (parallel [(const_int 0) (const_int 1)])))]
9685 "* return (TARGET_LITTLE_ENDIAN
9686 ? \"mmullo.wl %1, %2, %0\"
9687 : \"mmulhi.wl %1, %2, %0\");"
9688 [(set_attr "type" "dmpy_media")])
9690 (define_expand "mmulsum_wq"
9691 [(match_operand:DI 0 "arith_reg_dest" "")
9692 (match_operand:V4HI 1 "arith_reg_operand" "")
9693 (match_operand:V4HI 2 "arith_reg_operand" "")
9694 (match_operand:DI 3 "arith_reg_operand" "")]
9698 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9699 operands[1], operands[2]));
9703 (define_insn "mmulsum_wq_i"
9704 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9705 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9710 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9711 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9712 (parallel [(const_int 0)]))
9713 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9714 (sign_extend:V4DI (match_dup 3)))
9715 (parallel [(const_int 1)])))
9717 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9718 (sign_extend:V4DI (match_dup 3)))
9719 (parallel [(const_int 2)]))
9720 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9721 (sign_extend:V4DI (match_dup 3)))
9722 (parallel [(const_int 3)]))))))]
9724 "mmulsum.wq %2, %3, %0"
9725 [(set_attr "type" "mac_media")])
9727 (define_expand "mperm_w"
9728 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9729 (match_operand:V4HI 1 "arith_reg_operand" "r")
9730 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9734 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9735 (operands[0], operands[1], operands[2]));
9739 ; This use of vec_select isn't exactly correct according to rtl.texi
9740 ; (because not constant), but it seems a straightforward extension.
9741 (define_insn "mperm_w_little"
9742 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9744 (match_operand:V4HI 1 "arith_reg_operand" "r")
9746 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9747 (const_int 2) (const_int 0))
9748 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9749 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9750 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9751 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9752 "mperm.w %1, %N2, %0"
9753 [(set_attr "type" "arith_media")])
9755 (define_insn "mperm_w_big"
9756 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9758 (match_operand:V4HI 1 "arith_reg_operand" "r")
9760 [(zero_extract:QI (not:QI (match_operand:QI 2
9761 "extend_reg_or_0_operand" "rU"))
9762 (const_int 2) (const_int 0))
9763 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9764 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9765 (zero_extract:QI (not:QI (match_dup 2))
9766 (const_int 2) (const_int 6))])))]
9767 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9768 "mperm.w %1, %N2, %0"
9769 [(set_attr "type" "arith_media")])
9771 (define_insn "mperm_w0"
9772 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9773 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9774 "trunc_hi_operand" "r"))))]
9776 "mperm.w %1, r63, %0"
9777 [(set_attr "type" "arith_media")])
9779 (define_expand "msad_ubq"
9780 [(match_operand:DI 0 "arith_reg_dest" "")
9781 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9782 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9783 (match_operand:DI 3 "arith_reg_operand" "")]
9787 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9788 operands[1], operands[2]));
9792 (define_insn "msad_ubq_i"
9793 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9798 (match_operand:DI 1 "arith_reg_operand" "0")
9799 (abs:DI (vec_select:DI
9802 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9804 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9805 (parallel [(const_int 0)]))))
9806 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9807 (zero_extend:V8DI (match_dup 3)))
9808 (parallel [(const_int 1)]))))
9810 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9811 (zero_extend:V8DI (match_dup 3)))
9812 (parallel [(const_int 2)])))
9813 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9814 (zero_extend:V8DI (match_dup 3)))
9815 (parallel [(const_int 3)])))))
9818 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9819 (zero_extend:V8DI (match_dup 3)))
9820 (parallel [(const_int 4)])))
9821 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9822 (zero_extend:V8DI (match_dup 3)))
9823 (parallel [(const_int 5)]))))
9825 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9826 (zero_extend:V8DI (match_dup 3)))
9827 (parallel [(const_int 6)])))
9828 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9829 (zero_extend:V8DI (match_dup 3)))
9830 (parallel [(const_int 7)])))))))]
9832 "msad.ubq %N2, %N3, %0"
9833 [(set_attr "type" "mac_media")])
9835 (define_insn "mshalds_l"
9836 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9839 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9840 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9843 "mshalds.l %1, %2, %0"
9844 [(set_attr "type" "mcmp_media")])
9846 (define_insn "mshalds_w"
9847 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9850 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9851 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9854 "mshalds.w %1, %2, %0"
9855 [(set_attr "type" "mcmp_media")])
9857 (define_insn "ashrv2si3"
9858 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9859 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9860 (match_operand:DI 2 "arith_reg_operand" "r")))]
9862 "mshard.l %1, %2, %0"
9863 [(set_attr "type" "arith_media")])
9865 (define_insn "ashrv4hi3"
9866 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9867 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9868 (match_operand:DI 2 "arith_reg_operand" "r")))]
9870 "mshard.w %1, %2, %0"
9871 [(set_attr "type" "arith_media")])
9873 (define_insn "mshards_q"
9874 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9876 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9877 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9879 "mshards.q %1, %N2, %0"
9880 [(set_attr "type" "mcmp_media")])
9882 (define_expand "mshfhi_b"
9883 [(match_operand:V8QI 0 "arith_reg_dest" "")
9884 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9885 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9889 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9890 (operands[0], operands[1], operands[2]));
9894 (define_expand "mshflo_b"
9895 [(match_operand:V8QI 0 "arith_reg_dest" "")
9896 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9897 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9901 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9902 (operands[0], operands[1], operands[2]));
9906 (define_insn "mshf4_b"
9908 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9910 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9911 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9912 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9913 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9915 "* return (TARGET_LITTLE_ENDIAN
9916 ? \"mshfhi.b %N1, %N2, %0\"
9917 : \"mshflo.b %N1, %N2, %0\");"
9918 [(set_attr "type" "arith_media")])
9920 (define_insn "mshf0_b"
9922 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9924 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9925 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9926 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9927 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9929 "* return (TARGET_LITTLE_ENDIAN
9930 ? \"mshflo.b %N1, %N2, %0\"
9931 : \"mshfhi.b %N1, %N2, %0\");"
9932 [(set_attr "type" "arith_media")])
9934 (define_expand "mshfhi_l"
9935 [(match_operand:V2SI 0 "arith_reg_dest" "")
9936 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9937 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9941 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9942 (operands[0], operands[1], operands[2]));
9946 (define_expand "mshflo_l"
9947 [(match_operand:V2SI 0 "arith_reg_dest" "")
9948 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9949 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9953 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9954 (operands[0], operands[1], operands[2]));
9958 (define_insn "mshf4_l"
9959 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9961 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9962 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9963 (parallel [(const_int 1) (const_int 3)])))]
9965 "* return (TARGET_LITTLE_ENDIAN
9966 ? \"mshfhi.l %N1, %N2, %0\"
9967 : \"mshflo.l %N1, %N2, %0\");"
9968 [(set_attr "type" "arith_media")])
9970 (define_insn "mshf0_l"
9971 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9973 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9974 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9975 (parallel [(const_int 0) (const_int 2)])))]
9977 "* return (TARGET_LITTLE_ENDIAN
9978 ? \"mshflo.l %N1, %N2, %0\"
9979 : \"mshfhi.l %N1, %N2, %0\");"
9980 [(set_attr "type" "arith_media")])
9982 (define_expand "mshfhi_w"
9983 [(match_operand:V4HI 0 "arith_reg_dest" "")
9984 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9985 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9989 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
9990 (operands[0], operands[1], operands[2]));
9994 (define_expand "mshflo_w"
9995 [(match_operand:V4HI 0 "arith_reg_dest" "")
9996 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9997 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10001 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10002 (operands[0], operands[1], operands[2]));
10006 (define_insn "mshf4_w"
10007 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10009 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10010 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10011 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10013 "* return (TARGET_LITTLE_ENDIAN
10014 ? \"mshfhi.w %N1, %N2, %0\"
10015 : \"mshflo.w %N1, %N2, %0\");"
10016 [(set_attr "type" "arith_media")])
10018 (define_insn "mshf0_w"
10019 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10021 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10022 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10023 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10025 "* return (TARGET_LITTLE_ENDIAN
10026 ? \"mshflo.w %N1, %N2, %0\"
10027 : \"mshfhi.w %N1, %N2, %0\");"
10028 [(set_attr "type" "arith_media")])
10030 (define_insn "mshflo_w_x"
10031 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10033 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10034 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10035 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10037 "mshflo.w %N1, %N2, %0"
10038 [(set_attr "type" "arith_media")])
10040 /* These are useful to expand ANDs and as combiner patterns. */
10041 (define_insn_and_split "mshfhi_l_di"
10042 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10043 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10045 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10046 (const_int -4294967296))))]
10049 mshfhi.l %N1, %N2, %0
10051 "TARGET_SHMEDIA && reload_completed
10052 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10053 [(set (match_dup 3) (match_dup 4))
10054 (set (match_dup 5) (match_dup 6))]
10057 operands[3] = gen_lowpart (SImode, operands[0]);
10058 operands[4] = gen_highpart (SImode, operands[1]);
10059 operands[5] = gen_highpart (SImode, operands[0]);
10060 operands[6] = gen_highpart (SImode, operands[2]);
10062 [(set_attr "type" "arith_media")])
10064 (define_insn "*mshfhi_l_di_rev"
10065 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10066 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10067 (const_int -4294967296))
10068 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10071 "mshfhi.l %N2, %N1, %0"
10072 [(set_attr "type" "arith_media")])
10075 [(set (match_operand:DI 0 "arith_reg_dest" "")
10076 (ior:DI (zero_extend:DI (match_operand:SI 1
10077 "extend_reg_or_0_operand" ""))
10078 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10079 (const_int -4294967296))))
10080 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10085 emit_insn (gen_ashldi3_media (operands[3],
10086 simplify_gen_subreg (DImode, operands[1],
10089 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10093 (define_insn "mshflo_l_di"
10094 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10095 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10096 (const_int 4294967295))
10097 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10101 "mshflo.l %N1, %N2, %0"
10102 [(set_attr "type" "arith_media")])
10104 (define_insn "*mshflo_l_di_rev"
10105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10106 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10108 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10109 (const_int 4294967295))))]
10112 "mshflo.l %N2, %N1, %0"
10113 [(set_attr "type" "arith_media")])
10115 ;; Combiner pattern for trampoline initialization.
10116 (define_insn_and_split "*double_shori"
10117 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10118 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10120 (match_operand:DI 2 "const_int_operand" "n")))]
10122 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10124 "rtx_equal_p (operands[0], operands[1])"
10128 HOST_WIDE_INT v = INTVAL (operands[2]);
10130 emit_insn (gen_shori_media (operands[0], operands[0],
10131 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10132 emit_insn (gen_shori_media (operands[0], operands[0],
10133 gen_int_mode (v, HImode)));
10138 (define_insn "*mshflo_l_di_x"
10139 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10140 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10142 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10146 "mshflo.l %N1, %N2, %0"
10147 [(set_attr "type" "arith_media")])
10149 (define_insn_and_split "concat_v2sf"
10150 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10151 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10152 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10153 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10157 mshflo.l %N1, %N2, %0
10160 "TARGET_SHMEDIA && reload_completed
10161 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10162 [(set (match_dup 3) (match_dup 1))
10163 (set (match_dup 4) (match_dup 2))]
10166 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10167 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10169 [(set_attr "type" "arith_media")])
10171 (define_insn "*mshflo_l_di_x_rev"
10172 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10173 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10175 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10178 "mshflo.l %N2, %N1, %0"
10179 [(set_attr "type" "arith_media")])
10181 (define_insn "ashlv2si3"
10182 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10183 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10184 (match_operand:DI 2 "arith_reg_operand" "r")))]
10186 "mshlld.l %1, %2, %0"
10187 [(set_attr "type" "arith_media")])
10189 (define_insn "ashlv4hi3"
10190 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10191 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10192 (match_operand:DI 2 "arith_reg_operand" "r")))]
10194 "mshlld.w %1, %2, %0"
10195 [(set_attr "type" "arith_media")])
10197 (define_insn "lshrv2si3"
10198 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10199 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10200 (match_operand:DI 2 "arith_reg_operand" "r")))]
10202 "mshlrd.l %1, %2, %0"
10203 [(set_attr "type" "arith_media")])
10205 (define_insn "lshrv4hi3"
10206 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10207 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10208 (match_operand:DI 2 "arith_reg_operand" "r")))]
10210 "mshlrd.w %1, %2, %0"
10211 [(set_attr "type" "arith_media")])
10213 (define_insn "subv2si3"
10214 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10215 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10216 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10218 "msub.l %N1, %2, %0"
10219 [(set_attr "type" "arith_media")])
10221 (define_insn "subv4hi3"
10222 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10223 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10224 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10226 "msub.w %N1, %2, %0"
10227 [(set_attr "type" "arith_media")])
10229 (define_insn "sssubv2si3"
10230 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10231 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10232 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10234 "msubs.l %N1, %2, %0"
10235 [(set_attr "type" "mcmp_media")])
10237 (define_insn "ussubv8qi3"
10238 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10239 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10240 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10242 "msubs.ub %1, %2, %0"
10243 [(set_attr "type" "mcmp_media")])
10245 (define_insn "sssubv4hi3"
10246 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10247 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10248 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10250 "msubs.w %N1, %2, %0"
10251 [(set_attr "type" "mcmp_media")])
10253 ;; Floating Point Intrinsics
10255 (define_insn "fcosa_s"
10256 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10257 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10261 [(set_attr "type" "atrans_media")])
10263 (define_insn "fsina_s"
10264 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10265 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10269 [(set_attr "type" "atrans_media")])
10271 (define_insn "fipr"
10272 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10273 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10274 "fp_arith_reg_operand" "f")
10275 (match_operand:V4SF 2
10276 "fp_arith_reg_operand" "f"))
10277 (parallel [(const_int 0)]))
10278 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10279 (parallel [(const_int 1)])))
10280 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10281 (parallel [(const_int 2)]))
10282 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10283 (parallel [(const_int 3)])))))]
10286 [(set_attr "type" "fparith_media")])
10288 (define_insn "fsrra_s"
10289 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10290 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10294 [(set_attr "type" "atrans_media")])
10296 (define_insn "ftrv"
10297 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10301 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10302 (parallel [(const_int 0) (const_int 5)
10303 (const_int 10) (const_int 15)]))
10304 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10306 (vec_select:V4SF (match_dup 1)
10307 (parallel [(const_int 4) (const_int 9)
10308 (const_int 14) (const_int 3)]))
10309 (vec_select:V4SF (match_dup 2)
10310 (parallel [(const_int 1) (const_int 2)
10311 (const_int 3) (const_int 0)]))))
10314 (vec_select:V4SF (match_dup 1)
10315 (parallel [(const_int 8) (const_int 13)
10316 (const_int 2) (const_int 7)]))
10317 (vec_select:V4SF (match_dup 2)
10318 (parallel [(const_int 2) (const_int 3)
10319 (const_int 0) (const_int 1)])))
10321 (vec_select:V4SF (match_dup 1)
10322 (parallel [(const_int 12) (const_int 1)
10323 (const_int 6) (const_int 11)]))
10324 (vec_select:V4SF (match_dup 2)
10325 (parallel [(const_int 3) (const_int 0)
10326 (const_int 1) (const_int 2)]))))))]
10329 [(set_attr "type" "fparith_media")])
10332 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10333 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10337 [(set_attr "type" "arith_media")])
10339 (define_insn "nsbsi"
10340 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10342 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10346 [(set_attr "type" "arith_media")])
10348 (define_insn "nsbdi"
10349 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10351 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10355 [(set_attr "type" "arith_media")])
10357 (define_expand "ffsdi2"
10358 [(set (match_operand:DI 0 "arith_reg_dest" "")
10359 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10363 rtx scratch = gen_reg_rtx (DImode);
10366 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10367 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10368 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10369 emit_insn (gen_nsbdi (scratch, scratch));
10370 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10371 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10372 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10374 = gen_rtx_EXPR_LIST (REG_EQUAL,
10375 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10379 (define_expand "ffssi2"
10380 [(set (match_operand:SI 0 "arith_reg_dest" "")
10381 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10385 rtx scratch = gen_reg_rtx (SImode);
10386 rtx discratch = gen_reg_rtx (DImode);
10389 emit_insn (gen_adddi3 (discratch,
10390 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10392 emit_insn (gen_andcdi3 (discratch,
10393 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10395 emit_insn (gen_nsbsi (scratch, discratch));
10396 last = emit_insn (gen_subsi3 (operands[0],
10397 force_reg (SImode, GEN_INT (63)), scratch));
10399 = gen_rtx_EXPR_LIST (REG_EQUAL,
10400 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10404 (define_insn "byterev"
10405 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10406 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10407 (parallel [(const_int 7) (const_int 6) (const_int 5)
10408 (const_int 4) (const_int 3) (const_int 2)
10409 (const_int 1) (const_int 0)])))]
10412 [(set_attr "type" "arith_media")])
10414 ;; The following description models the
10415 ;; SH4 pipeline using the DFA based scheduler.
10416 ;; The DFA based description is better way to model
10417 ;; a superscalar pipeline as compared to function unit
10418 ;; reservation model.
10419 ;; 1. The function unit based model is oriented to describe at most one
10420 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10421 ;; pipeline units by same insn. This can be done using DFA based description.
10422 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10423 ;; 3. Writing all unit reservations for an instruction class is more natural description
10424 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10425 ;; old function unit based model.
10426 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10429 ;; Two automata are defined to reduce number of states
10430 ;; which a single large automaton will have.(Factoring)
10432 (define_automaton "inst_pipeline,fpu_pipe")
10434 ;; This unit is basically the decode unit of the processor.
10435 ;; Since SH4 is a dual issue machine,it is as if there are two
10436 ;; units so that any insn can be processed by either one
10437 ;; of the decoding unit.
10439 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10442 ;; The fixed point arithmetic calculator(?? EX Unit).
10444 (define_cpu_unit "int" "inst_pipeline")
10446 ;; f1_1 and f1_2 are floating point units.Actually there is
10447 ;; a f1 unit which can overlap with other f1 unit but
10448 ;; not another F1 unit.It is as though there were two
10451 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10453 ;; The floating point units (except FS - F2 always precedes it.)
10455 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10457 ;; This is basically the MA unit of SH4
10458 ;; used in LOAD/STORE pipeline.
10460 (define_cpu_unit "memory" "inst_pipeline")
10462 ;; However, there are LS group insns that don't use it, even ones that
10463 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10464 (define_cpu_unit "load_store" "inst_pipeline")
10466 ;; The address calculator used for branch instructions.
10467 ;; This will be reserved after "issue" of branch instructions
10468 ;; and this is to make sure that no two branch instructions
10469 ;; can be issued in parallel.
10471 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10473 ;; ----------------------------------------------------
10474 ;; This reservation is to simplify the dual issue description.
10476 (define_reservation "issue" "pipe_01|pipe_02")
10478 ;; This is to express the locking of D stage.
10479 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10481 (define_reservation "d_lock" "pipe_01+pipe_02")
10483 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10484 (define_reservation "F01" "F0+F1")
10486 ;; This is to simplify description where F1,F2,FS
10487 ;; are used simultaneously.
10489 (define_reservation "fpu" "F1+F2")
10491 ;; This is to highlight the fact that f1
10492 ;; cannot overlap with F1.
10494 (exclusion_set "f1_1,f1_2" "F1")
10496 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10498 ;; Although reg moves have a latency of zero
10499 ;; we need to highlight that they use D stage
10504 (define_insn_reservation "reg_mov" 0
10505 (and (eq_attr "pipe_model" "sh4")
10506 (eq_attr "type" "move"))
10511 (define_insn_reservation "freg_mov" 0
10512 (and (eq_attr "pipe_model" "sh4")
10513 (eq_attr "type" "fmove"))
10514 "issue+load_store")
10516 ;; We don't model all pipeline stages; we model the issue ('D') stage
10517 ;; inasmuch as we allow only two instructions to issue simultanously,
10518 ;; and CO instructions prevent any simultanous issue of another instruction.
10519 ;; (This uses pipe_01 and pipe_02).
10520 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10521 ;; Double issue of EX / BR insns is prevented by using the int unit /
10522 ;; pcr_addrcalc unit in the EX stage.
10523 ;; Double issue of BR / LS instructions is prevented by using the
10524 ;; pcr_addrcalc / load_store unit in the issue cycle.
10525 ;; Double issue of FE instructions is prevented by using F0 in the first
10526 ;; pipeline stage after the first D stage.
10527 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10528 ;; (except in the cases outlined above), nor to describe the FS stage after
10531 ;; Other MT group intructions(1 step operations)
10536 (define_insn_reservation "mt" 1
10537 (and (eq_attr "pipe_model" "sh4")
10538 (eq_attr "type" "mt_group"))
10541 ;; Fixed Point Arithmetic Instructions(1 step operations)
10546 (define_insn_reservation "sh4_simple_arith" 1
10547 (and (eq_attr "pipe_model" "sh4")
10548 (eq_attr "insn_class" "ex_group"))
10551 ;; Load and store instructions have no alignment peculiarities for the SH4,
10552 ;; but they use the load-store unit, which they share with the fmove type
10553 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10554 ;; Loads have a latency of two.
10555 ;; However, call insns can only paired with a preceding insn, and have
10556 ;; a delay slot, so that we want two more insns to be scheduled between the
10557 ;; load of the function address and the call. This is equivalent to a
10558 ;; latency of three.
10559 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10560 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10561 ;; We only do this for SImode loads of general registers, to make the work
10562 ;; for ADJUST_COST easier.
10564 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10569 (define_insn_reservation "sh4_load" 2
10570 (and (eq_attr "pipe_model" "sh4")
10571 (eq_attr "type" "load,pcload"))
10572 "issue+load_store,nothing,memory")
10574 ;; calls / sfuncs need an extra instruction for their delay slot.
10575 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10576 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10577 ;; count of a dynamic shift.
10578 (define_insn_reservation "sh4_load_si" 3
10579 (and (eq_attr "pipe_model" "sh4")
10580 (eq_attr "type" "load_si,pcload_si"))
10581 "issue+load_store,nothing,memory")
10583 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10585 ;; The load latency is upped to three higher if the dependent insn does
10586 ;; double precision computation. We want the 'default' latency to reflect
10587 ;; that increased latency because otherwise the insn priorities won't
10588 ;; allow proper scheduling.
10589 (define_insn_reservation "sh4_fload" 3
10590 (and (eq_attr "pipe_model" "sh4")
10591 (eq_attr "type" "fload,pcfload"))
10592 "issue+load_store,nothing,memory")
10594 ;; (define_bypass 2 "sh4_fload" "!")
10596 (define_insn_reservation "sh4_store" 1
10597 (and (eq_attr "pipe_model" "sh4")
10598 (eq_attr "type" "store"))
10599 "issue+load_store,nothing,memory")
10601 ;; Load Store instructions.
10606 (define_insn_reservation "sh4_gp_fpul" 1
10607 (and (eq_attr "pipe_model" "sh4")
10608 (eq_attr "type" "gp_fpul"))
10609 "issue+load_store")
10611 ;; Load Store instructions.
10616 (define_insn_reservation "sh4_fpul_gp" 3
10617 (and (eq_attr "pipe_model" "sh4")
10618 (eq_attr "type" "fpul_gp"))
10619 "issue+load_store")
10621 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10623 ;; Latency when taken: 2 (or 1)
10625 ;; The latency is 1 when displacement is 0.
10626 ;; We can't really do much with the latency, even if we could express it,
10627 ;; but the pairing restrictions are useful to take into account.
10628 ;; ??? If the branch is likely, we might want to fill the delay slot;
10629 ;; if the branch is likely, but not very likely, should we pretend to use
10630 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10632 (define_insn_reservation "sh4_branch" 1
10633 (and (eq_attr "pipe_model" "sh4")
10634 (eq_attr "type" "cbranch,jump"))
10635 "issue+pcr_addrcalc")
10637 ;; Branch Far (JMP,RTS,BRAF)
10641 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10642 ;; can't be distinguished from bra for the "jump" pattern.
10644 (define_insn_reservation "sh4_return" 3
10645 (and (eq_attr "pipe_model" "sh4")
10646 (eq_attr "type" "return,jump_ind"))
10653 ;; this instruction can be executed in any of the pipelines
10654 ;; and blocks the pipeline for next 4 stages.
10656 (define_insn_reservation "sh4_return_from_exp" 5
10657 (and (eq_attr "pipe_model" "sh4")
10658 (eq_attr "type" "rte"))
10666 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10667 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10668 (define_insn_reservation "ocbwb" 6
10669 (and (eq_attr "pipe_model" "sh4")
10670 (eq_attr "type" "cwb"))
10671 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10677 ;; The SX stage is blocked for last 2 cycles.
10678 ;; OTOH, the only time that has an effect for insns generated by the compiler
10679 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10680 ;; or when we are doing a function call - and we don't do inter-function
10681 ;; scheduling. For the function call case, it's really best that we end with
10682 ;; something that models an rts.
10684 (define_insn_reservation "sh4_lds_to_pr" 3
10685 (and (eq_attr "pipe_model" "sh4")
10686 (eq_attr "type" "prset") )
10689 ;; calls introduce a longisch delay that is likely to flush the pipelines
10690 ;; of the caller's instructions. Ordinary functions tend to end with a
10691 ;; load to restore a register (in the delay slot of rts), while sfuncs
10692 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10693 ;; since there are no instructions that contend for memory access early.
10694 ;; We could, of course, provide exact scheduling information for specific
10695 ;; sfuncs, if that should prove useful.
10697 (define_insn_reservation "sh4_call" 16
10698 (and (eq_attr "pipe_model" "sh4")
10699 (eq_attr "type" "call,sfunc"))
10706 ;; The SX unit is blocked for last 2 cycles.
10708 (define_insn_reservation "ldsmem_to_pr" 3
10709 (and (eq_attr "pipe_model" "sh4")
10710 (eq_attr "type" "pload"))
10717 ;; The SX unit in second and third cycles.
10719 (define_insn_reservation "sts_from_pr" 2
10720 (and (eq_attr "pipe_model" "sh4")
10721 (eq_attr "type" "prget"))
10729 (define_insn_reservation "sh4_prstore_mem" 2
10730 (and (eq_attr "pipe_model" "sh4")
10731 (eq_attr "type" "pstore"))
10732 "d_lock*2,nothing,memory")
10738 ;; F1 is blocked for last three cycles.
10740 (define_insn_reservation "fpscr_load" 4
10741 (and (eq_attr "pipe_model" "sh4")
10742 (eq_attr "type" "gp_fpscr"))
10743 "d_lock,nothing,F1*3")
10748 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10750 ;; F1 is blocked for last three cycles.
10752 (define_insn_reservation "fpscr_load_mem" 4
10753 (and (eq_attr "pipe_model" "sh4")
10754 (eq_attr "type" "mem_fpscr"))
10755 "d_lock,nothing,(F1+memory),F1*2")
10758 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10763 (define_insn_reservation "multi" 4
10764 (and (eq_attr "pipe_model" "sh4")
10765 (eq_attr "type" "smpy,dmpy"))
10766 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10768 ;; Fixed STS from MACL / MACH
10773 (define_insn_reservation "sh4_mac_gp" 3
10774 (and (eq_attr "pipe_model" "sh4")
10775 (eq_attr "type" "mac_gp"))
10779 ;; Single precision floating point computation FCMP/EQ,
10780 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10785 (define_insn_reservation "fp_arith" 3
10786 (and (eq_attr "pipe_model" "sh4")
10787 (eq_attr "type" "fp"))
10790 (define_insn_reservation "fp_arith_ftrc" 3
10791 (and (eq_attr "pipe_model" "sh4")
10792 (eq_attr "type" "ftrc_s"))
10795 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10797 ;; Single Precision FDIV/SQRT
10799 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10801 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10803 (define_insn_reservation "fp_div" 12
10804 (and (eq_attr "pipe_model" "sh4")
10805 (eq_attr "type" "fdiv"))
10806 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10808 ;; Double Precision floating point computation
10809 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10811 ;; Latency: (3,4)/5
10814 (define_insn_reservation "dp_float" 4
10815 (and (eq_attr "pipe_model" "sh4")
10816 (eq_attr "type" "dfp_conv"))
10817 "issue,F01,F1+F2,F2")
10819 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10821 ;; Latency: (7,8)/9
10824 (define_insn_reservation "fp_double_arith" 8
10825 (and (eq_attr "pipe_model" "sh4")
10826 (eq_attr "type" "dfp_arith"))
10827 "issue,F01,F1+F2,fpu*4,F2")
10829 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10834 (define_insn_reservation "fp_double_cmp" 3
10835 (and (eq_attr "pipe_model" "sh4")
10836 (eq_attr "type" "dfp_cmp"))
10837 "d_lock,(d_lock+F01),F1+F2,F2")
10839 ;; Double precision FDIV/SQRT
10841 ;; Latency: (24,25)/26
10844 (define_insn_reservation "dp_div" 25
10845 (and (eq_attr "pipe_model" "sh4")
10846 (eq_attr "type" "dfdiv"))
10847 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10850 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10851 ;; case, we'd get a d_lock instead of issue at the end.
10852 (define_insn_reservation "arith3" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "arith3"))
10855 "issue,d_lock+pcr_addrcalc,issue")
10857 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10858 (define_insn_reservation "arith3b" 2
10859 (and (eq_attr "pipe_model" "sh4")
10860 (eq_attr "type" "arith3"))
10861 "issue,d_lock+pcr_addrcalc")