1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 GCC.
9 ;; GCC 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 ;; GCC 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 GCC; 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)
147 ;; These are used with unspec_volatile.
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
157 ;; -------------------------------------------------------------------------
159 ;; -------------------------------------------------------------------------
164 "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; tls_load load TLS related address
222 ;; arith_media SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media SHmedia compare instructions
225 ;; dfdiv_media SHmedia double precision divide and square root
226 ;; dfmul_media SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media SHmedia longword multiply
230 ;; fcmp_media SHmedia floating point compare instructions
231 ;; fdiv_media SHmedia single precision divide and square root
232 ;; fload_media SHmedia floating point register load instructions
233 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media SHmedia unconditional branch instructions
240 ;; load_media SHmedia general register load instructions
241 ;; pt_media SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media SHmedia ptabs instruction
243 ;; store_media SHmedia general register store instructions
244 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media SHmedia mac-style fixed point operations
246 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
247 ;; atrans SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil no-op move, will be deleted.
252 "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,tls_load,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"
253 (const_string "other"))
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
258 ;; mt_group SH4 "mt" group instructions.
260 ;; ex_group SH4 "ex" group instructions.
262 ;; ls_group SH4 "ls" group instructions.
265 (define_attr "insn_class"
266 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270 (eq_attr "type" "cbranch,jump") (const_string "br_group")
271 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272 (const_string "fe_group")
273 (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")]
274 (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
283 ;; Indicate if the fpu mode is set by this instruction
284 ;; "unknown" must have the value as "none" in fp_mode, and means
285 ;; that the instruction/abi has left the processor in an unknown
287 ;; "none" means that nothing has changed and no mode is set.
288 ;; This attribute is only used for the Renesas ABI.
289 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
291 ; If a conditional branch destination is within -252..258 bytes away
292 ; from the instruction it can be 2 bytes long. Something in the
293 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
294 ; branches are initially assumed to be 16 bytes long.
295 ; In machine_dependent_reorg, we split all branches that are longer than
298 ;; The maximum range used for SImode constant pool entries is 1018. A final
299 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
301 ;; instruction around the pool table, 2 bytes of alignment before the table,
302 ;; and 30 bytes of alignment after the table. That gives a maximum total
303 ;; pool size of 1058 bytes.
304 ;; Worst case code/pool content size ratio is 1:2 (using asms).
305 ;; Thus, in the worst case, there is one instruction in front of a maximum
306 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
308 ;; If we have a forward branch, the initial table will be put after the
309 ;; unconditional branch.
311 ;; ??? We could do much better by keeping track of the actual pcloads within
312 ;; the branch range and in the pcload range in front of the branch range.
314 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
316 (define_attr "short_cbranch_p" "no,yes"
317 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
319 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
321 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
323 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
325 ] (const_string "no")))
327 (define_attr "med_branch_p" "no,yes"
328 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
331 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
333 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
336 ] (const_string "no")))
338 (define_attr "med_cbranch_p" "no,yes"
339 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
342 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
347 ] (const_string "no")))
349 (define_attr "braf_branch_p" "no,yes"
350 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
352 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
355 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
357 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
360 ] (const_string "no")))
362 (define_attr "braf_cbranch_p" "no,yes"
363 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
365 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
368 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
370 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
373 ] (const_string "no")))
375 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
376 ; For wider ranges, we need a combination of a code and a data part.
377 ; If we can get a scratch register for a long range jump, the code
378 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
380 ; long; otherwise, it must be 6 bytes long.
382 ; All other instructions are two bytes long by default.
384 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385 ;; but getattrtab doesn't understand this.
386 (define_attr "length" ""
387 (cond [(eq_attr "type" "cbranch")
388 (cond [(eq_attr "short_cbranch_p" "yes")
390 (eq_attr "med_cbranch_p" "yes")
392 (eq_attr "braf_cbranch_p" "yes")
394 ;; ??? using pc is not computed transitively.
395 (ne (match_dup 0) (match_dup 0))
397 (ne (symbol_ref ("flag_pic")) (const_int 0))
400 (eq_attr "type" "jump")
401 (cond [(eq_attr "med_branch_p" "yes")
403 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
405 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
406 (symbol_ref "code_for_indirect_jump_scratch")))
407 (if_then_else (eq_attr "braf_branch_p" "yes")
410 (eq_attr "braf_branch_p" "yes")
412 ;; ??? using pc is not computed transitively.
413 (ne (match_dup 0) (match_dup 0))
415 (ne (symbol_ref ("flag_pic")) (const_int 0))
418 (eq_attr "type" "pt_media")
419 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420 (const_int 20) (const_int 12))
421 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425 ;; (define_function_unit {name} {num-units} {n-users} {test}
426 ;; {ready-delay} {issue-delay} [{conflict-list}])
428 ;; Load and store instructions save a cycle if they are aligned on a
429 ;; four byte boundary. Using a function unit for stores encourages
430 ;; gcc to separate load and store instructions by one instruction,
431 ;; which makes it more likely that the linker will be able to word
432 ;; align them when relaxing.
434 ;; Loads have a latency of two.
435 ;; However, call insns can have a delay slot, so that we want one more
436 ;; insn to be scheduled between the load of the function address and the call.
437 ;; This is equivalent to a latency of three.
438 ;; We cannot use a conflict list for this, because we need to distinguish
439 ;; between the actual call address and the function arguments.
440 ;; ADJUST_COST can only properly handle reductions of the cost, so we
441 ;; use a latency of three here.
442 ;; We only do this for SImode loads of general registers, to make the work
443 ;; for ADJUST_COST easier.
444 (define_function_unit "memory" 1 0
445 (and (eq_attr "pipe_model" "sh1")
446 (eq_attr "type" "load_si,pcload_si"))
448 (define_function_unit "memory" 1 0
449 (and (eq_attr "pipe_model" "sh1")
450 (eq_attr "type" "load,pcload,pload,store,pstore"))
453 (define_function_unit "int" 1 0
454 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
456 (define_function_unit "int" 1 0
457 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
459 (define_function_unit "int" 1 0
460 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
462 ;; ??? These are approximations.
463 (define_function_unit "mpy" 1 0
464 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
465 (define_function_unit "mpy" 1 0
466 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
468 (define_function_unit "fp" 1 0
469 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
470 (define_function_unit "fp" 1 0
471 (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
474 ;; SH-5 SHmedia scheduling
475 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
476 ;; single-issue machine. It has four pipelines, the branch unit (br),
477 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478 ;; the floating point unit (fpu).
479 ;; Here model the instructions with a latency greater than one cycle.
481 ;; Every instruction on SH-5 occupies the issue resource for at least one
483 (define_function_unit "sh5issue" 1 0
484 (and (eq_attr "pipe_model" "sh5media")
485 (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)
487 ;; Specify the various types of instruction which have latency > 1
488 (define_function_unit "sh5issue" 1 0
489 (and (eq_attr "pipe_model" "sh5media")
490 (eq_attr "type" "mcmp_media")) 2 1)
492 (define_function_unit "sh5issue" 1 0
493 (and (eq_attr "pipe_model" "sh5media")
494 (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495 ;; but see sh_adjust_cost for mac_media exception.
497 (define_function_unit "sh5issue" 1 0
498 (and (eq_attr "pipe_model" "sh5media")
499 (eq_attr "type" "fload_media,fmove_media")) 4 1)
501 (define_function_unit "sh5issue" 1 0
502 (and (eq_attr "pipe_model" "sh5media")
503 (eq_attr "type" "d2mpy_media")) 4 2)
505 (define_function_unit "sh5issue" 1 0
506 (and (eq_attr "pipe_model" "sh5media")
507 (eq_attr "type" "pt_media,ptabs_media")) 5 1)
509 (define_function_unit "sh5issue" 1 0
510 (and (eq_attr "pipe_model" "sh5media")
511 (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
513 (define_function_unit "sh5issue" 1 0
514 (and (eq_attr "pipe_model" "sh5media")
515 (eq_attr "type" "invalidate_line_media")) 7 7)
517 (define_function_unit "sh5issue" 1 0
518 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
520 (define_function_unit "sh5issue" 1 0
521 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
523 ;; Floating-point divide and square-root occupy an additional resource,
524 ;; which is not internally pipelined. However, other instructions
525 ;; can continue to issue.
526 (define_function_unit "sh5fds" 1 0
527 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media")) 19 19)
529 (define_function_unit "sh5fds" 1 0
530 (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
532 ; Definitions for filling branch delay slots.
534 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
536 ;; ??? This should be (nil) instead of (const_int 0)
537 (define_attr "hit_stack" "yes,no"
538 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
541 (const_string "yes")))
543 (define_attr "interrupt_function" "no,yes"
544 (const (symbol_ref "current_function_interrupt")))
546 (define_attr "in_delay_slot" "yes,no"
547 (cond [(eq_attr "type" "cbranch") (const_string "no")
548 (eq_attr "type" "pcload,pcload_si") (const_string "no")
549 (eq_attr "needs_delay_slot" "yes") (const_string "no")
550 (eq_attr "length" "2") (const_string "yes")
551 ] (const_string "no")))
553 (define_attr "cond_delay_slot" "yes,no"
554 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555 ] (const_string "no")))
557 (define_attr "is_sfunc" ""
558 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
560 (define_attr "is_mac_media" ""
561 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
563 (define_attr "branch_zero" "yes,no"
564 (cond [(eq_attr "type" "!cbranch") (const_string "no")
565 (ne (symbol_ref "(next_active_insn (insn)\
566 == (prev_active_insn\
567 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568 && get_attr_length (next_active_insn (insn)) == 2")
570 (const_string "yes")]
571 (const_string "no")))
573 ;; SH4 Double-precision computation with double-precision result -
574 ;; the two halves are ready at different times.
575 (define_attr "dfp_comp" "yes,no"
576 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577 (const_string "no")))
579 ;; Insns for which the latency of a preceding fp insn is decreased by one.
580 (define_attr "late_fp_use" "yes,no" (const_string "no"))
581 ;; And feeding insns for which this relevant.
582 (define_attr "any_fp_comp" "yes,no"
583 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584 (const_string "yes")]
585 (const_string "no")))
587 (define_attr "any_int_load" "yes,no"
588 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589 (const_string "yes")]
590 (const_string "no")))
593 (eq_attr "needs_delay_slot" "yes")
594 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
596 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597 ;; and thus we can't put a pop instruction in its delay slot.
598 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599 ;; instruction can go in the delay slot.
601 ;; Since a normal return (rts) implicitly uses the PR register,
602 ;; we can't allow PR register loads in an rts delay slot.
605 (eq_attr "type" "return")
606 [(and (eq_attr "in_delay_slot" "yes")
607 (ior (and (eq_attr "interrupt_function" "no")
608 (eq_attr "type" "!pload,prset"))
609 (and (eq_attr "interrupt_function" "yes")
611 (ne (symbol_ref "TARGET_SH3") (const_int 0))
612 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
614 ;; Since a call implicitly uses the PR register, we can't allow
615 ;; a PR register store in a jsr delay slot.
618 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619 [(and (eq_attr "in_delay_slot" "yes")
620 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
622 ;; Say that we have annulled true branches, since this gives smaller and
623 ;; faster code when branches are predicted as not taken.
626 (and (eq_attr "type" "cbranch")
627 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
628 ;; SH2e has a hardware bug that pretty much prohibits the use of
629 ;; annuled delay slots.
630 [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631 (not (eq_attr "cpu" "sh2e"))) (nil)])
633 ;; -------------------------------------------------------------------------
634 ;; SImode signed integer comparisons
635 ;; -------------------------------------------------------------------------
639 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
640 (match_operand:SI 1 "arith_operand" "K08,r"))
644 [(set_attr "type" "mt_group")])
646 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647 ;; That would still allow reload to create cmpi instructions, but would
648 ;; perhaps allow forcing the constant into a register when that is better.
649 ;; Probably should use r0 for mem/imm compares, but force constant into a
650 ;; register for pseudo/imm compares.
652 (define_insn "cmpeqsi_t"
654 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
655 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
661 [(set_attr "type" "mt_group")])
663 (define_insn "cmpgtsi_t"
665 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
671 [(set_attr "type" "mt_group")])
673 (define_insn "cmpgesi_t"
675 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
681 [(set_attr "type" "mt_group")])
683 ;; -------------------------------------------------------------------------
684 ;; SImode unsigned integer comparisons
685 ;; -------------------------------------------------------------------------
687 (define_insn "cmpgeusi_t"
689 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690 (match_operand:SI 1 "arith_reg_operand" "r")))]
693 [(set_attr "type" "mt_group")])
695 (define_insn "cmpgtusi_t"
697 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698 (match_operand:SI 1 "arith_reg_operand" "r")))]
701 [(set_attr "type" "mt_group")])
703 ;; We save the compare operands in the cmpxx patterns and use them when
704 ;; we generate the branch.
706 (define_expand "cmpsi"
708 (compare (match_operand:SI 0 "arith_operand" "")
709 (match_operand:SI 1 "arith_operand" "")))]
713 sh_compare_op0 = operands[0];
714 sh_compare_op1 = operands[1];
718 ;; -------------------------------------------------------------------------
719 ;; DImode signed integer comparisons
720 ;; -------------------------------------------------------------------------
722 ;; ??? Could get better scheduling by splitting the initial test from the
723 ;; rest of the insn after reload. However, the gain would hardly justify
724 ;; the sh.md size increase necessary to do that.
728 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
729 (match_operand:DI 1 "arith_operand" "r"))
732 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
734 [(set_attr "length" "6")
735 (set_attr "type" "arith3b")])
737 (define_insn "cmpeqdi_t"
739 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
740 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
743 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
744 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
745 [(set_attr "length" "6")
746 (set_attr "type" "arith3b")])
750 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
751 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
752 ;; If we applied this split when not optimizing, it would only be
753 ;; applied during the machine-dependent reorg, when no new basic blocks
755 "TARGET_SH1 && reload_completed && optimize"
756 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
757 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
758 (label_ref (match_dup 6))
760 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
765 = gen_rtx_REG (SImode,
766 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
768 = (operands[1] == const0_rtx
770 : gen_rtx_REG (SImode,
771 true_regnum (operands[1])
772 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
773 operands[4] = gen_lowpart (SImode, operands[0]);
774 operands[5] = gen_lowpart (SImode, operands[1]);
775 operands[6] = gen_label_rtx ();
778 (define_insn "cmpgtdi_t"
780 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
781 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
784 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
785 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
786 [(set_attr "length" "8")
787 (set_attr "type" "arith3")])
789 (define_insn "cmpgedi_t"
791 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
795 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
797 [(set_attr "length" "8,2")
798 (set_attr "type" "arith3,mt_group")])
800 ;; -------------------------------------------------------------------------
801 ;; DImode unsigned integer comparisons
802 ;; -------------------------------------------------------------------------
804 (define_insn "cmpgeudi_t"
806 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
807 (match_operand:DI 1 "arith_reg_operand" "r")))]
809 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
810 [(set_attr "length" "8")
811 (set_attr "type" "arith3")])
813 (define_insn "cmpgtudi_t"
815 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
816 (match_operand:DI 1 "arith_reg_operand" "r")))]
818 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
819 [(set_attr "length" "8")
820 (set_attr "type" "arith3")])
822 (define_insn "cmpeqdi_media"
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (eq:DI (match_operand:DI 1 "register_operand" "%r")
825 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
828 [(set_attr "type" "cmp_media")])
830 (define_insn "cmpgtdi_media"
831 [(set (match_operand:DI 0 "register_operand" "=r")
832 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
836 [(set_attr "type" "cmp_media")])
838 (define_insn "cmpgtudi_media"
839 [(set (match_operand:DI 0 "register_operand" "=r")
840 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
841 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843 "cmpgtu %N1, %N2, %0"
844 [(set_attr "type" "cmp_media")])
846 ;; We save the compare operands in the cmpxx patterns and use them when
847 ;; we generate the branch.
849 (define_expand "cmpdi"
851 (compare (match_operand:DI 0 "arith_operand" "")
852 (match_operand:DI 1 "arith_operand" "")))]
853 "TARGET_SH2 || TARGET_SHMEDIA"
856 sh_compare_op0 = operands[0];
857 sh_compare_op1 = operands[1];
860 ;; -------------------------------------------------------------------------
861 ;; Conditional move instructions
862 ;; -------------------------------------------------------------------------
864 ;; The insn names may seem reversed, but note that cmveq performs the move
865 ;; if op1 == 0, and cmvne does it if op1 != 0.
867 (define_insn "movdicc_false"
868 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
869 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
871 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
872 (match_operand:DI 3 "arith_reg_operand" "0")))]
875 [(set_attr "type" "arith_media")])
877 (define_insn "movdicc_true"
878 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
879 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
881 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
882 (match_operand:DI 3 "arith_reg_operand" "0")))]
885 [(set_attr "type" "arith_media")])
887 (define_expand "movdicc"
888 [(set (match_operand:DI 0 "register_operand" "")
889 (if_then_else:DI (match_operand 1 "comparison_operator" "")
890 (match_operand:DI 2 "register_operand" "")
891 (match_operand:DI 3 "register_operand" "")))]
895 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
896 && GET_MODE (sh_compare_op0) == DImode
897 && sh_compare_op1 == const0_rtx)
898 operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
899 sh_compare_op0, sh_compare_op1);
907 tmp = gen_reg_rtx (DImode);
909 switch (GET_CODE (operands[1]))
912 emit_insn (gen_seq (tmp));
913 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
917 emit_insn (gen_seq (tmp));
918 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
922 emit_insn (gen_sgt (tmp));
923 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
927 emit_insn (gen_slt (tmp));
928 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
932 emit_insn (gen_slt (tmp));
933 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
937 emit_insn (gen_sgt (tmp));
938 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
942 emit_insn (gen_sgtu (tmp));
943 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
947 emit_insn (gen_sltu (tmp));
948 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
952 emit_insn (gen_sltu (tmp));
953 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
957 emit_insn (gen_sgtu (tmp));
958 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
962 emit_insn (gen_sunordered (tmp));
963 operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
967 emit_insn (gen_sunordered (tmp));
968 operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
985 ;; -------------------------------------------------------------------------
986 ;; Addition instructions
987 ;; -------------------------------------------------------------------------
989 (define_expand "adddi3"
990 [(set (match_operand:DI 0 "arith_reg_operand" "")
991 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
992 (match_operand:DI 2 "arith_operand" "")))]
998 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1000 operands[2] = force_reg (DImode, operands[2]);
1001 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1006 (define_insn "*adddi3_media"
1007 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1008 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1009 (match_operand:DI 2 "arith_operand" "r,I10")))]
1014 [(set_attr "type" "arith_media")])
1016 (define_insn "adddi3z_media"
1017 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1019 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1020 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1022 "addz.l %1, %N2, %0"
1023 [(set_attr "type" "arith_media")])
1025 (define_insn "adddi3_compact"
1026 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1027 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1028 (match_operand:DI 2 "arith_reg_operand" "r")))
1029 (clobber (reg:SI T_REG))]
1032 [(set_attr "length" "6")])
1035 [(set (match_operand:DI 0 "arith_reg_operand" "")
1036 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1037 (match_operand:DI 2 "arith_reg_operand" "")))
1038 (clobber (reg:SI T_REG))]
1039 "TARGET_SH1 && reload_completed"
1043 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1044 high0 = gen_rtx_REG (SImode,
1045 true_regnum (operands[0])
1046 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1047 high2 = gen_rtx_REG (SImode,
1048 true_regnum (operands[2])
1049 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050 emit_insn (gen_clrt ());
1051 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1052 emit_insn (gen_addc1 (high0, high0, high2));
1057 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1058 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1059 (match_operand:SI 2 "arith_reg_operand" "r"))
1062 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1065 [(set_attr "type" "arith")])
1067 (define_insn "addc1"
1068 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1069 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1070 (match_operand:SI 2 "arith_reg_operand" "r"))
1072 (clobber (reg:SI T_REG))]
1075 [(set_attr "type" "arith")])
1077 (define_expand "addsi3"
1078 [(set (match_operand:SI 0 "arith_reg_operand" "")
1079 (plus:SI (match_operand:SI 1 "arith_operand" "")
1080 (match_operand:SI 2 "arith_operand" "")))]
1085 operands[1] = force_reg (SImode, operands[1]);
1088 (define_insn "addsi3_media"
1089 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1090 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1091 (match_operand:SI 2 "arith_operand" "r,I10")))]
1096 [(set_attr "type" "arith_media")])
1098 (define_insn "*addsi3_compact"
1099 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1100 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1101 (match_operand:SI 2 "arith_operand" "rI08")))]
1104 [(set_attr "type" "arith")])
1106 ;; -------------------------------------------------------------------------
1107 ;; Subtraction instructions
1108 ;; -------------------------------------------------------------------------
1110 (define_expand "subdi3"
1111 [(set (match_operand:DI 0 "arith_reg_operand" "")
1112 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1113 (match_operand:DI 2 "arith_reg_operand" "")))]
1119 operands[1] = force_reg (DImode, operands[1]);
1120 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1125 (define_insn "*subdi3_media"
1126 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1127 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1128 (match_operand:DI 2 "arith_reg_operand" "r")))]
1131 [(set_attr "type" "arith_media")])
1133 (define_insn "subdi3_compact"
1134 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1135 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1136 (match_operand:DI 2 "arith_reg_operand" "r")))
1137 (clobber (reg:SI T_REG))]
1140 [(set_attr "length" "6")])
1143 [(set (match_operand:DI 0 "arith_reg_operand" "")
1144 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1145 (match_operand:DI 2 "arith_reg_operand" "")))
1146 (clobber (reg:SI T_REG))]
1147 "TARGET_SH1 && reload_completed"
1151 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1152 high0 = gen_rtx_REG (SImode,
1153 true_regnum (operands[0])
1154 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1155 high2 = gen_rtx_REG (SImode,
1156 true_regnum (operands[2])
1157 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158 emit_insn (gen_clrt ());
1159 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1160 emit_insn (gen_subc1 (high0, high0, high2));
1165 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1166 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1167 (match_operand:SI 2 "arith_reg_operand" "r"))
1170 (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1173 [(set_attr "type" "arith")])
1175 (define_insn "subc1"
1176 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1177 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1178 (match_operand:SI 2 "arith_reg_operand" "r"))
1180 (clobber (reg:SI T_REG))]
1183 [(set_attr "type" "arith")])
1185 (define_insn "*subsi3_internal"
1186 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1188 (match_operand:SI 2 "arith_reg_operand" "r")))]
1191 [(set_attr "type" "arith")])
1193 (define_insn "*subsi3_media"
1194 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1195 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1196 (match_operand:SI 2 "extend_reg_operand" "r")))]
1199 [(set_attr "type" "arith_media")])
1201 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1202 ;; will sometimes save one instruction. Otherwise we might get
1203 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1206 (define_expand "subsi3"
1207 [(set (match_operand:SI 0 "arith_reg_operand" "")
1208 (minus:SI (match_operand:SI 1 "arith_operand" "")
1209 (match_operand:SI 2 "arith_reg_operand" "")))]
1213 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1215 emit_insn (gen_negsi2 (operands[0], operands[2]));
1216 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1221 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1223 if (operands[1] != const0_rtx)
1224 operands[1] = force_reg (SImode, operands[1]);
1228 ;; -------------------------------------------------------------------------
1229 ;; Division instructions
1230 ;; -------------------------------------------------------------------------
1232 ;; We take advantage of the library routines which don't clobber as many
1233 ;; registers as a normal function call would.
1235 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1236 ;; also has an effect on the register that holds the address of the sfunc.
1237 ;; To make this work, we have an extra dummy insn that shows the use
1238 ;; of this register for reorg.
1240 (define_insn "use_sfunc_addr"
1241 [(set (reg:SI PR_REG)
1242 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1245 [(set_attr "length" "0")])
1247 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1248 ;; hard register 0. If we used hard register 0, then the next instruction
1249 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1250 ;; gets allocated to a stack slot that needs its address reloaded, then
1251 ;; there is nothing to prevent reload from using r0 to reload the address.
1252 ;; This reload would clobber the value in r0 we are trying to store.
1253 ;; If we let reload allocate r0, then this problem can never happen.
1255 (define_insn "udivsi3_i1"
1256 [(set (match_operand:SI 0 "register_operand" "=z")
1257 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258 (clobber (reg:SI T_REG))
1259 (clobber (reg:SI PR_REG))
1260 (clobber (reg:SI R4_REG))
1261 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1262 "TARGET_SH1 && ! TARGET_SH4"
1264 [(set_attr "type" "sfunc")
1265 (set_attr "needs_delay_slot" "yes")])
1267 ; Since shmedia-nofpu code could be linked against shcompact code, and
1268 ; the udivsi3 libcall has the same name, we must consider all registers
1269 ; clobbered that are in the union of the registers clobbered by the
1270 ; shmedia and the shcompact implementation. Note, if the shcompact
1271 ; implementation actually used shcompact code, we'd need to clobber
1272 ; also r23 and fr23.
1273 (define_insn "udivsi3_i1_media"
1274 [(set (match_operand:SI 0 "register_operand" "=z")
1275 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1276 (clobber (reg:SI T_MEDIA_REG))
1277 (clobber (reg:SI PR_MEDIA_REG))
1278 (clobber (reg:SI R20_REG))
1279 (clobber (reg:SI R21_REG))
1280 (clobber (reg:SI R22_REG))
1281 (clobber (reg:DI TR0_REG))
1282 (clobber (reg:DI TR1_REG))
1283 (clobber (reg:DI TR2_REG))
1284 (use (match_operand:DI 1 "target_operand" "b"))]
1285 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1287 [(set_attr "type" "sfunc")
1288 (set_attr "needs_delay_slot" "yes")])
1290 (define_expand "udivsi3_i4_media"
1292 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1294 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1295 (set (match_dup 5) (float:DF (match_dup 3)))
1296 (set (match_dup 6) (float:DF (match_dup 4)))
1297 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1298 (set (match_dup 8) (fix:DI (match_dup 7)))
1299 (set (match_operand:SI 0 "register_operand" "")
1300 (truncate:SI (match_dup 8)))]
1301 "TARGET_SHMEDIA_FPU"
1304 operands[3] = gen_reg_rtx (DImode);
1305 operands[4] = gen_reg_rtx (DImode);
1306 operands[5] = gen_reg_rtx (DFmode);
1307 operands[6] = gen_reg_rtx (DFmode);
1308 operands[7] = gen_reg_rtx (DFmode);
1309 operands[8] = gen_reg_rtx (DImode);
1312 (define_insn "udivsi3_i4"
1313 [(set (match_operand:SI 0 "register_operand" "=y")
1314 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315 (clobber (reg:SI T_REG))
1316 (clobber (reg:SI PR_REG))
1317 (clobber (reg:DF DR0_REG))
1318 (clobber (reg:DF DR2_REG))
1319 (clobber (reg:DF DR4_REG))
1320 (clobber (reg:SI R0_REG))
1321 (clobber (reg:SI R1_REG))
1322 (clobber (reg:SI R4_REG))
1323 (clobber (reg:SI R5_REG))
1324 (use (reg:PSI FPSCR_REG))
1325 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1328 [(set_attr "type" "sfunc")
1329 (set_attr "fp_mode" "double")
1330 (set_attr "needs_delay_slot" "yes")])
1332 (define_insn "udivsi3_i4_single"
1333 [(set (match_operand:SI 0 "register_operand" "=y")
1334 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1335 (clobber (reg:SI T_REG))
1336 (clobber (reg:SI PR_REG))
1337 (clobber (reg:DF DR0_REG))
1338 (clobber (reg:DF DR2_REG))
1339 (clobber (reg:DF DR4_REG))
1340 (clobber (reg:SI R0_REG))
1341 (clobber (reg:SI R1_REG))
1342 (clobber (reg:SI R4_REG))
1343 (clobber (reg:SI R5_REG))
1344 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1345 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1347 [(set_attr "type" "sfunc")
1348 (set_attr "needs_delay_slot" "yes")])
1350 (define_expand "udivsi3"
1351 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1352 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1353 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1354 (parallel [(set (match_operand:SI 0 "register_operand" "")
1355 (udiv:SI (reg:SI R4_REG)
1357 (clobber (reg:SI T_REG))
1358 (clobber (reg:SI PR_REG))
1359 (clobber (reg:SI R4_REG))
1360 (use (match_dup 3))])]
1366 operands[3] = gen_reg_rtx (Pmode);
1367 /* Emit the move of the address to a pseudo outside of the libcall. */
1368 if (TARGET_HARD_SH4 && TARGET_SH2E)
1370 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1371 if (TARGET_FPU_SINGLE)
1372 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1374 last = gen_udivsi3_i4 (operands[0], operands[3]);
1376 else if (TARGET_SHMEDIA_FPU)
1378 operands[1] = force_reg (SImode, operands[1]);
1379 operands[2] = force_reg (SImode, operands[2]);
1380 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1383 else if (TARGET_SH5)
1385 emit_move_insn (operands[3],
1386 function_symbol (TARGET_FPU_ANY
1391 last = gen_udivsi3_i1_media (operands[0],
1394 : gen_rtx_SUBREG (DImode, operands[3],
1396 else if (TARGET_FPU_ANY)
1397 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1399 last = gen_udivsi3_i1 (operands[0], operands[3]);
1403 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1404 last = gen_udivsi3_i1 (operands[0], operands[3]);
1406 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1407 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1408 last = emit_insn (last);
1409 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1410 invariant code motion can move it. */
1411 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1412 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1416 (define_insn "divsi3_i1"
1417 [(set (match_operand:SI 0 "register_operand" "=z")
1418 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419 (clobber (reg:SI T_REG))
1420 (clobber (reg:SI PR_REG))
1421 (clobber (reg:SI R1_REG))
1422 (clobber (reg:SI R2_REG))
1423 (clobber (reg:SI R3_REG))
1424 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1425 "TARGET_SH1 && ! TARGET_SH4"
1427 [(set_attr "type" "sfunc")
1428 (set_attr "needs_delay_slot" "yes")])
1430 ; Since shmedia-nofpu code could be linked against shcompact code, and
1431 ; the sdivsi3 libcall has the same name, we must consider all registers
1432 ; clobbered that are in the union of the registers clobbered by the
1433 ; shmedia and the shcompact implementation. Note, if the shcompact
1434 ; implementation actually used shcompact code, we'd need to clobber
1435 ; also r22, r23 and fr23.
1436 (define_insn "divsi3_i1_media"
1437 [(set (match_operand:SI 0 "register_operand" "=z")
1438 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1439 (clobber (reg:SI T_MEDIA_REG))
1440 (clobber (reg:SI PR_MEDIA_REG))
1441 (clobber (reg:SI R1_REG))
1442 (clobber (reg:SI R2_REG))
1443 (clobber (reg:SI R3_REG))
1444 (clobber (reg:SI R20_REG))
1445 (clobber (reg:SI R21_REG))
1446 (clobber (reg:DI TR0_REG))
1447 (clobber (reg:DI TR1_REG))
1448 (clobber (reg:DI TR2_REG))
1449 (use (match_operand:DI 1 "target_operand" "b"))]
1450 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1452 [(set_attr "type" "sfunc")])
1454 (define_expand "divsi3_i4_media"
1455 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1456 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1457 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1458 (set (match_operand:SI 0 "register_operand" "=r")
1459 (fix:SI (match_dup 5)))]
1460 "TARGET_SHMEDIA_FPU"
1463 operands[3] = gen_reg_rtx (DFmode);
1464 operands[4] = gen_reg_rtx (DFmode);
1465 operands[5] = gen_reg_rtx (DFmode);
1468 (define_insn "divsi3_i4"
1469 [(set (match_operand:SI 0 "register_operand" "=y")
1470 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471 (clobber (reg:SI PR_REG))
1472 (clobber (reg:DF DR0_REG))
1473 (clobber (reg:DF DR2_REG))
1474 (use (reg:PSI FPSCR_REG))
1475 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1478 [(set_attr "type" "sfunc")
1479 (set_attr "fp_mode" "double")
1480 (set_attr "needs_delay_slot" "yes")])
1482 (define_insn "divsi3_i4_single"
1483 [(set (match_operand:SI 0 "register_operand" "=y")
1484 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1485 (clobber (reg:SI PR_REG))
1486 (clobber (reg:DF DR0_REG))
1487 (clobber (reg:DF DR2_REG))
1488 (clobber (reg:SI R2_REG))
1489 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1490 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1492 [(set_attr "type" "sfunc")
1493 (set_attr "needs_delay_slot" "yes")])
1495 (define_expand "divsi3"
1496 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1497 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1498 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1499 (parallel [(set (match_operand:SI 0 "register_operand" "")
1500 (div:SI (reg:SI R4_REG)
1502 (clobber (reg:SI T_REG))
1503 (clobber (reg:SI PR_REG))
1504 (clobber (reg:SI R1_REG))
1505 (clobber (reg:SI R2_REG))
1506 (clobber (reg:SI R3_REG))
1507 (use (match_dup 3))])]
1513 operands[3] = gen_reg_rtx (Pmode);
1514 /* Emit the move of the address to a pseudo outside of the libcall. */
1515 if (TARGET_HARD_SH4 && TARGET_SH2E)
1517 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1518 if (TARGET_FPU_SINGLE)
1519 last = gen_divsi3_i4_single (operands[0], operands[3]);
1521 last = gen_divsi3_i4 (operands[0], operands[3]);
1523 else if (TARGET_SHMEDIA_FPU)
1525 operands[1] = force_reg (SImode, operands[1]);
1526 operands[2] = force_reg (SImode, operands[2]);
1527 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1530 else if (TARGET_SH5)
1532 emit_move_insn (operands[3],
1533 function_symbol (TARGET_FPU_ANY
1538 last = gen_divsi3_i1_media (operands[0],
1541 : gen_rtx_SUBREG (DImode, operands[3],
1543 else if (TARGET_FPU_ANY)
1544 last = gen_divsi3_i4_single (operands[0], operands[3]);
1546 last = gen_divsi3_i1 (operands[0], operands[3]);
1550 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1551 last = gen_divsi3_i1 (operands[0], operands[3]);
1553 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1554 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1555 last = emit_insn (last);
1556 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1557 invariant code motion can move it. */
1558 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1559 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1563 ;; -------------------------------------------------------------------------
1564 ;; Multiplication instructions
1565 ;; -------------------------------------------------------------------------
1567 (define_insn "umulhisi3_i"
1568 [(set (reg:SI MACL_REG)
1569 (mult:SI (zero_extend:SI
1570 (match_operand:HI 0 "arith_reg_operand" "r"))
1572 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1575 [(set_attr "type" "smpy")])
1577 (define_insn "mulhisi3_i"
1578 [(set (reg:SI MACL_REG)
1579 (mult:SI (sign_extend:SI
1580 (match_operand:HI 0 "arith_reg_operand" "r"))
1582 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1585 [(set_attr "type" "smpy")])
1587 (define_expand "mulhisi3"
1588 [(set (reg:SI MACL_REG)
1589 (mult:SI (sign_extend:SI
1590 (match_operand:HI 1 "arith_reg_operand" ""))
1592 (match_operand:HI 2 "arith_reg_operand" ""))))
1593 (set (match_operand:SI 0 "arith_reg_operand" "")
1600 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1601 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1602 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1603 invariant code motion can move it. */
1604 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1605 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1606 /* expand_binop can't find a suitable code in umul_widen_optab to
1607 make a REG_EQUAL note from, so make one here.
1608 See also smulsi3_highpart.
1609 ??? Alternatively, we could put this at the calling site of expand_binop,
1610 i.e. expand_expr. */
1612 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1617 (define_expand "umulhisi3"
1618 [(set (reg:SI MACL_REG)
1619 (mult:SI (zero_extend:SI
1620 (match_operand:HI 1 "arith_reg_operand" ""))
1622 (match_operand:HI 2 "arith_reg_operand" ""))))
1623 (set (match_operand:SI 0 "arith_reg_operand" "")
1630 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1631 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1632 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1633 invariant code motion can move it. */
1634 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1635 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1636 /* expand_binop can't find a suitable code in umul_widen_optab to
1637 make a REG_EQUAL note from, so make one here.
1638 See also smulsi3_highpart.
1639 ??? Alternatively, we could put this at the calling site of expand_binop,
1640 i.e. expand_expr. */
1642 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1647 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1648 ;; a call to a routine which clobbers known registers.
1651 [(set (match_operand:SI 1 "register_operand" "=z")
1652 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1653 (clobber (reg:SI MACL_REG))
1654 (clobber (reg:SI T_REG))
1655 (clobber (reg:SI PR_REG))
1656 (clobber (reg:SI R3_REG))
1657 (clobber (reg:SI R2_REG))
1658 (clobber (reg:SI R1_REG))
1659 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1662 [(set_attr "type" "sfunc")
1663 (set_attr "needs_delay_slot" "yes")])
1665 (define_expand "mulsi3_call"
1666 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1667 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1668 (parallel[(set (match_operand:SI 0 "register_operand" "")
1669 (mult:SI (reg:SI R4_REG)
1671 (clobber (reg:SI MACL_REG))
1672 (clobber (reg:SI T_REG))
1673 (clobber (reg:SI PR_REG))
1674 (clobber (reg:SI R3_REG))
1675 (clobber (reg:SI R2_REG))
1676 (clobber (reg:SI R1_REG))
1677 (use (match_operand:SI 3 "register_operand" ""))])]
1681 (define_insn "mul_l"
1682 [(set (reg:SI MACL_REG)
1683 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1684 (match_operand:SI 1 "arith_reg_operand" "r")))]
1687 [(set_attr "type" "dmpy")])
1689 (define_expand "mulsi3"
1690 [(set (reg:SI MACL_REG)
1691 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1692 (match_operand:SI 2 "arith_reg_operand" "")))
1693 (set (match_operand:SI 0 "arith_reg_operand" "")
1702 /* The address must be set outside the libcall,
1703 since it goes into a pseudo. */
1704 rtx sym = function_symbol (\"__mulsi3\");
1705 rtx addr = force_reg (SImode, sym);
1706 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1709 last = emit_insn (insns);
1713 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1715 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1716 /* consec_sets_giv can only recognize the first insn that sets a
1717 giv as the giv insn. So we must tag this also with a REG_EQUAL
1719 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1721 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1722 invariant code motion can move it. */
1723 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1724 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1728 (define_insn "mulsidi3_i"
1729 [(set (reg:SI MACH_REG)
1733 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1734 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1736 (set (reg:SI MACL_REG)
1737 (mult:SI (match_dup 0)
1741 [(set_attr "type" "dmpy")])
1743 (define_expand "mulsidi3"
1744 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1745 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1746 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1747 "TARGET_SH2 || TARGET_SHMEDIA"
1752 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1758 (define_insn "mulsidi3_media"
1759 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1761 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1764 [(set_attr "type" "dmpy_media")])
1766 (define_insn "mulsidi3_compact"
1767 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1769 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1770 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1771 (clobber (reg:SI MACH_REG))
1772 (clobber (reg:SI MACL_REG))]
1777 [(set (match_operand:DI 0 "arith_reg_operand" "")
1779 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1780 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1781 (clobber (reg:SI MACH_REG))
1782 (clobber (reg:SI MACL_REG))]
1787 rtx low_dst = gen_lowpart (SImode, operands[0]);
1788 rtx high_dst = gen_highpart (SImode, operands[0]);
1790 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1792 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1793 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1794 /* We need something to tag the possible REG_EQUAL notes on to. */
1795 emit_move_insn (operands[0], operands[0]);
1799 (define_insn "umulsidi3_i"
1800 [(set (reg:SI MACH_REG)
1804 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1805 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1807 (set (reg:SI MACL_REG)
1808 (mult:SI (match_dup 0)
1812 [(set_attr "type" "dmpy")])
1814 (define_expand "umulsidi3"
1815 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1816 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1817 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1818 "TARGET_SH2 || TARGET_SHMEDIA"
1823 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1829 (define_insn "umulsidi3_media"
1830 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1832 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1835 [(set_attr "type" "dmpy_media")])
1837 (define_insn "umulsidi3_compact"
1838 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1840 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1841 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1842 (clobber (reg:SI MACH_REG))
1843 (clobber (reg:SI MACL_REG))]
1848 [(set (match_operand:DI 0 "arith_reg_operand" "")
1849 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1850 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1851 (clobber (reg:SI MACH_REG))
1852 (clobber (reg:SI MACL_REG))]
1857 rtx low_dst = gen_lowpart (SImode, operands[0]);
1858 rtx high_dst = gen_highpart (SImode, operands[0]);
1860 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1862 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1863 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1864 /* We need something to tag the possible REG_EQUAL notes on to. */
1865 emit_move_insn (operands[0], operands[0]);
1869 (define_insn "smulsi3_highpart_i"
1870 [(set (reg:SI MACH_REG)
1874 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1875 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1877 (clobber (reg:SI MACL_REG))]
1880 [(set_attr "type" "dmpy")])
1882 (define_expand "smulsi3_highpart"
1884 [(set (reg:SI MACH_REG)
1888 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1889 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1891 (clobber (reg:SI MACL_REG))])
1892 (set (match_operand:SI 0 "arith_reg_operand" "")
1899 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1900 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1901 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1902 invariant code motion can move it. */
1903 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1904 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1905 /* expand_binop can't find a suitable code in mul_highpart_optab to
1906 make a REG_EQUAL note from, so make one here.
1907 See also {,u}mulhisi.
1908 ??? Alternatively, we could put this at the calling site of expand_binop,
1909 i.e. expand_mult_highpart. */
1911 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1916 (define_insn "umulsi3_highpart_i"
1917 [(set (reg:SI MACH_REG)
1921 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1922 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1924 (clobber (reg:SI MACL_REG))]
1927 [(set_attr "type" "dmpy")])
1929 (define_expand "umulsi3_highpart"
1931 [(set (reg:SI MACH_REG)
1935 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1936 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1938 (clobber (reg:SI MACL_REG))])
1939 (set (match_operand:SI 0 "arith_reg_operand" "")
1946 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1947 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1948 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1949 invariant code motion can move it. */
1950 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1951 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1955 ;; -------------------------------------------------------------------------
1956 ;; Logical operations
1957 ;; -------------------------------------------------------------------------
1959 (define_insn "*andsi3_compact"
1960 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1961 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1962 (match_operand:SI 2 "logical_operand" "r,K08")))]
1965 [(set_attr "type" "arith")])
1967 ;; If the constant is 255, then emit an extu.b instruction instead of an
1968 ;; and, since that will give better code.
1970 (define_expand "andsi3"
1971 [(set (match_operand:SI 0 "arith_reg_operand" "")
1972 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1973 (match_operand:SI 2 "logical_operand" "")))]
1977 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1979 emit_insn (gen_zero_extendqisi2 (operands[0],
1980 gen_lowpart (QImode, operands[1])));
1985 (define_insn_and_split "anddi3"
1986 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1987 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1988 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1995 && ! logical_operand (operands[2], DImode)"
1999 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2000 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2002 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2005 [(set_attr "type" "arith_media")])
2007 (define_insn "andcdi3"
2008 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2009 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2010 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2013 [(set_attr "type" "arith_media")])
2015 (define_insn "iorsi3"
2016 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2017 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2018 (match_operand:SI 2 "logical_operand" "r,K08")))]
2021 [(set_attr "type" "arith")])
2023 (define_insn "iordi3"
2024 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2025 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2026 (match_operand:DI 2 "logical_operand" "r,I10")))]
2031 [(set_attr "type" "arith_media")])
2033 (define_insn "xorsi3"
2034 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2035 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2036 (match_operand:SI 2 "logical_operand" "K08,r")))]
2039 [(set_attr "type" "arith")])
2041 (define_insn "xordi3"
2042 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2043 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2044 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2049 [(set_attr "type" "arith_media")])
2051 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2052 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2054 [(set (match_operand:DI 0 "arith_reg_operand" "")
2055 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2056 [(match_operand 1 "any_register_operand" "")
2057 (match_operand 2 "any_register_operand" "")])))]
2059 [(set (match_dup 5) (match_dup 4))
2060 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2063 enum machine_mode inmode = GET_MODE (operands[1]);
2066 if (GET_CODE (operands[0]) == SUBREG)
2068 offset = SUBREG_BYTE (operands[0]);
2069 operands[0] = SUBREG_REG (operands[0]);
2071 if (GET_CODE (operands[0]) != REG)
2073 if (! TARGET_LITTLE_ENDIAN)
2074 offset += 8 - GET_MODE_SIZE (inmode);
2075 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2078 ;; -------------------------------------------------------------------------
2079 ;; Shifts and rotates
2080 ;; -------------------------------------------------------------------------
2082 (define_expand "rotldi3"
2083 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2084 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2085 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2087 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2089 (define_insn "rotldi3_mextr"
2090 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2091 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2092 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2096 static char templ[16];
2098 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2099 8 - (int) (INTVAL (operands[2]) >> 3));
2102 [(set_attr "type" "arith_media")])
2104 (define_expand "rotrdi3"
2105 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2106 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2107 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2109 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2111 (define_insn "rotrdi3_mextr"
2112 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2113 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2114 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2118 static char templ[16];
2120 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2123 [(set_attr "type" "arith_media")])
2125 (define_insn "rotlsi3_1"
2126 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2127 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2133 [(set_attr "type" "arith")])
2135 (define_insn "rotlsi3_31"
2136 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2139 (clobber (reg:SI T_REG))]
2142 [(set_attr "type" "arith")])
2144 (define_insn "rotlsi3_16"
2145 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2146 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2150 [(set_attr "type" "arith")])
2152 (define_expand "rotlsi3"
2153 [(set (match_operand:SI 0 "arith_reg_operand" "")
2154 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2155 (match_operand:SI 2 "immediate_operand" "")))]
2159 static const char rot_tab[] = {
2160 000, 000, 000, 000, 000, 000, 010, 001,
2161 001, 001, 011, 013, 003, 003, 003, 003,
2162 003, 003, 003, 003, 003, 013, 012, 002,
2163 002, 002, 010, 000, 000, 000, 000, 000,
2168 if (GET_CODE (operands[2]) != CONST_INT)
2170 count = INTVAL (operands[2]);
2171 choice = rot_tab[count];
2172 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2178 emit_move_insn (operands[0], operands[1]);
2179 count -= (count & 16) * 2;
2182 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2189 parts[0] = gen_reg_rtx (SImode);
2190 parts[1] = gen_reg_rtx (SImode);
2191 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2192 parts[choice-1] = operands[1];
2193 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2194 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2195 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2196 count = (count & ~16) - 8;
2200 for (; count > 0; count--)
2201 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2202 for (; count < 0; count++)
2203 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2208 (define_insn "*rotlhi3_8"
2209 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2210 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2214 [(set_attr "type" "arith")])
2216 (define_expand "rotlhi3"
2217 [(set (match_operand:HI 0 "arith_reg_operand" "")
2218 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2219 (match_operand:HI 2 "immediate_operand" "")))]
2223 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2230 ;; This pattern is used by init_expmed for computing the costs of shift
2233 (define_insn_and_split "ashlsi3_std"
2234 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2235 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2236 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2237 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2239 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2240 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2248 && GET_CODE (operands[2]) == CONST_INT
2249 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2250 [(set (match_dup 3) (match_dup 2))
2252 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2253 (clobber (match_dup 4))])]
2254 "operands[4] = gen_rtx_SCRATCH (SImode);"
2255 [(set_attr "length" "*,*,*,4")
2256 (set_attr "type" "dyn_shift,arith,arith,arith")])
2258 (define_insn "ashlhi3_k"
2259 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2260 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2261 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2262 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2266 [(set_attr "type" "arith")])
2268 (define_insn "ashlsi3_n"
2269 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2270 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2271 (match_operand:SI 2 "const_int_operand" "n")))
2272 (clobber (reg:SI T_REG))]
2273 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2275 [(set (attr "length")
2276 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2278 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2280 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2282 (const_string "8")))
2283 (set_attr "type" "arith")])
2286 [(set (match_operand:SI 0 "arith_reg_operand" "")
2287 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2288 (match_operand:SI 2 "const_int_operand" "")))
2289 (clobber (reg:SI T_REG))]
2290 "TARGET_SH1 && reload_completed"
2291 [(use (reg:SI R0_REG))]
2294 gen_shifty_op (ASHIFT, operands);
2298 (define_insn "ashlsi3_media"
2299 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2300 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2301 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2306 [(set_attr "type" "arith_media")])
2308 (define_expand "ashlsi3"
2309 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2310 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2311 (match_operand:SI 2 "nonmemory_operand" "")))
2312 (clobber (reg:SI T_REG))])]
2318 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2321 if (GET_CODE (operands[2]) == CONST_INT
2322 && sh_dynamicalize_shift_p (operands[2]))
2323 operands[2] = force_reg (SImode, operands[2]);
2326 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2329 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2333 (define_insn "ashlhi3"
2334 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2335 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2336 (match_operand:HI 2 "const_int_operand" "n")))
2337 (clobber (reg:SI T_REG))]
2340 [(set (attr "length")
2341 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2343 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2345 (const_string "6")))
2346 (set_attr "type" "arith")])
2349 [(set (match_operand:HI 0 "arith_reg_operand" "")
2350 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2351 (match_operand:HI 2 "const_int_operand" "")))
2352 (clobber (reg:SI T_REG))]
2353 "TARGET_SH1 && reload_completed"
2354 [(use (reg:SI R0_REG))]
2357 gen_shifty_hi_op (ASHIFT, operands);
2362 ; arithmetic shift right
2365 (define_insn "ashrsi3_k"
2366 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2368 (match_operand:SI 2 "const_int_operand" "M")))
2369 (clobber (reg:SI T_REG))]
2370 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2372 [(set_attr "type" "arith")])
2374 ;; We can't do HImode right shifts correctly unless we start out with an
2375 ;; explicit zero / sign extension; doing that would result in worse overall
2376 ;; code, so just let the machine independent code widen the mode.
2377 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2380 ;; ??? This should be a define expand.
2382 (define_insn "ashrsi2_16"
2383 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2384 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2388 [(set_attr "length" "4")])
2391 [(set (match_operand:SI 0 "arith_reg_operand" "")
2392 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2395 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2396 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2397 "operands[2] = gen_lowpart (HImode, operands[0]);")
2399 ;; ??? This should be a define expand.
2401 (define_insn "ashrsi2_31"
2402 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2403 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2405 (clobber (reg:SI T_REG))]
2408 [(set_attr "length" "4")])
2411 [(set (match_operand:SI 0 "arith_reg_operand" "")
2412 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2414 (clobber (reg:SI T_REG))]
2419 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2420 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2424 (define_insn "ashlsi_c"
2425 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2428 (lt:SI (match_dup 1) (const_int 0)))]
2431 [(set_attr "type" "arith")])
2433 (define_insn "ashrsi3_d"
2434 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2435 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2436 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2439 [(set_attr "type" "dyn_shift")])
2441 (define_insn "ashrsi3_n"
2442 [(set (reg:SI R4_REG)
2443 (ashiftrt:SI (reg:SI R4_REG)
2444 (match_operand:SI 0 "const_int_operand" "i")))
2445 (clobber (reg:SI T_REG))
2446 (clobber (reg:SI PR_REG))
2447 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2450 [(set_attr "type" "sfunc")
2451 (set_attr "needs_delay_slot" "yes")])
2453 (define_insn "ashrsi3_media"
2454 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2455 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2456 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2461 [(set_attr "type" "arith_media")])
2463 (define_expand "ashrsi3"
2464 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2465 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2466 (match_operand:SI 2 "nonmemory_operand" "")))
2467 (clobber (reg:SI T_REG))])]
2473 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2476 if (expand_ashiftrt (operands))
2482 ;; logical shift right
2484 (define_insn "lshrsi3_d"
2485 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2490 [(set_attr "type" "dyn_shift")])
2492 ;; Only the single bit shift clobbers the T bit.
2494 (define_insn "lshrsi3_m"
2495 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497 (match_operand:SI 2 "const_int_operand" "M")))
2498 (clobber (reg:SI T_REG))]
2499 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2501 [(set_attr "type" "arith")])
2503 (define_insn "lshrsi3_k"
2504 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506 (match_operand:SI 2 "const_int_operand" "P27")))]
2507 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2508 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2510 [(set_attr "type" "arith")])
2512 (define_insn "lshrsi3_n"
2513 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2514 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2515 (match_operand:SI 2 "const_int_operand" "n")))
2516 (clobber (reg:SI T_REG))]
2517 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2519 [(set (attr "length")
2520 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2522 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2524 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2526 (const_string "8")))
2527 (set_attr "type" "arith")])
2530 [(set (match_operand:SI 0 "arith_reg_operand" "")
2531 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2532 (match_operand:SI 2 "const_int_operand" "")))
2533 (clobber (reg:SI T_REG))]
2534 "TARGET_SH1 && reload_completed"
2535 [(use (reg:SI R0_REG))]
2538 gen_shifty_op (LSHIFTRT, operands);
2542 (define_insn "lshrsi3_media"
2543 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2544 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2545 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2550 [(set_attr "type" "arith_media")])
2552 (define_expand "lshrsi3"
2553 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2554 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2555 (match_operand:SI 2 "nonmemory_operand" "")))
2556 (clobber (reg:SI T_REG))])]
2562 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2565 if (GET_CODE (operands[2]) == CONST_INT
2566 && sh_dynamicalize_shift_p (operands[2]))
2567 operands[2] = force_reg (SImode, operands[2]);
2568 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2570 rtx count = copy_to_mode_reg (SImode, operands[2]);
2571 emit_insn (gen_negsi2 (count, count));
2572 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2575 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2579 ;; ??? This should be a define expand.
2581 (define_insn "ashldi3_k"
2582 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2583 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2585 (clobber (reg:SI T_REG))]
2587 "shll %R0\;rotcl %S0"
2588 [(set_attr "length" "4")
2589 (set_attr "type" "arith")])
2591 (define_insn "ashldi3_media"
2592 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2593 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2594 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2599 [(set_attr "type" "arith_media")])
2601 (define_expand "ashldi3"
2602 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2603 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2604 (match_operand:DI 2 "immediate_operand" "")))
2605 (clobber (reg:SI T_REG))])]
2611 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2614 if (GET_CODE (operands[2]) != CONST_INT
2615 || INTVAL (operands[2]) != 1)
2619 ;; ??? This should be a define expand.
2621 (define_insn "lshrdi3_k"
2622 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2623 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2625 (clobber (reg:SI T_REG))]
2627 "shlr %S0\;rotcr %R0"
2628 [(set_attr "length" "4")
2629 (set_attr "type" "arith")])
2631 (define_insn "lshrdi3_media"
2632 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2633 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2634 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2639 [(set_attr "type" "arith_media")])
2641 (define_expand "lshrdi3"
2642 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2643 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2644 (match_operand:DI 2 "immediate_operand" "")))
2645 (clobber (reg:SI T_REG))])]
2651 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2654 if (GET_CODE (operands[2]) != CONST_INT
2655 || INTVAL (operands[2]) != 1)
2659 ;; ??? This should be a define expand.
2661 (define_insn "ashrdi3_k"
2662 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2663 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2665 (clobber (reg:SI T_REG))]
2667 "shar %S0\;rotcr %R0"
2668 [(set_attr "length" "4")
2669 (set_attr "type" "arith")])
2671 (define_insn "ashrdi3_media"
2672 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2673 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2674 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2679 [(set_attr "type" "arith_media")])
2681 (define_expand "ashrdi3"
2682 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2683 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2684 (match_operand:DI 2 "immediate_operand" "")))
2685 (clobber (reg:SI T_REG))])]
2691 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2694 if (GET_CODE (operands[2]) != CONST_INT
2695 || INTVAL (operands[2]) != 1)
2699 ;; combined left/right shift
2702 [(set (match_operand:SI 0 "register_operand" "")
2703 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2704 (match_operand:SI 2 "const_int_operand" ""))
2705 (match_operand:SI 3 "const_int_operand" "")))]
2706 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2707 [(use (reg:SI R0_REG))]
2708 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2712 [(set (match_operand:SI 0 "register_operand" "")
2713 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2714 (match_operand:SI 2 "const_int_operand" ""))
2715 (match_operand:SI 3 "const_int_operand" "")))
2716 (clobber (reg:SI T_REG))]
2717 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2718 [(use (reg:SI R0_REG))]
2719 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2723 [(set (match_operand:SI 0 "register_operand" "=r")
2724 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2725 (match_operand:SI 2 "const_int_operand" "n"))
2726 (match_operand:SI 3 "const_int_operand" "n")))
2727 (clobber (reg:SI T_REG))]
2728 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2730 [(set (attr "length")
2731 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2733 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2737 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2739 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2741 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2743 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2744 (const_string "16")]
2745 (const_string "18")))
2746 (set_attr "type" "arith")])
2749 [(set (match_operand:SI 0 "register_operand" "=z")
2750 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2751 (match_operand:SI 2 "const_int_operand" "n"))
2752 (match_operand:SI 3 "const_int_operand" "n")))
2753 (clobber (reg:SI T_REG))]
2754 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2756 [(set (attr "length")
2757 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2759 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2761 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2763 (const_string "10")))
2764 (set_attr "type" "arith")])
2766 ;; shift left / and combination with a scratch register: The combine pass
2767 ;; does not accept the individual instructions, even though they are
2768 ;; cheap. But it needs a precise description so that it is usable after
2770 (define_insn "and_shl_scratch"
2771 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2775 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2776 (match_operand:SI 2 "const_int_operand" "N,n"))
2777 (match_operand:SI 3 "" "0,r"))
2778 (match_operand:SI 4 "const_int_operand" "n,n"))
2779 (match_operand:SI 5 "const_int_operand" "n,n")))
2780 (clobber (reg:SI T_REG))]
2783 [(set (attr "length")
2784 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2786 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2788 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2790 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2791 (const_string "10")]
2792 (const_string "12")))
2793 (set_attr "type" "arith")])
2796 [(set (match_operand:SI 0 "register_operand" "")
2800 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2801 (match_operand:SI 2 "const_int_operand" ""))
2802 (match_operand:SI 3 "register_operand" ""))
2803 (match_operand:SI 4 "const_int_operand" ""))
2804 (match_operand:SI 5 "const_int_operand" "")))
2805 (clobber (reg:SI T_REG))]
2807 [(use (reg:SI R0_REG))]
2810 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2812 if (INTVAL (operands[2]))
2814 gen_shifty_op (LSHIFTRT, operands);
2816 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2817 operands[2] = operands[4];
2818 gen_shifty_op (ASHIFT, operands);
2819 if (INTVAL (operands[5]))
2821 operands[2] = operands[5];
2822 gen_shifty_op (LSHIFTRT, operands);
2827 ;; signed left/right shift combination.
2829 [(set (match_operand:SI 0 "register_operand" "")
2831 (ashift:SI (match_operand:SI 1 "register_operand" "")
2832 (match_operand:SI 2 "const_int_operand" ""))
2833 (match_operand:SI 3 "const_int_operand" "")
2835 (clobber (reg:SI T_REG))]
2837 [(use (reg:SI R0_REG))]
2838 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2841 (define_insn "shl_sext_ext"
2842 [(set (match_operand:SI 0 "register_operand" "=r")
2844 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2845 (match_operand:SI 2 "const_int_operand" "n"))
2846 (match_operand:SI 3 "const_int_operand" "n")
2848 (clobber (reg:SI T_REG))]
2849 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2851 [(set (attr "length")
2852 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2854 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2856 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2858 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2862 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2864 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2866 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2867 (const_string "16")]
2868 (const_string "18")))
2869 (set_attr "type" "arith")])
2871 (define_insn "shl_sext_sub"
2872 [(set (match_operand:SI 0 "register_operand" "=z")
2874 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2875 (match_operand:SI 2 "const_int_operand" "n"))
2876 (match_operand:SI 3 "const_int_operand" "n")
2878 (clobber (reg:SI T_REG))]
2879 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2881 [(set (attr "length")
2882 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2884 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2886 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2888 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2889 (const_string "12")]
2890 (const_string "14")))
2891 (set_attr "type" "arith")])
2893 ;; These patterns are found in expansions of DImode shifts by 16, and
2894 ;; allow the xtrct instruction to be generated from C source.
2896 (define_insn "xtrct_left"
2897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2900 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2904 [(set_attr "type" "arith")])
2906 (define_insn "xtrct_right"
2907 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2910 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2914 [(set_attr "type" "arith")])
2916 ;; -------------------------------------------------------------------------
2918 ;; -------------------------------------------------------------------------
2921 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2922 (neg:SI (plus:SI (reg:SI T_REG)
2923 (match_operand:SI 1 "arith_reg_operand" "r"))))
2925 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2929 [(set_attr "type" "arith")])
2931 (define_insn "*negdi_media"
2932 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2933 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2936 [(set_attr "type" "arith_media")])
2938 (define_expand "negdi2"
2939 [(set (match_operand:DI 0 "arith_reg_operand" "")
2940 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2946 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2947 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2949 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2950 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2952 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2953 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2955 emit_insn (gen_clrt ());
2956 emit_insn (gen_negc (low_dst, low_src));
2957 emit_insn (gen_negc (high_dst, high_src));
2962 (define_insn "negsi2"
2963 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2964 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2967 [(set_attr "type" "arith")])
2969 (define_insn "one_cmplsi2"
2970 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2971 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2974 [(set_attr "type" "arith")])
2976 (define_expand "one_cmpldi2"
2977 [(set (match_operand:DI 0 "arith_reg_operand" "")
2978 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2980 "TARGET_SHMEDIA" "")
2982 ;; -------------------------------------------------------------------------
2983 ;; Zero extension instructions
2984 ;; -------------------------------------------------------------------------
2986 (define_insn "zero_extendsidi2"
2987 [(set (match_operand:DI 0 "register_operand" "=r")
2988 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2990 "addz.l %1, r63, %0"
2991 [(set_attr "type" "arith_media")])
2993 (define_insn "zero_extendhidi2"
2994 [(set (match_operand:DI 0 "register_operand" "=r,r")
2995 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3000 [(set_attr "type" "*,load_media")])
3003 [(set (match_operand:DI 0 "register_operand" "")
3004 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3005 "TARGET_SHMEDIA && reload_completed"
3006 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3007 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3010 if (GET_CODE (operands[1]) == TRUNCATE)
3011 operands[1] = XEXP (operands[1], 0);
3014 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3015 ;; reload the entire truncate expression.
3016 (define_insn_and_split "*loaddi_trunc"
3017 [(set (match_operand 0 "int_gpr_dest" "=r")
3018 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3019 "TARGET_SHMEDIA && reload_completed"
3021 "TARGET_SHMEDIA && reload_completed"
3022 [(set (match_dup 0) (match_dup 1))]
3023 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3025 (define_insn "zero_extendqidi2"
3026 [(set (match_operand:DI 0 "register_operand" "=r,r")
3027 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3032 [(set_attr "type" "arith_media,load_media")])
3034 (define_expand "zero_extendhisi2"
3035 [(set (match_operand:SI 0 "arith_reg_operand" "")
3036 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3040 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3041 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3044 (define_insn "*zero_extendhisi2_compact"
3045 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3046 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3049 [(set_attr "type" "arith")])
3051 (define_insn "*zero_extendhisi2_media"
3052 [(set (match_operand:SI 0 "register_operand" "=r,r")
3053 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3058 [(set_attr "type" "arith_media,load_media")])
3061 [(set (match_operand:SI 0 "register_operand" "")
3062 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3063 "TARGET_SHMEDIA && reload_completed"
3064 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3065 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3068 if (GET_CODE (operands[1]) == TRUNCATE)
3069 operands[1] = XEXP (operands[1], 0);
3072 (define_expand "zero_extendqisi2"
3073 [(set (match_operand:SI 0 "arith_reg_operand" "")
3074 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3078 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3079 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3082 (define_insn "*zero_extendqisi2_compact"
3083 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3084 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3087 [(set_attr "type" "arith")])
3089 (define_insn "*zero_extendqisi2_media"
3090 [(set (match_operand:SI 0 "register_operand" "=r,r")
3091 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3096 [(set_attr "type" "arith_media,load_media")])
3098 (define_insn "zero_extendqihi2"
3099 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3100 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3103 [(set_attr "type" "arith")])
3105 ;; -------------------------------------------------------------------------
3106 ;; Sign extension instructions
3107 ;; -------------------------------------------------------------------------
3109 ;; ??? This should be a define expand.
3110 ;; ??? Or perhaps it should be dropped?
3112 ;; convert_move generates good code for SH[1-4].
3113 (define_insn "extendsidi2"
3114 [(set (match_operand:DI 0 "register_operand" "=r,r")
3115 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3120 [(set_attr "type" "arith_media,load_media")])
3122 (define_insn "extendhidi2"
3123 [(set (match_operand:DI 0 "register_operand" "=r,r")
3124 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3129 [(set_attr "type" "*,load_media")])
3132 [(set (match_operand:DI 0 "register_operand" "")
3133 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3134 "TARGET_SHMEDIA && reload_completed"
3135 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3136 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3139 if (GET_CODE (operands[1]) == TRUNCATE)
3140 operands[1] = XEXP (operands[1], 0);
3143 (define_insn "extendqidi2"
3144 [(set (match_operand:DI 0 "register_operand" "=r,r")
3145 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3150 [(set_attr "type" "*,load_media")])
3153 [(set (match_operand:DI 0 "register_operand" "")
3154 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3155 "TARGET_SHMEDIA && reload_completed"
3156 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3157 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3160 if (GET_CODE (operands[1]) == TRUNCATE)
3161 operands[1] = XEXP (operands[1], 0);
3164 (define_expand "extendhisi2"
3165 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3166 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3170 (define_insn "*extendhisi2_compact"
3171 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3177 [(set_attr "type" "arith,load")])
3179 (define_insn "*extendhisi2_media"
3180 [(set (match_operand:SI 0 "register_operand" "=r,r")
3181 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3186 [(set_attr "type" "arith_media,load_media")])
3189 [(set (match_operand:SI 0 "register_operand" "")
3190 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3191 "TARGET_SHMEDIA && reload_completed"
3192 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3193 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3196 if (GET_CODE (operands[1]) == TRUNCATE)
3197 operands[1] = XEXP (operands[1], 0);
3200 (define_expand "extendqisi2"
3201 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3202 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3206 (define_insn "*extendqisi2_compact"
3207 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3208 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3213 [(set_attr "type" "arith,load")])
3215 (define_insn "*extendqisi2_media"
3216 [(set (match_operand:SI 0 "register_operand" "=r,r")
3217 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3222 [(set_attr "type" "arith_media,load_media")])
3225 [(set (match_operand:SI 0 "register_operand" "")
3226 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3227 "TARGET_SHMEDIA && reload_completed"
3228 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3229 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3232 if (GET_CODE (operands[1]) == TRUNCATE)
3233 operands[1] = XEXP (operands[1], 0);
3236 (define_insn "extendqihi2"
3237 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3238 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3243 [(set_attr "type" "arith,load")])
3245 /* It would seem useful to combine the truncXi patterns into the movXi
3246 patterns, but unary operators are ignored when matching constraints,
3247 so we need separate patterns. */
3248 (define_insn "truncdisi2"
3249 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3250 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3259 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3262 (define_insn "truncdihi2"
3263 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3264 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3267 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3269 [(set_attr "type" "arith_media,store_media")
3270 (set_attr "length" "8,4")])
3272 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3273 ; Because we use zero extension, we can't provide signed QImode compares
3274 ; using a simple compare or conditional banch insn.
3275 (define_insn "truncdiqi2"
3276 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3277 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3282 [(set_attr "type" "arith_media,store")])
3284 ;; -------------------------------------------------------------------------
3285 ;; Move instructions
3286 ;; -------------------------------------------------------------------------
3288 ;; define push and pop so it is easy for sh.c
3289 ;; We can't use push and pop on SHcompact because the stack must always
3290 ;; be 8-byte aligned.
3292 (define_expand "push"
3293 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3294 (match_operand:SI 0 "register_operand" "r,l,x"))]
3295 "TARGET_SH1 && ! TARGET_SH5"
3298 (define_expand "pop"
3299 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3300 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3301 "TARGET_SH1 && ! TARGET_SH5"
3304 (define_expand "push_e"
3305 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3306 (match_operand:SF 0 "" ""))
3307 (use (reg:PSI FPSCR_REG))
3308 (clobber (scratch:SI))])]
3309 "TARGET_SH1 && ! TARGET_SH5"
3312 (define_insn "push_fpul"
3313 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3314 "TARGET_SH2E && ! TARGET_SH5"
3316 [(set_attr "type" "store")
3317 (set_attr "late_fp_use" "yes")
3318 (set_attr "hit_stack" "yes")])
3320 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3322 (define_expand "push_4"
3323 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3324 (match_operand:DF 0 "" ""))
3325 (use (reg:PSI FPSCR_REG))
3326 (clobber (scratch:SI))])]
3327 "TARGET_SH1 && ! TARGET_SH5"
3330 (define_expand "pop_e"
3331 [(parallel [(set (match_operand:SF 0 "" "")
3332 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3333 (use (reg:PSI FPSCR_REG))
3334 (clobber (scratch:SI))])]
3335 "TARGET_SH1 && ! TARGET_SH5"
3338 (define_insn "pop_fpul"
3339 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3340 "TARGET_SH2E && ! TARGET_SH5"
3342 [(set_attr "type" "load")
3343 (set_attr "hit_stack" "yes")])
3345 (define_expand "pop_4"
3346 [(parallel [(set (match_operand:DF 0 "" "")
3347 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3348 (use (reg:PSI FPSCR_REG))
3349 (clobber (scratch:SI))])]
3350 "TARGET_SH1 && ! TARGET_SH5"
3353 (define_expand "push_fpscr"
3358 rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3359 gen_rtx (PRE_DEC, Pmode,
3360 stack_pointer_rtx)),
3362 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3366 (define_expand "pop_fpscr"
3371 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3372 gen_rtx (MEM, PSImode,
3373 gen_rtx (POST_INC, Pmode,
3374 stack_pointer_rtx))));
3375 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3379 ;; These two patterns can happen as the result of optimization, when
3380 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3381 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3384 [(set (reg:SI T_REG) (const_int 0))]
3389 [(set (reg:SI T_REG) (const_int 1))]
3393 ;; t/r must come after r/r, lest reload will try to reload stuff like
3394 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3395 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3396 (define_insn "movsi_i"
3397 [(set (match_operand:SI 0 "general_movdst_operand"
3398 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3399 (match_operand:SI 1 "general_movsrc_operand"
3400 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3403 && (register_operand (operands[0], SImode)
3404 || register_operand (operands[1], SImode))"
3421 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3422 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3424 ;; t/r must come after r/r, lest reload will try to reload stuff like
3425 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3426 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3427 ;; will require a reload.
3428 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3429 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3430 (define_insn "movsi_ie"
3431 [(set (match_operand:SI 0 "general_movdst_operand"
3432 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3433 (match_operand:SI 1 "general_movsrc_operand"
3434 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3436 && (register_operand (operands[0], SImode)
3437 || register_operand (operands[1], SImode))"