1 ;;- Machine description for Renesas / SuperH SH.
2 ;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;; 2003, 2004 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 "cmpsi_operand" "")
709 (match_operand:SI 1 "arith_operand" "")))]
713 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
714 && GET_CODE (operands[1]) != CONST_INT)
715 operands[0] = copy_to_mode_reg (SImode, operands[0]);
716 sh_compare_op0 = operands[0];
717 sh_compare_op1 = operands[1];
721 ;; -------------------------------------------------------------------------
722 ;; DImode signed integer comparisons
723 ;; -------------------------------------------------------------------------
725 ;; ??? Could get better scheduling by splitting the initial test from the
726 ;; rest of the insn after reload. However, the gain would hardly justify
727 ;; the sh.md size increase necessary to do that.
731 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
732 (match_operand:DI 1 "arith_operand" "r"))
735 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
737 [(set_attr "length" "6")
738 (set_attr "type" "arith3b")])
740 (define_insn "cmpeqdi_t"
742 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
743 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
746 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
747 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
748 [(set_attr "length" "6")
749 (set_attr "type" "arith3b")])
753 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
754 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
755 ;; If we applied this split when not optimizing, it would only be
756 ;; applied during the machine-dependent reorg, when no new basic blocks
758 "TARGET_SH1 && reload_completed && optimize"
759 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
760 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
761 (label_ref (match_dup 6))
763 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
768 = gen_rtx_REG (SImode,
769 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
771 = (operands[1] == const0_rtx
773 : gen_rtx_REG (SImode,
774 true_regnum (operands[1])
775 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
776 operands[4] = gen_lowpart (SImode, operands[0]);
777 operands[5] = gen_lowpart (SImode, operands[1]);
778 operands[6] = gen_label_rtx ();
781 (define_insn "cmpgtdi_t"
783 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
787 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
788 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
789 [(set_attr "length" "8")
790 (set_attr "type" "arith3")])
792 (define_insn "cmpgedi_t"
794 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
795 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
798 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
800 [(set_attr "length" "8,2")
801 (set_attr "type" "arith3,mt_group")])
803 ;; -------------------------------------------------------------------------
804 ;; DImode unsigned integer comparisons
805 ;; -------------------------------------------------------------------------
807 (define_insn "cmpgeudi_t"
809 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
810 (match_operand:DI 1 "arith_reg_operand" "r")))]
812 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
813 [(set_attr "length" "8")
814 (set_attr "type" "arith3")])
816 (define_insn "cmpgtudi_t"
818 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
819 (match_operand:DI 1 "arith_reg_operand" "r")))]
821 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
822 [(set_attr "length" "8")
823 (set_attr "type" "arith3")])
825 (define_insn "cmpeqdi_media"
826 [(set (match_operand:DI 0 "register_operand" "=r")
827 (eq:DI (match_operand:DI 1 "register_operand" "%r")
828 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
831 [(set_attr "type" "cmp_media")])
833 (define_insn "cmpgtdi_media"
834 [(set (match_operand:DI 0 "register_operand" "=r")
835 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
836 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
839 [(set_attr "type" "cmp_media")])
841 (define_insn "cmpgtudi_media"
842 [(set (match_operand:DI 0 "register_operand" "=r")
843 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
846 "cmpgtu %N1, %N2, %0"
847 [(set_attr "type" "cmp_media")])
849 ;; We save the compare operands in the cmpxx patterns and use them when
850 ;; we generate the branch.
852 (define_expand "cmpdi"
854 (compare (match_operand:DI 0 "arith_operand" "")
855 (match_operand:DI 1 "arith_operand" "")))]
856 "TARGET_SH2 || TARGET_SHMEDIA"
859 sh_compare_op0 = operands[0];
860 sh_compare_op1 = operands[1];
863 ;; -------------------------------------------------------------------------
864 ;; Conditional move instructions
865 ;; -------------------------------------------------------------------------
867 ;; The insn names may seem reversed, but note that cmveq performs the move
868 ;; if op1 == 0, and cmvne does it if op1 != 0.
870 (define_insn "movdicc_false"
871 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
872 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
874 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
875 (match_operand:DI 3 "arith_reg_operand" "0")))]
878 [(set_attr "type" "arith_media")])
880 (define_insn "movdicc_true"
881 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
882 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
884 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
885 (match_operand:DI 3 "arith_reg_operand" "0")))]
888 [(set_attr "type" "arith_media")])
890 (define_expand "movdicc"
891 [(set (match_operand:DI 0 "register_operand" "")
892 (if_then_else:DI (match_operand 1 "comparison_operator" "")
893 (match_operand:DI 2 "register_operand" "")
894 (match_operand:DI 3 "register_operand" "")))]
898 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
899 && GET_MODE (sh_compare_op0) == DImode
900 && sh_compare_op1 == const0_rtx)
901 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
902 sh_compare_op0, sh_compare_op1);
910 tmp = gen_reg_rtx (DImode);
912 switch (GET_CODE (operands[1]))
915 emit_insn (gen_seq (tmp));
916 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
920 emit_insn (gen_seq (tmp));
921 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
925 emit_insn (gen_sgt (tmp));
926 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
930 emit_insn (gen_slt (tmp));
931 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
935 emit_insn (gen_slt (tmp));
936 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
940 emit_insn (gen_sgt (tmp));
941 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
945 emit_insn (gen_sgtu (tmp));
946 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
950 emit_insn (gen_sltu (tmp));
951 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
955 emit_insn (gen_sltu (tmp));
956 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
960 emit_insn (gen_sgtu (tmp));
961 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
965 emit_insn (gen_sunordered (tmp));
966 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
970 emit_insn (gen_sunordered (tmp));
971 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
988 ;; -------------------------------------------------------------------------
989 ;; Addition instructions
990 ;; -------------------------------------------------------------------------
992 (define_expand "adddi3"
993 [(set (match_operand:DI 0 "arith_reg_operand" "")
994 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
995 (match_operand:DI 2 "arith_operand" "")))]
1001 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1003 operands[2] = force_reg (DImode, operands[2]);
1004 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1009 (define_insn "*adddi3_media"
1010 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1011 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1012 (match_operand:DI 2 "arith_operand" "r,I10")))]
1017 [(set_attr "type" "arith_media")])
1019 (define_insn "adddi3z_media"
1020 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1022 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1023 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1025 "addz.l %1, %N2, %0"
1026 [(set_attr "type" "arith_media")])
1028 (define_insn "adddi3_compact"
1029 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1030 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1031 (match_operand:DI 2 "arith_reg_operand" "r")))
1032 (clobber (reg:SI T_REG))]
1035 [(set_attr "length" "6")])
1038 [(set (match_operand:DI 0 "arith_reg_operand" "")
1039 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1040 (match_operand:DI 2 "arith_reg_operand" "")))
1041 (clobber (reg:SI T_REG))]
1042 "TARGET_SH1 && reload_completed"
1046 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1047 high0 = gen_rtx_REG (SImode,
1048 true_regnum (operands[0])
1049 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050 high2 = gen_rtx_REG (SImode,
1051 true_regnum (operands[2])
1052 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1053 emit_insn (gen_clrt ());
1054 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1055 emit_insn (gen_addc1 (high0, high0, high2));
1060 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062 (match_operand:SI 2 "arith_reg_operand" "r"))
1065 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1068 [(set_attr "type" "arith")])
1070 (define_insn "addc1"
1071 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1072 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1073 (match_operand:SI 2 "arith_reg_operand" "r"))
1075 (clobber (reg:SI T_REG))]
1078 [(set_attr "type" "arith")])
1080 (define_expand "addsi3"
1081 [(set (match_operand:SI 0 "arith_reg_operand" "")
1082 (plus:SI (match_operand:SI 1 "arith_operand" "")
1083 (match_operand:SI 2 "arith_operand" "")))]
1088 operands[1] = force_reg (SImode, operands[1]);
1091 (define_insn "addsi3_media"
1092 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1093 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1094 (match_operand:SI 2 "arith_operand" "r,I10")))]
1099 [(set_attr "type" "arith_media")])
1101 (define_insn "*addsi3_compact"
1102 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1103 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1104 (match_operand:SI 2 "arith_operand" "rI08")))]
1107 [(set_attr "type" "arith")])
1109 ;; -------------------------------------------------------------------------
1110 ;; Subtraction instructions
1111 ;; -------------------------------------------------------------------------
1113 (define_expand "subdi3"
1114 [(set (match_operand:DI 0 "arith_reg_operand" "")
1115 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1116 (match_operand:DI 2 "arith_reg_operand" "")))]
1122 operands[1] = force_reg (DImode, operands[1]);
1123 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1128 (define_insn "*subdi3_media"
1129 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1130 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1131 (match_operand:DI 2 "arith_reg_operand" "r")))]
1134 [(set_attr "type" "arith_media")])
1136 (define_insn "subdi3_compact"
1137 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1138 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1139 (match_operand:DI 2 "arith_reg_operand" "r")))
1140 (clobber (reg:SI T_REG))]
1143 [(set_attr "length" "6")])
1146 [(set (match_operand:DI 0 "arith_reg_operand" "")
1147 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1148 (match_operand:DI 2 "arith_reg_operand" "")))
1149 (clobber (reg:SI T_REG))]
1150 "TARGET_SH1 && reload_completed"
1154 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1155 high0 = gen_rtx_REG (SImode,
1156 true_regnum (operands[0])
1157 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158 high2 = gen_rtx_REG (SImode,
1159 true_regnum (operands[2])
1160 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1161 emit_insn (gen_clrt ());
1162 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1163 emit_insn (gen_subc1 (high0, high0, high2));
1168 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170 (match_operand:SI 2 "arith_reg_operand" "r"))
1173 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1178 [(set_attr "type" "arith")])
1180 (define_insn "subc1"
1181 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1182 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1183 (match_operand:SI 2 "arith_reg_operand" "r"))
1185 (clobber (reg:SI T_REG))]
1188 [(set_attr "type" "arith")])
1190 (define_insn "*subsi3_internal"
1191 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1192 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1193 (match_operand:SI 2 "arith_reg_operand" "r")))]
1196 [(set_attr "type" "arith")])
1198 (define_insn "*subsi3_media"
1199 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1200 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1201 (match_operand:SI 2 "extend_reg_operand" "r")))]
1204 [(set_attr "type" "arith_media")])
1206 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1207 ;; will sometimes save one instruction. Otherwise we might get
1208 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1211 (define_expand "subsi3"
1212 [(set (match_operand:SI 0 "arith_reg_operand" "")
1213 (minus:SI (match_operand:SI 1 "arith_operand" "")
1214 (match_operand:SI 2 "arith_reg_operand" "")))]
1218 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1220 emit_insn (gen_negsi2 (operands[0], operands[2]));
1221 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1226 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1228 if (operands[1] != const0_rtx)
1229 operands[1] = force_reg (SImode, operands[1]);
1233 ;; -------------------------------------------------------------------------
1234 ;; Division instructions
1235 ;; -------------------------------------------------------------------------
1237 ;; We take advantage of the library routines which don't clobber as many
1238 ;; registers as a normal function call would.
1240 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1241 ;; also has an effect on the register that holds the address of the sfunc.
1242 ;; To make this work, we have an extra dummy insn that shows the use
1243 ;; of this register for reorg.
1245 (define_insn "use_sfunc_addr"
1246 [(set (reg:SI PR_REG)
1247 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1248 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1250 [(set_attr "length" "0")])
1252 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1253 ;; hard register 0. If we used hard register 0, then the next instruction
1254 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1255 ;; gets allocated to a stack slot that needs its address reloaded, then
1256 ;; there is nothing to prevent reload from using r0 to reload the address.
1257 ;; This reload would clobber the value in r0 we are trying to store.
1258 ;; If we let reload allocate r0, then this problem can never happen.
1260 (define_insn "udivsi3_i1"
1261 [(set (match_operand:SI 0 "register_operand" "=z")
1262 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1263 (clobber (reg:SI T_REG))
1264 (clobber (reg:SI PR_REG))
1265 (clobber (reg:SI R4_REG))
1266 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267 "TARGET_SH1 && ! TARGET_SH4"
1269 [(set_attr "type" "sfunc")
1270 (set_attr "needs_delay_slot" "yes")])
1272 ; Since shmedia-nofpu code could be linked against shcompact code, and
1273 ; the udivsi3 libcall has the same name, we must consider all registers
1274 ; clobbered that are in the union of the registers clobbered by the
1275 ; shmedia and the shcompact implementation. Note, if the shcompact
1276 ; implementation actually used shcompact code, we'd need to clobber
1277 ; also r23 and fr23.
1278 (define_insn "udivsi3_i1_media"
1279 [(set (match_operand:SI 0 "register_operand" "=z")
1280 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1281 (clobber (reg:SI T_MEDIA_REG))
1282 (clobber (reg:SI PR_MEDIA_REG))
1283 (clobber (reg:SI R20_REG))
1284 (clobber (reg:SI R21_REG))
1285 (clobber (reg:SI R22_REG))
1286 (clobber (reg:DI TR0_REG))
1287 (clobber (reg:DI TR1_REG))
1288 (clobber (reg:DI TR2_REG))
1289 (use (match_operand:DI 1 "target_operand" "b"))]
1290 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1292 [(set_attr "type" "sfunc")
1293 (set_attr "needs_delay_slot" "yes")])
1295 (define_expand "udivsi3_i4_media"
1297 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1299 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1300 (set (match_dup 5) (float:DF (match_dup 3)))
1301 (set (match_dup 6) (float:DF (match_dup 4)))
1302 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1303 (set (match_dup 8) (fix:DI (match_dup 7)))
1304 (set (match_operand:SI 0 "register_operand" "")
1305 (truncate:SI (match_dup 8)))]
1306 "TARGET_SHMEDIA_FPU"
1309 operands[3] = gen_reg_rtx (DImode);
1310 operands[4] = gen_reg_rtx (DImode);
1311 operands[5] = gen_reg_rtx (DFmode);
1312 operands[6] = gen_reg_rtx (DFmode);
1313 operands[7] = gen_reg_rtx (DFmode);
1314 operands[8] = gen_reg_rtx (DImode);
1317 (define_insn "udivsi3_i4"
1318 [(set (match_operand:SI 0 "register_operand" "=y")
1319 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1320 (clobber (reg:SI T_REG))
1321 (clobber (reg:SI PR_REG))
1322 (clobber (reg:DF DR0_REG))
1323 (clobber (reg:DF DR2_REG))
1324 (clobber (reg:DF DR4_REG))
1325 (clobber (reg:SI R0_REG))
1326 (clobber (reg:SI R1_REG))
1327 (clobber (reg:SI R4_REG))
1328 (clobber (reg:SI R5_REG))
1329 (use (reg:PSI FPSCR_REG))
1330 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1331 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1333 [(set_attr "type" "sfunc")
1334 (set_attr "fp_mode" "double")
1335 (set_attr "needs_delay_slot" "yes")])
1337 (define_insn "udivsi3_i4_single"
1338 [(set (match_operand:SI 0 "register_operand" "=y")
1339 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1340 (clobber (reg:SI T_REG))
1341 (clobber (reg:SI PR_REG))
1342 (clobber (reg:DF DR0_REG))
1343 (clobber (reg:DF DR2_REG))
1344 (clobber (reg:DF DR4_REG))
1345 (clobber (reg:SI R0_REG))
1346 (clobber (reg:SI R1_REG))
1347 (clobber (reg:SI R4_REG))
1348 (clobber (reg:SI R5_REG))
1349 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1352 [(set_attr "type" "sfunc")
1353 (set_attr "needs_delay_slot" "yes")])
1355 (define_expand "udivsi3"
1356 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1357 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1358 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1359 (parallel [(set (match_operand:SI 0 "register_operand" "")
1360 (udiv:SI (reg:SI R4_REG)
1362 (clobber (reg:SI T_REG))
1363 (clobber (reg:SI PR_REG))
1364 (clobber (reg:SI R4_REG))
1365 (use (match_dup 3))])]
1371 operands[3] = gen_reg_rtx (Pmode);
1372 /* Emit the move of the address to a pseudo outside of the libcall. */
1373 if (TARGET_HARD_SH4 && TARGET_SH2E)
1375 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1376 if (TARGET_FPU_SINGLE)
1377 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1379 last = gen_udivsi3_i4 (operands[0], operands[3]);
1381 else if (TARGET_SHMEDIA_FPU)
1383 operands[1] = force_reg (SImode, operands[1]);
1384 operands[2] = force_reg (SImode, operands[2]);
1385 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1388 else if (TARGET_SH5)
1390 emit_move_insn (operands[3],
1391 function_symbol (TARGET_FPU_ANY
1396 last = gen_udivsi3_i1_media (operands[0],
1399 : gen_rtx_SUBREG (DImode, operands[3],
1401 else if (TARGET_FPU_ANY)
1402 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1404 last = gen_udivsi3_i1 (operands[0], operands[3]);
1408 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1409 last = gen_udivsi3_i1 (operands[0], operands[3]);
1411 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1412 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1413 last = emit_insn (last);
1414 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1415 invariant code motion can move it. */
1416 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1417 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1421 (define_insn "divsi3_i1"
1422 [(set (match_operand:SI 0 "register_operand" "=z")
1423 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424 (clobber (reg:SI T_REG))
1425 (clobber (reg:SI PR_REG))
1426 (clobber (reg:SI R1_REG))
1427 (clobber (reg:SI R2_REG))
1428 (clobber (reg:SI R3_REG))
1429 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1430 "TARGET_SH1 && ! TARGET_SH4"
1432 [(set_attr "type" "sfunc")
1433 (set_attr "needs_delay_slot" "yes")])
1435 ; Since shmedia-nofpu code could be linked against shcompact code, and
1436 ; the sdivsi3 libcall has the same name, we must consider all registers
1437 ; clobbered that are in the union of the registers clobbered by the
1438 ; shmedia and the shcompact implementation. Note, if the shcompact
1439 ; implementation actually used shcompact code, we'd need to clobber
1440 ; also r22, r23 and fr23.
1441 (define_insn "divsi3_i1_media"
1442 [(set (match_operand:SI 0 "register_operand" "=z")
1443 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1444 (clobber (reg:SI T_MEDIA_REG))
1445 (clobber (reg:SI PR_MEDIA_REG))
1446 (clobber (reg:SI R1_REG))
1447 (clobber (reg:SI R2_REG))
1448 (clobber (reg:SI R3_REG))
1449 (clobber (reg:SI R20_REG))
1450 (clobber (reg:SI R21_REG))
1451 (clobber (reg:DI TR0_REG))
1452 (clobber (reg:DI TR1_REG))
1453 (clobber (reg:DI TR2_REG))
1454 (use (match_operand:DI 1 "target_operand" "b"))]
1455 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1457 [(set_attr "type" "sfunc")])
1459 (define_expand "divsi3_i4_media"
1460 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1461 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1462 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1463 (set (match_operand:SI 0 "register_operand" "=r")
1464 (fix:SI (match_dup 5)))]
1465 "TARGET_SHMEDIA_FPU"
1468 operands[3] = gen_reg_rtx (DFmode);
1469 operands[4] = gen_reg_rtx (DFmode);
1470 operands[5] = gen_reg_rtx (DFmode);
1473 (define_insn "divsi3_i4"
1474 [(set (match_operand:SI 0 "register_operand" "=y")
1475 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1476 (clobber (reg:SI PR_REG))
1477 (clobber (reg:DF DR0_REG))
1478 (clobber (reg:DF DR2_REG))
1479 (use (reg:PSI FPSCR_REG))
1480 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1483 [(set_attr "type" "sfunc")
1484 (set_attr "fp_mode" "double")
1485 (set_attr "needs_delay_slot" "yes")])
1487 (define_insn "divsi3_i4_single"
1488 [(set (match_operand:SI 0 "register_operand" "=y")
1489 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1490 (clobber (reg:SI PR_REG))
1491 (clobber (reg:DF DR0_REG))
1492 (clobber (reg:DF DR2_REG))
1493 (clobber (reg:SI R2_REG))
1494 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1495 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1497 [(set_attr "type" "sfunc")
1498 (set_attr "needs_delay_slot" "yes")])
1500 (define_expand "divsi3"
1501 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1502 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1503 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1504 (parallel [(set (match_operand:SI 0 "register_operand" "")
1505 (div:SI (reg:SI R4_REG)
1507 (clobber (reg:SI T_REG))
1508 (clobber (reg:SI PR_REG))
1509 (clobber (reg:SI R1_REG))
1510 (clobber (reg:SI R2_REG))
1511 (clobber (reg:SI R3_REG))
1512 (use (match_dup 3))])]
1518 operands[3] = gen_reg_rtx (Pmode);
1519 /* Emit the move of the address to a pseudo outside of the libcall. */
1520 if (TARGET_HARD_SH4 && TARGET_SH2E)
1522 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1523 if (TARGET_FPU_SINGLE)
1524 last = gen_divsi3_i4_single (operands[0], operands[3]);
1526 last = gen_divsi3_i4 (operands[0], operands[3]);
1528 else if (TARGET_SHMEDIA_FPU)
1530 operands[1] = force_reg (SImode, operands[1]);
1531 operands[2] = force_reg (SImode, operands[2]);
1532 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1535 else if (TARGET_SH5)
1537 emit_move_insn (operands[3],
1538 function_symbol (TARGET_FPU_ANY
1543 last = gen_divsi3_i1_media (operands[0],
1546 : gen_rtx_SUBREG (DImode, operands[3],
1548 else if (TARGET_FPU_ANY)
1549 last = gen_divsi3_i4_single (operands[0], operands[3]);
1551 last = gen_divsi3_i1 (operands[0], operands[3]);
1555 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1556 last = gen_divsi3_i1 (operands[0], operands[3]);
1558 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1559 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1560 last = emit_insn (last);
1561 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1562 invariant code motion can move it. */
1563 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1564 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1568 ;; -------------------------------------------------------------------------
1569 ;; Multiplication instructions
1570 ;; -------------------------------------------------------------------------
1572 (define_insn "umulhisi3_i"
1573 [(set (reg:SI MACL_REG)
1574 (mult:SI (zero_extend:SI
1575 (match_operand:HI 0 "arith_reg_operand" "r"))
1577 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1580 [(set_attr "type" "smpy")])
1582 (define_insn "mulhisi3_i"
1583 [(set (reg:SI MACL_REG)
1584 (mult:SI (sign_extend:SI
1585 (match_operand:HI 0 "arith_reg_operand" "r"))
1587 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1590 [(set_attr "type" "smpy")])
1592 (define_expand "mulhisi3"
1593 [(set (reg:SI MACL_REG)
1594 (mult:SI (sign_extend:SI
1595 (match_operand:HI 1 "arith_reg_operand" ""))
1597 (match_operand:HI 2 "arith_reg_operand" ""))))
1598 (set (match_operand:SI 0 "arith_reg_operand" "")
1605 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1606 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1607 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1608 invariant code motion can move it. */
1609 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1610 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1611 /* expand_binop can't find a suitable code in umul_widen_optab to
1612 make a REG_EQUAL note from, so make one here.
1613 See also smulsi3_highpart.
1614 ??? Alternatively, we could put this at the calling site of expand_binop,
1615 i.e. expand_expr. */
1617 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1622 (define_expand "umulhisi3"
1623 [(set (reg:SI MACL_REG)
1624 (mult:SI (zero_extend:SI
1625 (match_operand:HI 1 "arith_reg_operand" ""))
1627 (match_operand:HI 2 "arith_reg_operand" ""))))
1628 (set (match_operand:SI 0 "arith_reg_operand" "")
1635 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1636 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1637 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1638 invariant code motion can move it. */
1639 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1640 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1641 /* expand_binop can't find a suitable code in umul_widen_optab to
1642 make a REG_EQUAL note from, so make one here.
1643 See also smulsi3_highpart.
1644 ??? Alternatively, we could put this at the calling site of expand_binop,
1645 i.e. expand_expr. */
1647 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1652 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1653 ;; a call to a routine which clobbers known registers.
1656 [(set (match_operand:SI 1 "register_operand" "=z")
1657 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1658 (clobber (reg:SI MACL_REG))
1659 (clobber (reg:SI T_REG))
1660 (clobber (reg:SI PR_REG))
1661 (clobber (reg:SI R3_REG))
1662 (clobber (reg:SI R2_REG))
1663 (clobber (reg:SI R1_REG))
1664 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1667 [(set_attr "type" "sfunc")
1668 (set_attr "needs_delay_slot" "yes")])
1670 (define_expand "mulsi3_call"
1671 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1672 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1673 (parallel[(set (match_operand:SI 0 "register_operand" "")
1674 (mult:SI (reg:SI R4_REG)
1676 (clobber (reg:SI MACL_REG))
1677 (clobber (reg:SI T_REG))
1678 (clobber (reg:SI PR_REG))
1679 (clobber (reg:SI R3_REG))
1680 (clobber (reg:SI R2_REG))
1681 (clobber (reg:SI R1_REG))
1682 (use (match_operand:SI 3 "register_operand" ""))])]
1686 (define_insn "mul_l"
1687 [(set (reg:SI MACL_REG)
1688 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1689 (match_operand:SI 1 "arith_reg_operand" "r")))]
1692 [(set_attr "type" "dmpy")])
1694 (define_expand "mulsi3"
1695 [(set (reg:SI MACL_REG)
1696 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1697 (match_operand:SI 2 "arith_reg_operand" "")))
1698 (set (match_operand:SI 0 "arith_reg_operand" "")
1707 /* The address must be set outside the libcall,
1708 since it goes into a pseudo. */
1709 rtx sym = function_symbol (\"__mulsi3\");
1710 rtx addr = force_reg (SImode, sym);
1711 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1714 last = emit_insn (insns);
1718 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1720 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1721 /* consec_sets_giv can only recognize the first insn that sets a
1722 giv as the giv insn. So we must tag this also with a REG_EQUAL
1724 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1726 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1727 invariant code motion can move it. */
1728 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1729 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1733 (define_insn "mulsidi3_i"
1734 [(set (reg:SI MACH_REG)
1738 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1739 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1741 (set (reg:SI MACL_REG)
1742 (mult:SI (match_dup 0)
1746 [(set_attr "type" "dmpy")])
1748 (define_expand "mulsidi3"
1749 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1750 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1751 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1752 "TARGET_SH2 || TARGET_SHMEDIA"
1757 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1763 (define_insn "mulsidi3_media"
1764 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1766 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1769 [(set_attr "type" "dmpy_media")])
1771 (define_insn "mulsidi3_compact"
1772 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1774 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1775 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1776 (clobber (reg:SI MACH_REG))
1777 (clobber (reg:SI MACL_REG))]
1782 [(set (match_operand:DI 0 "arith_reg_operand" "")
1784 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1785 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1786 (clobber (reg:SI MACH_REG))
1787 (clobber (reg:SI MACL_REG))]
1792 rtx low_dst = gen_lowpart (SImode, operands[0]);
1793 rtx high_dst = gen_highpart (SImode, operands[0]);
1795 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1797 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1798 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1799 /* We need something to tag the possible REG_EQUAL notes on to. */
1800 emit_move_insn (operands[0], operands[0]);
1804 (define_insn "umulsidi3_i"
1805 [(set (reg:SI MACH_REG)
1809 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1810 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1812 (set (reg:SI MACL_REG)
1813 (mult:SI (match_dup 0)
1817 [(set_attr "type" "dmpy")])
1819 (define_expand "umulsidi3"
1820 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1821 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1822 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1823 "TARGET_SH2 || TARGET_SHMEDIA"
1828 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1834 (define_insn "umulsidi3_media"
1835 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1836 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1837 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1840 [(set_attr "type" "dmpy_media")])
1842 (define_insn "umulsidi3_compact"
1843 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1845 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1846 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1847 (clobber (reg:SI MACH_REG))
1848 (clobber (reg:SI MACL_REG))]
1853 [(set (match_operand:DI 0 "arith_reg_operand" "")
1854 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1855 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1856 (clobber (reg:SI MACH_REG))
1857 (clobber (reg:SI MACL_REG))]
1862 rtx low_dst = gen_lowpart (SImode, operands[0]);
1863 rtx high_dst = gen_highpart (SImode, operands[0]);
1865 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1867 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1868 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1869 /* We need something to tag the possible REG_EQUAL notes on to. */
1870 emit_move_insn (operands[0], operands[0]);
1874 (define_insn "smulsi3_highpart_i"
1875 [(set (reg:SI MACH_REG)
1879 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1880 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1882 (clobber (reg:SI MACL_REG))]
1885 [(set_attr "type" "dmpy")])
1887 (define_expand "smulsi3_highpart"
1889 [(set (reg:SI MACH_REG)
1893 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1894 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1896 (clobber (reg:SI MACL_REG))])
1897 (set (match_operand:SI 0 "arith_reg_operand" "")
1904 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1905 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1906 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1907 invariant code motion can move it. */
1908 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1909 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1910 /* expand_binop can't find a suitable code in mul_highpart_optab to
1911 make a REG_EQUAL note from, so make one here.
1912 See also {,u}mulhisi.
1913 ??? Alternatively, we could put this at the calling site of expand_binop,
1914 i.e. expand_mult_highpart. */
1916 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1921 (define_insn "umulsi3_highpart_i"
1922 [(set (reg:SI MACH_REG)
1926 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1927 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1929 (clobber (reg:SI MACL_REG))]
1932 [(set_attr "type" "dmpy")])
1934 (define_expand "umulsi3_highpart"
1936 [(set (reg:SI MACH_REG)
1940 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1941 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1943 (clobber (reg:SI MACL_REG))])
1944 (set (match_operand:SI 0 "arith_reg_operand" "")
1951 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1952 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1953 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1954 invariant code motion can move it. */
1955 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1956 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1960 ;; -------------------------------------------------------------------------
1961 ;; Logical operations
1962 ;; -------------------------------------------------------------------------
1964 (define_insn "*andsi3_compact"
1965 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967 (match_operand:SI 2 "logical_operand" "r,K08")))]
1970 [(set_attr "type" "arith")])
1972 ;; If the constant is 255, then emit an extu.b instruction instead of an
1973 ;; and, since that will give better code.
1975 (define_expand "andsi3"
1976 [(set (match_operand:SI 0 "arith_reg_operand" "")
1977 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1978 (match_operand:SI 2 "logical_operand" "")))]
1982 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1984 emit_insn (gen_zero_extendqisi2 (operands[0],
1985 gen_lowpart (QImode, operands[1])));
1990 (define_insn_and_split "anddi3"
1991 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1992 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1993 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
2000 && ! logical_operand (operands[2], DImode)"
2004 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2005 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2007 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2010 [(set_attr "type" "arith_media")])
2012 (define_insn "andcdi3"
2013 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2014 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2015 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2018 [(set_attr "type" "arith_media")])
2020 (define_insn "iorsi3"
2021 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2022 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2023 (match_operand:SI 2 "logical_operand" "r,K08")))]
2026 [(set_attr "type" "arith")])
2028 (define_insn "iordi3"
2029 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2030 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2031 (match_operand:DI 2 "logical_operand" "r,I10")))]
2036 [(set_attr "type" "arith_media")])
2038 (define_insn "xorsi3"
2039 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2040 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2041 (match_operand:SI 2 "logical_operand" "K08,r")))]
2044 [(set_attr "type" "arith")])
2046 (define_insn "xordi3"
2047 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2048 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2049 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2054 [(set_attr "type" "arith_media")])
2056 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2057 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2059 [(set (match_operand:DI 0 "arith_reg_operand" "")
2060 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2061 [(match_operand 1 "any_register_operand" "")
2062 (match_operand 2 "any_register_operand" "")])))]
2064 [(set (match_dup 5) (match_dup 4))
2065 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2068 enum machine_mode inmode = GET_MODE (operands[1]);
2071 if (GET_CODE (operands[0]) == SUBREG)
2073 offset = SUBREG_BYTE (operands[0]);
2074 operands[0] = SUBREG_REG (operands[0]);
2076 if (GET_CODE (operands[0]) != REG)
2078 if (! TARGET_LITTLE_ENDIAN)
2079 offset += 8 - GET_MODE_SIZE (inmode);
2080 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2083 ;; -------------------------------------------------------------------------
2084 ;; Shifts and rotates
2085 ;; -------------------------------------------------------------------------
2087 (define_expand "rotldi3"
2088 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2089 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2090 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2092 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2094 (define_insn "rotldi3_mextr"
2095 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2096 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2097 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2101 static char templ[16];
2103 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2104 8 - (int) (INTVAL (operands[2]) >> 3));
2107 [(set_attr "type" "arith_media")])
2109 (define_expand "rotrdi3"
2110 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2111 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2112 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2114 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2116 (define_insn "rotrdi3_mextr"
2117 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2118 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2119 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2123 static char templ[16];
2125 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2128 [(set_attr "type" "arith_media")])
2130 (define_insn "rotlsi3_1"
2131 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2135 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2138 [(set_attr "type" "arith")])
2140 (define_insn "rotlsi3_31"
2141 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2142 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2144 (clobber (reg:SI T_REG))]
2147 [(set_attr "type" "arith")])
2149 (define_insn "rotlsi3_16"
2150 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2151 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2155 [(set_attr "type" "arith")])
2157 (define_expand "rotlsi3"
2158 [(set (match_operand:SI 0 "arith_reg_operand" "")
2159 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2160 (match_operand:SI 2 "immediate_operand" "")))]
2164 static const char rot_tab[] = {
2165 000, 000, 000, 000, 000, 000, 010, 001,
2166 001, 001, 011, 013, 003, 003, 003, 003,
2167 003, 003, 003, 003, 003, 013, 012, 002,
2168 002, 002, 010, 000, 000, 000, 000, 000,
2173 if (GET_CODE (operands[2]) != CONST_INT)
2175 count = INTVAL (operands[2]);
2176 choice = rot_tab[count];
2177 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2183 emit_move_insn (operands[0], operands[1]);
2184 count -= (count & 16) * 2;
2187 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2194 parts[0] = gen_reg_rtx (SImode);
2195 parts[1] = gen_reg_rtx (SImode);
2196 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2197 emit_move_insn (parts[choice-1], operands[1]);
2198 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2199 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2200 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2201 count = (count & ~16) - 8;
2205 for (; count > 0; count--)
2206 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2207 for (; count < 0; count++)
2208 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2213 (define_insn "*rotlhi3_8"
2214 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2215 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2219 [(set_attr "type" "arith")])
2221 (define_expand "rotlhi3"
2222 [(set (match_operand:HI 0 "arith_reg_operand" "")
2223 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2224 (match_operand:HI 2 "immediate_operand" "")))]
2228 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2235 ;; This pattern is used by init_expmed for computing the costs of shift
2238 (define_insn_and_split "ashlsi3_std"
2239 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2240 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2241 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2242 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2244 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2245 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2253 && GET_CODE (operands[2]) == CONST_INT
2254 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2255 [(set (match_dup 3) (match_dup 2))
2257 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2258 (clobber (match_dup 4))])]
2259 "operands[4] = gen_rtx_SCRATCH (SImode);"
2260 [(set_attr "length" "*,*,*,4")
2261 (set_attr "type" "dyn_shift,arith,arith,arith")])
2263 (define_insn "ashlhi3_k"
2264 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2265 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2266 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2267 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2271 [(set_attr "type" "arith")])
2273 (define_insn "ashlsi3_n"
2274 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2275 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2276 (match_operand:SI 2 "const_int_operand" "n")))
2277 (clobber (reg:SI T_REG))]
2278 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2280 [(set (attr "length")
2281 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2283 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2285 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2287 (const_string "8")))
2288 (set_attr "type" "arith")])
2291 [(set (match_operand:SI 0 "arith_reg_operand" "")
2292 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2293 (match_operand:SI 2 "const_int_operand" "")))
2294 (clobber (reg:SI T_REG))]
2295 "TARGET_SH1 && reload_completed"
2296 [(use (reg:SI R0_REG))]
2299 gen_shifty_op (ASHIFT, operands);
2303 (define_insn "ashlsi3_media"
2304 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2305 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2306 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2311 [(set_attr "type" "arith_media")])
2313 (define_expand "ashlsi3"
2314 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2315 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2316 (match_operand:SI 2 "nonmemory_operand" "")))
2317 (clobber (reg:SI T_REG))])]
2323 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2326 if (GET_CODE (operands[2]) == CONST_INT
2327 && sh_dynamicalize_shift_p (operands[2]))
2328 operands[2] = force_reg (SImode, operands[2]);
2331 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2334 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2338 (define_insn "ashlhi3"
2339 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2340 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2341 (match_operand:HI 2 "const_int_operand" "n")))
2342 (clobber (reg:SI T_REG))]
2345 [(set (attr "length")
2346 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2348 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2350 (const_string "6")))
2351 (set_attr "type" "arith")])
2354 [(set (match_operand:HI 0 "arith_reg_operand" "")
2355 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2356 (match_operand:HI 2 "const_int_operand" "")))
2357 (clobber (reg:SI T_REG))]
2358 "TARGET_SH1 && reload_completed"
2359 [(use (reg:SI R0_REG))]
2362 gen_shifty_hi_op (ASHIFT, operands);
2367 ; arithmetic shift right
2370 (define_insn "ashrsi3_k"
2371 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2372 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2373 (match_operand:SI 2 "const_int_operand" "M")))
2374 (clobber (reg:SI T_REG))]
2375 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2377 [(set_attr "type" "arith")])
2379 ;; We can't do HImode right shifts correctly unless we start out with an
2380 ;; explicit zero / sign extension; doing that would result in worse overall
2381 ;; code, so just let the machine independent code widen the mode.
2382 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2385 ;; ??? This should be a define expand.
2387 (define_insn "ashrsi2_16"
2388 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2393 [(set_attr "length" "4")])
2396 [(set (match_operand:SI 0 "arith_reg_operand" "")
2397 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2400 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2401 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2402 "operands[2] = gen_lowpart (HImode, operands[0]);")
2404 ;; ??? This should be a define expand.
2406 (define_insn "ashrsi2_31"
2407 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2408 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2410 (clobber (reg:SI T_REG))]
2413 [(set_attr "length" "4")])
2416 [(set (match_operand:SI 0 "arith_reg_operand" "")
2417 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2419 (clobber (reg:SI T_REG))]
2424 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2425 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2429 (define_insn "ashlsi_c"
2430 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2431 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2433 (lt:SI (match_dup 1) (const_int 0)))]
2436 [(set_attr "type" "arith")])
2438 (define_insn "ashrsi3_d"
2439 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2440 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2441 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2444 [(set_attr "type" "dyn_shift")])
2446 (define_insn "ashrsi3_n"
2447 [(set (reg:SI R4_REG)
2448 (ashiftrt:SI (reg:SI R4_REG)
2449 (match_operand:SI 0 "const_int_operand" "i")))
2450 (clobber (reg:SI T_REG))
2451 (clobber (reg:SI PR_REG))
2452 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2455 [(set_attr "type" "sfunc")
2456 (set_attr "needs_delay_slot" "yes")])
2458 (define_insn "ashrsi3_media"
2459 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2460 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2461 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2466 [(set_attr "type" "arith_media")])
2468 (define_expand "ashrsi3"
2469 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2470 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2471 (match_operand:SI 2 "nonmemory_operand" "")))
2472 (clobber (reg:SI T_REG))])]
2478 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2481 if (expand_ashiftrt (operands))
2487 ;; logical shift right
2489 (define_insn "lshrsi3_d"
2490 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2495 [(set_attr "type" "dyn_shift")])
2497 ;; Only the single bit shift clobbers the T bit.
2499 (define_insn "lshrsi3_m"
2500 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2501 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2502 (match_operand:SI 2 "const_int_operand" "M")))
2503 (clobber (reg:SI T_REG))]
2504 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2506 [(set_attr "type" "arith")])
2508 (define_insn "lshrsi3_k"
2509 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2510 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2511 (match_operand:SI 2 "const_int_operand" "P27")))]
2512 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2513 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2515 [(set_attr "type" "arith")])
2517 (define_insn "lshrsi3_n"
2518 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2519 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2520 (match_operand:SI 2 "const_int_operand" "n")))
2521 (clobber (reg:SI T_REG))]
2522 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2524 [(set (attr "length")
2525 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2527 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2529 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2531 (const_string "8")))
2532 (set_attr "type" "arith")])
2535 [(set (match_operand:SI 0 "arith_reg_operand" "")
2536 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2537 (match_operand:SI 2 "const_int_operand" "")))
2538 (clobber (reg:SI T_REG))]
2539 "TARGET_SH1 && reload_completed"
2540 [(use (reg:SI R0_REG))]
2543 gen_shifty_op (LSHIFTRT, operands);
2547 (define_insn "lshrsi3_media"
2548 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2549 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2550 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2555 [(set_attr "type" "arith_media")])
2557 (define_expand "lshrsi3"
2558 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2559 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2560 (match_operand:SI 2 "nonmemory_operand" "")))
2561 (clobber (reg:SI T_REG))])]
2567 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2570 if (GET_CODE (operands[2]) == CONST_INT
2571 && sh_dynamicalize_shift_p (operands[2]))
2572 operands[2] = force_reg (SImode, operands[2]);
2573 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2575 rtx count = copy_to_mode_reg (SImode, operands[2]);
2576 emit_insn (gen_negsi2 (count, count));
2577 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2580 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2584 ;; ??? This should be a define expand.
2586 (define_insn "ashldi3_k"
2587 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2588 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2590 (clobber (reg:SI T_REG))]
2592 "shll %R0\;rotcl %S0"
2593 [(set_attr "length" "4")
2594 (set_attr "type" "arith")])
2596 (define_insn "ashldi3_media"
2597 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2598 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2599 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2604 [(set_attr "type" "arith_media")])
2606 (define_expand "ashldi3"
2607 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2608 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2609 (match_operand:DI 2 "immediate_operand" "")))
2610 (clobber (reg:SI T_REG))])]
2616 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2619 if (GET_CODE (operands[2]) != CONST_INT
2620 || INTVAL (operands[2]) != 1)
2624 ;; ??? This should be a define expand.
2626 (define_insn "lshrdi3_k"
2627 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2628 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2630 (clobber (reg:SI T_REG))]
2632 "shlr %S0\;rotcr %R0"
2633 [(set_attr "length" "4")
2634 (set_attr "type" "arith")])
2636 (define_insn "lshrdi3_media"
2637 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2638 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2639 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2644 [(set_attr "type" "arith_media")])
2646 (define_expand "lshrdi3"
2647 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2648 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2649 (match_operand:DI 2 "immediate_operand" "")))
2650 (clobber (reg:SI T_REG))])]
2656 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2659 if (GET_CODE (operands[2]) != CONST_INT
2660 || INTVAL (operands[2]) != 1)
2664 ;; ??? This should be a define expand.
2666 (define_insn "ashrdi3_k"
2667 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2668 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2670 (clobber (reg:SI T_REG))]
2672 "shar %S0\;rotcr %R0"
2673 [(set_attr "length" "4")
2674 (set_attr "type" "arith")])
2676 (define_insn "ashrdi3_media"
2677 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2678 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2679 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2684 [(set_attr "type" "arith_media")])
2686 (define_expand "ashrdi3"
2687 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2688 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2689 (match_operand:DI 2 "immediate_operand" "")))
2690 (clobber (reg:SI T_REG))])]
2696 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2699 if (GET_CODE (operands[2]) != CONST_INT
2700 || INTVAL (operands[2]) != 1)
2704 ;; combined left/right shift
2707 [(set (match_operand:SI 0 "register_operand" "")
2708 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2709 (match_operand:SI 2 "const_int_operand" ""))
2710 (match_operand:SI 3 "const_int_operand" "")))]
2711 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2712 [(use (reg:SI R0_REG))]
2713 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2717 [(set (match_operand:SI 0 "register_operand" "")
2718 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2719 (match_operand:SI 2 "const_int_operand" ""))
2720 (match_operand:SI 3 "const_int_operand" "")))
2721 (clobber (reg:SI T_REG))]
2722 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2723 [(use (reg:SI R0_REG))]
2724 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2728 [(set (match_operand:SI 0 "register_operand" "=r")
2729 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730 (match_operand:SI 2 "const_int_operand" "n"))
2731 (match_operand:SI 3 "const_int_operand" "n")))
2732 (clobber (reg:SI T_REG))]
2733 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2735 [(set (attr "length")
2736 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2738 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2740 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2742 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2744 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2746 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2748 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2749 (const_string "16")]
2750 (const_string "18")))
2751 (set_attr "type" "arith")])
2754 [(set (match_operand:SI 0 "register_operand" "=z")
2755 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2756 (match_operand:SI 2 "const_int_operand" "n"))
2757 (match_operand:SI 3 "const_int_operand" "n")))
2758 (clobber (reg:SI T_REG))]
2759 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2761 [(set (attr "length")
2762 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2764 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2766 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2768 (const_string "10")))
2769 (set_attr "type" "arith")])
2771 ;; shift left / and combination with a scratch register: The combine pass
2772 ;; does not accept the individual instructions, even though they are
2773 ;; cheap. But it needs a precise description so that it is usable after
2775 (define_insn "and_shl_scratch"
2776 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2780 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2781 (match_operand:SI 2 "const_int_operand" "N,n"))
2782 (match_operand:SI 3 "" "0,r"))
2783 (match_operand:SI 4 "const_int_operand" "n,n"))
2784 (match_operand:SI 5 "const_int_operand" "n,n")))
2785 (clobber (reg:SI T_REG))]
2788 [(set (attr "length")
2789 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2791 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2793 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2795 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2796 (const_string "10")]
2797 (const_string "12")))
2798 (set_attr "type" "arith")])
2801 [(set (match_operand:SI 0 "register_operand" "")
2805 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2806 (match_operand:SI 2 "const_int_operand" ""))
2807 (match_operand:SI 3 "register_operand" ""))
2808 (match_operand:SI 4 "const_int_operand" ""))
2809 (match_operand:SI 5 "const_int_operand" "")))
2810 (clobber (reg:SI T_REG))]
2812 [(use (reg:SI R0_REG))]
2815 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2817 if (INTVAL (operands[2]))
2819 gen_shifty_op (LSHIFTRT, operands);
2821 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2822 operands[2] = operands[4];
2823 gen_shifty_op (ASHIFT, operands);
2824 if (INTVAL (operands[5]))
2826 operands[2] = operands[5];
2827 gen_shifty_op (LSHIFTRT, operands);
2832 ;; signed left/right shift combination.
2834 [(set (match_operand:SI 0 "register_operand" "")
2836 (ashift:SI (match_operand:SI 1 "register_operand" "")
2837 (match_operand:SI 2 "const_int_operand" ""))
2838 (match_operand:SI 3 "const_int_operand" "")
2840 (clobber (reg:SI T_REG))]
2842 [(use (reg:SI R0_REG))]
2843 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2846 (define_insn "shl_sext_ext"
2847 [(set (match_operand:SI 0 "register_operand" "=r")
2849 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2850 (match_operand:SI 2 "const_int_operand" "n"))
2851 (match_operand:SI 3 "const_int_operand" "n")
2853 (clobber (reg:SI T_REG))]
2854 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2856 [(set (attr "length")
2857 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2859 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2861 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2863 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2865 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2867 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2869 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2871 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2872 (const_string "16")]
2873 (const_string "18")))
2874 (set_attr "type" "arith")])
2876 (define_insn "shl_sext_sub"
2877 [(set (match_operand:SI 0 "register_operand" "=z")
2879 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2880 (match_operand:SI 2 "const_int_operand" "n"))
2881 (match_operand:SI 3 "const_int_operand" "n")
2883 (clobber (reg:SI T_REG))]
2884 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2886 [(set (attr "length")
2887 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2889 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2891 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2893 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2894 (const_string "12")]
2895 (const_string "14")))
2896 (set_attr "type" "arith")])
2898 ;; These patterns are found in expansions of DImode shifts by 16, and
2899 ;; allow the xtrct instruction to be generated from C source.
2901 (define_insn "xtrct_left"
2902 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2905 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2909 [(set_attr "type" "arith")])
2911 (define_insn "xtrct_right"
2912 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2915 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2919 [(set_attr "type" "arith")])
2921 ;; -------------------------------------------------------------------------
2923 ;; -------------------------------------------------------------------------
2926 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2927 (neg:SI (plus:SI (reg:SI T_REG)
2928 (match_operand:SI 1 "arith_reg_operand" "r"))))
2930 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2934 [(set_attr "type" "arith")])
2936 (define_insn "*negdi_media"
2937 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2938 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2941 [(set_attr "type" "arith_media")])
2943 (define_expand "negdi2"
2944 [(set (match_operand:DI 0 "arith_reg_operand" "")
2945 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2951 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2952 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2954 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2955 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2957 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2958 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2960 emit_insn (gen_clrt ());
2961 emit_insn (gen_negc (low_dst, low_src));
2962 emit_insn (gen_negc (high_dst, high_src));
2967 (define_insn "negsi2"
2968 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2969 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2972 [(set_attr "type" "arith")])
2974 (define_insn "one_cmplsi2"
2975 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2979 [(set_attr "type" "arith")])
2981 (define_expand "one_cmpldi2"
2982 [(set (match_operand:DI 0 "arith_reg_operand" "")
2983 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2985 "TARGET_SHMEDIA" "")
2987 ;; -------------------------------------------------------------------------
2988 ;; Zero extension instructions
2989 ;; -------------------------------------------------------------------------
2991 (define_insn "zero_extendsidi2"
2992 [(set (match_operand:DI 0 "register_operand" "=r")
2993 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2995 "addz.l %1, r63, %0"
2996 [(set_attr "type" "arith_media")])
2998 (define_insn "zero_extendhidi2"
2999 [(set (match_operand:DI 0 "register_operand" "=r,r")
3000 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3005 [(set_attr "type" "*,load_media")])
3008 [(set (match_operand:DI 0 "register_operand" "")
3009 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3010 "TARGET_SHMEDIA && reload_completed"
3011 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3012 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3015 if (GET_CODE (operands[1]) == TRUNCATE)
3016 operands[1] = XEXP (operands[1], 0);
3019 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3020 ;; reload the entire truncate expression.
3021 (define_insn_and_split "*loaddi_trunc"
3022 [(set (match_operand 0 "int_gpr_dest" "=r")
3023 (truncate (match_operand:DI 1 "memory_operand" "m")))]
3024 "TARGET_SHMEDIA && reload_completed"
3026 "TARGET_SHMEDIA && reload_completed"
3027 [(set (match_dup 0) (match_dup 1))]
3028 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3030 (define_insn "zero_extendqidi2"
3031 [(set (match_operand:DI 0 "register_operand" "=r,r")
3032 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3037 [(set_attr "type" "arith_media,load_media")])
3039 (define_expand "zero_extendhisi2"
3040 [(set (match_operand:SI 0 "arith_reg_operand" "")
3041 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3045 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3046 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3049 (define_insn "*zero_extendhisi2_compact"
3050 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3051 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3054 [(set_attr "type" "arith")])
3056 (define_insn "*zero_extendhisi2_media"
3057 [(set (match_operand:SI 0 "register_operand" "=r,r")
3058 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3063 [(set_attr "type" "arith_media,load_media")])
3066 [(set (match_operand:SI 0 "register_operand" "")
3067 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3068 "TARGET_SHMEDIA && reload_completed"
3069 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3070 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3073 if (GET_CODE (operands[1]) == TRUNCATE)
3074 operands[1] = XEXP (operands[1], 0);
3077 (define_expand "zero_extendqisi2"
3078 [(set (match_operand:SI 0 "arith_reg_operand" "")
3079 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3083 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3084 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3087 (define_insn "*zero_extendqisi2_compact"
3088 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3089 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3092 [(set_attr "type" "arith")])
3094 (define_insn "*zero_extendqisi2_media"
3095 [(set (match_operand:SI 0 "register_operand" "=r,r")
3096 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3101 [(set_attr "type" "arith_media,load_media")])
3103 (define_insn "zero_extendqihi2"
3104 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3105 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3108 [(set_attr "type" "arith")])
3110 ;; -------------------------------------------------------------------------
3111 ;; Sign extension instructions
3112 ;; -------------------------------------------------------------------------
3114 ;; ??? This should be a define expand.
3115 ;; ??? Or perhaps it should be dropped?
3117 ;; convert_move generates good code for SH[1-4].
3118 (define_insn "extendsidi2"
3119 [(set (match_operand:DI 0 "register_operand" "=r,r")
3120 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3125 [(set_attr "type" "arith_media,load_media")])
3127 (define_insn "extendhidi2"
3128 [(set (match_operand:DI 0 "register_operand" "=r,r")
3129 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3134 [(set_attr "type" "*,load_media")])
3137 [(set (match_operand:DI 0 "register_operand" "")
3138 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3139 "TARGET_SHMEDIA && reload_completed"
3140 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3141 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3144 if (GET_CODE (operands[1]) == TRUNCATE)
3145 operands[1] = XEXP (operands[1], 0);
3148 (define_insn "extendqidi2"
3149 [(set (match_operand:DI 0 "register_operand" "=r,r")
3150 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3155 [(set_attr "type" "*,load_media")])
3158 [(set (match_operand:DI 0 "register_operand" "")
3159 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3160 "TARGET_SHMEDIA && reload_completed"
3161 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3162 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3165 if (GET_CODE (operands[1]) == TRUNCATE)
3166 operands[1] = XEXP (operands[1], 0);
3169 (define_expand "extendhisi2"
3170 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3171 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3175 (define_insn "*extendhisi2_compact"
3176 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3177 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3182 [(set_attr "type" "arith,load")])
3184 (define_insn "*extendhisi2_media"
3185 [(set (match_operand:SI 0 "register_operand" "=r,r")
3186 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3191 [(set_attr "type" "arith_media,load_media")])
3194 [(set (match_operand:SI 0 "register_operand" "")
3195 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3196 "TARGET_SHMEDIA && reload_completed"
3197 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3198 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3201 if (GET_CODE (operands[1]) == TRUNCATE)
3202 operands[1] = XEXP (operands[1], 0);
3205 (define_expand "extendqisi2"
3206 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3207 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3211 (define_insn "*extendqisi2_compact"
3212 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3213 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3218 [(set_attr "type" "arith,load")])
3220 (define_insn "*extendqisi2_media"
3221 [(set (match_operand:SI 0 "register_operand" "=r,r")
3222 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3227 [(set_attr "type" "arith_media,load_media")])
3230 [(set (match_operand:SI 0 "register_operand" "")
3231 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3232 "TARGET_SHMEDIA && reload_completed"
3233 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3234 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3237 if (GET_CODE (operands[1]) == TRUNCATE)
3238 operands[1] = XEXP (operands[1], 0);
3241 (define_insn "extendqihi2"
3242 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3243 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3248 [(set_attr "type" "arith,load")])
3250 /* It would seem useful to combine the truncXi patterns into the movXi
3251 patterns, but unary operators are ignored when matching constraints,
3252 so we need separate patterns. */
3253 (define_insn "truncdisi2"
3254 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3255 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3264 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3267 (define_insn "truncdihi2"
3268 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3269 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3272 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3274 [(set_attr "type" "arith_media,store_media")
3275 (set_attr "length" "8,4")])
3277 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3278 ; Because we use zero extension, we can't provide signed QImode compares
3279 ; using a simple compare or conditional banch insn.
3280 (define_insn "truncdiqi2"
3281 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3282 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3287 [(set_attr "type" "arith_media,store")])
3289 ;; -------------------------------------------------------------------------
3290 ;; Move instructions
3291 ;; -------------------------------------------------------------------------
3293 ;; define push and pop so it is easy for sh.c
3294 ;; We can't use push and pop on SHcompact because the stack must always
3295 ;; be 8-byte aligned.
3297 (define_expand "push"
3298 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3299 (match_operand:SI 0 "register_operand" "r,l,x"))]
3300 "TARGET_SH1 && ! TARGET_SH5"
3303 (define_expand "pop"
3304 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3305 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3306 "TARGET_SH1 && ! TARGET_SH5"
3309 (define_expand "push_e"
3310 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3311 (match_operand:SF 0 "" ""))
3312 (use (reg:PSI FPSCR_REG))
3313 (clobber (scratch:SI))])]
3314 "TARGET_SH1 && ! TARGET_SH5"
3317 (define_insn "push_fpul"
3318 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3319 "TARGET_SH2E && ! TARGET_SH5"
3321 [(set_attr "type" "store")
3322 (set_attr "late_fp_use" "yes")
3323 (set_attr "hit_stack" "yes")])
3325 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3327 (define_expand "push_4"
3328 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3329 (match_operand:DF 0 "" ""))
3330 (use (reg:PSI FPSCR_REG))
3331 (clobber (scratch:SI))])]
3332 "TARGET_SH1 && ! TARGET_SH5"
3335 (define_expand "pop_e"
3336 [(parallel [(set (match_operand:SF 0 "" "")
3337 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3338 (use (reg:PSI FPSCR_REG))
3339 (clobber (scratch:SI))])]
3340 "TARGET_SH1 && ! TARGET_SH5"
3343 (define_insn "pop_fpul"
3344 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3345 "TARGET_SH2E && ! TARGET_SH5"
3347 [(set_attr "type" "load")
3348 (set_attr "hit_stack" "yes")])
3350 (define_expand "pop_4"
3351 [(parallel [(set (match_operand:DF 0 "" "")
3352 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3353 (use (reg:PSI FPSCR_REG))
3354 (clobber (scratch:SI))])]
3355 "TARGET_SH1 && ! TARGET_SH5"
3358 (define_expand "push_fpscr"
3363 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3364 gen_rtx_PRE_DEC (Pmode,
3365 stack_pointer_rtx)),
3367 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3371 (define_expand "pop_fpscr"
3376 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3377 gen_rtx_MEM (PSImode,
3378 gen_rtx_POST_INC (Pmode,
3379 stack_pointer_rtx))));
3380 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3384 ;; These two patterns can happen as the result of optimization, when
3385 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3386 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3389 [(set (reg:SI T_REG) (const_int 0))]
3394 [(set (reg:SI T_REG) (const_int 1))]
3398 ;; t/r must come after r/r, lest reload will try to reload stuff like
3399 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3400 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3401 (define_insn "movsi_i"
3402 [(set (match_operand:SI 0 "general_movdst_operand"
3403 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3404 (match_operand:SI 1 "general_movsrc_operand"
3405 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3408 && (register_operand (operands[0], SImode)
3409 || register_operand (operands[1], SImode))"
3426 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3427 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3429 ;; t/r must come after r/r, lest reload will try to reload stuff like
3430 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3431 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3432 ;; will require a reload.
3433 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3434 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3435 (define_insn "movsi_ie"
3436 [(set (match_operand:SI 0 "general_movdst_operand"
3437 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3438 (match_operand:SI 1 "general_movsrc_operand"
3439 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3441 && (register_operand (operands[0], SImode)
3442 || register_operand (operands[1], SImode))"