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)
138 (UNSPEC_EH_RETURN 19)
140 ;; These are used with unspec_volatile.
146 (UNSPECV_WINDOW_END 10)
147 (UNSPECV_CONST_END 11)
150 ;; -------------------------------------------------------------------------
152 ;; -------------------------------------------------------------------------
157 "sh1,sh2,sh3,sh3e,sh4,sh5"
158 (const (symbol_ref "sh_cpu_attr")))
160 (define_attr "endian" "big,little"
161 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
162 (const_string "little") (const_string "big"))))
164 ;; Indicate if the default fpu mode is single precision.
165 (define_attr "fpu_single" "yes,no"
166 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
167 (const_string "yes") (const_string "no"))))
169 (define_attr "fmovd" "yes,no"
170 (const (if_then_else (symbol_ref "TARGET_FMOVD")
171 (const_string "yes") (const_string "no"))))
173 (define_attr "pipe_model" "sh1,sh4,sh5media"
175 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
176 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
177 (const_string "sh1"))))
179 ;; cbranch conditional branch instructions
180 ;; jump unconditional jumps
181 ;; arith ordinary arithmetic
182 ;; arith3 a compound insn that behaves similarly to a sequence of
183 ;; three insns of type arith
184 ;; arith3b like above, but might end with a redirected branch
186 ;; load_si Likewise, SImode variant for general register.
187 ;; fload Likewise, but load to fp register.
189 ;; move general purpose register to register
190 ;; mt_group other sh4 mt instructions
191 ;; fmove register to register, floating point
192 ;; smpy word precision integer multiply
193 ;; dmpy longword or doublelongword precision integer multiply
195 ;; pload load of pr reg, which can't be put into delay slot of rts
196 ;; prset copy register to pr reg, ditto
197 ;; pstore store of pr reg, which can't be put into delay slot of jsr
198 ;; prget copy pr to register, ditto
199 ;; pcload pc relative load of constant value
200 ;; pcfload Likewise, but load to fp register.
201 ;; pcload_si Likewise, SImode variant for general register.
202 ;; rte return from exception
203 ;; sfunc special function call with known used registers
204 ;; call function call
206 ;; fdiv floating point divide (or square root)
207 ;; gp_fpul move from general purpose register to fpul
208 ;; fpul_gp move from fpul to general purpose register
209 ;; mac_gp move from mac[lh] to general purpose register
210 ;; dfp_arith, dfp_cmp,dfp_conv
211 ;; ftrc_s fix_truncsfsi2_i4
212 ;; dfdiv double precision floating point divide (or square root)
213 ;; cwb ic_invalidate_line_i
214 ;; arith_media SHmedia arithmetic, logical, and shift instructions
215 ;; cbranch_media SHmedia conditional branch instructions
216 ;; cmp_media SHmedia compare instructions
217 ;; dfdiv_media SHmedia double precision divide and square root
218 ;; dfmul_media SHmedia double precision multiply instruction
219 ;; dfparith_media SHmedia double precision floating point arithmetic
220 ;; dfpconv_media SHmedia double precision floating point conversions
221 ;; dmpy_media SHmedia longword multiply
222 ;; fcmp_media SHmedia floating point compare instructions
223 ;; fdiv_media SHmedia single precision divide and square root
224 ;; fload_media SHmedia floating point register load instructions
225 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
226 ;; fparith_media SHmedia single precision floating point arithmetic
227 ;; fpconv_media SHmedia single precision floating point conversions
228 ;; fstore_media SHmedia floating point register store instructions
229 ;; gettr_media SHmedia gettr instruction
230 ;; invalidate_line_media SHmedia invaldiate_line sequence
231 ;; jump_media SHmedia unconditional branch instructions
232 ;; load_media SHmedia general register load instructions
233 ;; pt_media SHmedia pt instruction (expanded by assembler)
234 ;; ptabs_media SHmedia ptabs instruction
235 ;; store_media SHmedia general register store instructions
236 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
237 ;; mac_media SHmedia mac-style fixed point operations
238 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
239 ;; atrans SHmedia approximate transcendential functions
240 ;; ustore_media SHmedia unaligned stores
241 ;; nil no-op move, will be deleted.
244 "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"
245 (const_string "other"))
247 ;; We define a new attribute namely "insn_class".We use
248 ;; this for the DFA based pipeline description.
250 ;; mt_group SH4 "mt" group instructions.
252 ;; ex_group SH4 "ex" group instructions.
254 ;; ls_group SH4 "ls" group instructions.
257 (define_attr "insn_class"
258 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
259 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
260 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
261 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
262 (eq_attr "type" "cbranch,jump") (const_string "br_group")
263 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
264 (const_string "fe_group")
265 (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")]
266 (const_string "none")))
267 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
268 ;; so these do not belong in an insn group, although they are modeled
269 ;; with their own define_insn_reservations.
271 ;; Indicate what precision must be selected in fpscr for this insn, if any.
273 (define_attr "fp_mode" "single,double,none" (const_string "none"))
275 ; If a conditional branch destination is within -252..258 bytes away
276 ; from the instruction it can be 2 bytes long. Something in the
277 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
278 ; branches are initially assumed to be 16 bytes long.
279 ; In machine_dependent_reorg, we split all branches that are longer than
282 ;; The maximum range used for SImode constant pool entries is 1018. A final
283 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
284 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
285 ;; instruction around the pool table, 2 bytes of alignment before the table,
286 ;; and 30 bytes of alignment after the table. That gives a maximum total
287 ;; pool size of 1058 bytes.
288 ;; Worst case code/pool content size ratio is 1:2 (using asms).
289 ;; Thus, in the worst case, there is one instruction in front of a maximum
290 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
291 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
292 ;; If we have a forward branch, the initial table will be put after the
293 ;; unconditional branch.
295 ;; ??? We could do much better by keeping track of the actual pcloads within
296 ;; the branch range and in the pcload range in front of the branch range.
298 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
300 (define_attr "short_cbranch_p" "no,yes"
301 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
303 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
305 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
307 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
309 ] (const_string "no")))
311 (define_attr "med_branch_p" "no,yes"
312 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
315 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
317 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
320 ] (const_string "no")))
322 (define_attr "med_cbranch_p" "no,yes"
323 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
326 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
328 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
331 ] (const_string "no")))
333 (define_attr "braf_branch_p" "no,yes"
334 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
339 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
341 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
344 ] (const_string "no")))
346 (define_attr "braf_cbranch_p" "no,yes"
347 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
349 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
352 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
354 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
357 ] (const_string "no")))
359 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
360 ; For wider ranges, we need a combination of a code and a data part.
361 ; If we can get a scratch register for a long range jump, the code
362 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
363 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
364 ; long; otherwise, it must be 6 bytes long.
366 ; All other instructions are two bytes long by default.
368 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
369 ;; but getattrtab doesn't understand this.
370 (define_attr "length" ""
371 (cond [(eq_attr "type" "cbranch")
372 (cond [(eq_attr "short_cbranch_p" "yes")
374 (eq_attr "med_cbranch_p" "yes")
376 (eq_attr "braf_cbranch_p" "yes")
378 ;; ??? using pc is not computed transitively.
379 (ne (match_dup 0) (match_dup 0))
381 (ne (symbol_ref ("flag_pic")) (const_int 0))
384 (eq_attr "type" "jump")
385 (cond [(eq_attr "med_branch_p" "yes")
387 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
389 (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
390 (symbol_ref "code_for_indirect_jump_scratch")))
391 (if_then_else (eq_attr "braf_branch_p" "yes")
394 (eq_attr "braf_branch_p" "yes")
396 ;; ??? using pc is not computed transitively.
397 (ne (match_dup 0) (match_dup 0))
399 (ne (symbol_ref ("flag_pic")) (const_int 0))
402 (eq_attr "type" "pt_media")
403 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
404 (const_int 20) (const_int 12))
405 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
409 ;; (define_function_unit {name} {num-units} {n-users} {test}
410 ;; {ready-delay} {issue-delay} [{conflict-list}])
412 ;; Load and store instructions save a cycle if they are aligned on a
413 ;; four byte boundary. Using a function unit for stores encourages
414 ;; gcc to separate load and store instructions by one instruction,
415 ;; which makes it more likely that the linker will be able to word
416 ;; align them when relaxing.
418 ;; Loads have a latency of two.
419 ;; However, call insns can have a delay slot, so that we want one more
420 ;; insn to be scheduled between the load of the function address and the call.
421 ;; This is equivalent to a latency of three.
422 ;; We cannot use a conflict list for this, because we need to distinguish
423 ;; between the actual call address and the function arguments.
424 ;; ADJUST_COST can only properly handle reductions of the cost, so we
425 ;; use a latency of three here.
426 ;; We only do this for SImode loads of general registers, to make the work
427 ;; for ADJUST_COST easier.
428 (define_function_unit "memory" 1 0
429 (and (eq_attr "pipe_model" "sh1")
430 (eq_attr "type" "load_si,pcload_si"))
432 (define_function_unit "memory" 1 0
433 (and (eq_attr "pipe_model" "sh1")
434 (eq_attr "type" "load,pcload,pload,store,pstore"))
437 (define_function_unit "int" 1 0
438 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
440 (define_function_unit "int" 1 0
441 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
443 (define_function_unit "int" 1 0
444 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
446 ;; ??? These are approximations.
447 (define_function_unit "mpy" 1 0
448 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
449 (define_function_unit "mpy" 1 0
450 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
452 (define_function_unit "fp" 1 0
453 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
454 (define_function_unit "fp" 1 0
455 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
458 ;; SH-5 SHmedia scheduling
459 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
460 ;; single-issue machine. It has four pipelines, the branch unit (br),
461 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
462 ;; the floating point unit (fpu).
463 ;; Here model the instructions with a latency greater than one cycle.
465 ;; Every instruction on SH-5 occupies the issue resource for at least one
467 (define_function_unit "sh5issue" 1 0
468 (and (eq_attr "pipe_model" "sh5media")
469 (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)
471 ;; Specify the various types of instruction which have latency > 1
472 (define_function_unit "sh5issue" 1 0
473 (and (eq_attr "pipe_model" "sh5media")
474 (eq_attr "type" "mcmp_media")) 2 1)
476 (define_function_unit "sh5issue" 1 0
477 (and (eq_attr "pipe_model" "sh5media")
478 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
479 ;; but see sh_adjust_cost for mac_media exception.
481 (define_function_unit "sh5issue" 1 0
482 (and (eq_attr "pipe_model" "sh5media")
483 (eq_attr "type" "fload_media,fmove_media")) 4 1)
485 (define_function_unit "sh5issue" 1 0
486 (and (eq_attr "pipe_model" "sh5media")
487 (eq_attr "type" "d2mpy_media")) 4 2)
489 (define_function_unit "sh5issue" 1 0
490 (and (eq_attr "pipe_model" "sh5media")
491 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
493 (define_function_unit "sh5issue" 1 0
494 (and (eq_attr "pipe_model" "sh5media")
495 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "invalidate_line_media")) 7 7)
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
504 (define_function_unit "sh5issue" 1 0
505 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
507 ;; Floating-point divide and square-root occupy an additional resource,
508 ;; which is not internally pipelined. However, other instructions
509 ;; can continue to issue.
510 (define_function_unit "sh5fds" 1 0
511 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
513 (define_function_unit "sh5fds" 1 0
514 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
516 ; Definitions for filling branch delay slots.
518 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
520 ;; ??? This should be (nil) instead of (const_int 0)
521 (define_attr "hit_stack" "yes,no"
522 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
525 (const_string "yes")))
527 (define_attr "interrupt_function" "no,yes"
528 (const (symbol_ref "current_function_interrupt")))
530 (define_attr "in_delay_slot" "yes,no"
531 (cond [(eq_attr "type" "cbranch") (const_string "no")
532 (eq_attr "type" "pcload,pcload_si") (const_string "no")
533 (eq_attr "needs_delay_slot" "yes") (const_string "no")
534 (eq_attr "length" "2") (const_string "yes")
535 ] (const_string "no")))
537 (define_attr "cond_delay_slot" "yes,no"
538 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
539 ] (const_string "no")))
541 (define_attr "is_sfunc" ""
542 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
544 (define_attr "is_mac_media" ""
545 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
547 (define_attr "branch_zero" "yes,no"
548 (cond [(eq_attr "type" "!cbranch") (const_string "no")
549 (ne (symbol_ref "(next_active_insn (insn)\
550 == (prev_active_insn\
551 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
552 && get_attr_length (next_active_insn (insn)) == 2")
554 (const_string "yes")]
555 (const_string "no")))
557 ;; SH4 Double-precision computation with double-precision result -
558 ;; the two halves are ready at different times.
559 (define_attr "dfp_comp" "yes,no"
560 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
561 (const_string "no")))
563 ;; Insns for which the latency of a preceding fp insn is decreased by one.
564 (define_attr "late_fp_use" "yes,no" (const_string "no"))
565 ;; And feeding insns for which this relevant.
566 (define_attr "any_fp_comp" "yes,no"
567 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
568 (const_string "yes")]
569 (const_string "no")))
571 (define_attr "any_int_load" "yes,no"
572 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
573 (const_string "yes")]
574 (const_string "no")))
577 (eq_attr "needs_delay_slot" "yes")
578 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
580 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
581 ;; and thus we can't put a pop instruction in its delay slot.
582 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
583 ;; instruction can go in the delay slot.
585 ;; Since a normal return (rts) implicitly uses the PR register,
586 ;; we can't allow PR register loads in an rts delay slot.
589 (eq_attr "type" "return")
590 [(and (eq_attr "in_delay_slot" "yes")
591 (ior (and (eq_attr "interrupt_function" "no")
592 (eq_attr "type" "!pload,prset"))
593 (and (eq_attr "interrupt_function" "yes")
595 (ne (symbol_ref "TARGET_SH3") (const_int 0))
596 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
598 ;; Since a call implicitly uses the PR register, we can't allow
599 ;; a PR register store in a jsr delay slot.
602 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
603 [(and (eq_attr "in_delay_slot" "yes")
604 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
606 ;; Say that we have annulled true branches, since this gives smaller and
607 ;; faster code when branches are predicted as not taken.
610 (and (eq_attr "type" "cbranch")
611 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
612 [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
614 ;; -------------------------------------------------------------------------
615 ;; SImode signed integer comparisons
616 ;; -------------------------------------------------------------------------
620 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
621 (match_operand:SI 1 "arith_operand" "L,r"))
625 [(set_attr "type" "mt_group")])
627 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
628 ;; That would still allow reload to create cmpi instructions, but would
629 ;; perhaps allow forcing the constant into a register when that is better.
630 ;; Probably should use r0 for mem/imm compares, but force constant into a
631 ;; register for pseudo/imm compares.
633 (define_insn "cmpeqsi_t"
635 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
636 (match_operand:SI 1 "arith_operand" "N,rI,r")))]
642 [(set_attr "type" "mt_group")])
644 (define_insn "cmpgtsi_t"
646 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
647 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
652 [(set_attr "type" "mt_group")])
654 (define_insn "cmpgesi_t"
656 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
657 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
662 [(set_attr "type" "mt_group")])
664 ;; -------------------------------------------------------------------------
665 ;; SImode unsigned integer comparisons
666 ;; -------------------------------------------------------------------------
668 (define_insn "cmpgeusi_t"
670 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
671 (match_operand:SI 1 "arith_reg_operand" "r")))]
674 [(set_attr "type" "mt_group")])
676 (define_insn "cmpgtusi_t"
678 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
679 (match_operand:SI 1 "arith_reg_operand" "r")))]
682 [(set_attr "type" "mt_group")])
684 ;; We save the compare operands in the cmpxx patterns and use them when
685 ;; we generate the branch.
687 (define_expand "cmpsi"
689 (compare (match_operand:SI 0 "arith_operand" "")
690 (match_operand:SI 1 "arith_operand" "")))]
694 sh_compare_op0 = operands[0];
695 sh_compare_op1 = operands[1];
699 ;; -------------------------------------------------------------------------
700 ;; DImode signed integer comparisons
701 ;; -------------------------------------------------------------------------
703 ;; ??? Could get better scheduling by splitting the initial test from the
704 ;; rest of the insn after reload. However, the gain would hardly justify
705 ;; the sh.md size increase necessary to do that.
709 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
710 (match_operand:DI 1 "arith_operand" "r"))
713 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
715 [(set_attr "length" "6")
716 (set_attr "type" "arith3b")])
718 (define_insn "cmpeqdi_t"
720 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
724 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
725 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
726 [(set_attr "length" "6")
727 (set_attr "type" "arith3b")])
731 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
732 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
733 ;; If we applied this split when not optimizing, it would only be
734 ;; applied during the machine-dependent reorg, when no new basic blocks
736 "TARGET_SH1 && reload_completed && optimize"
737 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
738 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
739 (label_ref (match_dup 6))
741 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
746 = gen_rtx_REG (SImode,
747 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
749 = (operands[1] == const0_rtx
751 : gen_rtx_REG (SImode,
752 true_regnum (operands[1])
753 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
754 operands[4] = gen_lowpart (SImode, operands[0]);
755 operands[5] = gen_lowpart (SImode, operands[1]);
756 operands[6] = gen_label_rtx ();
759 (define_insn "cmpgtdi_t"
761 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
762 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
765 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
766 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
767 [(set_attr "length" "8")
768 (set_attr "type" "arith3")])
770 (define_insn "cmpgedi_t"
772 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
776 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
778 [(set_attr "length" "8,2")
779 (set_attr "type" "arith3,mt_group")])
781 ;; -------------------------------------------------------------------------
782 ;; DImode unsigned integer comparisons
783 ;; -------------------------------------------------------------------------
785 (define_insn "cmpgeudi_t"
787 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
788 (match_operand:DI 1 "arith_reg_operand" "r")))]
790 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
791 [(set_attr "length" "8")
792 (set_attr "type" "arith3")])
794 (define_insn "cmpgtudi_t"
796 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
797 (match_operand:DI 1 "arith_reg_operand" "r")))]
799 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
800 [(set_attr "length" "8")
801 (set_attr "type" "arith3")])
803 (define_insn "cmpeqdi_media"
804 [(set (match_operand:DI 0 "register_operand" "=r")
805 (eq:DI (match_operand:DI 1 "register_operand" "%r")
806 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
809 [(set_attr "type" "cmp_media")])
811 (define_insn "cmpgtdi_media"
812 [(set (match_operand:DI 0 "register_operand" "=r")
813 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
814 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
817 [(set_attr "type" "cmp_media")])
819 (define_insn "cmpgtudi_media"
820 [(set (match_operand:DI 0 "register_operand" "=r")
821 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
822 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
824 "cmpgtu %N1, %N2, %0"
825 [(set_attr "type" "cmp_media")])
827 ;; We save the compare operands in the cmpxx patterns and use them when
828 ;; we generate the branch.
830 (define_expand "cmpdi"
832 (compare (match_operand:DI 0 "arith_operand" "")
833 (match_operand:DI 1 "arith_operand" "")))]
834 "TARGET_SH2 || TARGET_SHMEDIA"
837 sh_compare_op0 = operands[0];
838 sh_compare_op1 = operands[1];
841 ;; -------------------------------------------------------------------------
842 ;; Conditional move instructions
843 ;; -------------------------------------------------------------------------
845 ;; The insn names may seem reversed, but note that cmveq performs the move
846 ;; if op1 == 0, and cmvne does it if op1 != 0.
848 (define_insn "movdicc_false"
849 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
850 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
852 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
853 (match_operand:DI 3 "arith_reg_operand" "0")))]
856 [(set_attr "type" "arith_media")])
858 (define_insn "movdicc_true"
859 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
860 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
862 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
863 (match_operand:DI 3 "arith_reg_operand" "0")))]
866 [(set_attr "type" "arith_media")])
868 (define_expand "movdicc"
869 [(set (match_operand:DI 0 "register_operand" "")
870 (if_then_else:DI (match_operand 1 "comparison_operator" "")
871 (match_operand:DI 2 "register_operand" "")
872 (match_operand:DI 3 "register_operand" "")))]
876 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
877 && GET_MODE (sh_compare_op0) == DImode
878 && sh_compare_op1 == const0_rtx)
879 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
880 sh_compare_op0, sh_compare_op1);
888 tmp = gen_reg_rtx (DImode);
890 switch (GET_CODE (operands[1]))
893 emit_insn (gen_seq (tmp));
894 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
898 emit_insn (gen_seq (tmp));
899 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
903 emit_insn (gen_sgt (tmp));
904 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
908 emit_insn (gen_slt (tmp));
909 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
913 emit_insn (gen_slt (tmp));
914 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
918 emit_insn (gen_sgt (tmp));
919 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
923 emit_insn (gen_sgtu (tmp));
924 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
928 emit_insn (gen_sltu (tmp));
929 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
933 emit_insn (gen_sltu (tmp));
934 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
938 emit_insn (gen_sgtu (tmp));
939 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
943 emit_insn (gen_sunordered (tmp));
944 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
948 emit_insn (gen_sunordered (tmp));
949 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
966 ;; -------------------------------------------------------------------------
967 ;; Addition instructions
968 ;; -------------------------------------------------------------------------
970 (define_expand "adddi3"
971 [(set (match_operand:DI 0 "arith_reg_operand" "")
972 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
973 (match_operand:DI 2 "arith_operand" "")))]
979 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
981 operands[2] = force_reg (DImode, operands[2]);
982 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
987 (define_insn "*adddi3_media"
988 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
989 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
990 (match_operand:DI 2 "arith_operand" "r,P")))]
995 [(set_attr "type" "arith_media")])
997 (define_insn "adddi3z_media"
998 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1000 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1001 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1003 "addz.l %1, %N2, %0"
1004 [(set_attr "type" "arith_media")])
1006 (define_insn "adddi3_compact"
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1009 (match_operand:DI 2 "arith_reg_operand" "r")))
1010 (clobber (reg:SI T_REG))]
1013 [(set_attr "length" "6")])
1016 [(set (match_operand:DI 0 "arith_reg_operand" "")
1017 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1018 (match_operand:DI 2 "arith_reg_operand" "")))
1019 (clobber (reg:SI T_REG))]
1020 "TARGET_SH1 && reload_completed"
1024 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1025 high0 = gen_rtx_REG (SImode,
1026 true_regnum (operands[0])
1027 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1028 high2 = gen_rtx_REG (SImode,
1029 true_regnum (operands[2])
1030 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1031 emit_insn (gen_clrt ());
1032 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1033 emit_insn (gen_addc1 (high0, high0, high2));
1038 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1039 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1040 (match_operand:SI 2 "arith_reg_operand" "r"))
1043 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1046 [(set_attr "type" "arith")])
1048 (define_insn "addc1"
1049 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1050 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1051 (match_operand:SI 2 "arith_reg_operand" "r"))
1053 (clobber (reg:SI T_REG))]
1056 [(set_attr "type" "arith")])
1058 (define_expand "addsi3"
1059 [(set (match_operand:SI 0 "arith_reg_operand" "")
1060 (plus:SI (match_operand:SI 1 "arith_operand" "")
1061 (match_operand:SI 2 "arith_operand" "")))]
1066 operands[1] = force_reg (SImode, operands[1]);
1069 (define_insn "addsi3_media"
1070 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1071 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1072 (match_operand:SI 2 "arith_operand" "r,P")))]
1077 [(set_attr "type" "arith_media")])
1079 (define_insn "*addsi3_compact"
1080 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1081 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1082 (match_operand:SI 2 "arith_operand" "rI")))]
1085 [(set_attr "type" "arith")])
1087 ;; -------------------------------------------------------------------------
1088 ;; Subtraction instructions
1089 ;; -------------------------------------------------------------------------
1091 (define_expand "subdi3"
1092 [(set (match_operand:DI 0 "arith_reg_operand" "")
1093 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1094 (match_operand:DI 2 "arith_reg_operand" "")))]
1100 operands[1] = force_reg (DImode, operands[1]);
1101 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1106 (define_insn "*subdi3_media"
1107 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1108 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1109 (match_operand:DI 2 "arith_reg_operand" "r")))]
1112 [(set_attr "type" "arith_media")])
1114 (define_insn "subdi3_compact"
1115 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1116 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1117 (match_operand:DI 2 "arith_reg_operand" "r")))
1118 (clobber (reg:SI T_REG))]
1121 [(set_attr "length" "6")])
1124 [(set (match_operand:DI 0 "arith_reg_operand" "")
1125 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1126 (match_operand:DI 2 "arith_reg_operand" "")))
1127 (clobber (reg:SI T_REG))]
1128 "TARGET_SH1 && reload_completed"
1132 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1133 high0 = gen_rtx_REG (SImode,
1134 true_regnum (operands[0])
1135 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1136 high2 = gen_rtx_REG (SImode,
1137 true_regnum (operands[2])
1138 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1139 emit_insn (gen_clrt ());
1140 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1141 emit_insn (gen_subc1 (high0, high0, high2));
1146 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1147 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1148 (match_operand:SI 2 "arith_reg_operand" "r"))
1151 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1154 [(set_attr "type" "arith")])
1156 (define_insn "subc1"
1157 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1158 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1159 (match_operand:SI 2 "arith_reg_operand" "r"))
1161 (clobber (reg:SI T_REG))]
1164 [(set_attr "type" "arith")])
1166 (define_insn "*subsi3_internal"
1167 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169 (match_operand:SI 2 "arith_reg_operand" "r")))]
1172 [(set_attr "type" "arith")])
1174 (define_insn "*subsi3_media"
1175 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1176 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1177 (match_operand:SI 2 "extend_reg_operand" "r")))]
1180 [(set_attr "type" "arith_media")])
1182 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1183 ;; will sometimes save one instruction. Otherwise we might get
1184 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1187 (define_expand "subsi3"
1188 [(set (match_operand:SI 0 "arith_reg_operand" "")
1189 (minus:SI (match_operand:SI 1 "arith_operand" "")
1190 (match_operand:SI 2 "arith_reg_operand" "")))]
1194 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1196 emit_insn (gen_negsi2 (operands[0], operands[2]));
1197 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1202 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1204 if (operands[1] != const0_rtx)
1205 operands[1] = force_reg (SImode, operands[1]);
1209 ;; -------------------------------------------------------------------------
1210 ;; Division instructions
1211 ;; -------------------------------------------------------------------------
1213 ;; We take advantage of the library routines which don't clobber as many
1214 ;; registers as a normal function call would.
1216 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1217 ;; also has an effect on the register that holds the address of the sfunc.
1218 ;; To make this work, we have an extra dummy insn that shows the use
1219 ;; of this register for reorg.
1221 (define_insn "use_sfunc_addr"
1222 [(set (reg:SI PR_REG)
1223 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1226 [(set_attr "length" "0")])
1228 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1229 ;; hard register 0. If we used hard register 0, then the next instruction
1230 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1231 ;; gets allocated to a stack slot that needs its address reloaded, then
1232 ;; there is nothing to prevent reload from using r0 to reload the address.
1233 ;; This reload would clobber the value in r0 we are trying to store.
1234 ;; If we let reload allocate r0, then this problem can never happen.
1236 (define_insn "udivsi3_i1"
1237 [(set (match_operand:SI 0 "register_operand" "=z")
1238 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1239 (clobber (reg:SI T_REG))
1240 (clobber (reg:SI PR_REG))
1241 (clobber (reg:SI R4_REG))
1242 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1243 "TARGET_SH1 && ! TARGET_SH4"
1245 [(set_attr "type" "sfunc")
1246 (set_attr "needs_delay_slot" "yes")])
1248 ; Since shmedia-nofpu code could be linked against shcompact code, and
1249 ; the udivsi3 libcall has the same name, we must consider all registers
1250 ; clobbered that are in the union of the registers clobbered by the
1251 ; shmedia and the shcompact implementation. Note, if the shcompact
1252 ; implemenation actually used shcompact code, we'd need to clobber
1253 ; also r23 and fr23.
1254 (define_insn "udivsi3_i1_media"
1255 [(set (match_operand:SI 0 "register_operand" "=z")
1256 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257 (clobber (reg:SI T_MEDIA_REG))
1258 (clobber (reg:SI PR_MEDIA_REG))
1259 (clobber (reg:SI R20_REG))
1260 (clobber (reg:SI R21_REG))
1261 (clobber (reg:SI R22_REG))
1262 (clobber (reg:DI TR0_REG))
1263 (clobber (reg:DI TR1_REG))
1264 (clobber (reg:DI TR2_REG))
1265 (use (match_operand:DI 1 "target_operand" "b"))]
1266 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1268 [(set_attr "type" "sfunc")
1269 (set_attr "needs_delay_slot" "yes")])
1271 (define_expand "udivsi3_i4_media"
1273 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1275 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1276 (set (match_dup 5) (float:DF (match_dup 3)))
1277 (set (match_dup 6) (float:DF (match_dup 4)))
1278 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1279 (set (match_dup 8) (fix:DI (match_dup 7)))
1280 (set (match_operand:SI 0 "register_operand" "")
1281 (truncate:SI (match_dup 8)))]
1282 "TARGET_SHMEDIA_FPU"
1285 operands[3] = gen_reg_rtx (DImode);
1286 operands[4] = gen_reg_rtx (DImode);
1287 operands[5] = gen_reg_rtx (DFmode);
1288 operands[6] = gen_reg_rtx (DFmode);
1289 operands[7] = gen_reg_rtx (DFmode);
1290 operands[8] = gen_reg_rtx (DImode);
1293 (define_insn "udivsi3_i4"
1294 [(set (match_operand:SI 0 "register_operand" "=y")
1295 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1296 (clobber (reg:SI T_REG))
1297 (clobber (reg:SI PR_REG))
1298 (clobber (reg:DF DR0_REG))
1299 (clobber (reg:DF DR2_REG))
1300 (clobber (reg:DF DR4_REG))
1301 (clobber (reg:SI R0_REG))
1302 (clobber (reg:SI R1_REG))
1303 (clobber (reg:SI R4_REG))
1304 (clobber (reg:SI R5_REG))
1305 (use (reg:PSI FPSCR_REG))
1306 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1307 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1309 [(set_attr "type" "sfunc")
1310 (set_attr "fp_mode" "double")
1311 (set_attr "needs_delay_slot" "yes")])
1313 (define_insn "udivsi3_i4_single"
1314 [(set (match_operand:SI 0 "register_operand" "=y")
1315 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1316 (clobber (reg:SI T_REG))
1317 (clobber (reg:SI PR_REG))
1318 (clobber (reg:DF DR0_REG))
1319 (clobber (reg:DF DR2_REG))
1320 (clobber (reg:DF DR4_REG))
1321 (clobber (reg:SI R0_REG))
1322 (clobber (reg:SI R1_REG))
1323 (clobber (reg:SI R4_REG))
1324 (clobber (reg:SI R5_REG))
1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1328 [(set_attr "type" "sfunc")
1329 (set_attr "needs_delay_slot" "yes")])
1331 (define_expand "udivsi3"
1332 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1333 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1334 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1335 (parallel [(set (match_operand:SI 0 "register_operand" "")
1336 (udiv:SI (reg:SI R4_REG)
1338 (clobber (reg:SI T_REG))
1339 (clobber (reg:SI PR_REG))
1340 (clobber (reg:SI R4_REG))
1341 (use (match_dup 3))])]
1347 operands[3] = gen_reg_rtx (Pmode);
1348 /* Emit the move of the address to a pseudo outside of the libcall. */
1349 if (TARGET_HARD_SH4 && TARGET_SH3E)
1351 emit_move_insn (operands[3],
1352 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1353 if (TARGET_FPU_SINGLE)
1354 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1356 last = gen_udivsi3_i4 (operands[0], operands[3]);
1358 else if (TARGET_SHMEDIA_FPU)
1360 operands[1] = force_reg (SImode, operands[1]);
1361 operands[2] = force_reg (SImode, operands[2]);
1362 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1365 else if (TARGET_SH5)
1367 emit_move_insn (operands[3],
1368 gen_rtx_SYMBOL_REF (Pmode,
1374 last = gen_udivsi3_i1_media (operands[0],
1377 : gen_rtx_SUBREG (DImode, operands[3],
1379 else if (TARGET_FPU_ANY)
1380 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1382 last = gen_udivsi3_i1 (operands[0], operands[3]);
1386 emit_move_insn (operands[3],
1387 gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1388 last = gen_udivsi3_i1 (operands[0], operands[3]);
1390 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1391 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1392 last = emit_insn (last);
1393 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1394 invariant code motion can move it. */
1395 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1396 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1400 (define_insn "divsi3_i1"
1401 [(set (match_operand:SI 0 "register_operand" "=z")
1402 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1403 (clobber (reg:SI T_REG))
1404 (clobber (reg:SI PR_REG))
1405 (clobber (reg:SI R1_REG))
1406 (clobber (reg:SI R2_REG))
1407 (clobber (reg:SI R3_REG))
1408 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1409 "TARGET_SH1 && ! TARGET_SH4"
1411 [(set_attr "type" "sfunc")
1412 (set_attr "needs_delay_slot" "yes")])
1414 ; Since shmedia-nofpu code could be linked against shcompact code, and
1415 ; the sdivsi3 libcall has the same name, we must consider all registers
1416 ; clobbered that are in the union of the registers clobbered by the
1417 ; shmedia and the shcompact implementation. Note, if the shcompact
1418 ; implemenation actually used shcompact code, we'd need to clobber
1419 ; also r22, r23 and fr23.
1420 (define_insn "divsi3_i1_media"
1421 [(set (match_operand:SI 0 "register_operand" "=z")
1422 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1423 (clobber (reg:SI T_MEDIA_REG))
1424 (clobber (reg:SI PR_MEDIA_REG))
1425 (clobber (reg:SI R1_REG))
1426 (clobber (reg:SI R2_REG))
1427 (clobber (reg:SI R3_REG))
1428 (clobber (reg:SI R20_REG))
1429 (clobber (reg:SI R21_REG))
1430 (clobber (reg:DI TR0_REG))
1431 (clobber (reg:DI TR1_REG))
1432 (clobber (reg:DI TR2_REG))
1433 (use (match_operand:DI 1 "target_operand" "b"))]
1434 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1436 [(set_attr "type" "sfunc")])
1438 (define_expand "divsi3_i4_media"
1439 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1440 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1441 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1442 (set (match_operand:SI 0 "register_operand" "=r")
1443 (fix:SI (match_dup 5)))]
1444 "TARGET_SHMEDIA_FPU"
1447 operands[3] = gen_reg_rtx (DFmode);
1448 operands[4] = gen_reg_rtx (DFmode);
1449 operands[5] = gen_reg_rtx (DFmode);
1452 (define_insn "divsi3_i4"
1453 [(set (match_operand:SI 0 "register_operand" "=y")
1454 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1455 (clobber (reg:SI PR_REG))
1456 (clobber (reg:DF DR0_REG))
1457 (clobber (reg:DF DR2_REG))
1458 (use (reg:PSI FPSCR_REG))
1459 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1460 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1462 [(set_attr "type" "sfunc")
1463 (set_attr "fp_mode" "double")
1464 (set_attr "needs_delay_slot" "yes")])
1466 (define_insn "divsi3_i4_single"
1467 [(set (match_operand:SI 0 "register_operand" "=y")
1468 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1469 (clobber (reg:SI PR_REG))
1470 (clobber (reg:DF DR0_REG))
1471 (clobber (reg:DF DR2_REG))
1472 (clobber (reg:SI R2_REG))
1473 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1474 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1476 [(set_attr "type" "sfunc")
1477 (set_attr "needs_delay_slot" "yes")])
1479 (define_expand "divsi3"
1480 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1481 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1482 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1483 (parallel [(set (match_operand:SI 0 "register_operand" "")
1484 (div:SI (reg:SI R4_REG)
1486 (clobber (reg:SI T_REG))
1487 (clobber (reg:SI PR_REG))
1488 (clobber (reg:SI R1_REG))
1489 (clobber (reg:SI R2_REG))
1490 (clobber (reg:SI R3_REG))
1491 (use (match_dup 3))])]
1497 operands[3] = gen_reg_rtx (Pmode);
1498 /* Emit the move of the address to a pseudo outside of the libcall. */
1499 if (TARGET_HARD_SH4 && TARGET_SH3E)
1501 emit_move_insn (operands[3],
1502 gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1503 if (TARGET_FPU_SINGLE)
1504 last = gen_divsi3_i4_single (operands[0], operands[3]);
1506 last = gen_divsi3_i4 (operands[0], operands[3]);
1508 else if (TARGET_SHMEDIA_FPU)
1510 operands[1] = force_reg (SImode, operands[1]);
1511 operands[2] = force_reg (SImode, operands[2]);
1512 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1515 else if (TARGET_SH5)
1517 emit_move_insn (operands[3],
1518 gen_rtx_SYMBOL_REF (Pmode,
1524 last = gen_divsi3_i1_media (operands[0],
1527 : gen_rtx_SUBREG (DImode, operands[3],
1529 else if (TARGET_FPU_ANY)
1530 last = gen_divsi3_i4_single (operands[0], operands[3]);
1532 last = gen_divsi3_i1 (operands[0], operands[3]);
1536 emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1537 last = gen_divsi3_i1 (operands[0], operands[3]);
1539 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1540 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1541 last = emit_insn (last);
1542 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1543 invariant code motion can move it. */
1544 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1545 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1549 ;; -------------------------------------------------------------------------
1550 ;; Multiplication instructions
1551 ;; -------------------------------------------------------------------------
1553 (define_insn "umulhisi3_i"
1554 [(set (reg:SI MACL_REG)
1555 (mult:SI (zero_extend:SI
1556 (match_operand:HI 0 "arith_reg_operand" "r"))
1558 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1561 [(set_attr "type" "smpy")])
1563 (define_insn "mulhisi3_i"
1564 [(set (reg:SI MACL_REG)
1565 (mult:SI (sign_extend:SI
1566 (match_operand:HI 0 "arith_reg_operand" "r"))
1568 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1571 [(set_attr "type" "smpy")])
1573 (define_expand "mulhisi3"
1574 [(set (reg:SI MACL_REG)
1575 (mult:SI (sign_extend:SI
1576 (match_operand:HI 1 "arith_reg_operand" ""))
1578 (match_operand:HI 2 "arith_reg_operand" ""))))
1579 (set (match_operand:SI 0 "arith_reg_operand" "")
1586 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1587 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1588 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1589 invariant code motion can move it. */
1590 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1591 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1592 /* expand_binop can't find a suitable code in umul_widen_optab to
1593 make a REG_EQUAL note from, so make one here.
1594 See also smulsi3_highpart.
1595 ??? Alternatively, we could put this at the calling site of expand_binop,
1596 i.e. expand_expr. */
1598 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1603 (define_expand "umulhisi3"
1604 [(set (reg:SI MACL_REG)
1605 (mult:SI (zero_extend:SI
1606 (match_operand:HI 1 "arith_reg_operand" ""))
1608 (match_operand:HI 2 "arith_reg_operand" ""))))
1609 (set (match_operand:SI 0 "arith_reg_operand" "")
1616 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1617 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1618 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1619 invariant code motion can move it. */
1620 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1621 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1622 /* expand_binop can't find a suitable code in umul_widen_optab to
1623 make a REG_EQUAL note from, so make one here.
1624 See also smulsi3_highpart.
1625 ??? Alternatively, we could put this at the calling site of expand_binop,
1626 i.e. expand_expr. */
1628 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1633 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1634 ;; a call to a routine which clobbers known registers.
1637 [(set (match_operand:SI 1 "register_operand" "=z")
1638 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1639 (clobber (reg:SI MACL_REG))
1640 (clobber (reg:SI T_REG))
1641 (clobber (reg:SI PR_REG))
1642 (clobber (reg:SI R3_REG))
1643 (clobber (reg:SI R2_REG))
1644 (clobber (reg:SI R1_REG))
1645 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1648 [(set_attr "type" "sfunc")
1649 (set_attr "needs_delay_slot" "yes")])
1651 (define_expand "mulsi3_call"
1652 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1653 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1654 (parallel[(set (match_operand:SI 0 "register_operand" "")
1655 (mult:SI (reg:SI R4_REG)
1657 (clobber (reg:SI MACL_REG))
1658 (clobber (reg:SI T_REG))
1659 (clobber (reg:SI PR_REG))
1660 (clobber (reg:SI R3_REG))
1661 (clobber (reg:SI R2_REG))
1662 (clobber (reg:SI R1_REG))
1663 (use (match_operand:SI 3 "register_operand" ""))])]
1667 (define_insn "mul_l"
1668 [(set (reg:SI MACL_REG)
1669 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1670 (match_operand:SI 1 "arith_reg_operand" "r")))]
1673 [(set_attr "type" "dmpy")])
1675 (define_expand "mulsi3"
1676 [(set (reg:SI MACL_REG)
1677 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1678 (match_operand:SI 2 "arith_reg_operand" "")))
1679 (set (match_operand:SI 0 "arith_reg_operand" "")
1688 /* The address must be set outside the libcall,
1689 since it goes into a pseudo. */
1690 rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1691 rtx addr = force_reg (SImode, sym);
1692 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1695 last = emit_insn (insns);
1699 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1701 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1702 /* consec_sets_giv can only recognize the first insn that sets a
1703 giv as the giv insn. So we must tag this also with a REG_EQUAL
1705 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1707 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1708 invariant code motion can move it. */
1709 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1710 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1714 (define_insn "mulsidi3_i"
1715 [(set (reg:SI MACH_REG)
1719 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1720 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1722 (set (reg:SI MACL_REG)
1723 (mult:SI (match_dup 0)
1727 [(set_attr "type" "dmpy")])
1729 (define_expand "mulsidi3"
1730 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1731 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1732 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1733 "TARGET_SH2 || TARGET_SHMEDIA"
1738 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1744 (define_insn "mulsidi3_media"
1745 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1746 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1747 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1750 [(set_attr "type" "dmpy_media")])
1752 (define_insn "mulsidi3_compact"
1753 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1755 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1756 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1757 (clobber (reg:SI MACH_REG))
1758 (clobber (reg:SI MACL_REG))]
1763 [(set (match_operand:DI 0 "arith_reg_operand" "")
1765 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1766 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1767 (clobber (reg:SI MACH_REG))
1768 (clobber (reg:SI MACL_REG))]
1773 rtx low_dst = gen_lowpart (SImode, operands[0]);
1774 rtx high_dst = gen_highpart (SImode, operands[0]);
1776 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1778 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1779 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1780 /* We need something to tag the possible REG_EQUAL notes on to. */
1781 emit_move_insn (operands[0], operands[0]);
1785 (define_insn "umulsidi3_i"
1786 [(set (reg:SI MACH_REG)
1790 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1791 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1793 (set (reg:SI MACL_REG)
1794 (mult:SI (match_dup 0)
1798 [(set_attr "type" "dmpy")])
1800 (define_expand "umulsidi3"
1801 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1802 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1803 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1804 "TARGET_SH2 || TARGET_SHMEDIA"
1809 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1815 (define_insn "umulsidi3_media"
1816 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1817 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1818 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1821 [(set_attr "type" "dmpy_media")])
1823 (define_insn "umulsidi3_compact"
1824 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1826 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1827 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1828 (clobber (reg:SI MACH_REG))
1829 (clobber (reg:SI MACL_REG))]
1834 [(set (match_operand:DI 0 "arith_reg_operand" "")
1835 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1836 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1837 (clobber (reg:SI MACH_REG))
1838 (clobber (reg:SI MACL_REG))]
1843 rtx low_dst = gen_lowpart (SImode, operands[0]);
1844 rtx high_dst = gen_highpart (SImode, operands[0]);
1846 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1848 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1849 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1850 /* We need something to tag the possible REG_EQUAL notes on to. */
1851 emit_move_insn (operands[0], operands[0]);
1855 (define_insn "smulsi3_highpart_i"
1856 [(set (reg:SI MACH_REG)
1860 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1861 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1863 (clobber (reg:SI MACL_REG))]
1866 [(set_attr "type" "dmpy")])
1868 (define_expand "smulsi3_highpart"
1870 [(set (reg:SI MACH_REG)
1874 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1875 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1877 (clobber (reg:SI MACL_REG))])
1878 (set (match_operand:SI 0 "arith_reg_operand" "")
1885 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1886 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1887 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1888 invariant code motion can move it. */
1889 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1890 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1891 /* expand_binop can't find a suitable code in mul_highpart_optab to
1892 make a REG_EQUAL note from, so make one here.
1893 See also {,u}mulhisi.
1894 ??? Alternatively, we could put this at the calling site of expand_binop,
1895 i.e. expand_mult_highpart. */
1897 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1902 (define_insn "umulsi3_highpart_i"
1903 [(set (reg:SI MACH_REG)
1907 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1908 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1910 (clobber (reg:SI MACL_REG))]
1913 [(set_attr "type" "dmpy")])
1915 (define_expand "umulsi3_highpart"
1917 [(set (reg:SI MACH_REG)
1921 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1922 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1924 (clobber (reg:SI MACL_REG))])
1925 (set (match_operand:SI 0 "arith_reg_operand" "")
1932 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1933 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1934 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1935 invariant code motion can move it. */
1936 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1937 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1941 ;; -------------------------------------------------------------------------
1942 ;; Logical operations
1943 ;; -------------------------------------------------------------------------
1945 (define_insn "*andsi3_compact"
1946 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1947 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1948 (match_operand:SI 2 "logical_operand" "r,L")))]
1951 [(set_attr "type" "arith")])
1953 ;; If the constant is 255, then emit an extu.b instruction instead of an
1954 ;; and, since that will give better code.
1956 (define_expand "andsi3"
1957 [(set (match_operand:SI 0 "arith_reg_operand" "")
1958 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1959 (match_operand:SI 2 "logical_operand" "")))]
1963 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1965 emit_insn (gen_zero_extendqisi2 (operands[0],
1966 gen_lowpart (QImode, operands[1])));
1971 (define_insn_and_split "anddi3"
1972 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1973 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1974 (match_operand:DI 2 "and_operand" "r,P,Z")))]
1981 && ! logical_operand (operands[2], DImode)"
1985 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1986 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1988 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1991 [(set_attr "type" "arith_media")])
1993 (define_insn "andcdi3"
1994 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1995 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1996 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1999 [(set_attr "type" "arith_media")])
2001 (define_insn "iorsi3"
2002 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2003 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2004 (match_operand:SI 2 "logical_operand" "r,L")))]
2007 [(set_attr "type" "arith")])
2009 (define_insn "iordi3"
2010 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2011 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2012 (match_operand:DI 2 "logical_operand" "r,P")))]
2017 [(set_attr "type" "arith_media")])
2019 (define_insn "xorsi3"
2020 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2021 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2022 (match_operand:SI 2 "logical_operand" "L,r")))]
2025 [(set_attr "type" "arith")])
2027 (define_insn "xordi3"
2028 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2029 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2030 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2035 [(set_attr "type" "arith_media")])
2037 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2038 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2040 [(set (match_operand:DI 0 "arith_reg_operand" "")
2041 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2042 [(match_operand 1 "any_register_operand" "")
2043 (match_operand 2 "any_register_operand" "")])))]
2045 [(set (match_dup 5) (match_dup 4))
2046 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2049 enum machine_mode inmode = GET_MODE (operands[1]);
2050 int regno, offset = 0;
2052 if (GET_CODE (operands[0]) == SUBREG)
2054 offset = SUBREG_BYTE (operands[0]);
2055 operands[0] = SUBREG_REG (operands[0]);
2057 if (GET_CODE (operands[0]) != REG)
2059 if (! TARGET_LITTLE_ENDIAN)
2060 offset += 8 - GET_MODE_SIZE (inmode);
2061 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2064 ;; -------------------------------------------------------------------------
2065 ;; Shifts and rotates
2066 ;; -------------------------------------------------------------------------
2068 (define_expand "rotldi3"
2069 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2070 (rotate: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 "rotldi3_mextr"
2076 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2077 (rotate: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\",
2085 8 - (int) (INTVAL (operands[2]) >> 3));
2088 [(set_attr "type" "arith_media")])
2090 (define_expand "rotrdi3"
2091 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2092 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2093 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2095 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2097 (define_insn "rotrdi3_mextr"
2098 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2099 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2100 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2104 static char templ[16];
2106 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2109 [(set_attr "type" "arith_media")])
2111 (define_insn "rotlsi3_1"
2112 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2113 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2116 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2119 [(set_attr "type" "arith")])
2121 (define_insn "rotlsi3_31"
2122 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2123 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2125 (clobber (reg:SI T_REG))]
2128 [(set_attr "type" "arith")])
2130 (define_insn "rotlsi3_16"
2131 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2136 [(set_attr "type" "arith")])
2138 (define_expand "rotlsi3"
2139 [(set (match_operand:SI 0 "arith_reg_operand" "")
2140 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2141 (match_operand:SI 2 "immediate_operand" "")))]
2145 static const char rot_tab[] = {
2146 000, 000, 000, 000, 000, 000, 010, 001,
2147 001, 001, 011, 013, 003, 003, 003, 003,
2148 003, 003, 003, 003, 003, 013, 012, 002,
2149 002, 002, 010, 000, 000, 000, 000, 000,
2154 if (GET_CODE (operands[2]) != CONST_INT)
2156 count = INTVAL (operands[2]);
2157 choice = rot_tab[count];
2158 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2164 emit_move_insn (operands[0], operands[1]);
2165 count -= (count & 16) * 2;
2168 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2175 parts[0] = gen_reg_rtx (SImode);
2176 parts[1] = gen_reg_rtx (SImode);
2177 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2178 parts[choice-1] = operands[1];
2179 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2180 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2181 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2182 count = (count & ~16) - 8;
2186 for (; count > 0; count--)
2187 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2188 for (; count < 0; count++)
2189 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2194 (define_insn "*rotlhi3_8"
2195 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2196 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2200 [(set_attr "type" "arith")])
2202 (define_expand "rotlhi3"
2203 [(set (match_operand:HI 0 "arith_reg_operand" "")
2204 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2205 (match_operand:HI 2 "immediate_operand" "")))]
2209 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2216 ;; This pattern is used by init_expmed for computing the costs of shift
2219 (define_insn_and_split "ashlsi3_std"
2220 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2221 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2222 (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2223 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2225 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2226 && CONST_OK_FOR_K (INTVAL (operands[2])))"
2234 && GET_CODE (operands[2]) == CONST_INT
2235 && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2236 [(set (match_dup 3) (match_dup 2))
2238 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2239 (clobber (match_dup 4))])]
2240 "operands[4] = gen_rtx_SCRATCH (SImode);"
2241 [(set_attr "length" "*,*,*,4")
2242 (set_attr "type" "dyn_shift,arith,arith,arith")])
2244 (define_insn "ashlhi3_k"
2245 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2246 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2247 (match_operand:HI 2 "const_int_operand" "M,K")))]
2248 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2252 [(set_attr "type" "arith")])
2254 (define_insn "ashlsi3_n"
2255 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2256 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2257 (match_operand:SI 2 "const_int_operand" "n")))
2258 (clobber (reg:SI T_REG))]
2259 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2261 [(set (attr "length")
2262 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2264 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2266 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2268 (const_string "8")))
2269 (set_attr "type" "arith")])
2272 [(set (match_operand:SI 0 "arith_reg_operand" "")
2273 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2274 (match_operand:SI 2 "const_int_operand" "")))
2275 (clobber (reg:SI T_REG))]
2276 "TARGET_SH1 && reload_completed"
2277 [(use (reg:SI R0_REG))]
2280 gen_shifty_op (ASHIFT, operands);
2284 (define_insn "ashlsi3_media"
2285 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2286 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2287 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2292 [(set_attr "type" "arith_media")])
2294 (define_expand "ashlsi3"
2295 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2296 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2297 (match_operand:SI 2 "nonmemory_operand" "")))
2298 (clobber (reg:SI T_REG))])]
2304 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2307 if (GET_CODE (operands[2]) == CONST_INT
2308 && sh_dynamicalize_shift_p (operands[2]))
2309 operands[2] = force_reg (SImode, operands[2]);
2312 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2315 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2319 (define_insn "ashlhi3"
2320 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2321 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2322 (match_operand:HI 2 "const_int_operand" "n")))
2323 (clobber (reg:SI T_REG))]
2326 [(set (attr "length")
2327 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2329 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2331 (const_string "6")))
2332 (set_attr "type" "arith")])
2335 [(set (match_operand:HI 0 "arith_reg_operand" "")
2336 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2337 (match_operand:HI 2 "const_int_operand" "")))
2338 (clobber (reg:SI T_REG))]
2339 "TARGET_SH1 && reload_completed"
2340 [(use (reg:SI R0_REG))]
2343 gen_shifty_hi_op (ASHIFT, operands);
2348 ; arithmetic shift right
2351 (define_insn "ashrsi3_k"
2352 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2353 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2354 (match_operand:SI 2 "const_int_operand" "M")))
2355 (clobber (reg:SI T_REG))]
2356 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2358 [(set_attr "type" "arith")])
2360 ;; We can't do HImode right shifts correctly unless we start out with an
2361 ;; explicit zero / sign extension; doing that would result in worse overall
2362 ;; code, so just let the machine independent code widen the mode.
2363 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2366 ;; ??? This should be a define expand.
2368 (define_insn "ashrsi2_16"
2369 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2374 [(set_attr "length" "4")])
2377 [(set (match_operand:SI 0 "arith_reg_operand" "")
2378 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2381 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2382 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2383 "operands[2] = gen_lowpart (HImode, operands[0]);")
2385 ;; ??? This should be a define expand.
2387 (define_insn "ashrsi2_31"
2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2391 (clobber (reg:SI T_REG))]
2394 [(set_attr "length" "4")])
2397 [(set (match_operand:SI 0 "arith_reg_operand" "")
2398 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2400 (clobber (reg:SI T_REG))]
2405 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2406 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2410 (define_insn "ashlsi_c"
2411 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2412 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2414 (lt:SI (match_dup 1) (const_int 0)))]
2417 [(set_attr "type" "arith")])
2419 (define_insn "ashrsi3_d"
2420 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2421 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2422 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2425 [(set_attr "type" "dyn_shift")])
2427 (define_insn "ashrsi3_n"
2428 [(set (reg:SI R4_REG)
2429 (ashiftrt:SI (reg:SI R4_REG)
2430 (match_operand:SI 0 "const_int_operand" "i")))
2431 (clobber (reg:SI T_REG))
2432 (clobber (reg:SI PR_REG))
2433 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2436 [(set_attr "type" "sfunc")
2437 (set_attr "needs_delay_slot" "yes")])
2439 (define_insn "ashrsi3_media"
2440 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2441 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2442 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2447 [(set_attr "type" "arith_media")])
2449 (define_expand "ashrsi3"
2450 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2451 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2452 (match_operand:SI 2 "nonmemory_operand" "")))
2453 (clobber (reg:SI T_REG))])]
2459 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2462 if (expand_ashiftrt (operands))
2468 ;; logical shift right
2470 (define_insn "lshrsi3_d"
2471 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2476 [(set_attr "type" "dyn_shift")])
2478 ;; Only the single bit shift clobbers the T bit.
2480 (define_insn "lshrsi3_m"
2481 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2482 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2483 (match_operand:SI 2 "const_int_operand" "M")))
2484 (clobber (reg:SI T_REG))]
2485 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2487 [(set_attr "type" "arith")])
2489 (define_insn "lshrsi3_k"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492 (match_operand:SI 2 "const_int_operand" "K")))]
2493 "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2494 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2496 [(set_attr "type" "arith")])
2498 (define_insn "lshrsi3_n"
2499 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2500 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2501 (match_operand:SI 2 "const_int_operand" "n")))
2502 (clobber (reg:SI T_REG))]
2503 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2505 [(set (attr "length")
2506 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2508 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2510 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2512 (const_string "8")))
2513 (set_attr "type" "arith")])
2516 [(set (match_operand:SI 0 "arith_reg_operand" "")
2517 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2518 (match_operand:SI 2 "const_int_operand" "")))
2519 (clobber (reg:SI T_REG))]
2520 "TARGET_SH1 && reload_completed"
2521 [(use (reg:SI R0_REG))]
2524 gen_shifty_op (LSHIFTRT, operands);
2528 (define_insn "lshrsi3_media"
2529 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2530 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2531 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2536 [(set_attr "type" "arith_media")])
2538 (define_expand "lshrsi3"
2539 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2540 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2541 (match_operand:SI 2 "nonmemory_operand" "")))
2542 (clobber (reg:SI T_REG))])]
2548 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2551 if (GET_CODE (operands[2]) == CONST_INT
2552 && sh_dynamicalize_shift_p (operands[2]))
2553 operands[2] = force_reg (SImode, operands[2]);
2554 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2556 rtx count = copy_to_mode_reg (SImode, operands[2]);
2557 emit_insn (gen_negsi2 (count, count));
2558 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2561 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2565 ;; ??? This should be a define expand.
2567 (define_insn "ashldi3_k"
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2569 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2571 (clobber (reg:SI T_REG))]
2573 "shll %R0\;rotcl %S0"
2574 [(set_attr "length" "4")
2575 (set_attr "type" "arith")])
2577 (define_insn "ashldi3_media"
2578 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2579 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2580 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2585 [(set_attr "type" "arith_media")])
2587 (define_expand "ashldi3"
2588 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2589 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2590 (match_operand:DI 2 "immediate_operand" "")))
2591 (clobber (reg:SI T_REG))])]
2597 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2600 if (GET_CODE (operands[2]) != CONST_INT
2601 || INTVAL (operands[2]) != 1)
2605 ;; ??? This should be a define expand.
2607 (define_insn "lshrdi3_k"
2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2609 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2611 (clobber (reg:SI T_REG))]
2613 "shlr %S0\;rotcr %R0"
2614 [(set_attr "length" "4")
2615 (set_attr "type" "arith")])
2617 (define_insn "lshrdi3_media"
2618 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2619 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2620 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2625 [(set_attr "type" "arith_media")])
2627 (define_expand "lshrdi3"
2628 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2629 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2630 (match_operand:DI 2 "immediate_operand" "")))
2631 (clobber (reg:SI T_REG))])]
2637 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2640 if (GET_CODE (operands[2]) != CONST_INT
2641 || INTVAL (operands[2]) != 1)
2645 ;; ??? This should be a define expand.
2647 (define_insn "ashrdi3_k"
2648 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2649 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2651 (clobber (reg:SI T_REG))]
2653 "shar %S0\;rotcr %R0"
2654 [(set_attr "length" "4")
2655 (set_attr "type" "arith")])
2657 (define_insn "ashrdi3_media"
2658 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2659 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2660 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2665 [(set_attr "type" "arith_media")])
2667 (define_expand "ashrdi3"
2668 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2669 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2670 (match_operand:DI 2 "immediate_operand" "")))
2671 (clobber (reg:SI T_REG))])]
2677 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2680 if (GET_CODE (operands[2]) != CONST_INT
2681 || INTVAL (operands[2]) != 1)
2685 ;; combined left/right shift
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2690 (match_operand:SI 2 "const_int_operand" ""))
2691 (match_operand:SI 3 "const_int_operand" "")))]
2692 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2693 [(use (reg:SI R0_REG))]
2694 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2698 [(set (match_operand:SI 0 "register_operand" "")
2699 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2700 (match_operand:SI 2 "const_int_operand" ""))
2701 (match_operand:SI 3 "const_int_operand" "")))
2702 (clobber (reg:SI T_REG))]
2703 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2704 [(use (reg:SI R0_REG))]
2705 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2709 [(set (match_operand:SI 0 "register_operand" "=r")
2710 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2711 (match_operand:SI 2 "const_int_operand" "n"))
2712 (match_operand:SI 3 "const_int_operand" "n")))
2713 (clobber (reg:SI T_REG))]
2714 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2716 [(set (attr "length")
2717 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2719 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2721 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2723 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2725 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2727 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2729 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2730 (const_string "16")]
2731 (const_string "18")))
2732 (set_attr "type" "arith")])
2735 [(set (match_operand:SI 0 "register_operand" "=z")
2736 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2737 (match_operand:SI 2 "const_int_operand" "n"))
2738 (match_operand:SI 3 "const_int_operand" "n")))
2739 (clobber (reg:SI T_REG))]
2740 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2742 [(set (attr "length")
2743 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2745 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2747 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2749 (const_string "10")))
2750 (set_attr "type" "arith")])
2752 ;; shift left / and combination with a scratch register: The combine pass
2753 ;; does not accept the individual instructions, even though they are
2754 ;; cheap. But it needs a precise description so that it is usable after
2756 (define_insn "and_shl_scratch"
2757 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2761 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2762 (match_operand:SI 2 "const_int_operand" "N,n"))
2763 (match_operand:SI 3 "" "0,r"))
2764 (match_operand:SI 4 "const_int_operand" "n,n"))
2765 (match_operand:SI 5 "const_int_operand" "n,n")))
2766 (clobber (reg:SI T_REG))]
2769 [(set (attr "length")
2770 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2772 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2774 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2776 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2777 (const_string "10")]
2778 (const_string "12")))
2779 (set_attr "type" "arith")])
2782 [(set (match_operand:SI 0 "register_operand" "")
2786 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2787 (match_operand:SI 2 "const_int_operand" ""))
2788 (match_operand:SI 3 "register_operand" ""))
2789 (match_operand:SI 4 "const_int_operand" ""))
2790 (match_operand:SI 5 "const_int_operand" "")))
2791 (clobber (reg:SI T_REG))]
2793 [(use (reg:SI R0_REG))]
2796 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2798 if (INTVAL (operands[2]))
2800 gen_shifty_op (LSHIFTRT, operands);
2802 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2803 operands[2] = operands[4];
2804 gen_shifty_op (ASHIFT, operands);
2805 if (INTVAL (operands[5]))
2807 operands[2] = operands[5];
2808 gen_shifty_op (LSHIFTRT, operands);
2813 ;; signed left/right shift combination.
2815 [(set (match_operand:SI 0 "register_operand" "")
2817 (ashift:SI (match_operand:SI 1 "register_operand" "")
2818 (match_operand:SI 2 "const_int_operand" ""))
2819 (match_operand:SI 3 "const_int_operand" "")
2821 (clobber (reg:SI T_REG))]
2823 [(use (reg:SI R0_REG))]
2824 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2827 (define_insn "shl_sext_ext"
2828 [(set (match_operand:SI 0 "register_operand" "=r")
2830 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2831 (match_operand:SI 2 "const_int_operand" "n"))
2832 (match_operand:SI 3 "const_int_operand" "n")
2834 (clobber (reg:SI T_REG))]
2835 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2837 [(set (attr "length")
2838 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2840 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2842 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2844 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2846 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2848 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2850 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2852 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2853 (const_string "16")]
2854 (const_string "18")))
2855 (set_attr "type" "arith")])
2857 (define_insn "shl_sext_sub"
2858 [(set (match_operand:SI 0 "register_operand" "=z")
2860 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2861 (match_operand:SI 2 "const_int_operand" "n"))
2862 (match_operand:SI 3 "const_int_operand" "n")
2864 (clobber (reg:SI T_REG))]
2865 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2867 [(set (attr "length")
2868 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2870 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2872 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2874 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2875 (const_string "12")]
2876 (const_string "14")))
2877 (set_attr "type" "arith")])
2879 ;; These patterns are found in expansions of DImode shifts by 16, and
2880 ;; allow the xtrct instruction to be generated from C source.
2882 (define_insn "xtrct_left"
2883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2886 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2890 [(set_attr "type" "arith")])
2892 (define_insn "xtrct_right"
2893 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2894 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2896 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2900 [(set_attr "type" "arith")])
2902 ;; -------------------------------------------------------------------------
2904 ;; -------------------------------------------------------------------------
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908 (neg:SI (plus:SI (reg:SI T_REG)
2909 (match_operand:SI 1 "arith_reg_operand" "r"))))
2911 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2915 [(set_attr "type" "arith")])
2917 (define_insn "*negdi_media"
2918 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2919 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2922 [(set_attr "type" "arith_media")])
2924 (define_expand "negdi2"
2925 [(set (match_operand:DI 0 "arith_reg_operand" "")
2926 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2932 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2933 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2935 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2936 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2938 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2939 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2941 emit_insn (gen_clrt ());
2942 emit_insn (gen_negc (low_dst, low_src));
2943 emit_insn (gen_negc (high_dst, high_src));
2948 (define_insn "negsi2"
2949 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2953 [(set_attr "type" "arith")])
2955 (define_insn "one_cmplsi2"
2956 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2957 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2960 [(set_attr "type" "arith")])
2962 (define_expand "one_cmpldi2"
2963 [(set (match_operand:DI 0 "arith_reg_operand" "")
2964 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2966 "TARGET_SHMEDIA" "")
2968 ;; -------------------------------------------------------------------------
2969 ;; Zero extension instructions
2970 ;; -------------------------------------------------------------------------
2972 (define_insn "zero_extendsidi2"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2976 "addz.l %1, r63, %0"
2977 [(set_attr "type" "arith_media")])
2979 (define_insn "zero_extendhidi2"
2980 [(set (match_operand:DI 0 "register_operand" "=r,r")
2981 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2986 [(set_attr "type" "*,load_media")])
2989 [(set (match_operand:DI 0 "register_operand" "")
2990 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2991 "TARGET_SHMEDIA && reload_completed"
2992 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2993 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2996 if (GET_CODE (operands[1]) == TRUNCATE)
2997 operands[1] = XEXP (operands[1], 0);
3000 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3001 ;; reload the entrire truncate expression.
3002 (define_insn_and_split "*loaddi_trunc"
3003 [(set (match_operand 0 "int_gpr_dest" "=r")
3004 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3005 "TARGET_SHMEDIA && reload_completed"
3007 "TARGET_SHMEDIA && reload_completed"
3008 [(set (match_dup 0) (match_dup 1))]
3009 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3011 (define_insn "zero_extendqidi2"
3012 [(set (match_operand:DI 0 "register_operand" "=r,r")
3013 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3018 [(set_attr "type" "arith_media,load_media")])
3020 (define_expand "zero_extendhisi2"
3021 [(set (match_operand:SI 0 "arith_reg_operand" "")
3022 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3026 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3027 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3030 (define_insn "*zero_extendhisi2_compact"
3031 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3032 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3035 [(set_attr "type" "arith")])
3037 (define_insn "*zero_extendhisi2_media"
3038 [(set (match_operand:SI 0 "register_operand" "=r,r")
3039 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3044 [(set_attr "type" "arith_media,load_media")])
3047 [(set (match_operand:SI 0 "register_operand" "")
3048 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3049 "TARGET_SHMEDIA && reload_completed"
3050 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3051 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3054 if (GET_CODE (operands[1]) == TRUNCATE)
3055 operands[1] = XEXP (operands[1], 0);
3058 (define_expand "zero_extendqisi2"
3059 [(set (match_operand:SI 0 "arith_reg_operand" "")
3060 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3064 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3065 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3068 (define_insn "*zero_extendqisi2_compact"
3069 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3070 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3073 [(set_attr "type" "arith")])
3075 (define_insn "*zero_extendqisi2_media"
3076 [(set (match_operand:SI 0 "register_operand" "=r,r")
3077 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3082 [(set_attr "type" "arith_media,load_media")])
3084 (define_insn "zero_extendqihi2"
3085 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3086 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3089 [(set_attr "type" "arith")])
3091 ;; -------------------------------------------------------------------------
3092 ;; Sign extension instructions
3093 ;; -------------------------------------------------------------------------
3095 ;; ??? This should be a define expand.
3096 ;; ??? Or perhaps it should be dropped?
3098 ;; convert_move generates good code for SH[1-4].
3099 (define_insn "extendsidi2"
3100 [(set (match_operand:DI 0 "register_operand" "=r,r")
3101 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3106 [(set_attr "type" "arith_media,load_media")])
3108 (define_insn "extendhidi2"
3109 [(set (match_operand:DI 0 "register_operand" "=r,r")
3110 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3115 [(set_attr "type" "*,load_media")])
3118 [(set (match_operand:DI 0 "register_operand" "")
3119 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3120 "TARGET_SHMEDIA && reload_completed"
3121 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3122 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3125 if (GET_CODE (operands[1]) == TRUNCATE)
3126 operands[1] = XEXP (operands[1], 0);
3129 (define_insn "extendqidi2"
3130 [(set (match_operand:DI 0 "register_operand" "=r,r")
3131 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3136 [(set_attr "type" "*,load_media")])
3139 [(set (match_operand:DI 0 "register_operand" "")
3140 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3141 "TARGET_SHMEDIA && reload_completed"
3142 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3143 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3146 if (GET_CODE (operands[1]) == TRUNCATE)
3147 operands[1] = XEXP (operands[1], 0);
3150 (define_expand "extendhisi2"
3151 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3152 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3156 (define_insn "*extendhisi2_compact"
3157 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3163 [(set_attr "type" "arith,load")])
3165 (define_insn "*extendhisi2_media"
3166 [(set (match_operand:SI 0 "register_operand" "=r,r")
3167 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3172 [(set_attr "type" "arith_media,load_media")])
3175 [(set (match_operand:SI 0 "register_operand" "")
3176 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3177 "TARGET_SHMEDIA && reload_completed"
3178 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3179 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3182 if (GET_CODE (operands[1]) == TRUNCATE)
3183 operands[1] = XEXP (operands[1], 0);
3186 (define_expand "extendqisi2"
3187 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3188 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3192 (define_insn "*extendqisi2_compact"
3193 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3199 [(set_attr "type" "arith,load")])
3201 (define_insn "*extendqisi2_media"
3202 [(set (match_operand:SI 0 "register_operand" "=r,r")
3203 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3208 [(set_attr "type" "arith_media,load_media")])
3211 [(set (match_operand:SI 0 "register_operand" "")
3212 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3213 "TARGET_SHMEDIA && reload_completed"
3214 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3215 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3218 if (GET_CODE (operands[1]) == TRUNCATE)
3219 operands[1] = XEXP (operands[1], 0);
3222 (define_insn "extendqihi2"
3223 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3224 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3229 [(set_attr "type" "arith,load")])
3231 /* It would seem useful to combine the truncXi patterns into the movXi
3232 patterns, but unary operators are ignored when matching constraints,
3233 so we need separate patterns. */
3234 (define_insn "truncdisi2"
3235 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3236 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3245 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3248 (define_insn "truncdihi2"
3249 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3250 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3253 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3255 [(set_attr "type" "arith_media,store_media")
3256 (set_attr "length" "8,4")])
3258 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3259 ; Because we use zero extension, we can't provide signed QImode compares
3260 ; using a simple compare or conditional banch insn.
3261 (define_insn "truncdiqi2"
3262 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3263 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3268 [(set_attr "type" "arith_media,store")])
3270 ;; -------------------------------------------------------------------------
3271 ;; Move instructions
3272 ;; -------------------------------------------------------------------------
3274 ;; define push and pop so it is easy for sh.c
3275 ;; We can't use push and pop on SHcompact because the stack must always
3276 ;; be 8-byte aligned.
3278 (define_expand "push"
3279 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3280 (match_operand:SI 0 "register_operand" "r,l,x"))]
3281 "TARGET_SH1 && ! TARGET_SH5"
3284 (define_expand "pop"
3285 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3286 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3287 "TARGET_SH1 && ! TARGET_SH5"
3290 (define_expand "push_e"
3291 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3292 (match_operand:SF 0 "" ""))
3293 (use (reg:PSI FPSCR_REG))
3294 (clobber (scratch:SI))])]
3295 "TARGET_SH1 && ! TARGET_SH5"
3298 (define_insn "push_fpul"
3299 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3300 "TARGET_SH3E && ! TARGET_SH5"
3302 [(set_attr "type" "store")
3303 (set_attr "late_fp_use" "yes")
3304 (set_attr "hit_stack" "yes")])
3306 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3308 (define_expand "push_4"
3309 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3310 (match_operand:DF 0 "" ""))
3311 (use (reg:PSI FPSCR_REG))
3312 (clobber (scratch:SI))])]
3313 "TARGET_SH1 && ! TARGET_SH5"
3316 (define_expand "pop_e"
3317 [(parallel [(set (match_operand:SF 0 "" "")
3318 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3319 (use (reg:PSI FPSCR_REG))
3320 (clobber (scratch:SI))])]
3321 "TARGET_SH1 && ! TARGET_SH5"
3324 (define_insn "pop_fpul"
3325 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3326 "TARGET_SH3E && ! TARGET_SH5"
3328 [(set_attr "type" "load")
3329 (set_attr "hit_stack" "yes")])
3331 (define_expand "pop_4"
3332 [(parallel [(set (match_operand:DF 0 "" "")
3333 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3334 (use (reg:PSI FPSCR_REG))
3335 (clobber (scratch:SI))])]
3336 "TARGET_SH1 && ! TARGET_SH5"
3339 (define_expand "push_fpscr"
3344 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3345 gen_rtx (PRE_DEC, Pmode,
3346 stack_pointer_rtx)),
3348 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3352 (define_expand "pop_fpscr"
3357 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3358 gen_rtx (MEM, PSImode,
3359 gen_rtx (POST_INC, Pmode,
3360 stack_pointer_rtx))));
3361 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3365 ;; These two patterns can happen as the result of optimization, when
3366 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3367 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3370 [(set (reg:SI T_REG) (const_int 0))]
3375 [(set (reg:SI T_REG) (const_int 1))]
3379 ;; t/r must come after r/r, lest reload will try to reload stuff like
3380 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3381 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3382 (define_insn "movsi_i"
3383 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3384 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3387 && (register_operand (operands[0], SImode)
3388 || register_operand (operands[1], SImode))"
3405 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3406 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3408 ;; t/r must come after r/r, lest reload will try to reload stuff like
3409 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3410 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3411 ;; will require a reload.
3412 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3413 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3414 (define_insn "movsi_ie"
3415 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3416 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3418 && (register_operand (operands[0], SImode)
3419 || register_operand (operands[1], SImode))"
3443 ! move optimized away"
3444 [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
3445 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3446 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3448 (define_insn "movsi_i_lowpart"
3449 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3450 (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3452 && (register_operand (operands[0], SImode)
3453 || register_operand (operands[1], SImode))"
3463 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3465 (define_insn "*movsi_media"
3466 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3467 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,m,f,rU,f,f,r,*b,T"))]
3469 && (register_operand (operands[0], SImode)
3470 || sh_register_operand (operands[1], SImode))"
3485 [(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")
3486 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3488 (define_insn "*movsi_media_nofpu"
3489 [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3490 (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,rU,r,*b,T"))]
3492 && (register_operand (operands[0], SImode)
3493 || sh_register_operand (operands[1], SImode))"
3503 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3504 (set_attr "length" "4,4,8,4,4,4,4,12")])
3507 [(set (match_operand:SI 0 "arith_reg_operand" "")
3508 (match_operand:SI 1 "immediate_operand" ""))]
3509 "TARGET_SHMEDIA && reload_completed
3510 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3511 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3514 operands[2] = shallow_copy_rtx (operands[1]);
3515 PUT_MODE (operands[2], DImode);
3519 [(set (match_operand:SI 0 "register_operand" "")
3520 (match_operand:SI 1 "immediate_operand" ""))]
3521 "TARGET_SHMEDIA && reload_completed
3522 && ((GET_CODE (operands[1]) == CONST_INT
3523 && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3524 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3525 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3527 (define_expand "movsi"
3528 [(set (match_operand:SI 0 "general_movdst_operand" "")
3529 (match_operand:SI 1 "general_movsrc_operand" ""))]
3531 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3533 (define_expand "ic_invalidate_line"
3534 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3535 (match_dup 1)] UNSPEC_ICACHE)
3536 (clobber (scratch:SI))])]
3537 "TARGET_HARD_SH4 || TARGET_SH5"
3542 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3545 else if (TARGET_SHCOMPACT)
3547 operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3548 operands[1] = force_reg (Pmode, operands[1]);
3549 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3552 operands[0] = force_reg (Pmode, operands[0]);
3553 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3557 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3558 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3559 ;; the requirement *1*00 for associative address writes. The alignment of
3560 ;; %0 implies that its least significant bit is cleared,
3561 ;; thus we clear the V bit of a matching entry if there is one.
3562 (define_insn "ic_invalidate_line_i"
3563 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3564 (match_operand:SI 1 "register_operand" "r")]
3566 (clobber (match_scratch:SI 2 "=&r"))]
3568 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3569 [(set_attr "length" "8")
3570 (set_attr "type" "cwb")])
3572 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3573 ;; an add in the code that calculates the address.
3574 (define_insn "ic_invalidate_line_media"
3575 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3578 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3579 [(set_attr "length" "16")
3580 (set_attr "type" "invalidate_line_media")])
3582 (define_insn "ic_invalidate_line_compact"
3583 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3584 (match_operand:SI 1 "register_operand" "r")]
3586 (clobber (reg:SI PR_REG))]
3589 [(set_attr "type" "sfunc")
3590 (set_attr "needs_delay_slot" "yes")])
3592 (define_expand "initialize_trampoline"
3593 [(match_operand:SI 0 "" "")
3594 (match_operand:SI 1 "" "")
3595 (match_operand:SI 2 "" "")]
3601 tramp = force_reg (Pmode, operands[0]);
3602 sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3603 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3604 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3606 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3610 (define_insn "initialize_trampoline_compact"
3611 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3612 (match_operand:SI 1 "register_operand" "r")
3613 (reg:SI R2_REG) (reg:SI R3_REG)]
3616 (clobber (reg:SI PR_REG))]
3619 [(set_attr "type" "sfunc")
3620 (set_attr "needs_delay_slot" "yes")])
3622 (define_insn "movqi_i"
3623 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3624 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3626 && (arith_reg_operand (operands[0], QImode)
3627 || arith_reg_operand (operands[1], QImode))"
3635 [(set_attr "type" "move,load,store,move,move,move")])
3637 (define_insn "*movqi_media"
3638 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3639 (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,rU"))]
3641 && (arith_reg_operand (operands[0], QImode)
3642 || arith_reg_or_0_operand (operands[1], QImode))"
3648 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3650 (define_expand "movqi"
3651 [(set (match_operand:QI 0 "general_operand" "")
3652 (match_operand:QI 1 "general_operand" ""))]
3654 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3656 (define_expand "reload_inqi"
3657 [(set (match_operand:SI 2 "" "=&r")
3658 (match_operand:QI 1 "inqhi_operand" ""))
3659 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3660 (truncate:HI (match_dup 3)))]
3664 rtx inner = XEXP (operands[1], 0);
3665 int regno = REGNO (inner);
3667 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3668 operands[1] = gen_rtx_REG (SImode, regno);
3669 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3672 (define_insn "movhi_i"
3673 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3674 (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3676 && (arith_reg_operand (operands[0], HImode)
3677 || arith_reg_operand (operands[1], HImode))"
3687 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3689 (define_insn "*movhi_media"
3690 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3691 (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,rU"))]
3693 && (arith_reg_operand (operands[0], HImode)
3694 || arith_reg_or_0_operand (operands[1], HImode))"
3701 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3704 [(set (match_operand:HI 0 "register_operand" "")
3705 (match_operand:HI 1 "immediate_operand" ""))]
3706 "TARGET_SHMEDIA && reload_completed
3707 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3708 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3710 (define_expand "movhi"
3711 [(set (match_operand:HI 0 "general_movdst_operand" "")
3712 (match_operand:HI 1 "general_movsrc_operand" ""))]
3714 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3716 (define_expand "reload_inhi"
3717 [(set (match_operand:SI 2 "" "=&r")
3718 (match_operand:HI 1 "inqhi_operand" ""))
3719 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3720 (truncate:HI (match_dup 3)))]
3724 rtx inner = XEXP (operands[1], 0);
3725 int regno = REGNO (inner);
3727 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3728 operands[1] = gen_rtx_REG (SImode, regno);
3729 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3732 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3733 ;; compiled with -m2 -ml -O3 -funroll-loops
3734 (define_insn "*movdi_i"
3735 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3736 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3738 && (arith_reg_operand (operands[0], DImode)
3739 || arith_reg_operand (operands[1], DImode))"
3740 "* return output_movedouble (insn, operands, DImode);"
3741 [(set_attr "length" "4")
3742 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3744 ;; If the output is a register and the input is memory or a register, we have
3745 ;; to be careful and see which word needs to be loaded first.
3748 [(set (match_operand:DI 0 "general_movdst_operand" "")
3749 (match_operand:DI 1 "general_movsrc_operand" ""))]
3750 "TARGET_SH1 && reload_completed"
3751 [(set (match_dup 2) (match_dup 3))
3752 (set (match_dup 4) (match_dup 5))]
3757 if ((GET_CODE (operands[0]) == MEM
3758 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3759 || (GET_CODE (operands[1]) == MEM
3760 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3763 if (GET_CODE (operands[0]) == REG)
3764 regno = REGNO (operands[0]);
3765 else if (GET_CODE (operands[0]) == SUBREG)
3766 regno = subreg_regno (operands[0]);
3767 else if (GET_CODE (operands[0]) == MEM)
3773 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3775 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3776 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3777 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3778 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3782 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3783 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3784 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3785 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3788 if (operands[2] == 0 || operands[3] == 0
3789 || operands[4] == 0 || operands[5] == 0)
3793 (define_insn "*movdi_media"
3794 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3795 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,m,f,rU,f,f,r,*b,T"))]
3797 && (register_operand (operands[0], DImode)
3798 || sh_register_operand (operands[1], DImode))"
3813 [(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")
3814 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3816 (define_insn "*movdi_media_nofpu"
3817 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3818 (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rlU,r,*b,T"))]
3820 && (register_operand (operands[0], DImode)
3821 || sh_register_operand (operands[1], DImode))"
3831 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3832 (set_attr "length" "4,4,16,4,4,4,4,*")])
3835 [(set (match_operand:DI 0 "arith_reg_operand" "")
3836 (match_operand:DI 1 "immediate_operand" ""))]
3837 "TARGET_SHMEDIA && reload_completed
3838 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3839 [(set (match_dup 0) (match_dup 1))]
3844 if (TARGET_SHMEDIA64)
3845 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3847 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3849 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3855 (define_expand "movdi_const"
3856 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3857 (const:DI (sign_extend:DI
3860 (match_operand:DI 1 "immediate_operand" "s")
3863 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3871 (const_int 32)))))))))
3873 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3881 (const_int 16)))))))))
3883 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3889 (match_dup 1))))))))]
3890 "TARGET_SHMEDIA64 && reload_completed
3891 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3894 sh_mark_label (operands[1], 4);
3897 (define_expand "movdi_const_32bit"
3898 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899 (const:DI (sign_extend:DI
3902 (match_operand:DI 1 "immediate_operand" "s")
3905 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3911 (match_dup 1))))))))]
3912 "TARGET_SHMEDIA32 && reload_completed
3913 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3916 sh_mark_label (operands[1], 2);
3919 (define_expand "movdi_const_16bit"
3920 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3921 (const:DI (sign_extend:DI
3923 (match_operand:DI 1 "immediate_operand" "s")))))]
3924 "TARGET_SHMEDIA && flag_pic && reload_completed
3925 && GET_CODE (operands[1]) == SYMBOL_REF"
3929 [(set (match_operand:DI 0 "arith_reg_operand" "")
3930 (match_operand:DI 1 "immediate_operand" ""))]
3931 "TARGET_SHMEDIA && reload_completed
3932 && GET_CODE (operands[1]) == CONST_INT
3933 && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3934 [(set (match_dup 0) (match_dup 2))
3938 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3939 unsigned HOST_WIDE_INT low = val;
3940 unsigned HOST_WIDE_INT high = val;
3941 unsigned HOST_WIDE_INT sign;
3942 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3944 /* Sign-extend the 16 least-significant bits. */
3949 /* Arithmetic shift right the word by 16 bits. */
3952 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3957 /* If we can't generate the constant with a two-insn movi / shori
3958 sequence, try some other strategies. */
3959 if (! CONST_OK_FOR_J (high))
3961 /* Try constant load / left shift. We know VAL != 0. */
3962 val2 = val ^ (val-1);
3965 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3967 if (CONST_OK_FOR_J (val >> trailing_zeroes)
3968 || (! CONST_OK_FOR_J (high >> 16)
3969 && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3971 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3972 operands[1] = gen_ashldi3_media (operands[0], operands[0],
3973 GEN_INT (trailing_zeroes));
3977 /* Try constant load / right shift. */
3978 val2 = (val >> 15) + 1;
3979 if (val2 == (val2 & -val2))
3981 int shift = 49 - exact_log2 (val2);
3983 val2 = trunc_int_for_mode (val << shift, DImode);
3984 if (CONST_OK_FOR_J (val2))
3986 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3992 val2 = val & 0xffff;
3993 if ((val >> 16 & 0xffff) == val2
3994 && (val >> 32 & 0xffff) == val2
3995 && (val >> 48 & 0xffff) == val2)
3997 val2 = (HOST_WIDE_INT) val >> 48;
3998 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3999 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4002 /* Try movi / mshflo.l */
4003 val2 = (HOST_WIDE_INT) val >> 32;
4004 if (val2 == trunc_int_for_mode (val, SImode))
4006 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4010 /* Try movi / mshflo.l w/ r63. */
4011 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4012 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
4014 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4020 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4023 operands[2] = GEN_INT (val2);
4027 [(set (match_operand:DI 0 "arith_reg_operand" "")
4028 (match_operand:DI 1 "immediate_operand" ""))]
4029 "TARGET_SHMEDIA && reload_completed
4030 && GET_CODE (operands[1]) == CONST_DOUBLE"
4031 [(set (match_dup 0) (match_dup 2))
4033 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4034 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4037 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4038 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4039 unsigned HOST_WIDE_INT val = low;
4040 unsigned HOST_WIDE_INT sign;
4042 /* Sign-extend the 16 least-significant bits. */
4046 operands[1] = GEN_INT (val);
4048 /* Arithmetic shift right the double-word by 16 bits. */
4050 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4053 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4057 /* This will only be true if high is a sign-extension of low, i.e.,
4058 it must be either 0 or (unsigned)-1, and be zero iff the
4059 most-significant bit of low is set. */
4060 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4061 operands[2] = GEN_INT (low);
4063 operands[2] = immed_double_const (low, high, DImode);
4066 (define_insn "shori_media"
4067 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4068 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4072 (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4077 [(set_attr "type" "arith_media,*")])
4079 (define_expand "movdi"
4080 [(set (match_operand:DI 0 "general_movdst_operand" "")
4081 (match_operand:DI 1 "general_movsrc_operand" ""))]
4083 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4085 (define_insn "movdf_media"
4086 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4087 (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
4089 && (register_operand (operands[0], DFmode)
4090 || sh_register_operand (operands[1], DFmode))"
4101 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4103 (define_insn "movdf_media_nofpu"
4104 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4105 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rU"))]
4107 && (register_operand (operands[0], DFmode)
4108 || sh_register_operand (operands[1], DFmode))"
4114 [(set_attr "type" "arith_media,*,load_media,store_media")])
4117 [(set (match_operand:DF 0 "arith_reg_operand" "")
4118 (match_operand:DF 1 "immediate_operand" ""))]
4119 "TARGET_SHMEDIA && reload_completed"
4120 [(set (match_dup 3) (match_dup 2))]
4123 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4125 REAL_VALUE_TYPE value;
4127 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4128 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4130 if (HOST_BITS_PER_WIDE_INT >= 64)
4131 operands[2] = immed_double_const ((unsigned long) values[endian]
4132 | ((HOST_WIDE_INT) values[1 - endian]
4134 else if (HOST_BITS_PER_WIDE_INT == 32)
4135 operands[2] = immed_double_const (values[endian], values[1 - endian],
4140 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4143 ;; ??? This should be a define expand.
4145 (define_insn "movdf_k"
4146 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4147 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4149 && (! TARGET_SH4 || reload_completed
4150 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4151 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4152 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4153 && (arith_reg_operand (operands[0], DFmode)
4154 || arith_reg_operand (operands[1], DFmode))"
4155 "* return output_movedouble (insn, operands, DFmode);"
4156 [(set_attr "length" "4")
4157 (set_attr "type" "move,pcload,load,store")])
4159 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4160 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4161 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4162 ;; the d/m/c/X alternative, which is split later into single-precision
4163 ;; instructions. And when not optimizing, no splits are done before fixing
4164 ;; up pcloads, so we need usable length information for that.
4165 (define_insn "movdf_i4"
4166 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4167 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4168 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4169 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4171 && (arith_reg_operand (operands[0], DFmode)
4172 || arith_reg_operand (operands[1], DFmode))"
4184 [(set_attr_alternative "length"
4185 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4187 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4188 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4189 (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4191 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4192 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4193 ;; increment or decrement r15 explicitly.
4195 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4196 (const_int 10) (const_int 8))
4198 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4199 (const_int 10) (const_int 8))])
4200 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4201 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4202 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4203 (const_string "double")
4204 (const_string "none")))])
4206 ;; Moving DFmode between fp/general registers through memory
4207 ;; (the top of the stack) is faster than moving through fpul even for
4208 ;; little endian. Because the type of an instruction is important for its
4209 ;; scheduling, it is beneficial to split these operations, rather than
4210 ;; emitting them in one single chunk, even if this will expose a stack
4211 ;; use that will prevent scheduling of other stack accesses beyond this
4214 [(set (match_operand:DF 0 "register_operand" "")
4215 (match_operand:DF 1 "register_operand" ""))
4216 (use (match_operand:PSI 2 "fpscr_operand" ""))
4217 (clobber (match_scratch:SI 3 "=X"))]
4218 "TARGET_SH4 && reload_completed
4219 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4225 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4227 emit_move_insn (stack_pointer_rtx,
4228 plus_constant (stack_pointer_rtx, -8));
4229 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4232 tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4233 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4234 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4235 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4236 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4237 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4239 tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4240 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4241 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4242 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4244 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4248 ;; local-alloc sometimes allocates scratch registers even when not required,
4249 ;; so we must be prepared to handle these.
4251 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4253 [(set (match_operand:DF 0 "general_movdst_operand" "")
4254 (match_operand:DF 1 "general_movsrc_operand" ""))
4255 (use (match_operand:PSI 2 "fpscr_operand" ""))
4256 (clobber (match_scratch:SI 3 ""))]
4259 && true_regnum (operands[0]) < 16
4260 && true_regnum (operands[1]) < 16"
4261 [(set (match_dup 0) (match_dup 1))]
4264 /* If this was a reg <-> mem operation with base + index reg addressing,
4265 we have to handle this in a special way. */
4266 rtx mem = operands[0];
4268 if (! memory_operand (mem, DFmode))
4273 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4274 mem = SUBREG_REG (mem);
4275 if (GET_CODE (mem) == MEM)
4277 rtx addr = XEXP (mem, 0);
4278 if (GET_CODE (addr) == PLUS
4279 && GET_CODE (XEXP (addr, 0)) == REG
4280 && GET_CODE (XEXP (addr, 1)) == REG)
4283 rtx reg0 = gen_rtx (REG, Pmode, 0);
4284 rtx regop = operands[store_p], word0 ,word1;
4286 if (GET_CODE (regop) == SUBREG)
4287 alter_subreg (®op);
4288 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4292 mem = copy_rtx (mem);
4293 PUT_MODE (mem, SImode);
4294 word0 = gen_rtx (SUBREG, SImode, regop, 0);
4295 alter_subreg (&word0);
4296 word1 = gen_rtx (SUBREG, SImode, regop, 4);
4297 alter_subreg (&word1);
4298 if (store_p || ! refers_to_regno_p (REGNO (word0),
4299 REGNO (word0) + 1, addr, 0))
4302 ? gen_movsi_ie (mem, word0)
4303 : gen_movsi_ie (word0, mem));
4304 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4305 mem = copy_rtx (mem);
4307 ? gen_movsi_ie (mem, word1)
4308 : gen_movsi_ie (word1, mem));
4309 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4313 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4314 emit_insn (gen_movsi_ie (word1, mem));
4315 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4316 mem = copy_rtx (mem);
4317 emit_insn (gen_movsi_ie (word0, mem));
4324 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4326 [(set (match_operand:DF 0 "register_operand" "")
4327 (match_operand:DF 1 "memory_operand" ""))
4328 (use (match_operand:PSI 2 "fpscr_operand" ""))
4329 (clobber (reg:SI R0_REG))]
4330 "TARGET_SH4 && reload_completed"
4331 [(parallel [(set (match_dup 0) (match_dup 1))
4333 (clobber (scratch:SI))])]
4336 (define_expand "reload_indf"
4337 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4338 (match_operand:DF 1 "immediate_operand" "FQ"))
4339 (use (reg:PSI FPSCR_REG))
4340 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4344 (define_expand "reload_outdf"
4345 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4346 (match_operand:DF 1 "register_operand" "af,r"))
4347 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4351 ;; Simplify no-op moves.
4353 [(set (match_operand:SF 0 "register_operand" "")
4354 (match_operand:SF 1 "register_operand" ""))
4355 (use (match_operand:PSI 2 "fpscr_operand" ""))
4356 (clobber (match_scratch:SI 3 "X"))]
4357 "TARGET_SH3E && reload_completed
4358 && true_regnum (operands[0]) == true_regnum (operands[1])"
4359 [(set (match_dup 0) (match_dup 0))]
4362 ;; fmovd substitute post-reload splits
4364 [(set (match_operand:DF 0 "register_operand" "")
4365 (match_operand:DF 1 "register_operand" ""))
4366 (use (match_operand:PSI 2 "fpscr_operand" ""))
4367 (clobber (match_scratch:SI 3 "X"))]
4368 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4369 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4370 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4374 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4375 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4376 gen_rtx (REG, SFmode, src), operands[2]));
4377 emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4378 gen_rtx (REG, SFmode, src + 1), operands[2]));
4383 [(set (match_operand:DF 0 "register_operand" "")
4384 (mem:DF (match_operand:SI 1 "register_operand" "")))
4385 (use (match_operand:PSI 2 "fpscr_operand" ""))
4386 (clobber (match_scratch:SI 3 ""))]
4387 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4388 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4389 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4393 int regno = true_regnum (operands[0]);
4395 rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4397 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4398 regno + !! TARGET_LITTLE_ENDIAN),
4399 mem2, operands[2]));
4400 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4401 insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4402 regno + ! TARGET_LITTLE_ENDIAN),
4403 gen_rtx (MEM, SFmode, operands[1]),
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (use (match_operand:PSI 2 "fpscr_operand" ""))
4412 (clobber (match_scratch:SI 3 ""))]
4413 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4414 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4418 int regno = true_regnum (operands[0]);
4419 rtx addr, insn, adjust = NULL_RTX;
4420 rtx mem2 = copy_rtx (operands[1]);
4421 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4422 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4424 PUT_MODE (mem2, SFmode);
4425 operands[1] = copy_rtx (mem2);
4426 addr = XEXP (mem2, 0);
4427 if (GET_CODE (addr) != POST_INC)
4429 /* If we have to modify the stack pointer, the value that we have
4430 read with post-increment might be modified by an interrupt,
4431 so write it back. */
4432 if (REGNO (addr) == STACK_POINTER_REGNUM)
4433 adjust = gen_push_e (reg0);
4435 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4436 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4438 addr = XEXP (addr, 0);
4439 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4440 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4441 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4445 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4450 [(set (match_operand:DF 0 "memory_operand" "")
4451 (match_operand:DF 1 "register_operand" ""))
4452 (use (match_operand:PSI 2 "fpscr_operand" ""))
4453 (clobber (match_scratch:SI 3 ""))]
4454 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4455 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4459 int regno = true_regnum (operands[1]);
4460 rtx insn, addr, adjust = NULL_RTX;
4462 operands[0] = copy_rtx (operands[0]);
4463 PUT_MODE (operands[0], SFmode);
4464 insn = emit_insn (gen_movsf_ie (operands[0],
4465 gen_rtx (REG, SFmode,
4466 regno + ! TARGET_LITTLE_ENDIAN),
4468 operands[0] = copy_rtx (operands[0]);
4469 addr = XEXP (operands[0], 0);
4470 if (GET_CODE (addr) != PRE_DEC)
4472 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4473 emit_insn_before (adjust, insn);
4474 XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4476 addr = XEXP (addr, 0);
4478 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4479 insn = emit_insn (gen_movsf_ie (operands[0],
4480 gen_rtx (REG, SFmode,
4481 regno + !! TARGET_LITTLE_ENDIAN),
4483 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4487 ;; If the output is a register and the input is memory or a register, we have
4488 ;; to be careful and see which word needs to be loaded first.
4491 [(set (match_operand:DF 0 "general_movdst_operand" "")
4492 (match_operand:DF 1 "general_movsrc_operand" ""))]
4493 "TARGET_SH1 && reload_completed"
4494 [(set (match_dup 2) (match_dup 3))
4495 (set (match_dup 4) (match_dup 5))]
4500 if ((GET_CODE (operands[0]) == MEM
4501 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4502 || (GET_CODE (operands[1]) == MEM
4503 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4506 if (GET_CODE (operands[0]) == REG)
4507 regno = REGNO (operands[0]);
4508 else if (GET_CODE (operands[0]) == SUBREG)
4509 regno = subreg_regno (operands[0]);
4510 else if (GET_CODE (operands[0]) == MEM)
4516 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4518 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4519 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4520 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4521 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4525 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4526 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4527 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4528 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4531 if (operands[2] == 0 || operands[3] == 0
4532 || operands[4] == 0 || operands[5] == 0)
4536 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4537 ;; used only once, let combine add in the index again.
4540 [(set (match_operand:SI 0 "register_operand" "")
4541 (match_operand:SI 1 "" ""))
4542 (clobber (match_operand 2 "register_operand" ""))]
4543 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4544 [(use (reg:SI R0_REG))]
4547 rtx addr, reg, const_int;
4549 if (GET_CODE (operands[1]) != MEM)
4551 addr = XEXP (operands[1], 0);
4552 if (GET_CODE (addr) != PLUS)
4554 reg = XEXP (addr, 0);
4555 const_int = XEXP (addr, 1);
4556 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4557 && GET_CODE (const_int) == CONST_INT))
4559 emit_move_insn (operands[2], const_int);
4560 emit_move_insn (operands[0],
4561 change_address (operands[1], VOIDmode,
4562 gen_rtx_PLUS (SImode, reg, operands[2])));
4567 [(set (match_operand:SI 1 "" "")
4568 (match_operand:SI 0 "register_operand" ""))
4569 (clobber (match_operand 2 "register_operand" ""))]
4570 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4571 [(use (reg:SI R0_REG))]
4574 rtx addr, reg, const_int;
4576 if (GET_CODE (operands[1]) != MEM)
4578 addr = XEXP (operands[1], 0);
4579 if (GET_CODE (addr) != PLUS)
4581 reg = XEXP (addr, 0);
4582 const_int = XEXP (addr, 1);
4583 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4584 && GET_CODE (const_int) == CONST_INT))
4586 emit_move_insn (operands[2], const_int);
4587 emit_move_insn (change_address (operands[1], VOIDmode,
4588 gen_rtx_PLUS (SImode, reg, operands[2])),
4593 (define_expand "movdf"
4594 [(set (match_operand:DF 0 "general_movdst_operand" "")
4595 (match_operand:DF 1 "general_movsrc_operand" ""))]
4599 if (prepare_move_operands (operands, DFmode)) DONE;
4602 if (TARGET_SHMEDIA_FPU)
4603 emit_insn (gen_movdf_media (operands[0], operands[1]));
4605 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4610 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4615 ;;This is incompatible with the way gcc uses subregs.
4616 ;;(define_insn "movv2sf_i"
4617 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4618 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4619 ;; "TARGET_SHMEDIA_FPU
4620 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4621 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4625 ;; fst%M0.p %m0, %1"
4626 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4628 (define_insn_and_split "movv2sf_i"
4629 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4630 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4631 "TARGET_SHMEDIA_FPU"
4633 "TARGET_SHMEDIA_FPU && reload_completed"
4634 [(set (match_dup 0) (match_dup 1))]
4637 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4638 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4641 (define_expand "movv2sf"
4642 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4643 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4644 "TARGET_SHMEDIA_FPU"
4647 if (prepare_move_operands (operands, V2SFmode))
4651 (define_expand "addv2sf3"
4652 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4653 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4654 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4655 "TARGET_SHMEDIA_FPU"
4658 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4662 (define_expand "subv2sf3"
4663 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4664 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4665 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4666 "TARGET_SHMEDIA_FPU"
4669 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4673 (define_expand "mulv2sf3"
4674 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4675 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4676 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4677 "TARGET_SHMEDIA_FPU"
4680 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4684 (define_expand "divv2sf3"
4685 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4686 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4688 "TARGET_SHMEDIA_FPU"
4691 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4695 (define_insn_and_split "*movv4sf_i"
4696 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4697 (match_operand:V4SF 1 "general_operand" "fU,m,fU"))]
4698 "TARGET_SHMEDIA_FPU"
4700 "&& reload_completed"
4706 for (i = 0; i < 4/2; i++)
4710 if (GET_CODE (operands[0]) == MEM)
4711 x = gen_rtx_MEM (V2SFmode,
4712 plus_constant (XEXP (operands[0], 0),
4713 i * GET_MODE_SIZE (V2SFmode)));
4715 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4717 if (GET_CODE (operands[1]) == MEM)
4718 y = gen_rtx_MEM (V2SFmode,
4719 plus_constant (XEXP (operands[1], 0),
4720 i * GET_MODE_SIZE (V2SFmode)));
4722 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4724 emit_insn (gen_movv2sf_i (x, y));
4729 [(set_attr "length" "8")])
4731 (define_expand "movv4sf"
4732 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4733 (match_operand:V4SF 1 "general_operand" ""))]
4734 "TARGET_SHMEDIA_FPU"
4737 if (prepare_move_operands (operands, V4SFmode))
4741 (define_insn_and_split "*movv16sf_i"
4742 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4743 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4744 "TARGET_SHMEDIA_FPU"
4746 "&& reload_completed"
4752 for (i = 0; i < 16/2; i++)
4756 if (GET_CODE (operands[0]) == MEM)
4757 x = gen_rtx_MEM (V2SFmode,
4758 plus_constant (XEXP (operands[0], 0),
4759 i * GET_MODE_SIZE (V2SFmode)));
4762 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4766 if (GET_CODE (operands[1]) == MEM)
4767 y = gen_rtx_MEM (V2SFmode,
4768 plus_constant (XEXP (operands[1], 0),
4769 i * GET_MODE_SIZE (V2SFmode)));
4772 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4776 emit_insn (gen_movv2sf_i (x, y));
4781 [(set_attr "length" "32")])
4783 (define_expand "movv16sf"
4784 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786 "TARGET_SHMEDIA_FPU"
4789 if (prepare_move_operands (operands, V16SFmode))
4793 (define_insn "movsf_media"
4794 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4795 (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,rU"))]
4797 && (register_operand (operands[0], SFmode)
4798 || sh_register_operand (operands[1], SFmode))"
4809 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4811 (define_insn "movsf_media_nofpu"
4812 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4813 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rU"))]
4815 && (register_operand (operands[0], SFmode)
4816 || sh_register_operand (operands[1], SFmode))"
4822 [(set_attr "type" "arith_media,*,load_media,store_media")])
4825 [(set (match_operand:SF 0 "arith_reg_operand" "")
4826 (match_operand:SF 1 "immediate_operand" ""))]
4827 "TARGET_SHMEDIA && reload_completed
4828 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4829 [(set (match_dup 3) (match_dup 2))]
4833 REAL_VALUE_TYPE value;
4835 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4836 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4837 operands[2] = GEN_INT (values);
4839 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4842 (define_insn "movsf_i"
4843 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4844 (match_operand:SF 1 "general_movsrc_operand" "r,I,FQ,mr,r,r,l"))]
4847 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4848 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4849 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4850 && (arith_reg_operand (operands[0], SFmode)
4851 || arith_reg_operand (operands[1], SFmode))"
4860 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4862 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4863 ;; update_flow_info would not know where to put REG_EQUAL notes
4864 ;; when the destination changes mode.
4865 (define_insn "movsf_ie"
4866 [(set (match_operand:SF 0 "general_movdst_operand"
4867 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4868 (match_operand:SF 1 "general_movsrc_operand"
4869 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4870 (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"))
4871 (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4874 && (arith_reg_operand (operands[0], SFmode)
4875 || arith_reg_operand (operands[1], SFmode)
4876 || arith_reg_operand (operands[3], SImode)
4877 || (fpul_operand (operands[0], SFmode)
4878 && memory_operand (operands[1], SFmode)
4879 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4880 || (fpul_operand (operands[1], SFmode)
4881 && memory_operand (operands[0], SFmode)
4882 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4902 ! move optimized away"
4903 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4904 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4905 (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4906 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4907 (const_string "single")
4908 (const_string "none")))])
4911 [(set (match_operand:SF 0 "register_operand" "")
4912 (match_operand:SF 1 "register_operand" ""))
4913 (use (match_operand:PSI 2 "fpscr_operand" ""))
4914 (clobber (reg:SI FPUL_REG))]
4916 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4918 (clobber (scratch:SI))])
4919 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4921 (clobber (scratch:SI))])]
4924 (define_expand "movsf"
4925 [(set (match_operand:SF 0 "general_movdst_operand" "")
4926 (match_operand:SF 1 "general_movsrc_operand" ""))]
4930 if (prepare_move_operands (operands, SFmode))
4934 if (TARGET_SHMEDIA_FPU)
4935 emit_insn (gen_movsf_media (operands[0], operands[1]));
4937 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4942 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4947 (define_insn "mov_nop"
4948 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4951 [(set_attr "length" "0")
4952 (set_attr "type" "nil")])
4954 (define_expand "reload_insf"
4955 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4956 (match_operand:SF 1 "immediate_operand" "FQ"))
4957 (use (reg:PSI FPSCR_REG))
4958 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4962 (define_expand "reload_insi"
4963 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4964 (match_operand:SF 1 "immediate_operand" "FQ"))
4965 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4969 (define_insn "*movsi_y"
4970 [(set (match_operand:SI 0 "register_operand" "=y,y")
4971 (match_operand:SI 1 "immediate_operand" "Qi,I"))
4972 (clobber (match_scratch:SI 2 "=&z,r"))]
4974 && (reload_in_progress || reload_completed)"
4976 [(set_attr "length" "4")
4977 (set_attr "type" "pcload,move")])
4980 [(set (match_operand:SI 0 "register_operand" "")
4981 (match_operand:SI 1 "immediate_operand" ""))
4982 (clobber (match_operand:SI 2 "register_operand" ""))]
4984 [(set (match_dup 2) (match_dup 1))
4985 (set (match_dup 0) (match_dup 2))]
4989 [(set (match_operand:SI 0 "register_operand" "")
4990 (match_operand:SI 1 "memory_operand" ""))
4991 (clobber (reg:SI R0_REG))]
4993 [(set (match_dup 0) (match_dup 1))]
4996 ;; ------------------------------------------------------------------------
4997 ;; Define the real conditional branch instructions.
4998 ;; ------------------------------------------------------------------------
5000 (define_insn "branch_true"
5001 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5002 (label_ref (match_operand 0 "" ""))
5005 "* return output_branch (1, insn, operands);"
5006 [(set_attr "type" "cbranch")])
5008 (define_insn "branch_false"
5009 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5010 (label_ref (match_operand 0 "" ""))
5013 "* return output_branch (0, insn, operands);"
5014 [(set_attr "type" "cbranch")])
5016 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5017 ;; which destination is too far away.
5018 ;; The const_int_operand is distinct for each branch target; it avoids
5019 ;; unwanted matches with redundant_insn.
5020 (define_insn "block_branch_redirect"
5021 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5024 [(set_attr "length" "0")])
5026 ;; This one has the additional purpose to record a possible scratch register
5027 ;; for the following branch.
5028 (define_insn "indirect_jump_scratch"
5029 [(set (match_operand:SI 0 "register_operand" "=r")
5030 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
5033 [(set_attr "length" "0")])
5035 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5036 ;; being pulled into the delay slot of a condbranch that has been made to
5037 ;; jump around the unconditional jump because it was out of range.
5038 (define_insn "stuff_delay_slot"
5040 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5041 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5044 [(set_attr "length" "0")
5045 (set_attr "cond_delay_slot" "yes")])
5047 ;; Conditional branch insns
5049 (define_expand "beq_media"
5051 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5052 (match_operand:DI 2 "arith_operand" "r,O"))
5053 (label_ref:DI (match_operand 0 "" ""))
5058 (define_insn "*beq_media_i"
5060 (if_then_else (match_operator 3 "equality_comparison_operator"
5061 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5062 (match_operand:DI 2 "arith_operand" "r,O")])
5063 (match_operand:DI 0 "target_operand" "b,b")
5069 [(set_attr "type" "cbranch_media")])
5071 (define_expand "bne_media"
5073 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5074 (match_operand:DI 2 "arith_operand" "r,O"))
5075 (label_ref:DI (match_operand 0 "" ""))
5080 (define_expand "bgt_media"
5082 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5083 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5084 (label_ref:DI (match_operand 0 "" ""))
5089 (define_expand "bge_media"
5091 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5092 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5093 (label_ref:DI (match_operand 0 "" ""))
5098 (define_expand "bgtu_media"
5100 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5101 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5102 (label_ref:DI (match_operand 0 "" ""))
5107 (define_expand "bgeu_media"
5109 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5110 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5111 (label_ref:DI (match_operand 0 "" ""))
5116 (define_insn "*bgt_media_i"
5118 (if_then_else (match_operator 3 "greater_comparison_operator"
5119 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5120 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5121 (match_operand:DI 0 "target_operand" "b")
5124 "b%o3%' %N1, %N2, %0"
5125 [(set_attr "type" "cbranch_media")])
5127 ;; These are only needed to make invert_jump() happy.
5128 (define_insn "*blt_media_i"
5130 (if_then_else (match_operator 3 "less_comparison_operator"
5131 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5132 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5133 (match_operand:DI 0 "target_operand" "b")
5136 "b%o3%' %N2, %N1, %0"
5137 [(set_attr "type" "cbranch_media")])
5139 (define_expand "beq"
5141 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5142 (label_ref (match_operand 0 "" ""))
5149 if (GET_MODE (sh_compare_op0) != DImode)
5151 rtx tmp = gen_reg_rtx (DImode);
5153 emit_insn (gen_seq (tmp));
5154 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5158 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5159 emit_jump_insn (gen_beq_media (operands[0],
5160 sh_compare_op0, sh_compare_op1));
5164 from_compare (operands, EQ);
5167 (define_expand "bne"
5169 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5170 (label_ref (match_operand 0 "" ""))
5177 if (GET_MODE (sh_compare_op0) != DImode)
5179 rtx tmp = gen_reg_rtx (DImode);
5181 emit_insn (gen_seq (tmp));
5182 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5186 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5187 emit_jump_insn (gen_bne_media (operands[0],
5188 sh_compare_op0, sh_compare_op1));
5192 from_compare (operands, EQ);
5195 (define_expand "bgt"
5197 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5198 (label_ref (match_operand 0 "" ""))
5205 if (GET_MODE (sh_compare_op0) != DImode)
5207 rtx tmp = gen_reg_rtx (DImode);
5209 emit_insn (gen_sgt (tmp));
5210 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5214 if (sh_compare_op0 != const0_rtx)
5215 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5216 if (sh_compare_op1 != const0_rtx)
5217 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5218 emit_jump_insn (gen_bgt_media (operands[0],
5219 sh_compare_op0, sh_compare_op1));
5223 from_compare (operands, GT);
5226 (define_expand "blt"
5228 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5229 (label_ref (match_operand 0 "" ""))
5236 if (GET_MODE (sh_compare_op0) != DImode)
5238 rtx tmp = gen_reg_rtx (DImode);
5240 emit_insn (gen_slt (tmp));
5241 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5245 if (sh_compare_op0 != const0_rtx)
5246 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5247 if (sh_compare_op1 != const0_rtx)
5248 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5249 emit_jump_insn (gen_bgt_media (operands[0],
5250 sh_compare_op1, sh_compare_op0));
5254 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5256 rtx tmp = sh_compare_op0;
5257 sh_compare_op0 = sh_compare_op1;
5258 sh_compare_op1 = tmp;
5259 emit_insn (gen_bgt (operands[0]));
5262 from_compare (operands, GE);
5265 (define_expand "ble"
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5275 if (GET_MODE (sh_compare_op0) != DImode)
5277 rtx tmp = gen_reg_rtx (DImode);
5279 emit_insn (gen_sle (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288 emit_jump_insn (gen_bge_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5295 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5297 rtx tmp = sh_compare_op0;
5298 sh_compare_op0 = sh_compare_op1;
5299 sh_compare_op1 = tmp;
5300 emit_insn (gen_bge (operands[0]));
5303 from_compare (operands, GT);
5306 (define_expand "bge"
5308 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5309 (label_ref (match_operand 0 "" ""))
5316 if (GET_MODE (sh_compare_op0) != DImode)
5318 rtx tmp = gen_reg_rtx (DImode);
5320 emit_insn (gen_sge (tmp));
5321 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5325 if (sh_compare_op0 != const0_rtx)
5326 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5327 if (sh_compare_op1 != const0_rtx)
5328 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5329 emit_jump_insn (gen_bge_media (operands[0],
5330 sh_compare_op0, sh_compare_op1));
5336 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5338 rtx tmp = sh_compare_op0;
5339 sh_compare_op0 = sh_compare_op1;
5340 sh_compare_op1 = tmp;
5341 emit_insn (gen_ble (operands[0]));
5344 from_compare (operands, GE);
5347 (define_expand "bgtu"
5349 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5350 (label_ref (match_operand 0 "" ""))
5357 if (sh_compare_op0 != const0_rtx)
5358 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5359 if (sh_compare_op1 != const0_rtx)
5360 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5361 emit_jump_insn (gen_bgtu_media (operands[0],
5362 sh_compare_op0, sh_compare_op1));
5366 from_compare (operands, GTU);
5369 (define_expand "bltu"
5371 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5372 (label_ref (match_operand 0 "" ""))
5379 if (sh_compare_op0 != const0_rtx)
5380 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5381 if (sh_compare_op1 != const0_rtx)
5382 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5383 emit_jump_insn (gen_bgtu_media (operands[0],
5384 sh_compare_op1, sh_compare_op0));
5388 from_compare (operands, GEU);
5391 (define_expand "bgeu"
5393 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5394 (label_ref (match_operand 0 "" ""))
5401 if (sh_compare_op0 != const0_rtx)
5402 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5403 if (sh_compare_op1 != const0_rtx)
5404 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5405 emit_jump_insn (gen_bgeu_media (operands[0],
5406 sh_compare_op0, sh_compare_op1));
5410 from_compare (operands, GEU);
5413 (define_expand "bleu"
5415 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5416 (label_ref (match_operand 0 "" ""))
5423 if (sh_compare_op0 != const0_rtx)
5424 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425 if (sh_compare_op1 != const0_rtx)
5426 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5427 emit_jump_insn (gen_bgeu_media (operands[0],
5428 sh_compare_op1, sh_compare_op0));
5432 from_compare (operands, GTU);
5435 (define_expand "bunordered"
5436 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5438 (if_then_else (ne (match_dup 1) (const_int 0))
5439 (label_ref:DI (match_operand 0 "" ""))
5444 operands[1] = gen_reg_rtx (DImode);
5445 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5446 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5449 ;; ------------------------------------------------------------------------
5450 ;; Jump and linkage insns
5451 ;; ------------------------------------------------------------------------
5453 (define_insn "jump_compact"
5455 (label_ref (match_operand 0 "" "")))]
5459 /* The length is 16 if the delay slot is unfilled. */
5460 if (get_attr_length(insn) > 4)
5461 return output_far_jump(insn, operands[0]);
5463 return \"bra %l0%#\";
5465 [(set_attr "type" "jump")
5466 (set_attr "needs_delay_slot" "yes")])
5468 (define_insn "jump_media"
5470 (match_operand:DI 0 "target_operand" "b"))]
5473 [(set_attr "type" "jump_media")])
5475 (define_expand "jump"
5477 (label_ref (match_operand 0 "" "")))]
5482 emit_jump_insn (gen_jump_compact (operands[0]));
5483 else if (TARGET_SHMEDIA)
5485 if (reload_in_progress || reload_completed)
5487 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5493 (define_insn "force_mode_for_call"
5494 [(use (reg:PSI FPSCR_REG))]
5497 [(set_attr "length" "0")
5498 (set (attr "fp_mode")
5499 (if_then_else (eq_attr "fpu_single" "yes")
5500 (const_string "single") (const_string "double")))])
5502 (define_insn "calli"
5503 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5504 (match_operand 1 "" ""))
5505 (use (reg:PSI FPSCR_REG))
5506 (clobber (reg:SI PR_REG))]
5509 [(set_attr "type" "call")
5510 (set (attr "fp_mode")
5511 (if_then_else (eq_attr "fpu_single" "yes")
5512 (const_string "single") (const_string "double")))
5513 (set_attr "needs_delay_slot" "yes")])
5515 ;; This is a pc-rel call, using bsrf, for use with PIC.
5517 (define_insn "calli_pcrel"
5518 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5519 (match_operand 1 "" ""))
5520 (use (reg:PSI FPSCR_REG))
5521 (use (reg:SI PIC_REG))
5522 (use (match_operand 2 "" ""))
5523 (clobber (reg:SI PR_REG))]
5526 [(set_attr "type" "call")
5527 (set (attr "fp_mode")
5528 (if_then_else (eq_attr "fpu_single" "yes")
5529 (const_string "single") (const_string "double")))
5530 (set_attr "needs_delay_slot" "yes")])
5532 (define_insn_and_split "call_pcrel"
5533 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5534 (match_operand 1 "" ""))
5535 (use (reg:PSI FPSCR_REG))
5536 (use (reg:SI PIC_REG))
5537 (clobber (reg:SI PR_REG))
5538 (clobber (match_scratch:SI 2 "=r"))]
5545 rtx lab = PATTERN (gen_call_site ());
5547 if (SYMBOL_REF_FLAG (operands[0]))
5548 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5550 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5551 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5554 [(set_attr "type" "call")
5555 (set (attr "fp_mode")
5556 (if_then_else (eq_attr "fpu_single" "yes")
5557 (const_string "single") (const_string "double")))
5558 (set_attr "needs_delay_slot" "yes")])
5560 (define_insn "call_compact"
5561 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5562 (match_operand 1 "" ""))
5563 (match_operand 2 "immediate_operand" "n")
5564 (use (reg:SI R0_REG))
5565 (use (reg:SI R1_REG))
5566 (use (reg:PSI FPSCR_REG))
5567 (clobber (reg:SI PR_REG))]
5568 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5570 [(set_attr "type" "call")
5571 (set (attr "fp_mode")
5572 (if_then_else (eq_attr "fpu_single" "yes")
5573 (const_string "single") (const_string "double")))
5574 (set_attr "needs_delay_slot" "yes")])
5576 (define_insn "call_compact_rettramp"
5577 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5578 (match_operand 1 "" ""))
5579 (match_operand 2 "immediate_operand" "n")
5580 (use (reg:SI R0_REG))
5581 (use (reg:SI R1_REG))
5582 (use (reg:PSI FPSCR_REG))
5583 (clobber (reg:SI R10_REG))
5584 (clobber (reg:SI PR_REG))]
5585 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5587 [(set_attr "type" "call")
5588 (set (attr "fp_mode")
5589 (if_then_else (eq_attr "fpu_single" "yes")
5590 (const_string "single") (const_string "double")))
5591 (set_attr "needs_delay_slot" "yes")])
5593 (define_insn "call_media"
5594 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5595 (match_operand 1 "" ""))
5596 (clobber (reg:DI PR_MEDIA_REG))]
5599 [(set_attr "type" "jump_media")])
5601 (define_insn "call_valuei"
5602 [(set (match_operand 0 "" "=rf")
5603 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5604 (match_operand 2 "" "")))
5605 (use (reg:PSI FPSCR_REG))
5606 (clobber (reg:SI PR_REG))]
5609 [(set_attr "type" "call")
5610 (set (attr "fp_mode")
5611 (if_then_else (eq_attr "fpu_single" "yes")
5612 (const_string "single") (const_string "double")))
5613 (set_attr "needs_delay_slot" "yes")])
5615 (define_insn "call_valuei_pcrel"
5616 [(set (match_operand 0 "" "=rf")
5617 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5618 (match_operand 2 "" "")))
5619 (use (reg:PSI FPSCR_REG))
5620 (use (reg:SI PIC_REG))
5621 (use (match_operand 3 "" ""))
5622 (clobber (reg:SI PR_REG))]
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5631 (define_insn_and_split "call_value_pcrel"
5632 [(set (match_operand 0 "" "=rf")
5633 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5634 (match_operand 2 "" "")))
5635 (use (reg:PSI FPSCR_REG))
5636 (use (reg:SI PIC_REG))
5637 (clobber (reg:SI PR_REG))
5638 (clobber (match_scratch:SI 3 "=r"))]
5645 rtx lab = PATTERN (gen_call_site ());
5647 if (SYMBOL_REF_FLAG (operands[1]))
5648 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5650 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5651 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5655 [(set_attr "type" "call")
5656 (set (attr "fp_mode")
5657 (if_then_else (eq_attr "fpu_single" "yes")
5658 (const_string "single") (const_string "double")))
5659 (set_attr "needs_delay_slot" "yes")])
5661 (define_insn "call_value_compact"
5662 [(set (match_operand 0 "" "=rf")
5663 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5664 (match_operand 2 "" "")))
5665 (match_operand 3 "immediate_operand" "n")
5666 (use (reg:SI R0_REG))
5667 (use (reg:SI R1_REG))
5668 (use (reg:PSI FPSCR_REG))
5669 (clobber (reg:SI PR_REG))]
5670 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5672 [(set_attr "type" "call")
5673 (set (attr "fp_mode")
5674 (if_then_else (eq_attr "fpu_single" "yes")
5675 (const_string "single") (const_string "double")))
5676 (set_attr "needs_delay_slot" "yes")])
5678 (define_insn "call_value_compact_rettramp"
5679 [(set (match_operand 0 "" "=rf")
5680 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5681 (match_operand 2 "" "")))
5682 (match_operand 3 "immediate_operand" "n")
5683 (use (reg:SI R0_REG))
5684 (use (reg:SI R1_REG))
5685 (use (reg:PSI FPSCR_REG))
5686 (clobber (reg:SI R10_REG))
5687 (clobber (reg:SI PR_REG))]
5688 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5690 [(set_attr "type" "call")
5691 (set (attr "fp_mode")
5692 (if_then_else (eq_attr "fpu_single" "yes")
5693 (const_string "single") (const_string "double")))
5694 (set_attr "needs_delay_slot" "yes")])
5696 (define_insn "call_value_media"
5697 [(set (match_operand 0 "" "=rf")
5698 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5699 (match_operand 2 "" "")))
5700 (clobber (reg:DI PR_MEDIA_REG))]
5703 [(set_attr "type" "jump_media")])
5705 (define_expand "call"
5706 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5707 (match_operand 1 "" ""))
5708 (match_operand 2 "" "")
5709 (use (reg:PSI FPSCR_REG))
5710 (clobber (reg:SI PR_REG))])]
5716 operands[0] = XEXP (operands[0], 0);
5717 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5719 if (! SYMBOL_REF_FLAG (operands[0]))
5721 rtx reg = gen_reg_rtx (Pmode);
5723 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5728 operands[0] = gen_sym2PIC (operands[0]);
5729 PUT_MODE (operands[0], Pmode);
5732 if (GET_MODE (operands[0]) == SImode)
5734 if (GET_CODE (operands[0]) == REG)
5735 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5736 else if (GET_CODE (operands[0]) == SUBREG)
5738 operands[0] = SUBREG_REG (operands[0]);
5739 if (GET_MODE (operands[0]) != DImode)
5740 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5744 operands[0] = shallow_copy_rtx (operands[0]);
5745 PUT_MODE (operands[0], DImode);
5748 if (! target_reg_operand (operands[0], DImode))
5749 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5750 emit_call_insn (gen_call_media (operands[0], operands[1]));
5753 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5755 rtx cookie_rtx = operands[2];
5756 long cookie = INTVAL (cookie_rtx);
5757 rtx func = XEXP (operands[0], 0);
5762 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5764 rtx reg = gen_reg_rtx (Pmode);
5766 emit_insn (gen_symGOTPLT2reg (reg, func));
5770 func = legitimize_pic_address (func, Pmode, 0);
5773 r0 = gen_rtx_REG (SImode, R0_REG);
5774 r1 = gen_rtx_REG (SImode, R1_REG);
5776 /* Since such a call function may use all call-clobbered
5777 registers, we force a mode switch earlier, so that we don't
5778 run out of registers when adjusting fpscr for the call. */
5779 emit_insn (gen_force_mode_for_call ());
5781 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5782 \"__GCC_shcompact_call_trampoline\");
5785 rtx reg = gen_reg_rtx (Pmode);
5787 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5790 operands[0] = force_reg (SImode, operands[0]);
5792 emit_move_insn (r0, func);
5793 emit_move_insn (r1, cookie_rtx);
5795 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5796 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5799 emit_call_insn (gen_call_compact (operands[0], operands[1],
5804 else if (TARGET_SHCOMPACT && flag_pic
5805 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5806 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5808 rtx reg = gen_reg_rtx (Pmode);
5810 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5811 XEXP (operands[0], 0) = reg;
5813 if (flag_pic && TARGET_SH2
5814 && GET_CODE (operands[0]) == MEM
5815 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5817 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5821 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5823 emit_call_insn (gen_calli (operands[0], operands[1]));
5827 (define_insn "call_pop_compact"
5828 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5829 (match_operand 1 "" ""))
5830 (match_operand 2 "immediate_operand" "n")
5831 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5832 (match_operand 3 "immediate_operand" "n")))
5833 (use (reg:SI R0_REG))
5834 (use (reg:SI R1_REG))
5835 (use (reg:PSI FPSCR_REG))
5836 (clobber (reg:SI PR_REG))]
5837 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5839 [(set_attr "type" "call")
5840 (set (attr "fp_mode")
5841 (if_then_else (eq_attr "fpu_single" "yes")
5842 (const_string "single") (const_string "double")))
5843 (set_attr "needs_delay_slot" "yes")])
5845 (define_insn "call_pop_compact_rettramp"
5846 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5847 (match_operand 1 "" ""))
5848 (match_operand 2 "immediate_operand" "n")
5849 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5850 (match_operand 3 "immediate_operand" "n")))
5851 (use (reg:SI R0_REG))
5852 (use (reg:SI R1_REG))
5853 (use (reg:PSI FPSCR_REG))
5854 (clobber (reg:SI R10_REG))
5855 (clobber (reg:SI PR_REG))]
5856 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5858 [(set_attr "type" "call")
5859 (set (attr "fp_mode")
5860 (if_then_else (eq_attr "fpu_single" "yes")
5861 (const_string "single") (const_string "double")))
5862 (set_attr "needs_delay_slot" "yes")])
5864 (define_expand "call_pop"
5865 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5866 (match_operand 1 "" ""))
5867 (match_operand 2 "" "")
5868 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5869 (match_operand 3 "" "")))])]
5873 if (operands[2] && INTVAL (operands[2]))
5875 rtx cookie_rtx = operands[2];
5876 long cookie = INTVAL (cookie_rtx);
5877 rtx func = XEXP (operands[0], 0);
5882 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5884 rtx reg = gen_reg_rtx (Pmode);
5886 emit_insn (gen_symGOTPLT2reg (reg, func));
5890 func = legitimize_pic_address (func, Pmode, 0);
5893 r0 = gen_rtx_REG (SImode, R0_REG);
5894 r1 = gen_rtx_REG (SImode, R1_REG);
5896 /* Since such a call function may use all call-clobbered
5897 registers, we force a mode switch earlier, so that we don't
5898 run out of registers when adjusting fpscr for the call. */
5899 emit_insn (gen_force_mode_for_call ());
5901 operands[0] = gen_rtx_SYMBOL_REF (SImode,
5902 \"__GCC_shcompact_call_trampoline\");
5905 rtx reg = gen_reg_rtx (Pmode);
5907 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5910 operands[0] = force_reg (SImode, operands[0]);
5912 emit_move_insn (r0, func);
5913 emit_move_insn (r1, cookie_rtx);
5915 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5916 emit_call_insn (gen_call_pop_compact_rettramp
5917 (operands[0], operands[1], operands[2], operands[3]));
5919 emit_call_insn (gen_call_pop_compact
5920 (operands[0], operands[1], operands[2], operands[3]));
5928 (define_expand "call_value"
5929 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5930 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5931 (match_operand 2 "" "")))
5932 (match_operand 3 "" "")
5933 (use (reg:PSI FPSCR_REG))
5934 (clobber (reg:SI PR_REG))])]
5940 operands[1] = XEXP (operands[1], 0);
5941 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5943 if (! SYMBOL_REF_FLAG (operands[1]))
5945 rtx reg = gen_reg_rtx (Pmode);
5947 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5952 operands[1] = gen_sym2PIC (operands[1]);
5953 PUT_MODE (operands[1], Pmode);
5956 if (GET_MODE (operands[1]) == SImode)
5958 if (GET_CODE (operands[1]) == REG)
5959 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5960 else if (GET_CODE (operands[1]) == SUBREG)
5962 operands[1] = SUBREG_REG (operands[1]);
5963 if (GET_MODE (operands[1]) != DImode)
5964 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5968 operands[1] = shallow_copy_rtx (operands[1]);
5969 PUT_MODE (operands[1], DImode);
5972 if (! target_reg_operand (operands[1], DImode))
5973 operands[1] = copy_to_mode_reg (DImode, operands[1]);
5974 emit_call_insn (gen_call_value_media (operands[0], operands[1],
5978 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5980 rtx cookie_rtx = operands[3];
5981 long cookie = INTVAL (cookie_rtx);
5982 rtx func = XEXP (operands[1], 0);
5987 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5989 rtx reg = gen_reg_rtx (Pmode);
5991 emit_insn (gen_symGOTPLT2reg (reg, func));
5995 func = legitimize_pic_address (func, Pmode, 0);
5998 r0 = gen_rtx_REG (SImode, R0_REG);
5999 r1 = gen_rtx_REG (SImode, R1_REG);
6001 /* Since such a call function may use all call-clobbered
6002 registers, we force a mode switch earlier, so that we don't
6003 run out of registers when adjusting fpscr for the call. */
6004 emit_insn (gen_force_mode_for_call ());
6006 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6007 \"__GCC_shcompact_call_trampoline\");
6010 rtx reg = gen_reg_rtx (Pmode);
6012 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6015 operands[1] = force_reg (SImode, operands[1]);
6017 emit_move_insn (r0, func);
6018 emit_move_insn (r1, cookie_rtx);
6020 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6021 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6026 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6027 operands[2], operands[3]));
6031 else if (TARGET_SHCOMPACT && flag_pic
6032 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6033 && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
6035 rtx reg = gen_reg_rtx (Pmode);
6037 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6038 XEXP (operands[1], 0) = reg;
6040 if (flag_pic && TARGET_SH2
6041 && GET_CODE (operands[1]) == MEM
6042 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6044 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6049 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6051 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6055 (define_insn "sibcalli"
6056 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6057 (match_operand 1 "" ""))
6058 (use (reg:PSI FPSCR_REG))
6062 [(set_attr "needs_delay_slot" "yes")
6063 (set (attr "fp_mode")
6064 (if_then_else (eq_attr "fpu_single" "yes")
6065 (const_string "single") (const_string "double")))
6066 (set_attr "type" "jump_ind")])
6068 (define_insn "sibcalli_pcrel"
6069 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6070 (match_operand 1 "" ""))
6071 (use (match_operand 2 "" ""))
6072 (use (reg:PSI FPSCR_REG))
6076 [(set_attr "needs_delay_slot" "yes")
6077 (set (attr "fp_mode")
6078 (if_then_else (eq_attr "fpu_single" "yes")
6079 (const_string "single") (const_string "double")))
6080 (set_attr "type" "jump_ind")])
6082 (define_insn_and_split "sibcall_pcrel"
6083 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6084 (match_operand 1 "" ""))
6085 (use (reg:PSI FPSCR_REG))
6086 (clobber (match_scratch:SI 2 "=k"))
6094 rtx lab = PATTERN (gen_call_site ());
6097 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6098 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6100 SIBLING_CALL_P (call_insn) = 1;
6103 [(set_attr "needs_delay_slot" "yes")
6104 (set (attr "fp_mode")
6105 (if_then_else (eq_attr "fpu_single" "yes")
6106 (const_string "single") (const_string "double")))
6107 (set_attr "type" "jump_ind")])
6109 (define_insn "sibcall_compact"
6110 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6111 (match_operand 1 "" ""))
6113 (use (match_operand:SI 2 "register_operand" "z,x"))
6114 (use (reg:SI R1_REG))
6115 (use (reg:PSI FPSCR_REG))
6116 ;; We want to make sure the `x' above will only match MACH_REG
6117 ;; because sibcall_epilogue may clobber MACL_REG.
6118 (clobber (reg:SI MACL_REG))]
6122 jmp @%0\\n sts %2, r0"
6123 [(set_attr "needs_delay_slot" "yes,no")
6124 (set_attr "length" "2,4")
6125 (set (attr "fp_mode") (const_string "single"))
6126 (set_attr "type" "jump_ind")])
6128 (define_insn "sibcall_media"
6129 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6130 (match_operand 1 "" ""))
6134 [(set_attr "type" "jump_media")])
6136 (define_expand "sibcall"
6138 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6139 (match_operand 1 "" ""))
6140 (match_operand 2 "" "")
6141 (use (reg:PSI FPSCR_REG))
6148 operands[0] = XEXP (operands[0], 0);
6149 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6151 if (! SYMBOL_REF_FLAG (operands[0]))
6153 rtx reg = gen_reg_rtx (Pmode);
6155 /* We must not use GOTPLT for sibcalls, because PIC_REG
6156 must be restored before the PLT code gets to run. */
6157 emit_insn (gen_symGOT2reg (reg, operands[0]));
6162 operands[0] = gen_sym2PIC (operands[0]);
6163 PUT_MODE (operands[0], Pmode);
6166 if (GET_MODE (operands[0]) == SImode)
6168 if (GET_CODE (operands[0]) == REG)
6169 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6170 else if (GET_CODE (operands[0]) == SUBREG)
6172 operands[0] = SUBREG_REG (operands[0]);
6173 if (GET_MODE (operands[0]) != DImode)
6174 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6178 operands[0] = shallow_copy_rtx (operands[0]);
6179 PUT_MODE (operands[0], DImode);
6182 if (! target_reg_operand (operands[0], DImode))
6183 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6184 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6187 else if (TARGET_SHCOMPACT && operands[2]
6188 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6190 rtx cookie_rtx = operands[2];
6191 long cookie = INTVAL (cookie_rtx);
6192 rtx func = XEXP (operands[0], 0);
6197 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6199 rtx reg = gen_reg_rtx (Pmode);
6201 emit_insn (gen_symGOT2reg (reg, func));
6205 func = legitimize_pic_address (func, Pmode, 0);
6208 /* FIXME: if we could tell whether all argument registers are
6209 already taken, we could decide whether to force the use of
6210 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6211 simple way to tell. We could use the CALL_COOKIE, but we
6212 can't currently tell a register used for regular argument
6213 passing from one that is unused. If we leave it up to reload
6214 to decide which register to use, it seems to always choose
6215 R0_REG, which leaves no available registers in SIBCALL_REGS
6216 to hold the address of the trampoline. */
6217 mach = gen_rtx_REG (SImode, MACH_REG);
6218 r1 = gen_rtx_REG (SImode, R1_REG);
6220 /* Since such a call function may use all call-clobbered
6221 registers, we force a mode switch earlier, so that we don't
6222 run out of registers when adjusting fpscr for the call. */
6223 emit_insn (gen_force_mode_for_call ());
6225 operands[0] = gen_rtx_SYMBOL_REF (SImode,
6226 \"__GCC_shcompact_call_trampoline\");
6229 rtx reg = gen_reg_rtx (Pmode);
6231 emit_insn (gen_symGOT2reg (reg, operands[0]));
6234 operands[0] = force_reg (SImode, operands[0]);
6236 /* We don't need a return trampoline, since the callee will
6237 return directly to the upper caller. */
6238 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6240 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6241 cookie_rtx = GEN_INT (cookie);
6244 emit_move_insn (mach, func);
6245 emit_move_insn (r1, cookie_rtx);
6247 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6250 else if (TARGET_SHCOMPACT && flag_pic
6251 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6252 && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6254 rtx reg = gen_reg_rtx (Pmode);
6256 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6257 XEXP (operands[0], 0) = reg;
6259 if (flag_pic && TARGET_SH2
6260 && GET_CODE (operands[0]) == MEM
6261 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6262 /* The PLT needs the PIC register, but the epilogue would have
6263 to restore it, so we can only use PC-relative PIC calls for
6264 static functions. */
6265 && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6267 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6271 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6273 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6277 (define_expand "sibcall_value"
6278 [(set (match_operand 0 "" "")
6279 (call (match_operand 1 "" "")
6280 (match_operand 2 "" "")))
6281 (match_operand 3 "" "")]
6285 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6289 (define_insn "call_value_pop_compact"
6290 [(set (match_operand 0 "" "=rf")
6291 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6292 (match_operand 2 "" "")))
6293 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6294 (match_operand 4 "immediate_operand" "n")))
6295 (match_operand 3 "immediate_operand" "n")
6296 (use (reg:SI R0_REG))
6297 (use (reg:SI R1_REG))
6298 (use (reg:PSI FPSCR_REG))
6299 (clobber (reg:SI PR_REG))]
6300 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6302 [(set_attr "type" "call")
6303 (set (attr "fp_mode")
6304 (if_then_else (eq_attr "fpu_single" "yes")
6305 (const_string "single") (const_string "double")))
6306 (set_attr "needs_delay_slot" "yes")])
6308 (define_insn "call_value_pop_compact_rettramp"
6309 [(set (match_operand 0 "" "=rf")
6310 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6311 (match_operand 2 "" "")))
6312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6313 (match_operand 4 "immediate_operand" "n")))
6314 (match_operand 3 "immediate_operand" "n")
6315 (use (reg:SI R0_REG))
6316 (use (reg:SI R1_REG))
6317 (use (reg:PSI FPSCR_REG))
6318 (clobber (reg:SI R10_REG))
6319 (clobber (reg:SI PR_REG))]
6320 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6322 [(set_attr "type" "call")
6323 (set (attr "fp_mode")
6324 (if_then_else (eq_attr "fpu_single" "yes")
6325 (const_string "single") (const_string "double")))
6326 (set_attr "needs_delay_slot" "yes")])
6328 (define_expand "call_value_pop"
6329 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6330 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6331 (match_operand 2 "" "")))
6332 (match_operand 3 "" "")
6333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6334 (match_operand 4 "" "")))])]
6338 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6340 rtx cookie_rtx = operands[3];
6341 long cookie = INTVAL (cookie_rtx);
6342 rtx func = XEXP (operands[1], 0);
6347 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6349 rtx reg = gen_reg_rtx (Pmode);
6351 emit_insn (gen_symGOTPLT2reg (reg, func));
6355 func = legitimize_pic_address (func, Pmode, 0);
6358 r0 = gen_rtx_REG (SImode, R0_REG);
6359 r1 = gen_rtx_REG (SImode, R1_REG);
6361 /* Since such a call function may use all call-clobbered
6362 registers, we force a mode switch earlier, so that we don't
6363 run out of registers when adjusting fpscr for the call. */
6364 emit_insn (gen_force_mode_for_call ());
6366 operands[1] = gen_rtx_SYMBOL_REF (SImode,
6367 \"__GCC_shcompact_call_trampoline\");
6370 rtx reg = gen_reg_rtx (Pmode);
6372 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6375 operands[1] = force_reg (SImode, operands[1]);
6377 emit_move_insn (r0, func);
6378 emit_move_insn (r1, cookie_rtx);
6380 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6381 emit_call_insn (gen_call_value_pop_compact_rettramp
6382 (operands[0], operands[1], operands[2],
6383 operands[3], operands[4]));
6385 emit_call_insn (gen_call_value_pop_compact
6386 (operands[0], operands[1], operands[2],
6387 operands[3], operands[4]));
6395 (define_expand "sibcall_epilogue"
6400 sh_expand_epilogue ();
6401 if (TARGET_SHCOMPACT)
6405 /* If epilogue clobbers r0, preserve it in macl. */
6406 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6407 if ((set = single_set (insn))
6408 && GET_CODE (SET_DEST (set)) == REG
6409 && REGNO (SET_DEST (set)) == R0_REG)
6411 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6412 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6415 /* We can't tell at this point whether the sibcall is a
6416 sibcall_compact and, if it is, whether it uses r0 or
6417 mach as operand 2, so let the instructions that
6418 preserve r0 be optimized away if r0 turns out to be
6420 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6421 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6423 i = emit_move_insn (r0, tmp);
6424 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6432 (define_insn "indirect_jump_compact"
6434 (match_operand:SI 0 "arith_reg_operand" "r"))]
6437 [(set_attr "needs_delay_slot" "yes")
6438 (set_attr "type" "jump_ind")])
6440 (define_expand "indirect_jump"
6442 (match_operand 0 "register_operand" ""))]
6446 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6450 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6451 ;; which can be present in structured code from indirect jumps which can not
6452 ;; be present in structured code. This allows -fprofile-arcs to work.
6454 ;; For SH1 processors.
6455 (define_insn "casesi_jump_1"
6457 (match_operand:SI 0 "register_operand" "r"))
6458 (use (label_ref (match_operand 1 "" "")))]
6461 [(set_attr "needs_delay_slot" "yes")
6462 (set_attr "type" "jump_ind")])
6464 ;; For all later processors.
6465 (define_insn "casesi_jump_2"
6466 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6467 (label_ref (match_operand 1 "" ""))))
6468 (use (label_ref (match_operand 2 "" "")))]
6470 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6472 [(set_attr "needs_delay_slot" "yes")
6473 (set_attr "type" "jump_ind")])
6475 (define_insn "casesi_jump_media"
6476 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6477 (use (label_ref (match_operand 1 "" "")))]
6480 [(set_attr "type" "jump_media")])
6482 ;; Call subroutine returning any type.
6483 ;; ??? This probably doesn't work.
6485 (define_expand "untyped_call"
6486 [(parallel [(call (match_operand 0 "" "")
6488 (match_operand 1 "" "")
6489 (match_operand 2 "" "")])]
6490 "TARGET_SH3E || TARGET_SHMEDIA"
6495 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6497 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6499 rtx set = XVECEXP (operands[2], 0, i);
6500 emit_move_insn (SET_DEST (set), SET_SRC (set));
6503 /* The optimizer does not know that the call sets the function value
6504 registers we stored in the result block. We avoid problems by
6505 claiming that all hard registers are used and clobbered at this
6507 emit_insn (gen_blockage ());
6512 ;; ------------------------------------------------------------------------
6514 ;; ------------------------------------------------------------------------
6517 [(set (reg:SI T_REG)
6518 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6519 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6522 [(set_attr "type" "arith")])
6529 ;; Load address of a label. This is only generated by the casesi expand,
6530 ;; and by machine_dependent_reorg (fixing up fp moves).
6531 ;; This must use unspec, because this only works for labels that are
6535 [(set (reg:SI R0_REG)
6536 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6539 [(set_attr "in_delay_slot" "no")
6540 (set_attr "type" "arith")])
6542 ;; machine_dependent_reorg() will make this a `mova'.
6543 (define_insn "mova_const"
6544 [(set (reg:SI R0_REG)
6545 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6548 [(set_attr "in_delay_slot" "no")
6549 (set_attr "type" "arith")])
6551 (define_expand "GOTaddr2picreg"
6552 [(set (reg:SI R0_REG)
6553 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6555 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6556 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6559 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6560 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6563 operands[1] = gen_datalabel_ref (operands[1]);
6567 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6568 rtx dipic = operands[0];
6569 rtx lab = PATTERN (gen_call_site ());
6572 equiv = operands[1];
6573 operands[1] = gen_rtx_MINUS (DImode,
6577 gen_rtx_MINUS (DImode,
6578 gen_rtx_CONST (DImode,
6581 operands[1] = gen_sym2PIC (operands[1]);
6582 PUT_MODE (operands[1], DImode);
6584 if (GET_MODE (dipic) != DImode)
6585 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6587 if (TARGET_SHMEDIA64)
6588 emit_insn (gen_movdi_const (dipic, operands[1]));
6590 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6592 emit_insn (gen_ptrel (tr, dipic, lab));
6594 if (GET_MODE (operands[0]) != GET_MODE (tr))
6595 tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6597 insn = emit_move_insn (operands[0], tr);
6599 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6607 ;; When generating PIC, we must match label_refs especially, because
6608 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6609 ;; them to do, because they can't be loaded directly into
6610 ;; non-branch-target registers.
6612 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6613 (match_operand:DI 1 "" "T"))]
6614 "TARGET_SHMEDIA && flag_pic
6615 && EXTRA_CONSTRAINT_T (operands[1])"
6617 [(set_attr "type" "pt_media")
6618 (set_attr "length" "*")])
6621 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6622 (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6623 UNSPEC_DATALABEL)))]
6624 "TARGET_SHMEDIA && flag_pic
6625 && EXTRA_CONSTRAINT_T (operands[1])"
6626 "ptb/u datalabel %1, %0"
6627 [(set_attr "type" "pt_media")
6628 (set_attr "length" "*")])
6630 (define_insn "ptrel"
6631 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6632 (plus:DI (match_operand:DI 1 "register_operand" "r")
6634 (match_operand:DI 2 "" "")]
6636 "%O2: ptrel/u %1, %0"
6637 [(set_attr "type" "ptabs_media")])
6639 (define_expand "builtin_setjmp_receiver"
6640 [(match_operand 0 "" "")]
6644 emit_insn (gen_GOTaddr2picreg ());
6648 (define_expand "call_site"
6649 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6653 static HOST_WIDE_INT i = 0;
6654 operands[0] = GEN_INT (i);
6658 (define_expand "sym_label2reg"
6659 [(set (match_operand:SI 0 "" "")
6662 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6665 (match_operand:SI 2 "" "")
6669 (define_expand "symGOT_load"
6670 [(set (match_dup 2) (match_operand 1 "" ""))
6671 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6672 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6678 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6679 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6683 rtx reg = operands[2];
6685 if (GET_MODE (reg) != DImode)
6686 reg = gen_rtx_SUBREG (DImode, reg, 0);
6689 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6691 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6694 emit_move_insn (operands[2], operands[1]);
6696 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6698 gen_rtx_REG (Pmode, PIC_REG)));
6700 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6702 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6709 (define_expand "sym2GOT"
6710 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6714 (define_expand "symGOT2reg"
6715 [(match_operand 0 "" "") (match_operand 1 "" "")]
6721 gotsym = gen_sym2GOT (operands[1]);
6722 PUT_MODE (gotsym, Pmode);
6723 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6725 RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6730 (define_expand "sym2GOTPLT"
6731 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6735 (define_expand "symGOTPLT2reg"
6736 [(match_operand 0 "" "") (match_operand 1 "" "")]
6740 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6744 (define_expand "sym2GOTOFF"
6745 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6749 (define_expand "symGOTOFF2reg"
6750 [(match_operand 0 "" "") (match_operand 1 "" "")]
6754 rtx gotoffsym, insn;
6755 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6757 gotoffsym = gen_sym2GOTOFF (operands[1]);
6758 PUT_MODE (gotoffsym, Pmode);
6759 emit_move_insn (t, gotoffsym);
6760 insn = emit_move_insn (operands[0],
6761 gen_rtx_PLUS (Pmode, t,
6762 gen_rtx_REG (Pmode, PIC_REG)));
6764 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6770 (define_expand "symPLT_label2reg"
6771 [(set (match_operand:SI 0 "" "")
6774 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6778 (match_operand:SI 2 "" "")
6780 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6781 ;; Even though the PIC register is not really used by the call
6782 ;; sequence in which this is expanded, the PLT code assumes the PIC
6783 ;; register is set, so we must not skip its initialization. Since
6784 ;; we only use this expand as part of calling sequences, and never
6785 ;; to take the address of a function, this is the best point to
6786 ;; insert the (use). Using the PLT to take the address of a
6787 ;; function would be wrong, not only because the PLT entry could
6788 ;; then be called from a function that doesn't initialize the PIC
6789 ;; register to the proper GOT, but also because pointers to the
6790 ;; same function might not compare equal, should they be set by
6791 ;; different shared libraries.
6792 (use (reg:SI PIC_REG))]
6796 (define_expand "sym2PIC"
6797 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6801 ;; case instruction for switch statements.
6803 ;; Operand 0 is index
6804 ;; operand 1 is the minimum bound
6805 ;; operand 2 is the maximum bound - minimum bound + 1
6806 ;; operand 3 is CODE_LABEL for the table;
6807 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6809 (define_expand "casesi"
6810 [(match_operand:SI 0 "arith_reg_operand" "")
6811 (match_operand:SI 1 "arith_reg_operand" "")
6812 (match_operand:SI 2 "arith_reg_operand" "")
6813 (match_operand 3 "" "") (match_operand 4 "" "")]
6817 rtx reg = gen_reg_rtx (SImode);
6818 rtx reg2 = gen_reg_rtx (SImode);
6821 rtx reg = gen_reg_rtx (DImode);
6822 rtx reg2 = gen_reg_rtx (DImode);
6823 rtx reg3 = gen_reg_rtx (DImode);
6824 rtx reg4 = gen_reg_rtx (DImode);
6825 rtx reg5 = gen_reg_rtx (DImode);
6827 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6828 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6829 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6831 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6832 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6833 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6834 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6835 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6836 (DImode, operands[3])));
6837 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6838 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6839 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6843 operands[1] = copy_to_mode_reg (SImode, operands[1]);
6844 operands[2] = copy_to_mode_reg (SImode, operands[2]);
6845 /* If optimizing, casesi_worker depends on the mode of the instruction
6846 before label it 'uses' - operands[3]. */
6847 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6849 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6851 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6853 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6854 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6855 operands[3], but to lab. We will fix this up in
6856 machine_dependent_reorg. */
6861 (define_expand "casesi_0"
6862 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6863 (set (match_dup 4) (minus:SI (match_dup 4)
6864 (match_operand:SI 1 "arith_operand" "")))
6866 (gtu:SI (match_dup 4)
6867 (match_operand:SI 2 "arith_reg_operand" "")))
6869 (if_then_else (ne (reg:SI T_REG)
6871 (label_ref (match_operand 3 "" ""))
6876 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6877 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6878 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6880 (define_insn "casesi_worker_0"
6881 [(set (match_operand:SI 0 "register_operand" "=r,r")
6882 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6883 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6884 (clobber (match_scratch:SI 3 "=X,1"))
6885 (clobber (match_scratch:SI 4 "=&z,z"))]
6890 [(set (match_operand:SI 0 "register_operand" "")
6891 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6892 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6893 (clobber (match_scratch:SI 3 ""))
6894 (clobber (match_scratch:SI 4 ""))]
6895 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6896 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6897 (parallel [(set (match_dup 0)
6898 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6899 (label_ref (match_dup 2))] UNSPEC_CASESI))
6900 (clobber (match_dup 3))])
6901 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6902 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6905 [(set (match_operand:SI 0 "register_operand" "")
6906 (unspec:SI [(match_operand:SI 1 "register_operand" "")
6907 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6908 (clobber (match_scratch:SI 3 ""))
6909 (clobber (match_scratch:SI 4 ""))]
6910 "TARGET_SH2 && reload_completed"
6911 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6912 (parallel [(set (match_dup 0)
6913 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6914 (label_ref (match_dup 2))] UNSPEC_CASESI))
6915 (clobber (match_dup 3))])]
6916 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6918 (define_insn "*casesi_worker"
6919 [(set (match_operand:SI 0 "register_operand" "=r,r")
6920 (unspec:SI [(reg:SI R0_REG)
6921 (match_operand:SI 1 "register_operand" "0,r")
6922 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6923 (clobber (match_scratch:SI 3 "=X,1"))]
6927 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6929 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6932 switch (GET_MODE (diff_vec))
6935 return \"shll2 %1\;mov.l @(r0,%1),%0\";
6937 return \"add %1,%1\;mov.w @(r0,%1),%0\";
6939 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6940 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
6941 return \"mov.b @(r0,%1),%0\";
6946 [(set_attr "length" "4")])
6948 (define_insn "casesi_shift_media"
6949 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6950 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6951 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6956 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6958 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6961 switch (GET_MODE (diff_vec))
6964 return \"shlli %1, 2, %0\";
6966 return \"shlli %1, 1, %0\";
6968 if (rtx_equal_p (operands[0], operands[1]))
6970 return \"add %1, r63, %0\";
6975 [(set_attr "type" "arith_media")])
6977 (define_insn "casesi_load_media"
6978 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6979 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6980 (match_operand 2 "arith_reg_operand" "r")
6981 (label_ref:DI (match_operand 3 "" ""))] 2)))]
6985 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6987 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6990 switch (GET_MODE (diff_vec))
6993 return \"ldx.l %1, %2, %0\";
6996 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6997 return \"ldx.uw %1, %2, %0\";
6999 return \"ldx.w %1, %2, %0\";
7001 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7002 return \"ldx.ub %1, %2, %0\";
7003 return \"ldx.b %1, %2, %0\";
7008 [(set_attr "type" "load_media")])
7010 (define_expand "return"
7012 "reload_completed && ! sh_need_epilogue ()"
7017 emit_jump_insn (gen_return_media ());
7021 if (TARGET_SHCOMPACT
7022 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7024 emit_jump_insn (gen_shcompact_return_tramp ());
7029 (define_insn "*return_i"
7031 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7032 && (current_function_args_info.call_cookie
7033 & CALL_COOKIE_RET_TRAMP (1)))
7034 && reload_completed"
7036 [(set_attr "type" "return")
7037 (set_attr "needs_delay_slot" "yes")])
7039 (define_expand "shcompact_return_tramp"
7042 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7045 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7046 rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7047 \"__GCC_shcompact_return_trampoline\");
7050 emit_insn (gen_symGOTPLT2reg (reg, sym));
7052 emit_move_insn (reg, sym);
7054 emit_jump_insn (gen_shcompact_return_tramp_i ());
7058 (define_insn "shcompact_return_tramp_i"
7059 [(parallel [(return) (use (reg:SI R0_REG))])]
7061 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7063 [(set_attr "type" "jump_ind")
7064 (set_attr "needs_delay_slot" "yes")])
7066 (define_insn "return_media_i"
7067 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7068 "TARGET_SHMEDIA && reload_completed"
7070 [(set_attr "type" "jump_media")])
7072 (define_expand "return_media"
7074 "TARGET_SHMEDIA && reload_completed"
7077 int tr_regno = sh_media_register_for_return ();
7082 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7085 tr = gen_rtx_REG (DImode, tr_regno);
7086 emit_move_insn (tr, r18);
7089 tr = gen_rtx_REG (DImode, tr_regno);
7091 emit_jump_insn (gen_return_media_i (tr));
7095 (define_insn "shcompact_preserve_incoming_args"
7096 [(set (match_operand:SI 0 "register_operand" "+r")
7097 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7100 [(set_attr "length" "0")])
7102 (define_insn "shcompact_incoming_args"
7103 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7104 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7105 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7106 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7107 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7108 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7109 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7110 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7111 (set (mem:BLK (reg:SI MACL_REG))
7112 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7113 (use (reg:SI R0_REG))
7114 (clobber (reg:SI R0_REG))
7115 (clobber (reg:SI MACL_REG))
7116 (clobber (reg:SI MACH_REG))
7117 (clobber (reg:SI PR_REG))]
7120 [(set_attr "needs_delay_slot" "yes")])
7122 (define_insn "shmedia_save_restore_regs_compact"
7123 [(set (reg:SI SP_REG)
7124 (plus:SI (reg:SI SP_REG)
7125 (match_operand:SI 0 "immediate_operand" "i")))
7126 (use (reg:SI R0_REG))
7127 (clobber (reg:SI PR_REG))]
7129 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7130 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7132 [(set_attr "needs_delay_slot" "yes")])
7134 (define_expand "prologue"
7137 "sh_expand_prologue (); DONE;")
7139 (define_expand "epilogue"
7144 sh_expand_epilogue ();
7145 emit_jump_insn (gen_return ());
7149 (define_expand "eh_return"
7150 [(use (match_operand 0 "register_operand" ""))
7151 (use (match_operand 1 "register_operand" ""))]
7154 rtx tmp, sa = operands[0], ra = operands[1];
7156 if (TARGET_SHMEDIA64)
7157 emit_insn (gen_eh_set_ra_di (ra));
7159 emit_insn (gen_eh_set_ra_si (ra));
7161 emit_move_insn (EH_RETURN_STACKADJ_RTX, sa);
7165 ;; Clobber the return address on the stack. We can't expand this
7166 ;; until we know where it will be put in the stack frame.
7168 (define_insn "eh_set_ra_si"
7169 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7170 (clobber (match_scratch:SI 1 "=&r"))]
7171 "! TARGET_SHMEDIA64"
7174 (define_insn "eh_set_ra_di"
7175 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7176 (clobber (match_scratch:DI 1 "=&r"))]
7181 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7182 (clobber (match_scratch 1 ""))]
7187 sh_set_return_address (operands[0], operands[1]);
7191 (define_insn "blockage"
7192 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7195 [(set_attr "length" "0")])
7197 ;; ------------------------------------------------------------------------
7199 ;; ------------------------------------------------------------------------
7202 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7203 (eq:SI (reg:SI T_REG) (const_int 1)))]
7206 [(set_attr "type" "arith")])
7208 (define_expand "seq"
7209 [(set (match_operand:SI 0 "arith_reg_operand" "")
7216 if (GET_MODE (operands[0]) != DImode)
7217 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7218 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7219 if (sh_compare_op1 != const0_rtx)
7220 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7221 ? GET_MODE (sh_compare_op0)
7222 : GET_MODE (sh_compare_op1),
7225 switch (GET_MODE (sh_compare_op0))
7228 emit_insn (gen_cmpeqdi_media (operands[0],
7229 sh_compare_op0, sh_compare_op1));
7233 if (! TARGET_SHMEDIA_FPU)
7235 emit_insn (gen_cmpeqsf_media (operands[0],
7236 sh_compare_op0, sh_compare_op1));
7240 if (! TARGET_SHMEDIA_FPU)
7242 emit_insn (gen_cmpeqdf_media (operands[0],
7243 sh_compare_op0, sh_compare_op1));
7251 operands[1] = prepare_scc_operands (EQ);
7254 (define_expand "slt"
7255 [(set (match_operand:SI 0 "arith_reg_operand" "")
7262 if (GET_MODE (operands[0]) != DImode)
7263 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7264 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7265 if (sh_compare_op1 != const0_rtx)
7266 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7267 ? GET_MODE (sh_compare_op0)
7268 : GET_MODE (sh_compare_op1),
7271 switch (GET_MODE (sh_compare_op0))
7274 emit_insn (gen_cmpgtdi_media (operands[0],
7275 sh_compare_op1, sh_compare_op0));
7279 if (! TARGET_SHMEDIA_FPU)
7281 emit_insn (gen_cmpgtsf_media (operands[0],
7282 sh_compare_op1, sh_compare_op0));
7286 if (! TARGET_SHMEDIA_FPU)
7288 emit_insn (gen_cmpgtdf_media (operands[0],
7289 sh_compare_op1, sh_compare_op0));
7297 operands[1] = prepare_scc_operands (LT);
7300 (define_expand "sle"
7301 [(match_operand:SI 0 "arith_reg_operand" "")]
7305 rtx tmp = sh_compare_op0;
7309 if (GET_MODE (operands[0]) != DImode)
7310 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7311 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7312 if (sh_compare_op1 != const0_rtx)
7313 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7314 ? GET_MODE (sh_compare_op0)
7315 : GET_MODE (sh_compare_op1),
7318 switch (GET_MODE (sh_compare_op0))
7322 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7324 emit_insn (gen_cmpgtdi_media (tmp,
7325 sh_compare_op0, sh_compare_op1));
7326 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7331 if (! TARGET_SHMEDIA_FPU)
7333 emit_insn (gen_cmpgesf_media (operands[0],
7334 sh_compare_op1, sh_compare_op0));
7338 if (! TARGET_SHMEDIA_FPU)
7340 emit_insn (gen_cmpgedf_media (operands[0],
7341 sh_compare_op1, sh_compare_op0));
7350 sh_compare_op0 = sh_compare_op1;
7351 sh_compare_op1 = tmp;
7352 emit_insn (gen_sge (operands[0]));
7356 (define_expand "sgt"
7357 [(set (match_operand:SI 0 "arith_reg_operand" "")
7364 if (GET_MODE (operands[0]) != DImode)
7365 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7366 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7367 if (sh_compare_op1 != const0_rtx)
7368 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7369 ? GET_MODE (sh_compare_op0)
7370 : GET_MODE (sh_compare_op1),
7373 switch (GET_MODE (sh_compare_op0))
7376 emit_insn (gen_cmpgtdi_media (operands[0],
7377 sh_compare_op0, sh_compare_op1));
7381 if (! TARGET_SHMEDIA_FPU)
7383 emit_insn (gen_cmpgtsf_media (operands[0],
7384 sh_compare_op0, sh_compare_op1));
7388 if (! TARGET_SHMEDIA_FPU)
7390 emit_insn (gen_cmpgtdf_media (operands[0],
7391 sh_compare_op0, sh_compare_op1));
7399 operands[1] = prepare_scc_operands (GT);
7402 (define_expand "sge"
7403 [(set (match_operand:SI 0 "arith_reg_operand" "")
7410 if (GET_MODE (operands[0]) != DImode)
7411 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7412 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7413 if (sh_compare_op1 != const0_rtx)
7414 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7415 ? GET_MODE (sh_compare_op0)
7416 : GET_MODE (sh_compare_op1),
7419 switch (GET_MODE (sh_compare_op0))
7423 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7425 emit_insn (gen_cmpgtdi_media (tmp,
7426 sh_compare_op1, sh_compare_op0));
7427 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7432 if (! TARGET_SHMEDIA_FPU)
7434 emit_insn (gen_cmpgesf_media (operands[0],
7435 sh_compare_op0, sh_compare_op1));
7439 if (! TARGET_SHMEDIA_FPU)
7441 emit_insn (gen_cmpgedf_media (operands[0],
7442 sh_compare_op0, sh_compare_op1));
7451 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7455 rtx lab = gen_label_rtx ();
7456 prepare_scc_operands (EQ);
7457 emit_jump_insn (gen_branch_true (lab));
7458 prepare_scc_operands (GT);
7460 emit_insn (gen_movt (operands[0]));
7463 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7466 operands[1] = prepare_scc_operands (GE);
7469 (define_expand "sgtu"
7470 [(set (match_operand:SI 0 "arith_reg_operand" "")
7477 if (GET_MODE (operands[0]) != DImode)
7478 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7479 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7480 if (sh_compare_op1 != const0_rtx)
7481 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7482 ? GET_MODE (sh_compare_op0)
7483 : GET_MODE (sh_compare_op1),
7486 emit_insn (gen_cmpgtudi_media (operands[0],
7487 sh_compare_op0, sh_compare_op1));
7490 operands[1] = prepare_scc_operands (GTU);
7493 (define_expand "sltu"
7494 [(set (match_operand:SI 0 "arith_reg_operand" "")
7501 if (GET_MODE (operands[0]) != DImode)
7502 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7503 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7504 if (sh_compare_op1 != const0_rtx)
7505 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7506 ? GET_MODE (sh_compare_op0)
7507 : GET_MODE (sh_compare_op1),
7510 emit_insn (gen_cmpgtudi_media (operands[0],
7511 sh_compare_op1, sh_compare_op0));
7514 operands[1] = prepare_scc_operands (LTU);
7517 (define_expand "sleu"
7518 [(set (match_operand:SI 0 "arith_reg_operand" "")
7527 if (GET_MODE (operands[0]) != DImode)
7528 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7529 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7530 if (sh_compare_op1 != const0_rtx)
7531 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7532 ? GET_MODE (sh_compare_op0)
7533 : GET_MODE (sh_compare_op1),
7536 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7538 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7539 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7543 operands[1] = prepare_scc_operands (LEU);
7546 (define_expand "sgeu"
7547 [(set (match_operand:SI 0 "arith_reg_operand" "")
7556 if (GET_MODE (operands[0]) != DImode)
7557 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7558 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7559 if (sh_compare_op1 != const0_rtx)
7560 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7561 ? GET_MODE (sh_compare_op0)
7562 : GET_MODE (sh_compare_op1),
7565 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7567 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7568 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7573 operands[1] = prepare_scc_operands (GEU);
7576 ;; sne moves the complement of the T reg to DEST like this:
7580 ;; This is better than xoring compare result with 1 because it does
7581 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7584 (define_expand "sne"
7585 [(set (match_dup 2) (const_int -1))
7586 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7587 (neg:SI (plus:SI (match_dup 1)
7590 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7599 if (GET_MODE (operands[0]) != DImode)
7600 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7602 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7605 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7606 if (sh_compare_op1 != const0_rtx)
7607 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7608 ? GET_MODE (sh_compare_op0)
7609 : GET_MODE (sh_compare_op1),
7612 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7614 emit_insn (gen_seq (tmp));
7615 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7620 operands[1] = prepare_scc_operands (EQ);
7621 operands[2] = gen_reg_rtx (SImode);
7624 (define_expand "sunordered"
7625 [(set (match_operand:DI 0 "arith_reg_operand" "")
7626 (unordered:DI (match_dup 1) (match_dup 2)))]
7627 "TARGET_SHMEDIA_FPU"
7630 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7631 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7634 ;; Use the same trick for FP sle / sge
7635 (define_expand "movnegt"
7636 [(set (match_dup 2) (const_int -1))
7637 (parallel [(set (match_operand 0 "" "")
7638 (neg:SI (plus:SI (match_dup 1)
7641 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7644 "operands[2] = gen_reg_rtx (SImode);")
7646 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7647 ;; This prevents a regression that occurred when we switched from xor to
7651 [(set (match_operand:SI 0 "arith_reg_operand" "")
7652 (plus:SI (reg:SI T_REG)
7655 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7656 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7659 ;; -------------------------------------------------------------------------
7660 ;; Instructions to cope with inline literal tables
7661 ;; -------------------------------------------------------------------------
7663 ; 2 byte integer in line
7665 (define_insn "consttable_2"
7666 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7667 (match_operand 1 "" "")]
7672 if (operands[1] != const0_rtx)
7673 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7676 [(set_attr "length" "2")
7677 (set_attr "in_delay_slot" "no")])
7679 ; 4 byte integer in line
7681 (define_insn "consttable_4"
7682 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7683 (match_operand 1 "" "")]
7688 if (operands[1] != const0_rtx)
7689 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7692 [(set_attr "length" "4")
7693 (set_attr "in_delay_slot" "no")])
7695 ; 8 byte integer in line
7697 (define_insn "consttable_8"
7698 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7699 (match_operand 1 "" "")]
7704 if (operands[1] != const0_rtx)
7705 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7708 [(set_attr "length" "8")
7709 (set_attr "in_delay_slot" "no")])
7711 ; 4 byte floating point
7713 (define_insn "consttable_sf"
7714 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7715 (match_operand 1 "" "")]
7720 if (operands[1] != const0_rtx)
7723 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7724 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7728 [(set_attr "length" "4")
7729 (set_attr "in_delay_slot" "no")])
7731 ; 8 byte floating point
7733 (define_insn "consttable_df"
7734 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7735 (match_operand 1 "" "")]
7740 if (operands[1] != const0_rtx)
7743 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7744 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7748 [(set_attr "length" "8")
7749 (set_attr "in_delay_slot" "no")])
7751 ;; Alignment is needed for some constant tables; it may also be added for
7752 ;; Instructions at the start of loops, or after unconditional branches.
7753 ;; ??? We would get more accurate lengths if we did instruction
7754 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7755 ;; here is too conservative.
7757 ; align to a two byte boundary
7759 (define_expand "align_2"
7760 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7764 ; align to a four byte boundary
7765 ;; align_4 and align_log are instructions for the starts of loops, or
7766 ;; after unconditional branches, which may take up extra room.
7768 (define_expand "align_4"
7769 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7773 ; align to a cache line boundary
7775 (define_insn "align_log"
7776 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7779 [(set_attr "length" "0")
7780 (set_attr "in_delay_slot" "no")])
7782 ; emitted at the end of the literal table, used to emit the
7783 ; 32bit branch labels if needed.
7785 (define_insn "consttable_end"
7786 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7788 "* return output_jump_label_table ();"
7789 [(set_attr "in_delay_slot" "no")])
7791 ; emitted at the end of the window in the literal table.
7793 (define_insn "consttable_window_end"
7794 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7797 [(set_attr "length" "0")
7798 (set_attr "in_delay_slot" "no")])
7800 ;; -------------------------------------------------------------------------
7802 ;; -------------------------------------------------------------------------
7804 ;; String/block move insn.
7806 (define_expand "movstrsi"
7807 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7808 (mem:BLK (match_operand:BLK 1 "" "")))
7809 (use (match_operand:SI 2 "nonmemory_operand" ""))
7810 (use (match_operand:SI 3 "immediate_operand" ""))
7811 (clobber (reg:SI PR_REG))
7812 (clobber (reg:SI R4_REG))
7813 (clobber (reg:SI R5_REG))
7814 (clobber (reg:SI R0_REG))])]
7815 "TARGET_SH1 && ! TARGET_SH5"
7818 if(expand_block_move (operands))
7823 (define_insn "block_move_real"
7824 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7825 (mem:BLK (reg:SI R5_REG)))
7826 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7827 (clobber (reg:SI PR_REG))
7828 (clobber (reg:SI R0_REG))])]
7829 "TARGET_SH1 && ! TARGET_HARD_SH4"
7831 [(set_attr "type" "sfunc")
7832 (set_attr "needs_delay_slot" "yes")])
7834 (define_insn "block_lump_real"
7835 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7836 (mem:BLK (reg:SI R5_REG)))
7837 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7838 (use (reg:SI R6_REG))
7839 (clobber (reg:SI PR_REG))
7840 (clobber (reg:SI T_REG))
7841 (clobber (reg:SI R4_REG))
7842 (clobber (reg:SI R5_REG))
7843 (clobber (reg:SI R6_REG))
7844 (clobber (reg:SI R0_REG))])]
7845 "TARGET_SH1 && ! TARGET_HARD_SH4"
7847 [(set_attr "type" "sfunc")
7848 (set_attr "needs_delay_slot" "yes")])
7850 (define_insn "block_move_real_i4"
7851 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7852 (mem:BLK (reg:SI R5_REG)))
7853 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7854 (clobber (reg:SI PR_REG))
7855 (clobber (reg:SI R0_REG))
7856 (clobber (reg:SI R1_REG))
7857 (clobber (reg:SI R2_REG))])]
7860 [(set_attr "type" "sfunc")
7861 (set_attr "needs_delay_slot" "yes")])
7863 (define_insn "block_lump_real_i4"
7864 [(parallel [(set (mem:BLK (reg:SI R4_REG))
7865 (mem:BLK (reg:SI R5_REG)))
7866 (use (match_operand:SI 0 "arith_reg_operand" "r"))
7867 (use (reg:SI R6_REG))
7868 (clobber (reg:SI PR_REG))
7869 (clobber (reg:SI T_REG))
7870 (clobber (reg:SI R4_REG))
7871 (clobber (reg:SI R5_REG))
7872 (clobber (reg:SI R6_REG))
7873 (clobber (reg:SI R0_REG))
7874 (clobber (reg:SI R1_REG))
7875 (clobber (reg:SI R2_REG))
7876 (clobber (reg:SI R3_REG))])]
7879 [(set_attr "type" "sfunc")
7880 (set_attr "needs_delay_slot" "yes")])
7882 ;; -------------------------------------------------------------------------
7883 ;; Floating point instructions.
7884 ;; -------------------------------------------------------------------------
7886 ;; ??? All patterns should have a type attribute.
7888 (define_expand "fpu_switch0"
7889 [(set (match_operand:SI 0 "" "") (match_dup 2))
7890 (set (match_dup 1) (mem:PSI (match_dup 0)))]
7894 operands[1] = get_fpscr_rtx ();
7895 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7897 operands[2] = legitimize_pic_address (operands[2], SImode,
7898 no_new_pseudos ? operands[0] : 0);
7901 (define_expand "fpu_switch1"
7902 [(set (match_operand:SI 0 "" "") (match_dup 2))
7903 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7904 (set (match_dup 1) (mem:PSI (match_dup 3)))]
7908 operands[1] = get_fpscr_rtx ();
7909 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7911 operands[2] = legitimize_pic_address (operands[2], SImode,
7912 no_new_pseudos ? operands[0] : 0);
7913 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7916 (define_expand "movpsi"
7917 [(set (match_operand:PSI 0 "register_operand" "")
7918 (match_operand:PSI 1 "general_movsrc_operand" ""))]
7922 ;; The c / m alternative is a fake to guide reload to load directly into
7923 ;; fpscr, since reload doesn't know how to use post-increment.
7924 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7925 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7926 ;; predicate after reload.
7927 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7928 ;; like a mac -> gpr move.
7929 (define_insn "fpu_switch"
7930 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
7931 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
7933 && (! reload_completed
7934 || true_regnum (operands[0]) != FPSCR_REG
7935 || GET_CODE (operands[1]) != MEM
7936 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7938 ! precision stays the same
7947 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
7948 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
7951 [(set (reg:PSI FPSCR_REG)
7952 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7953 "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7954 [(set (match_dup 0) (match_dup 0))]
7957 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7958 gen_rtx (MEM, PSImode,
7959 gen_rtx (POST_INC, Pmode,
7961 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7965 [(set (reg:PSI FPSCR_REG)
7966 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7968 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7971 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7972 gen_rtx (MEM, PSImode,
7973 gen_rtx (POST_INC, Pmode,
7975 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7978 ;; ??? This uses the fp unit, but has no type indicating that.
7979 ;; If we did that, this would either give a bogus latency or introduce
7980 ;; a bogus FIFO constraint.
7981 ;; Since this insn is currently only used for prologues/epilogues,
7982 ;; it is probably best to claim no function unit, which matches the
7984 (define_insn "toggle_sz"
7985 [(set (reg:PSI FPSCR_REG)
7986 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7990 (define_expand "addsf3"
7991 [(set (match_operand:SF 0 "arith_reg_operand" "")
7992 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7993 (match_operand:SF 2 "arith_reg_operand" "")))]
7994 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7999 expand_sf_binop (&gen_addsf3_i, operands);
8004 (define_insn "*addsf3_media"
8005 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8006 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8007 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8008 "TARGET_SHMEDIA_FPU"
8010 [(set_attr "type" "fparith_media")])
8012 (define_insn_and_split "unary_sf_op"
8013 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8018 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8019 (match_operator:SF 2 "unary_float_operator"
8020 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8021 (parallel [(match_operand 4
8022 "const_int_operand" "n")]))]))
8023 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8024 "TARGET_SHMEDIA_FPU"
8026 "TARGET_SHMEDIA_FPU && reload_completed"
8027 [(set (match_dup 5) (match_dup 6))]
8030 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8031 rtx op1 = gen_rtx_REG (SFmode,
8032 (true_regnum (operands[1])
8033 + (INTVAL (operands[4]) ^ endian)));
8035 operands[7] = gen_rtx_REG (SFmode,
8036 (true_regnum (operands[0])
8037 + (INTVAL (operands[3]) ^ endian)));
8038 operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8040 [(set_attr "type" "fparith_media")])
8042 (define_insn_and_split "binary_sf_op"
8043 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8048 (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
8049 (match_operator:SF 3 "binary_float_operator"
8050 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8051 (parallel [(match_operand 5
8052 "const_int_operand" "n")]))
8053 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8054 (parallel [(match_operand 6
8055 "const_int_operand" "n")]))]))
8056 (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
8057 "TARGET_SHMEDIA_FPU"
8059 "TARGET_SHMEDIA_FPU && reload_completed"
8060 [(set (match_dup 7) (match_dup 8))]
8063 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8064 rtx op1 = gen_rtx_REG (SFmode,
8065 (true_regnum (operands[1])
8066 + (INTVAL (operands[5]) ^ endian)));
8067 rtx op2 = gen_rtx_REG (SFmode,
8068 (true_regnum (operands[2])
8069 + (INTVAL (operands[6]) ^ endian)));
8071 operands[7] = gen_rtx_REG (SFmode,
8072 (true_regnum (operands[0])
8073 + (INTVAL (operands[4]) ^ endian)));
8074 operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8076 [(set_attr "type" "fparith_media")])
8078 (define_insn "addsf3_i"
8079 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8080 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8081 (match_operand:SF 2 "arith_reg_operand" "f")))
8082 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8085 [(set_attr "type" "fp")
8086 (set_attr "fp_mode" "single")])
8088 (define_expand "subsf3"
8089 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8090 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8091 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8092 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8097 expand_sf_binop (&gen_subsf3_i, operands);
8102 (define_insn "*subsf3_media"
8103 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8104 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8105 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8106 "TARGET_SHMEDIA_FPU"
8108 [(set_attr "type" "fparith_media")])
8110 (define_insn "subsf3_i"
8111 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8112 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8113 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8114 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8117 [(set_attr "type" "fp")
8118 (set_attr "fp_mode" "single")])
8120 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8121 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8122 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8123 ;; SH3E, we use a separate insn for SH3E mulsf3.
8125 (define_expand "mulsf3"
8126 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8127 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8128 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8129 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8133 expand_sf_binop (&gen_mulsf3_i4, operands);
8134 else if (TARGET_SH3E)
8135 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8136 if (! TARGET_SHMEDIA)
8140 (define_insn "*mulsf3_media"
8141 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8142 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8143 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8144 "TARGET_SHMEDIA_FPU"
8146 [(set_attr "type" "fparith_media")])
8148 (define_insn "mulsf3_i4"
8149 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8150 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8151 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8152 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8155 [(set_attr "type" "fp")
8156 (set_attr "fp_mode" "single")])
8158 (define_insn "mulsf3_ie"
8159 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8160 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8161 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8162 "TARGET_SH3E && ! TARGET_SH4"
8164 [(set_attr "type" "fp")])
8166 (define_insn "*mac_media"
8167 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8169 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8170 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8171 "TARGET_SHMEDIA_FPU"
8173 [(set_attr "type" "fparith_media")])
8175 (define_insn "*macsf3"
8176 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8178 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8179 (match_operand:SF 3 "arith_reg_operand" "0")))
8180 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8181 "TARGET_SH3E && ! TARGET_SH4"
8183 [(set_attr "type" "fp")
8184 (set_attr "fp_mode" "single")])
8186 (define_expand "divsf3"
8187 [(set (match_operand:SF 0 "arith_reg_operand" "")
8188 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8189 (match_operand:SF 2 "arith_reg_operand" "")))]
8190 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8195 expand_sf_binop (&gen_divsf3_i, operands);
8200 (define_insn "*divsf3_media"
8201 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8202 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8203 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8204 "TARGET_SHMEDIA_FPU"
8206 [(set_attr "type" "fdiv_media")])
8208 (define_insn "divsf3_i"
8209 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8210 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8211 (match_operand:SF 2 "arith_reg_operand" "f")))
8212 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8215 [(set_attr "type" "fdiv")
8216 (set_attr "fp_mode" "single")])
8218 (define_insn "floatdisf2"
8219 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8220 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8221 "TARGET_SHMEDIA_FPU"
8223 [(set_attr "type" "fpconv_media")])
8225 (define_expand "floatsisf2"
8226 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8227 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8228 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8233 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8238 (define_insn "*floatsisf2_media"
8239 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8240 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8241 "TARGET_SHMEDIA_FPU"
8243 [(set_attr "type" "fpconv_media")])
8245 (define_insn "floatsisf2_i4"
8246 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8247 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8248 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8251 [(set_attr "type" "fp")
8252 (set_attr "fp_mode" "single")])
8254 (define_insn "*floatsisf2_ie"
8255 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8256 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8257 "TARGET_SH3E && ! TARGET_SH4"
8259 [(set_attr "type" "fp")])
8261 (define_insn "fix_truncsfdi2"
8262 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8263 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8264 "TARGET_SHMEDIA_FPU"
8266 [(set_attr "type" "fpconv_media")])
8268 (define_expand "fix_truncsfsi2"
8269 [(set (match_operand:SI 0 "fpul_operand" "=y")
8270 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8271 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8276 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8281 (define_insn "*fix_truncsfsi2_media"
8282 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8283 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8284 "TARGET_SHMEDIA_FPU"
8286 [(set_attr "type" "fpconv_media")])
8288 (define_insn "fix_truncsfsi2_i4"
8289 [(set (match_operand:SI 0 "fpul_operand" "=y")
8290 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8291 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8294 [(set_attr "type" "ftrc_s")
8295 (set_attr "fp_mode" "single")])
8297 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8298 ;; fix_truncsfsi2_i4.
8299 ;; (define_insn "fix_truncsfsi2_i4_2"
8300 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8301 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8302 ;; (use (reg:PSI FPSCR_REG))
8303 ;; (clobber (reg:SI FPUL_REG))]
8306 ;; [(set_attr "length" "4")
8307 ;; (set_attr "fp_mode" "single")])
8310 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8311 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8312 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8313 ;; (clobber (reg:SI FPUL_REG))]
8315 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8316 ;; (use (match_dup 2))])
8317 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8319 (define_insn "*fixsfsi"
8320 [(set (match_operand:SI 0 "fpul_operand" "=y")
8321 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8322 "TARGET_SH3E && ! TARGET_SH4"
8324 [(set_attr "type" "fp")])
8326 (define_insn "cmpgtsf_t"
8327 [(set (reg:SI T_REG)
8328 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8329 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8330 "TARGET_SH3E && ! TARGET_SH4"
8332 [(set_attr "type" "fp")
8333 (set_attr "fp_mode" "single")])
8335 (define_insn "cmpeqsf_t"
8336 [(set (reg:SI T_REG)
8337 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8338 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8339 "TARGET_SH3E && ! TARGET_SH4"
8341 [(set_attr "type" "fp")
8342 (set_attr "fp_mode" "single")])
8344 (define_insn "ieee_ccmpeqsf_t"
8345 [(set (reg:SI T_REG)
8346 (ior:SI (reg:SI T_REG)
8347 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8348 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8349 "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8350 "* return output_ieee_ccmpeq (insn, operands);"
8351 [(set_attr "length" "4")])
8354 (define_insn "cmpgtsf_t_i4"
8355 [(set (reg:SI T_REG)
8356 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8357 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8358 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8361 [(set_attr "type" "fp")
8362 (set_attr "fp_mode" "single")])
8364 (define_insn "cmpeqsf_t_i4"
8365 [(set (reg:SI T_REG)
8366 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8367 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8368 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8371 [(set_attr "type" "fp")
8372 (set_attr "fp_mode" "single")])
8374 (define_insn "*ieee_ccmpeqsf_t_4"
8375 [(set (reg:SI T_REG)
8376 (ior:SI (reg:SI T_REG)
8377 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8378 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8379 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8380 "TARGET_IEEE && TARGET_SH4"
8381 "* return output_ieee_ccmpeq (insn, operands);"
8382 [(set_attr "length" "4")
8383 (set_attr "fp_mode" "single")])
8385 (define_insn "cmpeqsf_media"
8386 [(set (match_operand:DI 0 "register_operand" "=r")
8387 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8388 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8389 "TARGET_SHMEDIA_FPU"
8390 "fcmpeq.s %1, %2, %0"
8391 [(set_attr "type" "fcmp_media")])
8393 (define_insn "cmpgtsf_media"
8394 [(set (match_operand:DI 0 "register_operand" "=r")
8395 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8396 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8397 "TARGET_SHMEDIA_FPU"
8398 "fcmpgt.s %1, %2, %0"
8399 [(set_attr "type" "fcmp_media")])
8401 (define_insn "cmpgesf_media"
8402 [(set (match_operand:DI 0 "register_operand" "=r")
8403 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8404 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8405 "TARGET_SHMEDIA_FPU"
8406 "fcmpge.s %1, %2, %0"
8407 [(set_attr "type" "fcmp_media")])
8409 (define_insn "cmpunsf_media"
8410 [(set (match_operand:DI 0 "register_operand" "=r")
8411 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8412 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8413 "TARGET_SHMEDIA_FPU"
8414 "fcmpun.s %1, %2, %0"
8415 [(set_attr "type" "fcmp_media")])
8417 (define_expand "cmpsf"
8418 [(set (reg:SI T_REG)
8419 (compare (match_operand:SF 0 "arith_operand" "")
8420 (match_operand:SF 1 "arith_operand" "")))]
8421 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8424 sh_compare_op0 = operands[0];
8425 sh_compare_op1 = operands[1];
8429 (define_expand "negsf2"
8430 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8431 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8432 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8437 expand_sf_unop (&gen_negsf2_i, operands);
8442 (define_insn "*negsf2_media"
8443 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8445 "TARGET_SHMEDIA_FPU"
8447 [(set_attr "type" "fmove_media")])
8449 (define_insn "negsf2_i"
8450 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8451 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8452 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8455 [(set_attr "type" "fmove")
8456 (set_attr "fp_mode" "single")])
8458 (define_expand "sqrtsf2"
8459 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8460 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8461 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8466 expand_sf_unop (&gen_sqrtsf2_i, operands);
8471 (define_insn "*sqrtsf2_media"
8472 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8473 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8474 "TARGET_SHMEDIA_FPU"
8476 [(set_attr "type" "fdiv_media")])
8478 (define_insn "sqrtsf2_i"
8479 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8480 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8481 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8484 [(set_attr "type" "fdiv")
8485 (set_attr "fp_mode" "single")])
8487 (define_expand "abssf2"
8488 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8489 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8490 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8495 expand_sf_unop (&gen_abssf2_i, operands);
8500 (define_insn "*abssf2_media"
8501 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8502 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8503 "TARGET_SHMEDIA_FPU"
8505 [(set_attr "type" "fmove_media")])
8507 (define_insn "abssf2_i"
8508 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8509 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8510 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8513 [(set_attr "type" "fmove")
8514 (set_attr "fp_mode" "single")])
8516 (define_expand "adddf3"
8517 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8518 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8519 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8520 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8525 expand_df_binop (&gen_adddf3_i, operands);
8530 (define_insn "*adddf3_media"
8531 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8532 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8533 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8534 "TARGET_SHMEDIA_FPU"
8536 [(set_attr "type" "dfparith_media")])
8538 (define_insn "adddf3_i"
8539 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8540 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8541 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8542 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8545 [(set_attr "type" "dfp_arith")
8546 (set_attr "fp_mode" "double")])
8548 (define_expand "subdf3"
8549 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8550 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8551 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8552 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8557 expand_df_binop (&gen_subdf3_i, operands);
8562 (define_insn "*subdf3_media"
8563 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8564 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8565 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8566 "TARGET_SHMEDIA_FPU"
8568 [(set_attr "type" "dfparith_media")])
8570 (define_insn "subdf3_i"
8571 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8572 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8573 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8574 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8577 [(set_attr "type" "dfp_arith")
8578 (set_attr "fp_mode" "double")])
8580 (define_expand "muldf3"
8581 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8582 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8583 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8584 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8589 expand_df_binop (&gen_muldf3_i, operands);
8594 (define_insn "*muldf3_media"
8595 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8596 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8597 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8598 "TARGET_SHMEDIA_FPU"
8600 [(set_attr "type" "dfmul_media")])
8602 (define_insn "muldf3_i"
8603 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8604 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8605 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8606 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8609 [(set_attr "type" "dfp_arith")
8610 (set_attr "fp_mode" "double")])
8612 (define_expand "divdf3"
8613 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8614 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8615 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8616 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8621 expand_df_binop (&gen_divdf3_i, operands);
8626 (define_insn "*divdf3_media"
8627 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8628 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8629 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8630 "TARGET_SHMEDIA_FPU"
8632 [(set_attr "type" "dfdiv_media")])
8634 (define_insn "divdf3_i"
8635 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8636 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8637 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8638 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8641 [(set_attr "type" "dfdiv")
8642 (set_attr "fp_mode" "double")])
8644 (define_insn "floatdidf2"
8645 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8646 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8647 "TARGET_SHMEDIA_FPU"
8649 [(set_attr "type" "dfpconv_media")])
8651 (define_expand "floatsidf2"
8652 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8653 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8654 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8659 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8665 (define_insn "*floatsidf2_media"
8666 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8667 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8668 "TARGET_SHMEDIA_FPU"
8670 [(set_attr "type" "dfpconv_media")])
8672 (define_insn "floatsidf2_i"
8673 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8674 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8675 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8678 [(set_attr "type" "dfp_conv")
8679 (set_attr "fp_mode" "double")])
8681 (define_insn "fix_truncdfdi2"
8682 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8683 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8684 "TARGET_SHMEDIA_FPU"
8686 [(set_attr "type" "dfpconv_media")])
8688 (define_expand "fix_truncdfsi2"
8689 [(set (match_operand:SI 0 "fpul_operand" "")
8690 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8691 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8696 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8702 (define_insn "*fix_truncdfsi2_media"
8703 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8704 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8705 "TARGET_SHMEDIA_FPU"
8707 [(set_attr "type" "dfpconv_media")])
8709 (define_insn "fix_truncdfsi2_i"
8710 [(set (match_operand:SI 0 "fpul_operand" "=y")
8711 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8712 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8715 [(set_attr "type" "dfp_conv")
8716 (set_attr "dfp_comp" "no")
8717 (set_attr "fp_mode" "double")])
8719 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
8720 ;; fix_truncdfsi2_i.
8721 ;; (define_insn "fix_truncdfsi2_i4"
8722 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8723 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8724 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8725 ;; (clobber (reg:SI FPUL_REG))]
8728 ;; [(set_attr "length" "4")
8729 ;; (set_attr "fp_mode" "double")])
8732 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8733 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8734 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8735 ;; (clobber (reg:SI FPUL_REG))]
8737 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8738 ;; (use (match_dup 2))])
8739 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8741 (define_insn "cmpgtdf_t"
8742 [(set (reg:SI T_REG)
8743 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8744 (match_operand:DF 1 "arith_reg_operand" "f")))
8745 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8748 [(set_attr "type" "dfp_cmp")
8749 (set_attr "fp_mode" "double")])
8751 (define_insn "cmpeqdf_t"
8752 [(set (reg:SI T_REG)
8753 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8754 (match_operand:DF 1 "arith_reg_operand" "f")))
8755 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8758 [(set_attr "type" "dfp_cmp")
8759 (set_attr "fp_mode" "double")])
8761 (define_insn "*ieee_ccmpeqdf_t"
8762 [(set (reg:SI T_REG)
8763 (ior:SI (reg:SI T_REG)
8764 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8765 (match_operand:DF 1 "arith_reg_operand" "f"))))
8766 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8767 "TARGET_IEEE && TARGET_SH4"
8768 "* return output_ieee_ccmpeq (insn, operands);"
8769 [(set_attr "length" "4")
8770 (set_attr "fp_mode" "double")])
8772 (define_insn "cmpeqdf_media"
8773 [(set (match_operand:DI 0 "register_operand" "=r")
8774 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8775 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8776 "TARGET_SHMEDIA_FPU"
8778 [(set_attr "type" "fcmp_media")])
8780 (define_insn "cmpgtdf_media"
8781 [(set (match_operand:DI 0 "register_operand" "=r")
8782 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8783 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8784 "TARGET_SHMEDIA_FPU"
8786 [(set_attr "type" "fcmp_media")])
8788 (define_insn "cmpgedf_media"
8789 [(set (match_operand:DI 0 "register_operand" "=r")
8790 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8791 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8792 "TARGET_SHMEDIA_FPU"
8794 [(set_attr "type" "fcmp_media")])
8796 (define_insn "cmpundf_media"
8797 [(set (match_operand:DI 0 "register_operand" "=r")
8798 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8799 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8800 "TARGET_SHMEDIA_FPU"
8802 [(set_attr "type" "fcmp_media")])
8804 (define_expand "cmpdf"
8805 [(set (reg:SI T_REG)
8806 (compare (match_operand:DF 0 "arith_operand" "")
8807 (match_operand:DF 1 "arith_operand" "")))]
8808 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8811 sh_compare_op0 = operands[0];
8812 sh_compare_op1 = operands[1];
8816 (define_expand "negdf2"
8817 [(set (match_operand:DF 0 "arith_reg_operand" "")
8818 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8819 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8824 expand_df_unop (&gen_negdf2_i, operands);
8829 (define_insn "*negdf2_media"
8830 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8832 "TARGET_SHMEDIA_FPU"
8834 [(set_attr "type" "fmove_media")])
8836 (define_insn "negdf2_i"
8837 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8838 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8839 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8842 [(set_attr "type" "fmove")
8843 (set_attr "fp_mode" "double")])
8845 (define_expand "sqrtdf2"
8846 [(set (match_operand:DF 0 "arith_reg_operand" "")
8847 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8848 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8853 expand_df_unop (&gen_sqrtdf2_i, operands);
8858 (define_insn "*sqrtdf2_media"
8859 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8860 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8861 "TARGET_SHMEDIA_FPU"
8863 [(set_attr "type" "dfdiv_media")])
8865 (define_insn "sqrtdf2_i"
8866 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8867 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8868 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8871 [(set_attr "type" "dfdiv")
8872 (set_attr "fp_mode" "double")])
8874 (define_expand "absdf2"
8875 [(set (match_operand:DF 0 "arith_reg_operand" "")
8876 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8877 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8882 expand_df_unop (&gen_absdf2_i, operands);
8887 (define_insn "*absdf2_media"
8888 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8889 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8890 "TARGET_SHMEDIA_FPU"
8892 [(set_attr "type" "fmove_media")])
8894 (define_insn "absdf2_i"
8895 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8896 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8897 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8900 [(set_attr "type" "fmove")
8901 (set_attr "fp_mode" "double")])
8903 (define_expand "extendsfdf2"
8904 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8905 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8906 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8911 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8917 (define_insn "*extendsfdf2_media"
8918 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8919 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8920 "TARGET_SHMEDIA_FPU"
8922 [(set_attr "type" "dfpconv_media")])
8924 (define_insn "extendsfdf2_i4"
8925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8926 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8927 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8930 [(set_attr "type" "fp")
8931 (set_attr "fp_mode" "double")])
8933 (define_expand "truncdfsf2"
8934 [(set (match_operand:SF 0 "fpul_operand" "")
8935 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8936 "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8941 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8947 (define_insn "*truncdfsf2_media"
8948 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8949 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8950 "TARGET_SHMEDIA_FPU"
8952 [(set_attr "type" "dfpconv_media")])
8954 (define_insn "truncdfsf2_i4"
8955 [(set (match_operand:SF 0 "fpul_operand" "=y")
8956 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8957 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8960 [(set_attr "type" "fp")
8961 (set_attr "fp_mode" "double")])
8963 ;; Bit field extract patterns. These give better code for packed bitfields,
8964 ;; because they allow auto-increment addresses to be generated.
8966 (define_expand "insv"
8967 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8968 (match_operand:SI 1 "immediate_operand" "")
8969 (match_operand:SI 2 "immediate_operand" ""))
8970 (match_operand:SI 3 "general_operand" ""))]
8971 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8974 rtx addr_target, orig_address, shift_reg, qi_val;
8975 HOST_WIDE_INT bitsize, size, v;
8976 rtx x = operands[3];
8978 /* ??? expmed doesn't care for non-register predicates. */
8979 if (! memory_operand (operands[0], VOIDmode)
8980 || ! immediate_operand (operands[1], VOIDmode)
8981 || ! immediate_operand (operands[2], VOIDmode)
8982 || ! general_operand (x, VOIDmode))
8984 /* If this isn't a 16 / 24 / 32 bit field, or if
8985 it doesn't start on a byte boundary, then fail. */
8986 bitsize = INTVAL (operands[1]);
8987 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8988 || (INTVAL (operands[2]) % 8) != 0)
8992 orig_address = XEXP (operands[0], 0);
8993 shift_reg = gen_reg_rtx (SImode);
8994 if (GET_CODE (x) == CONST_INT)
8997 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9001 emit_insn (gen_movsi (shift_reg, operands[3]));
9002 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9004 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9006 operands[0] = replace_equiv_address (operands[0], addr_target);
9007 emit_insn (gen_movqi (operands[0], qi_val));
9011 if (GET_CODE (x) == CONST_INT)
9013 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9016 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9017 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9019 emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9020 emit_insn (gen_movqi (operands[0], qi_val));
9026 ;; -------------------------------------------------------------------------
9028 ;; -------------------------------------------------------------------------
9030 ;; This matches cases where a stack pointer increment at the start of the
9031 ;; epilogue combines with a stack slot read loading the return value.
9034 [(set (match_operand:SI 0 "arith_reg_operand" "")
9035 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9036 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9037 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9040 ;; See the comment on the dt combiner pattern above.
9043 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9044 (plus:SI (match_dup 0)
9047 (eq:SI (match_dup 0)
9052 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9053 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9054 ;; reload when the constant is too large for a reg+offset address.
9056 ;; ??? We would get much better code if this was done in reload. This would
9057 ;; require modifying find_reloads_address to recognize that if the constant
9058 ;; is out-of-range for an immediate add, then we get better code by reloading
9059 ;; the constant into a register than by reloading the sum into a register,
9060 ;; since the former is one instruction shorter if the address does not need
9061 ;; to be offsettable. Unfortunately this does not work, because there is
9062 ;; only one register, r0, that can be used as an index register. This register
9063 ;; is also the function return value register. So, if we try to force reload
9064 ;; to use double-reg addresses, then we end up with some instructions that
9065 ;; need to use r0 twice. The only way to fix this is to change the calling
9066 ;; convention so that r0 is not used to return values.
9069 [(set (match_operand:SI 0 "register_operand" "=r")
9070 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9071 (set (mem:SI (match_dup 0))
9072 (match_operand:SI 2 "general_movsrc_operand" ""))]
9073 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9074 "mov.l %2,@(%0,%1)")
9077 [(set (match_operand:SI 0 "register_operand" "=r")
9078 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9079 (set (match_operand:SI 2 "general_movdst_operand" "")
9080 (mem:SI (match_dup 0)))]
9081 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9082 "mov.l @(%0,%1),%2")
9085 [(set (match_operand:SI 0 "register_operand" "=r")
9086 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9087 (set (mem:HI (match_dup 0))
9088 (match_operand:HI 2 "general_movsrc_operand" ""))]
9089 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9090 "mov.w %2,@(%0,%1)")
9093 [(set (match_operand:SI 0 "register_operand" "=r")
9094 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9095 (set (match_operand:HI 2 "general_movdst_operand" "")
9096 (mem:HI (match_dup 0)))]
9097 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9098 "mov.w @(%0,%1),%2")
9101 [(set (match_operand:SI 0 "register_operand" "=r")
9102 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9103 (set (mem:QI (match_dup 0))
9104 (match_operand:QI 2 "general_movsrc_operand" ""))]
9105 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9106 "mov.b %2,@(%0,%1)")
9109 [(set (match_operand:SI 0 "register_operand" "=r")
9110 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9111 (set (match_operand:QI 2 "general_movdst_operand" "")
9112 (mem:QI (match_dup 0)))]
9113 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9114 "mov.b @(%0,%1),%2")
9117 [(set (match_operand:SI 0 "register_operand" "=r")
9118 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9119 (set (mem:SF (match_dup 0))
9120 (match_operand:SF 2 "general_movsrc_operand" ""))]
9121 "TARGET_SH1 && REGNO (operands[0]) == 0
9122 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9123 || (GET_CODE (operands[2]) == SUBREG
9124 && REGNO (SUBREG_REG (operands[2])) < 16))
9125 && reg_unused_after (operands[0], insn)"
9126 "mov.l %2,@(%0,%1)")
9129 [(set (match_operand:SI 0 "register_operand" "=r")
9130 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9131 (set (match_operand:SF 2 "general_movdst_operand" "")
9133 (mem:SF (match_dup 0)))]
9134 "TARGET_SH1 && REGNO (operands[0]) == 0
9135 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9136 || (GET_CODE (operands[2]) == SUBREG
9137 && REGNO (SUBREG_REG (operands[2])) < 16))
9138 && reg_unused_after (operands[0], insn)"
9139 "mov.l @(%0,%1),%2")
9142 [(set (match_operand:SI 0 "register_operand" "=r")
9143 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9144 (set (mem:SF (match_dup 0))
9145 (match_operand:SF 2 "general_movsrc_operand" ""))]
9146 "TARGET_SH3E && REGNO (operands[0]) == 0
9147 && ((GET_CODE (operands[2]) == REG
9148 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9149 || (GET_CODE (operands[2]) == SUBREG
9150 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9151 && reg_unused_after (operands[0], insn)"
9152 "fmov{.s|} %2,@(%0,%1)")
9155 [(set (match_operand:SI 0 "register_operand" "=r")
9156 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9157 (set (match_operand:SF 2 "general_movdst_operand" "")
9159 (mem:SF (match_dup 0)))]
9160 "TARGET_SH3E && REGNO (operands[0]) == 0
9161 && ((GET_CODE (operands[2]) == REG
9162 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9163 || (GET_CODE (operands[2]) == SUBREG
9164 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9165 && reg_unused_after (operands[0], insn)"
9166 "fmov{.s|} @(%0,%1),%2")
9168 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9169 (define_insn "sp_switch_1"
9176 xoperands[0] = sp_switch;
9177 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9178 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9179 return \"mov r0,r15\";
9181 [(set_attr "length" "10")])
9183 ;; Switch back to the original stack for interrupt functions with the
9184 ;; sp_switch attribute. */
9185 (define_insn "sp_switch_2"
9188 "mov.l @r15+,r15\;mov.l @r15+,r0"
9189 [(set_attr "length" "4")])
9191 ;; Integer vector moves
9193 (define_expand "movv8qi"
9194 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9195 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9197 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9199 (define_insn "movv8qi_i"
9200 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9201 (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9203 && (register_operand (operands[0], V8QImode)
9204 || sh_register_operand (operands[1], V8QImode))"
9211 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9212 (set_attr "length" "4,4,16,4,4")])
9215 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9216 (subreg:V8QI (const_int 0) 0))]
9219 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9220 (const_int 0) (const_int 0) (const_int 0)
9221 (const_int 0) (const_int 0)]))])
9224 [(set (match_operand 0 "arith_reg_dest" "")
9225 (match_operand 1 "sh_rep_vec" ""))]
9226 "TARGET_SHMEDIA && reload_completed
9227 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9228 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9229 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9230 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9231 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9232 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9233 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9234 [(set (match_dup 0) (match_dup 1))
9238 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9239 rtx elt1 = XVECEXP (operands[1], 0, 1);
9242 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9246 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9247 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9249 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9250 operands[1] = XVECEXP (operands[1], 0, 0);
9253 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9254 operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9255 ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9256 : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9259 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9261 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9267 [(set (match_operand 0 "arith_reg_dest" "")
9268 (match_operand 1 "sh_const_vec" ""))]
9269 "TARGET_SHMEDIA && reload_completed
9270 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9271 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9272 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9273 [(set (match_dup 0) (match_dup 1))]
9276 rtx v = operands[1];
9277 enum machine_mode new_mode
9278 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9280 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9282 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9285 (define_expand "movv2hi"
9286 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9287 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9289 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9291 (define_insn "movv2hi_i"
9292 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9293 (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9295 && (register_operand (operands[0], V2HImode)
9296 || sh_register_operand (operands[1], V2HImode))"
9303 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9304 (set_attr "length" "4,4,16,4,4")])
9306 (define_expand "movv4hi"
9307 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9308 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9310 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9312 (define_insn "movv4hi_i"
9313 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9314 (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9316 && (register_operand (operands[0], V4HImode)
9317 || sh_register_operand (operands[1], V4HImode))"
9324 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9325 (set_attr "length" "4,4,16,4,4")])
9327 (define_expand "movv2si"
9328 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9329 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9331 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9333 (define_insn "movv2si_i"
9334 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9335 (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rlU"))]
9337 && (register_operand (operands[0], V2SImode)
9338 || sh_register_operand (operands[1], V2SImode))"
9345 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9346 (set_attr "length" "4,4,16,4,4")])
9348 ;; Multimedia Intrinsics
9350 (define_insn "absv2si2"
9351 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9352 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9355 [(set_attr "type" "mcmp_media")])
9357 (define_insn "absv4hi2"
9358 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9359 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9362 [(set_attr "type" "mcmp_media")])
9364 (define_insn "addv2si3"
9365 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9366 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9367 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9370 [(set_attr "type" "arith_media")])
9372 (define_insn "addv4hi3"
9373 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9374 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9375 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9378 [(set_attr "type" "arith_media")])
9380 (define_insn "ssaddv2si3"
9381 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9382 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9383 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9385 "madds.l %1, %2, %0"
9386 [(set_attr "type" "mcmp_media")])
9388 (define_insn "usaddv8qi3"
9389 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9390 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9391 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9393 "madds.ub %1, %2, %0"
9394 [(set_attr "type" "mcmp_media")])
9396 (define_insn "ssaddv4hi3"
9397 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9398 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9399 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9401 "madds.w %1, %2, %0"
9402 [(set_attr "type" "mcmp_media")])
9404 (define_insn "negcmpeqv8qi"
9405 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9406 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9407 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9409 "mcmpeq.b %N1, %N2, %0"
9410 [(set_attr "type" "mcmp_media")])
9412 (define_insn "negcmpeqv2si"
9413 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9414 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9415 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9417 "mcmpeq.l %N1, %N2, %0"
9418 [(set_attr "type" "mcmp_media")])
9420 (define_insn "negcmpeqv4hi"
9421 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9422 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9423 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9425 "mcmpeq.w %N1, %N2, %0"
9426 [(set_attr "type" "mcmp_media")])
9428 (define_insn "negcmpgtuv8qi"
9429 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9430 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9431 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9433 "mcmpgt.ub %N1, %N2, %0"
9434 [(set_attr "type" "mcmp_media")])
9436 (define_insn "negcmpgtv2si"
9437 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9438 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9439 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9441 "mcmpgt.l %N1, %N2, %0"
9442 [(set_attr "type" "mcmp_media")])
9444 (define_insn "negcmpgtv4hi"
9445 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9446 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9447 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9449 "mcmpgt.w %N1, %N2, %0"
9450 [(set_attr "type" "mcmp_media")])
9453 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9454 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9455 (match_operand:DI 2 "arith_reg_operand" "r"))
9456 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9457 (not:DI (match_dup 2)))))]
9460 [(set_attr "type" "arith_media")])
9462 (define_insn "mcnvs_lw"
9463 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9465 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9466 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9468 "mcnvs.lw %N1, %N2, %0"
9469 [(set_attr "type" "mcmp_media")])
9471 (define_insn "mcnvs_wb"
9472 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9474 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9475 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9477 "mcnvs.wb %N1, %N2, %0"
9478 [(set_attr "type" "mcmp_media")])
9480 (define_insn "mcnvs_wub"
9481 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9483 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9484 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9486 "mcnvs.wub %N1, %N2, %0"
9487 [(set_attr "type" "mcmp_media")])
9489 (define_insn "mextr_rl"
9490 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9491 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9492 (match_operand:HI 3 "mextr_bit_offset" "i"))
9493 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9494 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9495 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9498 static char templ[16];
9500 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9501 (int) INTVAL (operands[3]) >> 3);
9504 [(set_attr "type" "arith_media")])
9506 (define_insn "*mextr_lr"
9507 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9508 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9509 (match_operand:HI 3 "mextr_bit_offset" "i"))
9510 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9511 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9512 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9515 static char templ[16];
9517 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9518 (int) INTVAL (operands[4]) >> 3);
9521 [(set_attr "type" "arith_media")])
9523 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9524 ; vector then varies depending on endianness.
9525 (define_expand "mextr1"
9526 [(match_operand:DI 0 "arith_reg_dest" "")
9527 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9528 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9532 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9533 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9537 (define_expand "mextr2"
9538 [(match_operand:DI 0 "arith_reg_dest" "")
9539 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9540 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9544 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9545 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9549 (define_expand "mextr3"
9550 [(match_operand:DI 0 "arith_reg_dest" "")
9551 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9552 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9556 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9557 GEN_INT (3 * 8), GEN_INT (5 * 8)));
9561 (define_expand "mextr4"
9562 [(match_operand:DI 0 "arith_reg_dest" "")
9563 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9564 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9568 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9569 GEN_INT (4 * 8), GEN_INT (4 * 8)));
9573 (define_expand "mextr5"
9574 [(match_operand:DI 0 "arith_reg_dest" "")
9575 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9576 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9580 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9581 GEN_INT (5 * 8), GEN_INT (3 * 8)));
9585 (define_expand "mextr6"
9586 [(match_operand:DI 0 "arith_reg_dest" "")
9587 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9588 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9592 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9593 GEN_INT (6 * 8), GEN_INT (2 * 8)));
9597 (define_expand "mextr7"
9598 [(match_operand:DI 0 "arith_reg_dest" "")
9599 (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9600 (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9604 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9605 GEN_INT (7 * 8), GEN_INT (1 * 8)));
9609 (define_expand "mmacfx_wl"
9610 [(match_operand:V2SI 0 "arith_reg_dest" "")
9611 (match_operand:V2HI 1 "extend_reg_operand" "")
9612 (match_operand:V2HI 2 "extend_reg_operand" "")
9613 (match_operand:V2SI 3 "arith_reg_operand" "")]
9617 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9618 operands[1], operands[2]));
9622 (define_insn "mmacfx_wl_i"
9623 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9625 (match_operand:V2SI 1 "arith_reg_operand" "0")
9630 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9631 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9634 "mmacfx.wl %2, %3, %0"
9635 [(set_attr "type" "mac_media")])
9637 (define_expand "mmacnfx_wl"
9638 [(match_operand:V2SI 0 "arith_reg_dest" "")
9639 (match_operand:V2HI 1 "extend_reg_operand" "")
9640 (match_operand:V2HI 2 "extend_reg_operand" "")
9641 (match_operand:V2SI 3 "arith_reg_operand" "")]
9645 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9646 operands[1], operands[2]));
9650 (define_insn "mmacnfx_wl_i"
9651 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9653 (match_operand:V2SI 1 "arith_reg_operand" "0")
9658 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9659 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9662 "mmacnfx.wl %2, %3, %0"
9663 [(set_attr "type" "mac_media")])
9665 (define_insn "mulv2si3"
9666 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9667 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9668 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9671 [(set_attr "type" "d2mpy_media")])
9673 (define_insn "mulv4hi3"
9674 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9675 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9676 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9679 [(set_attr "type" "dmpy_media")])
9681 (define_insn "mmulfx_l"
9682 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9686 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9687 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9690 "mmulfx.l %1, %2, %0"
9691 [(set_attr "type" "d2mpy_media")])
9693 (define_insn "mmulfx_w"
9694 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9698 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9699 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9702 "mmulfx.w %1, %2, %0"
9703 [(set_attr "type" "dmpy_media")])
9705 (define_insn "mmulfxrp_w"
9706 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9711 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9712 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9716 "mmulfxrp.w %1, %2, %0"
9717 [(set_attr "type" "dmpy_media")])
9719 (define_expand "mmulhi_wl"
9720 [(match_operand:V2SI 0 "arith_reg_dest" "")
9721 (match_operand:V4HI 1 "arith_reg_operand" "")
9722 (match_operand:V4HI 2 "arith_reg_operand" "")]
9726 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9727 (operands[0], operands[1], operands[2]));
9731 (define_expand "mmullo_wl"
9732 [(match_operand:V2SI 0 "arith_reg_dest" "")
9733 (match_operand:V4HI 1 "arith_reg_operand" "")
9734 (match_operand:V4HI 2 "arith_reg_operand" "")]
9738 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9739 (operands[0], operands[1], operands[2]));
9743 (define_insn "mmul23_wl"
9744 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9747 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9748 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9749 (parallel [(const_int 2) (const_int 3)])))]
9751 "* return (TARGET_LITTLE_ENDIAN
9752 ? \"mmulhi.wl %1, %2, %0\"
9753 : \"mmullo.wl %1, %2, %0\");"
9754 [(set_attr "type" "dmpy_media")])
9756 (define_insn "mmul01_wl"
9757 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9760 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9761 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9762 (parallel [(const_int 0) (const_int 1)])))]
9764 "* return (TARGET_LITTLE_ENDIAN
9765 ? \"mmullo.wl %1, %2, %0\"
9766 : \"mmulhi.wl %1, %2, %0\");"
9767 [(set_attr "type" "dmpy_media")])
9769 (define_expand "mmulsum_wq"
9770 [(match_operand:DI 0 "arith_reg_dest" "")
9771 (match_operand:V4HI 1 "arith_reg_operand" "")
9772 (match_operand:V4HI 2 "arith_reg_operand" "")
9773 (match_operand:DI 3 "arith_reg_operand" "")]
9777 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9778 operands[1], operands[2]));
9782 (define_insn "mmulsum_wq_i"
9783 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9784 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9789 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9790 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9791 (parallel [(const_int 0)]))
9792 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9793 (sign_extend:V4DI (match_dup 3)))
9794 (parallel [(const_int 1)])))
9796 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9797 (sign_extend:V4DI (match_dup 3)))
9798 (parallel [(const_int 2)]))
9799 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9800 (sign_extend:V4DI (match_dup 3)))
9801 (parallel [(const_int 3)]))))))]
9803 "mmulsum.wq %2, %3, %0"
9804 [(set_attr "type" "mac_media")])
9806 (define_expand "mperm_w"
9807 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9808 (match_operand:V4HI 1 "arith_reg_operand" "r")
9809 (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9813 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9814 (operands[0], operands[1], operands[2]));
9818 ; This use of vec_select isn't exactly correct according to rtl.texi
9819 ; (because not constant), but it seems a straightforward extension.
9820 (define_insn "mperm_w_little"
9821 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9823 (match_operand:V4HI 1 "arith_reg_operand" "r")
9825 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9826 (const_int 2) (const_int 0))
9827 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9828 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9829 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9830 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9831 "mperm.w %1, %N2, %0"
9832 [(set_attr "type" "arith_media")])
9834 (define_insn "mperm_w_big"
9835 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9837 (match_operand:V4HI 1 "arith_reg_operand" "r")
9839 [(zero_extract:QI (not:QI (match_operand:QI 2
9840 "extend_reg_or_0_operand" "rU"))
9841 (const_int 2) (const_int 0))
9842 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9843 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9844 (zero_extract:QI (not:QI (match_dup 2))
9845 (const_int 2) (const_int 6))])))]
9846 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9847 "mperm.w %1, %N2, %0"
9848 [(set_attr "type" "arith_media")])
9850 (define_insn "mperm_w0"
9851 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9852 (vec_duplicate:V4HI (truncate:HI (match_operand 1
9853 "trunc_hi_operand" "r"))))]
9855 "mperm.w %1, r63, %0"
9856 [(set_attr "type" "arith_media")])
9858 (define_expand "msad_ubq"
9859 [(match_operand:DI 0 "arith_reg_dest" "")
9860 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9861 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9862 (match_operand:DI 3 "arith_reg_operand" "")]
9866 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9867 operands[1], operands[2]));
9871 (define_insn "msad_ubq_i"
9872 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9877 (match_operand:DI 1 "arith_reg_operand" "0")
9878 (abs:DI (vec_select:DI
9881 (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9883 (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9884 (parallel [(const_int 0)]))))
9885 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9886 (zero_extend:V8DI (match_dup 3)))
9887 (parallel [(const_int 1)]))))
9889 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9890 (zero_extend:V8DI (match_dup 3)))
9891 (parallel [(const_int 2)])))
9892 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9893 (zero_extend:V8DI (match_dup 3)))
9894 (parallel [(const_int 3)])))))
9897 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9898 (zero_extend:V8DI (match_dup 3)))
9899 (parallel [(const_int 4)])))
9900 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9901 (zero_extend:V8DI (match_dup 3)))
9902 (parallel [(const_int 5)]))))
9904 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9905 (zero_extend:V8DI (match_dup 3)))
9906 (parallel [(const_int 6)])))
9907 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9908 (zero_extend:V8DI (match_dup 3)))
9909 (parallel [(const_int 7)])))))))]
9911 "msad.ubq %N2, %N3, %0"
9912 [(set_attr "type" "mac_media")])
9914 (define_insn "mshalds_l"
9915 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9918 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9919 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9922 "mshalds.l %1, %2, %0"
9923 [(set_attr "type" "mcmp_media")])
9925 (define_insn "mshalds_w"
9926 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9929 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9930 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9933 "mshalds.w %1, %2, %0"
9934 [(set_attr "type" "mcmp_media")])
9936 (define_insn "ashrv2si3"
9937 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9938 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9939 (match_operand:DI 2 "arith_reg_operand" "r")))]
9941 "mshard.l %1, %2, %0"
9942 [(set_attr "type" "arith_media")])
9944 (define_insn "ashrv4hi3"
9945 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9946 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9947 (match_operand:DI 2 "arith_reg_operand" "r")))]
9949 "mshard.w %1, %2, %0"
9950 [(set_attr "type" "arith_media")])
9952 (define_insn "mshards_q"
9953 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9955 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9956 (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9958 "mshards.q %1, %N2, %0"
9959 [(set_attr "type" "mcmp_media")])
9961 (define_expand "mshfhi_b"
9962 [(match_operand:V8QI 0 "arith_reg_dest" "")
9963 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9964 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9968 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9969 (operands[0], operands[1], operands[2]));
9973 (define_expand "mshflo_b"
9974 [(match_operand:V8QI 0 "arith_reg_dest" "")
9975 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9976 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9980 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9981 (operands[0], operands[1], operands[2]));
9985 (define_insn "mshf4_b"
9987 (match_operand:V8QI 0 "arith_reg_dest" "=r")
9989 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9990 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9991 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9992 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9994 "* return (TARGET_LITTLE_ENDIAN
9995 ? \"mshfhi.b %N1, %N2, %0\"
9996 : \"mshflo.b %N1, %N2, %0\");"
9997 [(set_attr "type" "arith_media")])
9999 (define_insn "mshf0_b"
10001 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10003 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
10004 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
10005 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10006 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10008 "* return (TARGET_LITTLE_ENDIAN
10009 ? \"mshflo.b %N1, %N2, %0\"
10010 : \"mshfhi.b %N1, %N2, %0\");"
10011 [(set_attr "type" "arith_media")])
10013 (define_expand "mshfhi_l"
10014 [(match_operand:V2SI 0 "arith_reg_dest" "")
10015 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10016 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10020 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10021 (operands[0], operands[1], operands[2]));
10025 (define_expand "mshflo_l"
10026 [(match_operand:V2SI 0 "arith_reg_dest" "")
10027 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10028 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
10032 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10033 (operands[0], operands[1], operands[2]));
10037 (define_insn "mshf4_l"
10038 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10040 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10041 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10042 (parallel [(const_int 1) (const_int 3)])))]
10044 "* return (TARGET_LITTLE_ENDIAN
10045 ? \"mshfhi.l %N1, %N2, %0\"
10046 : \"mshflo.l %N1, %N2, %0\");"
10047 [(set_attr "type" "arith_media")])
10049 (define_insn "mshf0_l"
10050 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10052 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10053 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
10054 (parallel [(const_int 0) (const_int 2)])))]
10056 "* return (TARGET_LITTLE_ENDIAN
10057 ? \"mshflo.l %N1, %N2, %0\"
10058 : \"mshfhi.l %N1, %N2, %0\");"
10059 [(set_attr "type" "arith_media")])
10061 (define_expand "mshfhi_w"
10062 [(match_operand:V4HI 0 "arith_reg_dest" "")
10063 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10064 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10068 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10069 (operands[0], operands[1], operands[2]));
10073 (define_expand "mshflo_w"
10074 [(match_operand:V4HI 0 "arith_reg_dest" "")
10075 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10076 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
10080 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10081 (operands[0], operands[1], operands[2]));
10085 (define_insn "mshf4_w"
10086 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10088 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10089 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10090 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10092 "* return (TARGET_LITTLE_ENDIAN
10093 ? \"mshfhi.w %N1, %N2, %0\"
10094 : \"mshflo.w %N1, %N2, %0\");"
10095 [(set_attr "type" "arith_media")])
10097 (define_insn "mshf0_w"
10098 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10100 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10101 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10102 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10104 "* return (TARGET_LITTLE_ENDIAN
10105 ? \"mshflo.w %N1, %N2, %0\"
10106 : \"mshfhi.w %N1, %N2, %0\");"
10107 [(set_attr "type" "arith_media")])
10109 (define_insn "mshflo_w_x"
10110 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10112 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10113 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10114 (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10116 "mshflo.w %N1, %N2, %0"
10117 [(set_attr "type" "arith_media")])
10119 /* These are useful to expand ANDs and as combiner patterns. */
10120 (define_insn_and_split "mshfhi_l_di"
10121 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10122 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10124 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10125 (const_int -4294967296))))]
10128 mshfhi.l %N1, %N2, %0
10130 "TARGET_SHMEDIA && reload_completed
10131 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10132 [(set (match_dup 3) (match_dup 4))
10133 (set (match_dup 5) (match_dup 6))]
10136 operands[3] = gen_lowpart (SImode, operands[0]);
10137 operands[4] = gen_highpart (SImode, operands[1]);
10138 operands[5] = gen_highpart (SImode, operands[0]);
10139 operands[6] = gen_highpart (SImode, operands[2]);
10141 [(set_attr "type" "arith_media")])
10143 (define_insn "*mshfhi_l_di_rev"
10144 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10145 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10146 (const_int -4294967296))
10147 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10150 "mshfhi.l %N2, %N1, %0"
10151 [(set_attr "type" "arith_media")])
10154 [(set (match_operand:DI 0 "arith_reg_dest" "")
10155 (ior:DI (zero_extend:DI (match_operand:SI 1
10156 "extend_reg_or_0_operand" ""))
10157 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10158 (const_int -4294967296))))
10159 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10164 emit_insn (gen_ashldi3_media (operands[3],
10165 simplify_gen_subreg (DImode, operands[1],
10168 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10172 (define_insn "mshflo_l_di"
10173 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10174 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10175 (const_int 4294967295))
10176 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10180 "mshflo.l %N1, %N2, %0"
10181 [(set_attr "type" "arith_media")])
10183 (define_insn "*mshflo_l_di_rev"
10184 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10185 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10187 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10188 (const_int 4294967295))))]
10191 "mshflo.l %N2, %N1, %0"
10192 [(set_attr "type" "arith_media")])
10194 ;; Combiner pattern for trampoline initialization.
10195 (define_insn_and_split "*double_shori"
10196 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10197 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10199 (match_operand:DI 2 "const_int_operand" "n")))]
10201 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10203 "rtx_equal_p (operands[0], operands[1])"
10207 HOST_WIDE_INT v = INTVAL (operands[2]);
10209 emit_insn (gen_shori_media (operands[0], operands[0],
10210 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10211 emit_insn (gen_shori_media (operands[0], operands[0],
10212 gen_int_mode (v, HImode)));
10217 (define_insn "*mshflo_l_di_x"
10218 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10219 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10221 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10225 "mshflo.l %N1, %N2, %0"
10226 [(set_attr "type" "arith_media")])
10228 (define_insn_and_split "concat_v2sf"
10229 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10230 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10231 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10232 (match_operand:SF 2 "register_operand" "rU,f,f")))]
10236 mshflo.l %N1, %N2, %0
10239 "TARGET_SHMEDIA && reload_completed
10240 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10241 [(set (match_dup 3) (match_dup 1))
10242 (set (match_dup 4) (match_dup 2))]
10245 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10246 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10248 [(set_attr "type" "arith_media")])
10250 (define_insn "*mshflo_l_di_x_rev"
10251 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10252 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10254 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10257 "mshflo.l %N2, %N1, %0"
10258 [(set_attr "type" "arith_media")])
10260 (define_insn "ashlv2si3"
10261 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10262 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10263 (match_operand:DI 2 "arith_reg_operand" "r")))]
10265 "mshlld.l %1, %2, %0"
10266 [(set_attr "type" "arith_media")])
10268 (define_insn "ashlv4hi3"
10269 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10270 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10271 (match_operand:DI 2 "arith_reg_operand" "r")))]
10273 "mshlld.w %1, %2, %0"
10274 [(set_attr "type" "arith_media")])
10276 (define_insn "lshrv2si3"
10277 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10278 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10279 (match_operand:DI 2 "arith_reg_operand" "r")))]
10281 "mshlrd.l %1, %2, %0"
10282 [(set_attr "type" "arith_media")])
10284 (define_insn "lshrv4hi3"
10285 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10286 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10287 (match_operand:DI 2 "arith_reg_operand" "r")))]
10289 "mshlrd.w %1, %2, %0"
10290 [(set_attr "type" "arith_media")])
10292 (define_insn "subv2si3"
10293 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10294 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10295 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10297 "msub.l %N1, %2, %0"
10298 [(set_attr "type" "arith_media")])
10300 (define_insn "subv4hi3"
10301 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10302 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10303 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10305 "msub.w %N1, %2, %0"
10306 [(set_attr "type" "arith_media")])
10308 (define_insn "sssubv2si3"
10309 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10310 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10311 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10313 "msubs.l %N1, %2, %0"
10314 [(set_attr "type" "mcmp_media")])
10316 (define_insn "ussubv8qi3"
10317 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10318 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10319 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10321 "msubs.ub %1, %2, %0"
10322 [(set_attr "type" "mcmp_media")])
10324 (define_insn "sssubv4hi3"
10325 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10326 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10327 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10329 "msubs.w %N1, %2, %0"
10330 [(set_attr "type" "mcmp_media")])
10332 ;; Floating Point Intrinsics
10334 (define_insn "fcosa_s"
10335 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10340 [(set_attr "type" "atrans_media")])
10342 (define_insn "fsina_s"
10343 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10344 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10348 [(set_attr "type" "atrans_media")])
10350 (define_insn "fipr"
10351 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10352 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10353 "fp_arith_reg_operand" "f")
10354 (match_operand:V4SF 2
10355 "fp_arith_reg_operand" "f"))
10356 (parallel [(const_int 0)]))
10357 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10358 (parallel [(const_int 1)])))
10359 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10360 (parallel [(const_int 2)]))
10361 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10362 (parallel [(const_int 3)])))))]
10365 [(set_attr "type" "fparith_media")])
10367 (define_insn "fsrra_s"
10368 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10369 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10373 [(set_attr "type" "atrans_media")])
10375 (define_insn "ftrv"
10376 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10380 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10381 (parallel [(const_int 0) (const_int 5)
10382 (const_int 10) (const_int 15)]))
10383 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10385 (vec_select:V4SF (match_dup 1)
10386 (parallel [(const_int 4) (const_int 9)
10387 (const_int 14) (const_int 3)]))
10388 (vec_select:V4SF (match_dup 2)
10389 (parallel [(const_int 1) (const_int 2)
10390 (const_int 3) (const_int 0)]))))
10393 (vec_select:V4SF (match_dup 1)
10394 (parallel [(const_int 8) (const_int 13)
10395 (const_int 2) (const_int 7)]))
10396 (vec_select:V4SF (match_dup 2)
10397 (parallel [(const_int 2) (const_int 3)
10398 (const_int 0) (const_int 1)])))
10400 (vec_select:V4SF (match_dup 1)
10401 (parallel [(const_int 12) (const_int 1)
10402 (const_int 6) (const_int 11)]))
10403 (vec_select:V4SF (match_dup 2)
10404 (parallel [(const_int 3) (const_int 0)
10405 (const_int 1) (const_int 2)]))))))]
10408 [(set_attr "type" "fparith_media")])
10411 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10412 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10416 [(set_attr "type" "arith_media")])
10418 (define_insn "nsbsi"
10419 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10421 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10425 [(set_attr "type" "arith_media")])
10427 (define_insn "nsbdi"
10428 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10430 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10434 [(set_attr "type" "arith_media")])
10436 (define_expand "ffsdi2"
10437 [(set (match_operand:DI 0 "arith_reg_dest" "")
10438 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10442 rtx scratch = gen_reg_rtx (DImode);
10445 emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10446 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10447 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10448 emit_insn (gen_nsbdi (scratch, scratch));
10449 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10450 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10451 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10453 = gen_rtx_EXPR_LIST (REG_EQUAL,
10454 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10458 (define_expand "ffssi2"
10459 [(set (match_operand:SI 0 "arith_reg_dest" "")
10460 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10464 rtx scratch = gen_reg_rtx (SImode);
10465 rtx discratch = gen_reg_rtx (DImode);
10468 emit_insn (gen_adddi3 (discratch,
10469 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10471 emit_insn (gen_andcdi3 (discratch,
10472 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10474 emit_insn (gen_nsbsi (scratch, discratch));
10475 last = emit_insn (gen_subsi3 (operands[0],
10476 force_reg (SImode, GEN_INT (63)), scratch));
10478 = gen_rtx_EXPR_LIST (REG_EQUAL,
10479 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10483 (define_insn "byterev"
10484 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10485 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10486 (parallel [(const_int 7) (const_int 6) (const_int 5)
10487 (const_int 4) (const_int 3) (const_int 2)
10488 (const_int 1) (const_int 0)])))]
10491 [(set_attr "type" "arith_media")])
10493 ;; The following description models the
10494 ;; SH4 pipeline using the DFA based scheduler.
10495 ;; The DFA based description is better way to model
10496 ;; a superscalar pipeline as compared to function unit
10497 ;; reservation model.
10498 ;; 1. The function unit based model is oriented to describe at most one
10499 ;; unit reservation by each insn. It is difficult to model unit reservations in multiple
10500 ;; pipeline units by same insn. This can be done using DFA based description.
10501 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10502 ;; 3. Writing all unit reservations for an instruction class is more natural description
10503 ;; of the pipeline and makes interface of the hazard recognizer simpler than the
10504 ;; old function unit based model.
10505 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10508 ;; Two automata are defined to reduce number of states
10509 ;; which a single large automaton will have.(Factoring)
10511 (define_automaton "inst_pipeline,fpu_pipe")
10513 ;; This unit is basically the decode unit of the processor.
10514 ;; Since SH4 is a dual issue machine,it is as if there are two
10515 ;; units so that any insn can be processed by either one
10516 ;; of the decoding unit.
10518 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10521 ;; The fixed point arithmetic calculator(?? EX Unit).
10523 (define_cpu_unit "int" "inst_pipeline")
10525 ;; f1_1 and f1_2 are floating point units.Actually there is
10526 ;; a f1 unit which can overlap with other f1 unit but
10527 ;; not another F1 unit.It is as though there were two
10530 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10532 ;; The floating point units (except FS - F2 always precedes it.)
10534 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10536 ;; This is basically the MA unit of SH4
10537 ;; used in LOAD/STORE pipeline.
10539 (define_cpu_unit "memory" "inst_pipeline")
10541 ;; However, there are LS group insns that don't use it, even ones that
10542 ;; complete in 0 cycles. So we use an extra unit for the issue of LS insns.
10543 (define_cpu_unit "load_store" "inst_pipeline")
10545 ;; The address calculator used for branch instructions.
10546 ;; This will be reserved after "issue" of branch instructions
10547 ;; and this is to make sure that no two branch instructions
10548 ;; can be issued in parallel.
10550 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10552 ;; ----------------------------------------------------
10553 ;; This reservation is to simplify the dual issue description.
10555 (define_reservation "issue" "pipe_01|pipe_02")
10557 ;; This is to express the locking of D stage.
10558 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10560 (define_reservation "d_lock" "pipe_01+pipe_02")
10562 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10563 (define_reservation "F01" "F0+F1")
10565 ;; This is to simplify description where F1,F2,FS
10566 ;; are used simultaneously.
10568 (define_reservation "fpu" "F1+F2")
10570 ;; This is to highlight the fact that f1
10571 ;; cannot overlap with F1.
10573 (exclusion_set "f1_1,f1_2" "F1")
10575 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10577 ;; Although reg moves have a latency of zero
10578 ;; we need to highlight that they use D stage
10583 (define_insn_reservation "reg_mov" 0
10584 (and (eq_attr "pipe_model" "sh4")
10585 (eq_attr "type" "move"))
10590 (define_insn_reservation "freg_mov" 0
10591 (and (eq_attr "pipe_model" "sh4")
10592 (eq_attr "type" "fmove"))
10593 "issue+load_store")
10595 ;; We don't model all pipeline stages; we model the issue ('D') stage
10596 ;; inasmuch as we allow only two instructions to issue simultanously,
10597 ;; and CO instructions prevent any simultanous issue of another instruction.
10598 ;; (This uses pipe_01 and pipe_02).
10599 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10600 ;; Double issue of EX / BR insns is prevented by using the int unit /
10601 ;; pcr_addrcalc unit in the EX stage.
10602 ;; Double issue of BR / LS instructions is prevented by using the
10603 ;; pcr_addrcalc / load_store unit in the issue cycle.
10604 ;; Double issue of FE instructions is prevented by using F0 in the first
10605 ;; pipeline stage after the first D stage.
10606 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10607 ;; (except in the cases outlined above), nor to describe the FS stage after
10610 ;; Other MT group intructions(1 step operations)
10615 (define_insn_reservation "mt" 1
10616 (and (eq_attr "pipe_model" "sh4")
10617 (eq_attr "type" "mt_group"))
10620 ;; Fixed Point Arithmetic Instructions(1 step operations)
10625 (define_insn_reservation "sh4_simple_arith" 1
10626 (and (eq_attr "pipe_model" "sh4")
10627 (eq_attr "insn_class" "ex_group"))
10630 ;; Load and store instructions have no alignment peculiarities for the SH4,
10631 ;; but they use the load-store unit, which they share with the fmove type
10632 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10633 ;; Loads have a latency of two.
10634 ;; However, call insns can only paired with a preceding insn, and have
10635 ;; a delay slot, so that we want two more insns to be scheduled between the
10636 ;; load of the function address and the call. This is equivalent to a
10637 ;; latency of three.
10638 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10639 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10640 ;; We only do this for SImode loads of general registers, to make the work
10641 ;; for ADJUST_COST easier.
10643 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10648 (define_insn_reservation "sh4_load" 2
10649 (and (eq_attr "pipe_model" "sh4")
10650 (eq_attr "type" "load,pcload"))
10651 "issue+load_store,nothing,memory")
10653 ;; calls / sfuncs need an extra instruction for their delay slot.
10654 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10655 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10656 ;; count of a dynamic shift.
10657 (define_insn_reservation "sh4_load_si" 3
10658 (and (eq_attr "pipe_model" "sh4")
10659 (eq_attr "type" "load_si,pcload_si"))
10660 "issue+load_store,nothing,memory")
10662 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10664 ;; The load latency is upped to three higher if the dependent insn does
10665 ;; double precision computation. We want the 'default' latency to reflect
10666 ;; that increased latency because otherwise the insn priorities won't
10667 ;; allow proper scheduling.
10668 (define_insn_reservation "sh4_fload" 3
10669 (and (eq_attr "pipe_model" "sh4")
10670 (eq_attr "type" "fload,pcfload"))
10671 "issue+load_store,nothing,memory")
10673 ;; (define_bypass 2 "sh4_fload" "!")
10675 (define_insn_reservation "sh4_store" 1
10676 (and (eq_attr "pipe_model" "sh4")
10677 (eq_attr "type" "store"))
10678 "issue+load_store,nothing,memory")
10680 ;; Load Store instructions.
10685 (define_insn_reservation "sh4_gp_fpul" 1
10686 (and (eq_attr "pipe_model" "sh4")
10687 (eq_attr "type" "gp_fpul"))
10688 "issue+load_store")
10690 ;; Load Store instructions.
10695 (define_insn_reservation "sh4_fpul_gp" 3
10696 (and (eq_attr "pipe_model" "sh4")
10697 (eq_attr "type" "fpul_gp"))
10698 "issue+load_store")
10700 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10702 ;; Latency when taken: 2 (or 1)
10704 ;; The latency is 1 when displacement is 0.
10705 ;; We can't really do much with the latency, even if we could express it,
10706 ;; but the pairing restrictions are useful to take into account.
10707 ;; ??? If the branch is likely, we might want to fill the delay slot;
10708 ;; if the branch is likely, but not very likely, should we pretend to use
10709 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10711 (define_insn_reservation "sh4_branch" 1
10712 (and (eq_attr "pipe_model" "sh4")
10713 (eq_attr "type" "cbranch,jump"))
10714 "issue+pcr_addrcalc")
10716 ;; Branch Far (JMP,RTS,BRAF)
10720 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10721 ;; can't be distinguished from bra for the "jump" pattern.
10723 (define_insn_reservation "sh4_return" 3
10724 (and (eq_attr "pipe_model" "sh4")
10725 (eq_attr "type" "return,jump_ind"))
10732 ;; this instruction can be executed in any of the pipelines
10733 ;; and blocks the pipeline for next 4 stages.
10735 (define_insn_reservation "sh4_return_from_exp" 5
10736 (and (eq_attr "pipe_model" "sh4")
10737 (eq_attr "type" "rte"))
10745 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10746 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10747 (define_insn_reservation "ocbwb" 6
10748 (and (eq_attr "pipe_model" "sh4")
10749 (eq_attr "type" "cwb"))
10750 "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10756 ;; The SX stage is blocked for last 2 cycles.
10757 ;; OTOH, the only time that has an effect for insns generated by the compiler
10758 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10759 ;; or when we are doing a function call - and we don't do inter-function
10760 ;; scheduling. For the function call case, it's really best that we end with
10761 ;; something that models an rts.
10763 (define_insn_reservation "sh4_lds_to_pr" 3
10764 (and (eq_attr "pipe_model" "sh4")
10765 (eq_attr "type" "prset") )
10768 ;; calls introduce a longisch delay that is likely to flush the pipelines
10769 ;; of the caller's instructions. Ordinary functions tend to end with a
10770 ;; load to restore a register (in the delay slot of rts), while sfuncs
10771 ;; tend to end with an EX or MT insn. But that is not actually relevant,
10772 ;; since there are no instructions that contend for memory access early.
10773 ;; We could, of course, provide exact scheduling information for specific
10774 ;; sfuncs, if that should prove useful.
10776 (define_insn_reservation "sh4_call" 16
10777 (and (eq_attr "pipe_model" "sh4")
10778 (eq_attr "type" "call,sfunc"))
10785 ;; The SX unit is blocked for last 2 cycles.
10787 (define_insn_reservation "ldsmem_to_pr" 3
10788 (and (eq_attr "pipe_model" "sh4")
10789 (eq_attr "type" "pload"))
10796 ;; The SX unit in second and third cycles.
10798 (define_insn_reservation "sts_from_pr" 2
10799 (and (eq_attr "pipe_model" "sh4")
10800 (eq_attr "type" "prget"))
10808 (define_insn_reservation "sh4_prstore_mem" 2
10809 (and (eq_attr "pipe_model" "sh4")
10810 (eq_attr "type" "pstore"))
10811 "d_lock*2,nothing,memory")
10817 ;; F1 is blocked for last three cycles.
10819 (define_insn_reservation "fpscr_load" 4
10820 (and (eq_attr "pipe_model" "sh4")
10821 (eq_attr "type" "gp_fpscr"))
10822 "d_lock,nothing,F1*3")
10827 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10829 ;; F1 is blocked for last three cycles.
10831 (define_insn_reservation "fpscr_load_mem" 4
10832 (and (eq_attr "pipe_model" "sh4")
10833 (eq_attr "type" "mem_fpscr"))
10834 "d_lock,nothing,(F1+memory),F1*2")
10837 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10842 (define_insn_reservation "multi" 4
10843 (and (eq_attr "pipe_model" "sh4")
10844 (eq_attr "type" "smpy,dmpy"))
10845 "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10847 ;; Fixed STS from MACL / MACH
10852 (define_insn_reservation "sh4_mac_gp" 3
10853 (and (eq_attr "pipe_model" "sh4")
10854 (eq_attr "type" "mac_gp"))
10858 ;; Single precision floating point computation FCMP/EQ,
10859 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10864 (define_insn_reservation "fp_arith" 3
10865 (and (eq_attr "pipe_model" "sh4")
10866 (eq_attr "type" "fp"))
10869 (define_insn_reservation "fp_arith_ftrc" 3
10870 (and (eq_attr "pipe_model" "sh4")
10871 (eq_attr "type" "ftrc_s"))
10874 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10876 ;; Single Precision FDIV/SQRT
10878 ;; Latency: 12/13 (FDIV); 11/12 (FSQRT)
10880 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10882 (define_insn_reservation "fp_div" 12
10883 (and (eq_attr "pipe_model" "sh4")
10884 (eq_attr "type" "fdiv"))
10885 "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10887 ;; Double Precision floating point computation
10888 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10890 ;; Latency: (3,4)/5
10893 (define_insn_reservation "dp_float" 4
10894 (and (eq_attr "pipe_model" "sh4")
10895 (eq_attr "type" "dfp_conv"))
10896 "issue,F01,F1+F2,F2")
10898 ;; Double-precision floating-point (FADD,FMUL,FSUB)
10900 ;; Latency: (7,8)/9
10903 (define_insn_reservation "fp_double_arith" 8
10904 (and (eq_attr "pipe_model" "sh4")
10905 (eq_attr "type" "dfp_arith"))
10906 "issue,F01,F1+F2,fpu*4,F2")
10908 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
10913 (define_insn_reservation "fp_double_cmp" 3
10914 (and (eq_attr "pipe_model" "sh4")
10915 (eq_attr "type" "dfp_cmp"))
10916 "d_lock,(d_lock+F01),F1+F2,F2")
10918 ;; Double precision FDIV/SQRT
10920 ;; Latency: (24,25)/26
10923 (define_insn_reservation "dp_div" 25
10924 (and (eq_attr "pipe_model" "sh4")
10925 (eq_attr "type" "dfdiv"))
10926 "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10929 ;; Use the branch-not-taken case to model arith3 insns. For the branch taken
10930 ;; case, we'd get a d_lock instead of issue at the end.
10931 (define_insn_reservation "arith3" 3
10932 (and (eq_attr "pipe_model" "sh4")
10933 (eq_attr "type" "arith3"))
10934 "issue,d_lock+pcr_addrcalc,issue")
10936 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10937 (define_insn_reservation "arith3b" 2
10938 (and (eq_attr "pipe_model" "sh4")
10939 (eq_attr "type" "arith3"))
10940 "issue,d_lock+pcr_addrcalc")