1;;- Machine description for the Hitachi SH.
2;;  Copyright (C) 1993 - 1999 Free Software Foundation, Inc.
3;;  Contributed by Steve Chamberlain (sac@cygnus.com).
4;;  Improved by Jim Wilson (wilson@cygnus.com).
5
6;; This file is part of GNU CC.
7
8;; GNU CC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
11;; any later version.
12
13;; GNU CC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with GNU CC; see the file COPYING.  If not, write to
20;; the Free Software Foundation, 59 Temple Place - Suite 330,
21;; Boston, MA 02111-1307, USA.
22
23
24;; ??? Should prepend a * to all pattern names which are not used.
25;; This will make the compiler smaller, and rebuilds after changes faster.
26
27;; ??? Should be enhanced to include support for many more GNU superoptimizer
28;; sequences.  Especially the sequences for arithmetic right shifts.
29
30;; ??? Should check all DImode patterns for consistency and usefulness.
31
32;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33;; way to generate them.
34
35;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36;; for a str* inline function.
37
38;; BSR is not generated by the compiler proper, but when relaxing, it
39;; generates .uses pseudo-ops that allow linker relaxation to create
40;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
42;; Special constraints for SH machine description:
43;;
44;;    t -- T
45;;    x -- mac
46;;    l -- pr
47;;    z -- r0
48;;
49;; Special formats used for outputting SH instructions:
50;;
51;;   %.  --  print a .s if insn needs delay slot
52;;   %@  --  print rte/rts if is/isn't an interrupt function
53;;   %#  --  output a nop if there is nothing to put in the delay slot
54;;   %O  --  print a constant without the #
55;;   %R  --  print the lsw reg of a double
56;;   %S  --  print the msw reg of a double
57;;   %T  --  print next word of a double REG or MEM
58;;
59;; Special predicates:
60;;
61;;  arith_operand          -- operand is valid source for arithmetic op
62;;  arith_reg_operand      -- operand is valid register for arithmetic op
63;;  general_movdst_operand -- operand is valid move destination
64;;  general_movsrc_operand -- operand is valid move source
65;;  logical_operand        -- operand is valid source for logical op
66;; -------------------------------------------------------------------------
67;; Attributes
68;; -------------------------------------------------------------------------
69
70;; Target CPU.
71
72(define_attr "cpu"
73 "sh1,sh2,sh3,sh3e,sh4"
74  (const (symbol_ref "sh_cpu_attr")))
75
76(define_attr "endian" "big,little"
77 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
78		      (const_string "little") (const_string "big"))))
79
80(define_attr "fmovd" "yes,no"
81  (const (if_then_else (symbol_ref "TARGET_FMOVD")
82		       (const_string "yes") (const_string "no"))))
83;; issues/clock
84(define_attr "issues" "1,2"
85  (const (if_then_else (symbol_ref "TARGET_SUPERSCALAR") (const_string "2") (const_string "1"))))
86
87;; cbranch	conditional branch instructions
88;; jump		unconditional jumps
89;; arith	ordinary arithmetic
90;; arith3	a compound insn that behaves similarly to a sequence of
91;;		three insns of type arith
92;; arith3b	like above, but might end with a redirected branch
93;; load		from memory
94;; load_si	Likewise, SImode variant for general register.
95;; store	to memory
96;; move		register to register
97;; fmove	register to register, floating point
98;; smpy		word precision integer multiply
99;; dmpy		longword or doublelongword precision integer multiply
100;; return	rts
101;; pload	load of pr reg, which can't be put into delay slot of rts
102;; pstore	store of pr reg, which can't be put into delay slot of jsr
103;; pcload	pc relative load of constant value
104;; pcload_si	Likewise, SImode variant for general register.
105;; rte		return from exception
106;; sfunc	special function call with known used registers
107;; call		function call
108;; fp		floating point
109;; fdiv		floating point divide (or square root)
110;; gp_fpul	move between general purpose register and fpul
111;; dfp_arith, dfp_cmp,dfp_conv
112;; dfdiv	double precision floating point divide (or square root)
113;; nil		no-op move, will be deleted.
114
115(define_attr "type"
116 "cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,other,load,load_si,store,move,fmove,smpy,dmpy,return,pload,pstore,pcload,pcload_si,rte,sfunc,call,fp,fdiv,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,nil"
117  (const_string "other"))
118
119; If a conditional branch destination is within -252..258 bytes away
120; from the instruction it can be 2 bytes long.  Something in the
121; range -4090..4100 bytes can be 6 bytes long.  All other conditional
122; branches are initially assumed to be 16 bytes long.
123; In machine_dependent_reorg, we split all branches that are longer than
124; 2 bytes.
125
126;; The maximum range used for SImode constant pool entrys is 1018.  A final
127;; instruction can add 8 bytes while only being 4 bytes in size, thus we
128;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
129;; instruction around the pool table, 2 bytes of alignment before the table,
130;; and 30 bytes of alignment after the table.  That gives a maximum total
131;; pool size of 1058 bytes.
132;; Worst case code/pool content size ratio is 1:2 (using asms).
133;; Thus, in the worst case, there is one instruction in front of a maximum
134;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
135;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
136;; If we have a forward branch, the initial table will be put after the
137;; unconditional branch.
138;;
139;; ??? We could do much better by keeping track of the actual pcloads within
140;; the branch range and in the pcload range in front of the branch range.
141
142;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
143;; inside an le.
144(define_attr "short_cbranch_p" "no,yes"
145  (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
146	 (const_string "no")
147	 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
148	 (const_string "yes")
149	 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
150	 (const_string "no")
151	 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
152	 (const_string "yes")
153         ] (const_string "no")))
154
155(define_attr "med_branch_p" "no,yes"
156  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
157	      (const_int 1988))
158	 (const_string "yes")
159	 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
160	 (const_string "no")
161	 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
162	      (const_int 8186))
163	 (const_string "yes")
164	 ] (const_string "no")))
165
166(define_attr "med_cbranch_p" "no,yes"
167  (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
168	      (const_int 1986))
169	 (const_string "yes")
170	 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
171	 (const_string "no")
172	 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
173	       (const_int 8184))
174	 (const_string "yes")
175	 ] (const_string "no")))
176
177(define_attr "braf_branch_p" "no,yes"
178  (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
179	 (const_string "no")
180	 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
181	      (const_int 20660))
182	 (const_string "yes")
183	 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
184	 (const_string "no")
185	 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
186	      (const_int 65530))
187	 (const_string "yes")
188	 ] (const_string "no")))
189
190(define_attr "braf_cbranch_p" "no,yes"
191  (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
192	 (const_string "no")
193	 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
194	      (const_int 20658))
195	 (const_string "yes")
196	 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
197	 (const_string "no")
198	 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
199	      (const_int 65528))
200	 (const_string "yes")
201	 ] (const_string "no")))
202
203; An unconditional jump in the range -4092..4098 can be 2 bytes long.
204; For wider ranges, we need a combination of a code and a data part.
205; If we can get a scratch register for a long range jump, the code
206; part can be 4 bytes long; otherwise, it must be 8 bytes long.
207; If the jump is in the range -32764..32770, the data part can be 2 bytes
208; long; otherwise, it must be 6 bytes long.
209
210; All other instructions are two bytes long by default.
211
212;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
213;; but getattrtab doesn't understand this.
214(define_attr "length" ""
215  (cond [(eq_attr "type" "cbranch")
216	 (cond [(eq_attr "short_cbranch_p" "yes")
217		(const_int 2)
218		(eq_attr "med_cbranch_p" "yes")
219		(const_int 6)
220		(eq_attr "braf_cbranch_p" "yes")
221		(const_int 12)
222;; ??? using pc is not computed transitively.
223		(ne (match_dup 0) (match_dup 0))
224		(const_int 14)
225		] (const_int 16))
226	 (eq_attr "type" "jump")
227	 (cond [(eq_attr "med_branch_p" "yes")
228		(const_int 2)
229		(and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
230			 (symbol_ref "INSN"))
231		     (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
232			 (symbol_ref "code_for_indirect_jump_scratch")))
233		(if_then_else (eq_attr "braf_branch_p" "yes")
234			      (const_int 6)
235			      (const_int 10))
236		(eq_attr "braf_branch_p" "yes")
237		(const_int 10)
238;; ??? using pc is not computed transitively.
239		(ne (match_dup 0) (match_dup 0))
240		(const_int 12)
241		] (const_int 14))
242	 ] (const_int 2)))
243
244;; (define_function_unit {name} {num-units} {n-users} {test}
245;;                       {ready-delay} {issue-delay} [{conflict-list}])
246
247;; Load and store instructions save a cycle if they are aligned on a
248;; four byte boundary.  Using a function unit for stores encourages
249;; gcc to separate load and store instructions by one instruction,
250;; which makes it more likely that the linker will be able to word
251;; align them when relaxing.
252
253;; Loads have a latency of two.
254;; However, call insns can have a delay slot, so that we want one more
255;; insn to be scheduled between the load of the function address and the call.
256;; This is equivalent to a latency of three.
257;; We cannot use a conflict list for this, because we need to distinguish
258;; between the actual call address and the function arguments.
259;; ADJUST_COST can only properly handle reductions of the cost, so we
260;; use a latency of three here.
261;; We only do this for SImode loads of general registers, to make the work
262;; for ADJUST_COST easier.
263(define_function_unit "memory" 1 0
264  (and (eq_attr "issues" "1")
265       (eq_attr "type" "load_si,pcload_si"))
266  3 2)
267(define_function_unit "memory" 1 0
268  (and (eq_attr "issues" "1")
269       (eq_attr "type" "load,pcload,pload,store,pstore"))
270  2 2)
271
272(define_function_unit "int"    1 0
273  (and (eq_attr "issues" "1") (eq_attr "type" "arith3,arith3b")) 3 3)
274
275(define_function_unit "int"    1 0
276  (and (eq_attr "issues" "1") (eq_attr "type" "dyn_shift")) 2 2)
277
278(define_function_unit "int"    1 0
279  (and (eq_attr "issues" "1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
280
281;; ??? These are approximations.
282(define_function_unit "mpy"    1 0
283  (and (eq_attr "issues" "1") (eq_attr "type" "smpy")) 2 2)
284(define_function_unit "mpy"    1 0
285  (and (eq_attr "issues" "1") (eq_attr "type" "dmpy")) 3 3)
286
287(define_function_unit "fp"     1 0
288  (and (eq_attr "issues" "1") (eq_attr "type" "fp,fmove")) 2 1)
289(define_function_unit "fp"     1 0
290  (and (eq_attr "issues" "1") (eq_attr "type" "fdiv")) 13 12)
291
292
293;; SH4 scheduling
294;; The SH4 is a dual-issue implementation, thus we have to multiply all
295;; costs by at least two.
296;; There will be single increments of the modeled that don't correspond
297;; to the actual target ;; whenever two insns to be issued depend one a
298;; single resource, and the scheduler picks to be the first one.
299;; If we multiplied the costs just by two, just two of these single
300;; increments would amount to an actual cycle.  By picking a larger
301;; factor, we can ameliorate the effect; However, we then have to make sure
302;; that only two insns are modeled as issued per actual cycle.
303;; Moreover, we need a way to specify the latency of insns that don't
304;; use an actual function unit.
305;; We use an 'issue' function unit to do that, and a cost factor of 10.
306
307(define_function_unit "issue" 2 0
308  (and (eq_attr "issues" "2") (eq_attr "type" "!nil,arith3"))
309  10 10)
310
311(define_function_unit "issue" 2 0
312  (and (eq_attr "issues" "2") (eq_attr "type" "arith3"))
313  30 30)
314
315;; There is no point in providing exact scheduling information about branches,
316;; because they are at the starts / ends of basic blocks anyways.
317
318;; Some insns cannot be issued before/after another insn in the same cycle,
319;; irrespective of the type of the other insn.
320
321;; default is dual-issue, but can't be paired with an insn that
322;; uses multiple function units.
323(define_function_unit "single_issue"     1 0
324  (and (eq_attr "issues" "2")
325       (eq_attr "type" "!smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul,call,sfunc,arith3,arith3b"))
326  1 10
327  [(eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul")])
328
329(define_function_unit "single_issue"     1 0
330  (and (eq_attr "issues" "2")
331       (eq_attr "type" "smpy,dmpy,pload,pstore,dfp_cmp,gp_fpul"))
332  10 10
333  [(const_int 1)])
334
335;; arith3 insns are always pairable at the start, but not inecessarily at
336;; the end; however, there doesn;t seem to be a way to express that.
337(define_function_unit "single_issue"     1 0
338  (and (eq_attr "issues" "2")
339       (eq_attr "type" "arith3"))
340  30 20
341  [(const_int 1)])
342
343;; arith3b insn are pairable at the end and have latency that prevents pairing
344;; with the following branch, but we don't want this latency be respected;
345;; When the following branch is immediately adjacent, we can redirect the
346;; internal branch, which is likly to be a larger win.
347(define_function_unit "single_issue"     1 0
348  (and (eq_attr "issues" "2")
349       (eq_attr "type" "arith3b"))
350  20 20
351  [(const_int 1)])
352
353;; calls introduce a longisch delay that is likely to flush the pipelines.
354(define_function_unit "single_issue"     1 0
355  (and (eq_attr "issues" "2")
356       (eq_attr "type" "call,sfunc"))
357  160 160
358  [(eq_attr "type" "!call") (eq_attr "type" "call")])
359
360;; Load and store instructions have no alignment peculiarities for the SH4,
361;; but they use the load-store unit, which they share with the fmove type
362;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
363;; Loads have a latency of two.
364;; However, call insns can only paired with a preceding insn, and have
365;; a delay slot, so that we want two more insns to be scheduled between the
366;; load of the function address and the call.  This is equivalent to a
367;; latency of three.
368;; We cannot use a conflict list for this, because we need to distinguish
369;; between the actual call address and the function arguments.
370;; ADJUST_COST can only properly handle reductions of the cost, so we
371;; use a latency of three here, which gets multiplied by 10 to yield 30.
372;; We only do this for SImode loads of general registers, to make the work
373;; for ADJUST_COST easier.
374
375;; When specifying different latencies for different insns using the
376;; the same function unit, genattrtab.c assumes a 'FIFO constraint'
377;; so that the blockage is at least READY-COST (E) + 1 - READY-COST (C)
378;; for an executing insn E and a candidate insn C.
379;; Therefore, we define three different function units for load_store:
380;; load_store, load and load_si.
381
382(define_function_unit "load_si" 1 0
383  (and (eq_attr "issues" "2")
384       (eq_attr "type" "load_si,pcload_si")) 30 10)
385(define_function_unit "load" 1 0
386  (and (eq_attr "issues" "2")
387       (eq_attr "type" "load,pcload,pload")) 20 10)
388(define_function_unit "load_store" 1 0
389  (and (eq_attr "issues" "2")
390       (eq_attr "type" "load_si,pcload_si,load,pcload,pload,store,pstore,fmove"))
391  10 10)
392
393(define_function_unit "int"    1 0
394  (and (eq_attr "issues" "2") (eq_attr "type" "arith,dyn_shift")) 10 10)
395
396;; Again, we have to pretend a lower latency for the "int" unit to avoid a
397;; spurious FIFO constraint; the multiply instructions use the "int"
398;; unit actually only for two cycles.
399(define_function_unit "int"    1 0
400  (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 20 20)
401
402;; We use a fictous "mpy" unit to express the actual latency.
403(define_function_unit "mpy"    1 0
404  (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 20)
405
406;; Again, we have to pretend a lower latency for the "int" unit to avoid a
407;; spurious FIFO constraint.
408(define_function_unit "int"     1 0
409  (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 10 10)
410
411;; We use a fictous "gp_fpul" unit to express the actual latency.
412(define_function_unit "gp_fpul"     1 0
413  (and (eq_attr "issues" "2") (eq_attr "type" "gp_fpul")) 20 10)
414
415;; ??? multiply uses the floating point unit, but with a two cycle delay.
416;; Thus, a simple single-precision fp operation could finish if issued in
417;; the very next cycle, but stalls when issued two or three cycles later.
418;; Similarily, a divide / sqrt can work without stalls if issued in
419;; the very next cycle, while it would have to block if issued two or
420;; three cycles later.
421;; There is no way to model this with gcc's function units.  This problem is
422;; actually mentioned in md.texi.  Tackling this problem requires first that
423;; it is possible to speak about the target in an open discussion.
424;; 
425;; However, simple double-precision operations always conflict.
426
427(define_function_unit "fp"    1 0
428  (and (eq_attr "issues" "2") (eq_attr "type" "smpy,dmpy")) 40 40
429  [(eq_attr "type" "dfp_cmp,dfp_conv,dfp_arith")])
430
431;; The "fp" unit is for pipeline stages F1 and F2.
432
433(define_function_unit "fp"     1 0
434  (and (eq_attr "issues" "2") (eq_attr "type" "fp")) 30 10)
435
436;; Again, we have to pretend a lower latency for the "fp" unit to avoid a
437;; spurious FIFO constraint; the bulk of the fdiv type insns executes in
438;; the F3 stage.
439(define_function_unit "fp"     1 0
440  (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 30 10)
441
442;; The "fdiv" function unit models the aggregate effect of the F1, F2 and F3
443;; pipeline stages on the pipelining of fdiv/fsqrt insns.
444;; We also use it to give the actual latency here.
445;; fsqrt is actually one cycle faster than fdiv (and the value used here),
446;; but that will hardly matter in practice for scheduling.
447(define_function_unit "fdiv"     1 0
448  (and (eq_attr "issues" "2") (eq_attr "type" "fdiv")) 120 100)
449
450;; There is again a late use of the "fp" unit by [d]fdiv type insns
451;; that we can't express.
452
453(define_function_unit "fp"     1 0
454  (and (eq_attr "issues" "2") (eq_attr "type" "dfp_cmp,dfp_conv")) 40 20)
455
456(define_function_unit "fp"     1 0
457  (and (eq_attr "issues" "2") (eq_attr "type" "dfp_arith")) 80 60)
458
459(define_function_unit "fp"     1 0
460  (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 10)
461
462(define_function_unit "fdiv"     1 0
463  (and (eq_attr "issues" "2") (eq_attr "type" "dfdiv")) 230 210)
464
465; Definitions for filling branch delay slots.
466
467(define_attr "needs_delay_slot" "yes,no" (const_string "no"))
468
469;; ??? This should be (nil) instead of (const_int 0)
470(define_attr "hit_stack" "yes,no"
471	(cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, 15)") (const_int 0))
472	       (const_string "no")]
473	      (const_string "yes")))
474
475(define_attr "interrupt_function" "no,yes"
476  (const (symbol_ref "pragma_interrupt")))
477
478(define_attr "in_delay_slot" "yes,no"
479  (cond [(eq_attr "type" "cbranch") (const_string "no")
480	 (eq_attr "type" "pcload,pcload_si") (const_string "no")
481	 (eq_attr "needs_delay_slot" "yes") (const_string "no")
482	 (eq_attr "length" "2") (const_string "yes")
483	 ] (const_string "no")))
484
485(define_attr "is_sfunc" ""
486  (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
487
488(define_delay
489  (eq_attr "needs_delay_slot" "yes")
490  [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
491
492;; On the SH and SH2, the rte instruction reads the return pc from the stack,
493;; and thus we can't put a pop instruction in its delay slot.
494;; ??? On the SH3, the rte instruction does not use the stack, so a pop
495;; instruction can go in the delay slot.
496
497;; Since a normal return (rts) implicitly uses the PR register,
498;; we can't allow PR register loads in an rts delay slot.
499
500(define_delay
501  (eq_attr "type" "return")
502  [(and (eq_attr "in_delay_slot" "yes")
503	(ior (and (eq_attr "interrupt_function" "no")
504		  (eq_attr "type" "!pload"))
505	     (and (eq_attr "interrupt_function" "yes")
506		  (eq_attr "hit_stack" "no")))) (nil) (nil)])
507
508;; Since a call implicitly uses the PR register, we can't allow
509;; a PR register store in a jsr delay slot.
510
511(define_delay
512  (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
513  [(and (eq_attr "in_delay_slot" "yes")
514	(eq_attr "type" "!pstore")) (nil) (nil)])
515
516;; Say that we have annulled true branches, since this gives smaller and
517;; faster code when branches are predicted as not taken.
518
519(define_delay
520  (and (eq_attr "type" "cbranch")
521       (ne (symbol_ref "TARGET_SH2") (const_int 0)))
522  [(eq_attr "in_delay_slot" "yes") (eq_attr "in_delay_slot" "yes") (nil)])
523
524;; -------------------------------------------------------------------------
525;; SImode signed integer comparisons
526;; -------------------------------------------------------------------------
527
528(define_insn ""
529  [(set (reg:SI 18)
530	(eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
531		       (match_operand:SI 1 "arith_operand" "L,r"))
532	       (const_int 0)))]
533  ""
534  "tst	%1,%0")
535
536;; ??? Perhaps should only accept reg/constant if the register is reg 0.
537;; That would still allow reload to create cmpi instructions, but would
538;; perhaps allow forcing the constant into a register when that is better.
539;; Probably should use r0 for mem/imm compares, but force constant into a
540;; register for pseudo/imm compares.
541
542(define_insn "cmpeqsi_t"
543  [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
544			   (match_operand:SI 1 "arith_operand" "N,rI,r")))]
545  ""
546  "@
547	tst	%0,%0
548	cmp/eq	%1,%0
549	cmp/eq	%1,%0")
550
551(define_insn "cmpgtsi_t"
552  [(set (reg:SI 18) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
553			   (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
554  ""
555  "@
556	cmp/gt	%1,%0
557	cmp/pl	%0")
558
559(define_insn "cmpgesi_t"
560  [(set (reg:SI 18) (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
561			   (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
562  ""
563  "@
564	cmp/ge	%1,%0
565	cmp/pz	%0")
566
567;; -------------------------------------------------------------------------
568;; SImode unsigned integer comparisons
569;; -------------------------------------------------------------------------
570
571(define_insn "cmpgeusi_t"
572  [(set (reg:SI 18) (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
573			    (match_operand:SI 1 "arith_reg_operand" "r")))]
574  ""
575  "cmp/hs	%1,%0")
576
577(define_insn "cmpgtusi_t"
578  [(set (reg:SI 18) (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
579			    (match_operand:SI 1 "arith_reg_operand" "r")))]
580  ""
581  "cmp/hi	%1,%0")
582
583;; We save the compare operands in the cmpxx patterns and use them when
584;; we generate the branch.
585
586(define_expand "cmpsi"
587  [(set (reg:SI 18) (compare (match_operand:SI 0 "arith_operand" "")
588			     (match_operand:SI 1 "arith_operand" "")))]
589  ""
590  "
591{
592  sh_compare_op0 = operands[0];
593  sh_compare_op1 = operands[1];
594  DONE;
595}")
596
597;; -------------------------------------------------------------------------
598;; DImode signed integer comparisons
599;; -------------------------------------------------------------------------
600
601;; ??? Could get better scheduling by splitting the initial test from the
602;; rest of the insn after reload.  However, the gain would hardly justify
603;; the sh.md size increase necessary to do that.
604
605(define_insn ""
606  [(set (reg:SI 18)
607	(eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
608		       (match_operand:DI 1 "arith_operand" "r"))
609	       (const_int 0)))]
610  ""
611  "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
612				 insn, operands);"
613  [(set_attr "length" "6")
614   (set_attr "type" "arith3b")])
615
616(define_insn "cmpeqdi_t"
617  [(set (reg:SI 18) (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
618			   (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
619  ""
620  "*
621  return output_branchy_insn
622   (EQ,
623    (which_alternative
624     ? \"cmp/eq\\t%S1,%S0\;bf\\t%l9\;cmp/eq\\t%R1,%R0\"
625     : \"tst\\t%S0,%S0\;bf\\t%l9\;tst\\t%R0,%R0\"),
626    insn, operands);"
627  [(set_attr "length" "6")
628   (set_attr "type" "arith3b")])
629
630(define_insn "cmpgtdi_t"
631  [(set (reg:SI 18) (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
632			   (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
633  "TARGET_SH2"
634  "@
635	cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
636	tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
637  [(set_attr "length" "8")
638   (set_attr "type" "arith3")])
639
640(define_insn "cmpgedi_t"
641  [(set (reg:SI 18) (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
642			   (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
643  "TARGET_SH2"
644  "@
645	cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
646	cmp/pz\\t%S0"
647  [(set_attr "length" "8,2")
648   (set_attr "type" "arith3,arith")])
649
650;; -------------------------------------------------------------------------
651;; DImode unsigned integer comparisons
652;; -------------------------------------------------------------------------
653
654(define_insn "cmpgeudi_t"
655  [(set (reg:SI 18) (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
656			    (match_operand:DI 1 "arith_reg_operand" "r")))]
657  "TARGET_SH2"
658  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
659  [(set_attr "length" "8")
660   (set_attr "type" "arith3")])
661
662(define_insn "cmpgtudi_t"
663  [(set (reg:SI 18) (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
664			    (match_operand:DI 1 "arith_reg_operand" "r")))]
665  "TARGET_SH2"
666  "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
667  [(set_attr "length" "8")
668   (set_attr "type" "arith3")])
669
670;; We save the compare operands in the cmpxx patterns and use them when
671;; we generate the branch.
672
673(define_expand "cmpdi"
674  [(set (reg:SI 18) (compare (match_operand:DI 0 "arith_operand" "")
675			     (match_operand:DI 1 "arith_operand" "")))]
676  "TARGET_SH2"
677  "
678{
679  sh_compare_op0 = operands[0];
680  sh_compare_op1 = operands[1];
681  DONE;
682}")
683
684;; -------------------------------------------------------------------------
685;; Addition instructions
686;; -------------------------------------------------------------------------
687
688;; ??? This should be a define expand.
689
690(define_insn "adddi3"
691  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
692	(plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
693		 (match_operand:DI 2 "arith_reg_operand" "r")))
694   (clobber (reg:SI 18))]
695  ""
696  "#"
697  [(set_attr "length" "6")])
698
699(define_split
700  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
701	(plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
702		 (match_operand:DI 2 "arith_reg_operand" "r")))
703   (clobber (reg:SI 18))]
704  "reload_completed"
705  [(const_int 0)]
706  "
707{
708  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
709  high0 = gen_rtx (REG, SImode,
710		   true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
711  high2 = gen_rtx (REG, SImode,
712		   true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
713  emit_insn (gen_clrt ());
714  emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
715  emit_insn (gen_addc1 (high0, high0, high2));
716  DONE;
717}")
718
719(define_insn "addc"
720  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
721	(plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
722			  (match_operand:SI 2 "arith_reg_operand" "r"))
723		 (reg:SI 18)))
724   (set (reg:SI 18)
725	(ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
726  ""
727  "addc	%2,%0"
728  [(set_attr "type" "arith")])
729
730(define_insn "addc1"
731  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
732	(plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
733			  (match_operand:SI 2 "arith_reg_operand" "r"))
734		 (reg:SI 18)))
735   (clobber (reg:SI 18))]
736  ""
737  "addc	%2,%0"
738  [(set_attr "type" "arith")])
739
740(define_insn "addsi3"
741  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
742	(plus:SI (match_operand:SI 1 "arith_operand" "%0")
743		 (match_operand:SI 2 "arith_operand" "rI")))]
744  ""
745  "add	%2,%0"
746  [(set_attr "type" "arith")])
747
748;; -------------------------------------------------------------------------
749;; Subtraction instructions
750;; -------------------------------------------------------------------------
751
752;; ??? This should be a define expand.
753
754(define_insn "subdi3"
755  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
756	(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
757		 (match_operand:DI 2 "arith_reg_operand" "r")))
758   (clobber (reg:SI 18))]
759  ""
760  "#"
761  [(set_attr "length" "6")])
762
763(define_split
764  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
765	(minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
766		  (match_operand:DI 2 "arith_reg_operand" "r")))
767   (clobber (reg:SI 18))]
768  "reload_completed"
769  [(const_int 0)]
770  "
771{
772  rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
773  high0 = gen_rtx (REG, SImode,
774		   true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
775  high2 = gen_rtx (REG, SImode,
776		   true_regnum (operands[2]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
777  emit_insn (gen_clrt ());
778  emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
779  emit_insn (gen_subc1 (high0, high0, high2));
780  DONE;
781}")
782
783(define_insn "subc"
784  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
785	(minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
786			    (match_operand:SI 2 "arith_reg_operand" "r"))
787		  (reg:SI 18)))
788   (set (reg:SI 18)
789	(gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
790  ""
791  "subc	%2,%0"
792  [(set_attr "type" "arith")])
793
794(define_insn "subc1"
795  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
796	(minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
797			    (match_operand:SI 2 "arith_reg_operand" "r"))
798		  (reg:SI 18)))
799   (clobber (reg:SI 18))]
800  ""
801  "subc	%2,%0"
802  [(set_attr "type" "arith")])
803
804(define_insn "*subsi3_internal"
805  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
806	(minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
807		  (match_operand:SI 2 "arith_reg_operand" "r")))]
808  ""
809  "sub	%2,%0"
810  [(set_attr "type" "arith")])
811
812;; Convert `constant - reg' to `neg rX; add rX, #const' since this
813;; will sometimes save one instruction.  Otherwise we might get
814;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
815;; are the same.
816
817(define_expand "subsi3"
818  [(set (match_operand:SI 0 "arith_reg_operand" "")
819	(minus:SI (match_operand:SI 1 "arith_operand" "")
820		  (match_operand:SI 2 "arith_reg_operand" "")))]
821  ""
822  "
823{
824  if (GET_CODE (operands[1]) == CONST_INT)
825    {
826      emit_insn (gen_negsi2 (operands[0], operands[2]));
827      emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
828      DONE;
829    }
830}")
831
832;; -------------------------------------------------------------------------
833;; Division instructions
834;; -------------------------------------------------------------------------
835
836;; We take advantage of the library routines which don't clobber as many
837;; registers as a normal function call would.
838
839;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
840;; also has an effect on the register that holds the address of the sfunc.
841;; To make this work, we have an extra dummy insns that shows the use
842;; of this register for reorg.
843
844(define_insn "use_sfunc_addr"
845  [(set (reg:SI 17) (unspec [(match_operand:SI 0 "register_operand" "r")] 5))]
846  ""
847  ""
848  [(set_attr "length" "0")])
849
850;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
851;; hard register 0.  If we used hard register 0, then the next instruction
852;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
853;; gets allocated to a stack slot that needs its address reloaded, then
854;; there is nothing to prevent reload from using r0 to reload the address.
855;; This reload would clobber the value in r0 we are trying to store.
856;; If we let reload allocate r0, then this problem can never happen.
857
858(define_insn ""
859  [(set (match_operand:SI 0 "register_operand" "=z")
860	(udiv:SI (reg:SI 4) (reg:SI 5)))
861   (clobber (reg:SI 18))
862   (clobber (reg:SI 17))
863   (clobber (reg:SI 4))
864   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
865  "! TARGET_SH4"
866  "jsr	@%1%#"
867  [(set_attr "type" "sfunc")
868   (set_attr "needs_delay_slot" "yes")])
869
870(define_insn "udivsi3_i4"
871  [(set (match_operand:SI 0 "register_operand" "=y")
872	(udiv:SI (reg:SI 4) (reg:SI 5)))
873   (clobber (reg:SI 17))
874   (clobber (reg:DF 24))
875   (clobber (reg:DF 26))
876   (clobber (reg:DF 28))
877   (clobber (reg:SI 0))
878   (clobber (reg:SI 1))
879   (clobber (reg:SI 4))
880   (clobber (reg:SI 5))
881   (use (reg:PSI 48))
882   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
883  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
884  "jsr	@%1%#"
885  [(set_attr "type" "sfunc")
886   (set_attr "needs_delay_slot" "yes")])
887
888(define_insn "udivsi3_i4_single"
889  [(set (match_operand:SI 0 "register_operand" "=y")
890	(udiv:SI (reg:SI 4) (reg:SI 5)))
891   (clobber (reg:SI 17))
892   (clobber (reg:DF 24))
893   (clobber (reg:DF 26))
894   (clobber (reg:DF 28))
895   (clobber (reg:SI 0))
896   (clobber (reg:SI 1))
897   (clobber (reg:SI 4))
898   (clobber (reg:SI 5))
899   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
900  "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
901  "jsr	@%1%#"
902  [(set_attr "type" "sfunc")
903   (set_attr "needs_delay_slot" "yes")])
904
905(define_expand "udivsi3"
906  [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
907   (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
908   (set (match_dup 3) (symbol_ref:SI "__udivsi3"))
909   (parallel [(set (match_operand:SI 0 "register_operand" "")
910		   (udiv:SI (reg:SI 4)
911			    (reg:SI 5)))
912	      (clobber (reg:SI 18))
913	      (clobber (reg:SI 17))
914	      (clobber (reg:SI 4))
915	      (use (match_dup 3))])]
916  ""
917  "
918{
919  operands[3] = gen_reg_rtx(SImode);
920  if (TARGET_HARD_SH4)
921    {
922      emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
923      emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
924      emit_move_insn (operands[3],
925		      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
926      if (TARGET_FPU_SINGLE)
927	emit_insn (gen_udivsi3_i4_single (operands[0], operands[3]));
928      else
929	emit_insn (gen_udivsi3_i4 (operands[0], operands[3]));
930      DONE;
931    }
932}")
933
934(define_insn ""
935  [(set (match_operand:SI 0 "register_operand" "=z")
936	(div:SI (reg:SI 4) (reg:SI 5)))
937   (clobber (reg:SI 18))
938   (clobber (reg:SI 17))
939   (clobber (reg:SI 1))
940   (clobber (reg:SI 2))
941   (clobber (reg:SI 3))
942   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
943  "! TARGET_SH4"
944  "jsr	@%1%#"
945  [(set_attr "type" "sfunc")
946   (set_attr "needs_delay_slot" "yes")])
947
948(define_insn "divsi3_i4"
949  [(set (match_operand:SI 0 "register_operand" "=y")
950	(div:SI (reg:SI 4) (reg:SI 5)))
951   (clobber (reg:SI 17))
952   (clobber (reg:DF 24))
953   (clobber (reg:DF 26))
954   (use (reg:PSI 48))
955   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
956  "TARGET_SH4 && ! TARGET_FPU_SINGLE"
957  "jsr	@%1%#"
958  [(set_attr "type" "sfunc")
959   (set_attr "needs_delay_slot" "yes")])
960
961(define_insn "divsi3_i4_single"
962  [(set (match_operand:SI 0 "register_operand" "=y")
963	(div:SI (reg:SI 4) (reg:SI 5)))
964   (clobber (reg:SI 17))
965   (clobber (reg:DF 24))
966   (clobber (reg:DF 26))
967   (clobber (reg:SI 2))
968   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
969  "TARGET_HARD_SH4 && TARGET_FPU_SINGLE"
970  "jsr	@%1%#"
971  [(set_attr "type" "sfunc")
972   (set_attr "needs_delay_slot" "yes")])
973
974(define_expand "divsi3"
975  [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
976   (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
977   (set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
978   (parallel [(set (match_operand:SI 0 "register_operand" "")
979		   (div:SI (reg:SI 4)
980			   (reg:SI 5)))
981	      (clobber (reg:SI 18))
982	      (clobber (reg:SI 17))
983	      (clobber (reg:SI 1))
984	      (clobber (reg:SI 2))
985	      (clobber (reg:SI 3))
986	      (use (match_dup 3))])]
987  ""
988  "
989{
990  operands[3] = gen_reg_rtx(SImode);
991  if (TARGET_HARD_SH4)
992    {
993      emit_move_insn (gen_rtx (REG, SImode, 4), operands[1]);
994      emit_move_insn (gen_rtx (REG, SImode, 5), operands[2]);
995      emit_move_insn (operands[3],
996		      gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
997      if (TARGET_FPU_SINGLE)
998	emit_insn (gen_divsi3_i4_single (operands[0], operands[3]));
999      else
1000	emit_insn (gen_divsi3_i4 (operands[0], operands[3]));
1001      DONE;
1002    }
1003}")
1004
1005;; -------------------------------------------------------------------------
1006;; Multiplication instructions
1007;; -------------------------------------------------------------------------
1008
1009(define_insn ""
1010  [(set (reg:SI 21)
1011	(mult:SI (zero_extend:SI (match_operand:HI 0 "arith_reg_operand" "r"))
1012		 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r"))))]
1013  ""
1014  "mulu	%1,%0"
1015  [(set_attr "type" "smpy")])
1016
1017(define_insn ""
1018  [(set (reg:SI 21)
1019	(mult:SI (sign_extend:SI
1020		  (match_operand:HI 0 "arith_reg_operand" "r"))
1021		 (sign_extend:SI
1022		  (match_operand:HI 1 "arith_reg_operand" "r"))))]
1023  ""
1024  "muls	%1,%0"
1025  [(set_attr "type" "smpy")])
1026
1027(define_expand "mulhisi3"
1028  [(set (reg:SI 21)
1029	(mult:SI (sign_extend:SI
1030		  (match_operand:HI 1 "arith_reg_operand" ""))
1031		 (sign_extend:SI
1032		  (match_operand:HI 2 "arith_reg_operand" ""))))
1033   (set (match_operand:SI 0 "arith_reg_operand" "")
1034	(reg:SI 21))]
1035  ""
1036  "")
1037
1038(define_expand "umulhisi3"
1039  [(set (reg:SI 21)
1040	(mult:SI (zero_extend:SI
1041		  (match_operand:HI 1 "arith_reg_operand" ""))
1042		 (zero_extend:SI
1043		  (match_operand:HI 2 "arith_reg_operand" ""))))
1044   (set (match_operand:SI 0 "arith_reg_operand" "")
1045	(reg:SI 21))]
1046  ""
1047  "")
1048
1049;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1050;; a call to a routine which clobbers known registers.
1051
1052(define_insn ""
1053  [(set (match_operand:SI 1 "register_operand" "=z")
1054	(mult:SI (reg:SI 4) (reg:SI 5)))
1055   (clobber (reg:SI 21))
1056   (clobber (reg:SI 18))
1057   (clobber (reg:SI 17))
1058   (clobber (reg:SI 3))
1059   (clobber (reg:SI 2))
1060   (clobber (reg:SI 1))
1061   (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1062  ""
1063  "jsr	@%0%#"
1064  [(set_attr "type" "sfunc")
1065   (set_attr "needs_delay_slot" "yes")])
1066
1067(define_expand "mulsi3_call"
1068  [(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
1069   (set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
1070   (parallel[(set (match_operand:SI 0 "register_operand" "")
1071		  (mult:SI (reg:SI 4)
1072			   (reg:SI 5)))
1073	     (clobber (reg:SI 21))
1074	     (clobber (reg:SI 18))
1075	     (clobber (reg:SI 17))
1076	     (clobber (reg:SI 3))
1077	     (clobber (reg:SI 2))
1078	     (clobber (reg:SI 1))
1079	     (use (match_operand:SI 3 "register_operand" ""))])]
1080  ""
1081  "")
1082
1083(define_insn "mul_l"
1084  [(set (reg:SI 21)
1085	(mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1086		 (match_operand:SI 1 "arith_reg_operand" "r")))]
1087  "TARGET_SH2"
1088  "mul.l	%1,%0"
1089  [(set_attr "type" "dmpy")])
1090
1091(define_expand "mulsi3"
1092  [(set (reg:SI 21)
1093	(mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1094		  (match_operand:SI 2 "arith_reg_operand" "")))
1095   (set (match_operand:SI 0 "arith_reg_operand" "")
1096	(reg:SI 21))]
1097  ""
1098  "
1099{
1100  rtx first, last;
1101
1102  if (!TARGET_SH2)
1103    {
1104      /* The address must be set outside the libcall,
1105	 since it goes into a pseudo.  */
1106      rtx addr = force_reg (SImode, gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\"));
1107      rtx insns = gen_mulsi3_call (operands[0], operands[1], operands[2], addr);
1108      first = XVECEXP (insns, 0, 0);
1109      last = XVECEXP (insns, 0, XVECLEN (insns, 0) - 1);
1110      emit_insn (insns);
1111    }
1112  else
1113    {
1114      rtx macl = gen_rtx_REG (SImode, MACL_REG);
1115      rtx giv_insn;
1116
1117      first = emit_insn (gen_mul_l (operands[1], operands[2]));
1118      /* consec_sets_giv can only recognize the first insn that sets a
1119	 giv as the giv insn.  So we must tag this also with a REG_EQUAL
1120	 note.  */
1121      giv_insn = emit_insn (gen_movsi_i ((operands[0]), macl));
1122      REG_NOTES (giv_insn)
1123	= gen_rtx_EXPR_LIST (REG_EQUAL,
1124			     gen_rtx_MULT (SImode, operands[1], operands[2]),
1125					   REG_NOTES (giv_insn));
1126      /* The sequence must end in a no-op move, lest cse puts macl in its
1127	 tables and does invalid substitutions.  */
1128      last = emit_insn (gen_movsi_i ((operands[0]), operands[0]));
1129    }
1130  /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1131     invariant code motion can move it.  */
1132  REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1133  REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1134  DONE;
1135}")
1136
1137(define_insn "mulsidi3_i"
1138  [(set (reg:DI 20)
1139	(mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1140		 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
1141  "TARGET_SH2"
1142  "dmuls.l	%1,%0"
1143  [(set_attr "type" "dmpy")])
1144
1145(define_expand "mulsidi3"
1146  [(set (reg:DI 20)
1147	(mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1148		 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1149   (set (match_operand:DI 0 "arith_reg_operand" "")
1150	(reg:DI 20))]
1151  "TARGET_SH2"
1152  "
1153{
1154  /* We must swap the two words when copying them from MACH/MACL to the
1155     output register.  */
1156  if (TARGET_LITTLE_ENDIAN)
1157    {
1158      rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
1159      rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
1160
1161      emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1162
1163      emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
1164      emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
1165      emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
1166      DONE;
1167    }
1168}")
1169
1170(define_insn "umulsidi3_i"
1171  [(set (reg:DI 20)
1172	(mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1173		 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))))]
1174  "TARGET_SH2"
1175  "dmulu.l	%1,%0"
1176  [(set_attr "type" "dmpy")])
1177
1178(define_expand "umulsidi3"
1179  [(set (reg:DI 20)
1180	(mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1181		 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1182   (set (match_operand:DI 0 "arith_reg_operand" "")
1183	(reg:DI 20))]
1184  "TARGET_SH2"
1185  "
1186{
1187  /* We must swap the two words when copying them from MACH/MACL to the
1188     output register.  */
1189  if (TARGET_LITTLE_ENDIAN)
1190    {
1191      rtx low_dst = operand_subword (operands[0], 0, 1, DImode);
1192      rtx high_dst = operand_subword (operands[0], 1, 1, DImode);
1193
1194      emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1195
1196      emit_insn (gen_rtx (CLOBBER, VOIDmode, operands[0]));
1197      emit_move_insn (low_dst, gen_rtx (REG, SImode, 21));
1198      emit_move_insn (high_dst, gen_rtx (REG, SImode, 20));
1199      DONE;
1200    }
1201}")
1202
1203(define_insn ""
1204  [(set (reg:SI 20)
1205	(truncate:SI
1206	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1207			       (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1208		      (const_int 32))))
1209   (clobber (reg:SI 21))]
1210  "TARGET_SH2"
1211  "dmuls.l	%1,%0"
1212  [(set_attr "type" "dmpy")])
1213
1214(define_expand "smulsi3_highpart"
1215  [(parallel [(set (reg:SI 20)
1216		   (truncate:SI
1217		    (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1218					  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1219				 (const_int 32))))
1220	      (clobber (reg:SI 21))])
1221   (set (match_operand:SI 0 "arith_reg_operand" "")
1222	(reg:SI 20))]
1223  "TARGET_SH2"
1224  "")
1225
1226(define_insn ""
1227  [(set (reg:SI 20)
1228	(truncate:SI
1229	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1230			       (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1231		      (const_int 32))))
1232   (clobber (reg:SI 21))]
1233  "TARGET_SH2"
1234  "dmulu.l	%1,%0"
1235  [(set_attr "type" "dmpy")])
1236
1237(define_expand "umulsi3_highpart"
1238  [(parallel [(set (reg:SI 20)
1239		   (truncate:SI
1240		    (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1241					  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1242				 (const_int 32))))
1243	      (clobber (reg:SI 21))])
1244   (set (match_operand:SI 0 "arith_reg_operand" "")
1245	(reg:SI 20))]
1246  "TARGET_SH2"
1247  "")
1248
1249;; -------------------------------------------------------------------------
1250;; Logical operations
1251;; -------------------------------------------------------------------------
1252
1253(define_insn ""
1254  [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1255	(and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1256		(match_operand:SI 2 "logical_operand" "r,L")))]
1257  ""
1258  "and	%2,%0"
1259  [(set_attr "type" "arith")])
1260
1261;; If the constant is 255, then emit a extu.b instruction instead of an
1262;; and, since that will give better code.
1263
1264(define_expand "andsi3"
1265  [(set (match_operand:SI 0 "arith_reg_operand" "")
1266	(and:SI (match_operand:SI 1 "arith_reg_operand" "")
1267		(match_operand:SI 2 "logical_operand" "")))]
1268  ""
1269  "
1270{
1271  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1272    {
1273      emit_insn (gen_zero_extendqisi2 (operands[0],
1274				       gen_lowpart (QImode, operands[1])));
1275      DONE;
1276    }
1277}")
1278
1279(define_insn "iorsi3"
1280  [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1281	(ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1282		(match_operand:SI 2 "logical_operand" "r,L")))]
1283  ""
1284  "or	%2,%0"
1285  [(set_attr "type" "arith")])
1286
1287(define_insn "xorsi3"
1288  [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1289	(xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1290		(match_operand:SI 2 "logical_operand" "L,r")))]
1291  ""
1292  "xor	%2,%0"
1293  [(set_attr "type" "arith")])
1294
1295;; -------------------------------------------------------------------------
1296;; Shifts and rotates
1297;; -------------------------------------------------------------------------
1298
1299(define_insn "rotlsi3_1"
1300  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1301	(rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1302		   (const_int 1)))
1303   (set (reg:SI 18)
1304	(lshiftrt:SI (match_dup 1) (const_int 31)))]
1305  ""
1306  "rotl	%0"
1307  [(set_attr "type" "arith")])
1308
1309(define_insn "rotlsi3_31"
1310  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1311	(rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
1312		   (const_int 31)))
1313   (clobber (reg:SI 18))]
1314  ""
1315  "rotr	%0"
1316  [(set_attr "type" "arith")])
1317
1318(define_insn "rotlsi3_16"
1319  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1320	(rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
1321		   (const_int 16)))]
1322  ""
1323  "swap.w	%1,%0"
1324  [(set_attr "type" "arith")])
1325
1326(define_expand "rotlsi3"
1327  [(set (match_operand:SI 0 "arith_reg_operand" "")
1328	(rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
1329		   (match_operand:SI 2 "immediate_operand" "")))]
1330  ""
1331  "
1332{
1333  static char rot_tab[] = {
1334    000, 000, 000, 000, 000, 000, 010, 001,
1335    001, 001, 011, 013, 003, 003, 003, 003,
1336    003, 003, 003, 003, 003, 013, 012, 002,
1337    002, 002, 010, 000, 000, 000, 000, 000,
1338  };
1339
1340  int count, choice;
1341
1342  if (GET_CODE (operands[2]) != CONST_INT)
1343    FAIL;
1344  count = INTVAL (operands[2]);
1345  choice = rot_tab[count];
1346  if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
1347    FAIL;
1348  choice &= 7;
1349  switch (choice)
1350    {
1351    case 0:
1352      emit_move_insn (operands[0], operands[1]);
1353      count -= (count & 16) * 2;
1354      break;
1355    case 3:
1356     emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
1357     count -= 16;
1358     break;
1359    case 1:
1360    case 2:
1361      {
1362	rtx parts[2];
1363	parts[0] = gen_reg_rtx (SImode);
1364	parts[1] = gen_reg_rtx (SImode);
1365	emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
1366	parts[choice-1] = operands[1];
1367	emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
1368	emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
1369	emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
1370	count = (count & ~16) - 8;
1371      }
1372    }
1373
1374  for (; count > 0; count--)
1375    emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
1376  for (; count < 0; count++)
1377    emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
1378
1379  DONE;
1380}")
1381
1382(define_insn "*rotlhi3_8"
1383  [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1384	(rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
1385		   (const_int 8)))]
1386  ""
1387  "swap.b	%1,%0"
1388  [(set_attr "type" "arith")])
1389
1390(define_expand "rotlhi3"
1391  [(set (match_operand:HI 0 "arith_reg_operand" "")
1392	(rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
1393		   (match_operand:HI 2 "immediate_operand" "")))]
1394  ""
1395  "
1396{
1397  if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
1398    FAIL;
1399}")
1400
1401;;
1402;; shift left
1403
1404(define_insn "ashlsi3_d"
1405  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1406	(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
1407		   (match_operand:SI 2 "arith_reg_operand" "r")))]
1408  "TARGET_SH3"
1409  "shld	%2,%0"
1410  [(set_attr "type" "dyn_shift")])
1411
1412(define_insn "ashlsi3_k"
1413  [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1414	(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0")
1415		   (match_operand:SI 2 "const_int_operand" "M,K")))]
1416  "CONST_OK_FOR_K (INTVAL (operands[2]))"
1417  "@
1418	add	%0,%0
1419	shll%O2	%0"
1420  [(set_attr "type" "arith")])
1421
1422(define_insn "ashlhi3_k"
1423  [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
1424	(ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
1425		   (match_operand:HI 2 "const_int_operand" "M,K")))]
1426  "CONST_OK_FOR_K (INTVAL (operands[2]))"
1427  "@
1428	add	%0,%0
1429	shll%O2	%0"
1430  [(set_attr "type" "arith")])
1431
1432(define_insn "ashlsi3_n"
1433  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1434	(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
1435		   (match_operand:SI 2 "const_int_operand" "n")))
1436   (clobber (reg:SI 18))]
1437  "! sh_dynamicalize_shift_p (operands[2])"
1438  "#"
1439  [(set (attr "length")
1440	(cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1441	       (const_string "2")
1442	       (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1443	       (const_string "4")
1444	       (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1445	       (const_string "6")]
1446	      (const_string "8")))
1447   (set_attr "type" "arith")])
1448
1449(define_split
1450  [(set (match_operand:SI 0 "arith_reg_operand" "")
1451	(ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
1452		   (match_operand:SI 2 "const_int_operand" "n")))
1453   (clobber (reg:SI 18))]
1454  ""
1455  [(use (reg:SI 0))]
1456  "
1457{
1458  gen_shifty_op (ASHIFT, operands);
1459  DONE;
1460}")
1461
1462(define_expand "ashlsi3"
1463  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1464		   (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
1465			      (match_operand:SI 2 "nonmemory_operand" "")))
1466	      (clobber (reg:SI 18))])]
1467  ""
1468  "
1469{
1470  if (GET_CODE (operands[2]) == CONST_INT
1471      && sh_dynamicalize_shift_p (operands[2]))
1472    operands[2] = force_reg (SImode, operands[2]);
1473  if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1474    {
1475      emit_insn (gen_ashlsi3_d (operands[0], operands[1], operands[2]));
1476      DONE;
1477    }
1478  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1479    FAIL;
1480}")
1481
1482(define_insn "ashlhi3"
1483  [(set (match_operand:HI 0 "arith_reg_operand" "=r")
1484	(ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
1485		   (match_operand:HI 2 "const_int_operand" "n")))
1486   (clobber (reg:SI 18))]
1487  ""
1488  "#"
1489  [(set (attr "length")
1490	(cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1491	       (const_string "2")
1492	       (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1493	       (const_string "4")]
1494	      (const_string "6")))
1495   (set_attr "type" "arith")])
1496
1497(define_split
1498  [(set (match_operand:HI 0 "arith_reg_operand" "")
1499	(ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
1500		   (match_operand:HI 2 "const_int_operand" "n")))
1501   (clobber (reg:SI 18))]
1502  ""
1503  [(use (reg:SI 0))]
1504  "
1505{
1506  gen_shifty_hi_op (ASHIFT, operands);
1507  DONE;
1508}")
1509
1510;
1511; arithmetic shift right
1512;
1513
1514(define_insn "ashrsi3_k"
1515  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1516	(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1517		     (match_operand:SI 2 "const_int_operand" "M")))
1518   (clobber (reg:SI 18))]
1519  "INTVAL (operands[2]) == 1"
1520  "shar	%0"
1521  [(set_attr "type" "arith")])
1522
1523;; We can't do HImode right shifts correctly unless we start out with an
1524;; explicit zero / sign extension; doing that would result in worse overall
1525;; code, so just let the machine independent code widen the mode.
1526;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
1527
1528
1529;; ??? This should be a define expand.
1530
1531(define_insn "ashrsi2_16"
1532  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1533        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
1534                     (const_int 16)))]
1535  ""
1536  "#"
1537  [(set_attr "length" "4")])
1538
1539(define_split
1540  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1541        (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
1542		     (const_int 16)))]
1543  ""
1544  [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
1545   (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
1546  "operands[2] = gen_lowpart (HImode, operands[0]);")
1547
1548;; ??? This should be a define expand.
1549
1550(define_insn "ashrsi2_31"
1551  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1552	(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1553		     (const_int 31)))
1554   (clobber (reg:SI 18))]
1555  ""
1556  "#"
1557  [(set_attr "length" "4")])
1558
1559(define_split
1560  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1561	(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1562		     (const_int 31)))
1563   (clobber (reg:SI 18))]
1564  ""
1565  [(const_int 0)]
1566  "
1567{
1568  emit_insn (gen_ashlsi_c (operands[0], operands[1]));
1569  emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
1570  DONE;
1571}")
1572
1573(define_insn "ashlsi_c"
1574  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1575	(ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
1576   (set (reg:SI 18) (lt:SI (match_dup 1)
1577			   (const_int 0)))]
1578  ""
1579  "shll	%0"
1580  [(set_attr "type" "arith")])
1581
1582(define_insn "ashrsi3_d"
1583  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1584	(ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1585		     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1586  "TARGET_SH3"
1587  "shad	%2,%0"
1588  [(set_attr "type" "dyn_shift")])
1589
1590(define_insn "ashrsi3_n"
1591  [(set (reg:SI 4)
1592	(ashiftrt:SI (reg:SI 4)
1593		     (match_operand:SI 0 "const_int_operand" "i")))
1594   (clobber (reg:SI 18))
1595   (clobber (reg:SI 17))
1596   (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1597  ""
1598  "jsr	@%1%#"
1599  [(set_attr "type" "sfunc")
1600   (set_attr "needs_delay_slot" "yes")])
1601
1602(define_expand "ashrsi3"
1603  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1604		   (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1605				(match_operand:SI 2 "nonmemory_operand" "")))
1606	      (clobber (reg:SI 18))])]
1607  ""
1608  "if (expand_ashiftrt (operands)) DONE; else FAIL;")
1609
1610;; logical shift right
1611
1612(define_insn "lshrsi3_d"
1613  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1614	(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1615		     (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1616  "TARGET_SH3"
1617  "shld	%2,%0"
1618  [(set_attr "type" "dyn_shift")])
1619
1620;;  Only the single bit shift clobbers the T bit.
1621
1622(define_insn "lshrsi3_m"
1623  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1624	(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1625		     (match_operand:SI 2 "const_int_operand" "M")))
1626   (clobber (reg:SI 18))]
1627  "CONST_OK_FOR_M (INTVAL (operands[2]))"
1628  "shlr	%0"
1629  [(set_attr "type" "arith")])
1630
1631(define_insn "lshrsi3_k"
1632  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1633	(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1634		     (match_operand:SI 2 "const_int_operand" "K")))]
1635  "CONST_OK_FOR_K (INTVAL (operands[2]))
1636   && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
1637  "shlr%O2	%0"
1638  [(set_attr "type" "arith")])
1639
1640(define_insn "lshrsi3_n"
1641  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1642	(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1643		     (match_operand:SI 2 "const_int_operand" "n")))
1644   (clobber (reg:SI 18))]
1645  "! sh_dynamicalize_shift_p (operands[2])"
1646  "#"
1647  [(set (attr "length")
1648	(cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
1649	       (const_string "2")
1650	       (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
1651	       (const_string "4")
1652	       (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
1653	       (const_string "6")]
1654	      (const_string "8")))
1655   (set_attr "type" "arith")])
1656
1657(define_split
1658  [(set (match_operand:SI 0 "arith_reg_operand" "")
1659	(lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1660		     (match_operand:SI 2 "const_int_operand" "n")))
1661   (clobber (reg:SI 18))]
1662  ""
1663  [(use (reg:SI 0))]
1664  "
1665{
1666  gen_shifty_op (LSHIFTRT, operands);
1667  DONE;
1668}")
1669
1670(define_expand "lshrsi3"
1671  [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
1672		   (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
1673				(match_operand:SI 2 "nonmemory_operand" "")))
1674	      (clobber (reg:SI 18))])]
1675  ""
1676  "
1677{
1678  if (GET_CODE (operands[2]) == CONST_INT
1679      && sh_dynamicalize_shift_p (operands[2]))
1680    operands[2] = force_reg (SImode, operands[2]);
1681  if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
1682    {
1683      rtx count = copy_to_mode_reg (SImode, operands[2]);
1684      emit_insn (gen_negsi2 (count, count));
1685      emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
1686      DONE;
1687    }
1688  if (! immediate_operand (operands[2], GET_MODE (operands[2])))
1689    FAIL;
1690}")
1691
1692;; ??? This should be a define expand.
1693
1694(define_insn "ashldi3_k"
1695  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1696	(ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
1697		   (const_int 1)))
1698   (clobber (reg:SI 18))]
1699  ""
1700  "shll	%R0\;rotcl	%S0"
1701  [(set_attr "length" "4")
1702   (set_attr "type" "arith")])
1703
1704(define_expand "ashldi3"
1705  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1706		   (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
1707			      (match_operand:DI 2 "immediate_operand" "")))
1708	      (clobber (reg:SI 18))])]
1709  ""
1710  "{ if (GET_CODE (operands[2]) != CONST_INT
1711	 || INTVAL (operands[2]) != 1) FAIL;} ")
1712
1713;; ??? This should be a define expand.
1714
1715(define_insn "lshrdi3_k"
1716  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1717	(lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1718		     (const_int 1)))
1719   (clobber (reg:SI 18))]
1720  ""
1721  "shlr	%S0\;rotcr	%R0"
1722  [(set_attr "length" "4")
1723   (set_attr "type" "arith")])
1724
1725(define_expand "lshrdi3"
1726  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1727		   (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1728			       (match_operand:DI 2 "immediate_operand" "")))
1729	     (clobber (reg:SI 18))])]
1730  ""
1731  "{ if (GET_CODE (operands[2]) != CONST_INT
1732	 || INTVAL (operands[2]) != 1) FAIL;} ")
1733
1734;; ??? This should be a define expand.
1735
1736(define_insn "ashrdi3_k"
1737  [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1738	(ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
1739		     (const_int 1)))
1740   (clobber (reg:SI 18))]
1741  ""
1742  "shar	%S0\;rotcr	%R0"
1743  [(set_attr "length" "4")
1744   (set_attr "type" "arith")])
1745
1746(define_expand "ashrdi3"
1747  [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
1748		   (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
1749				(match_operand:DI 2 "immediate_operand" "")))
1750	      (clobber (reg:SI 18))])]
1751  ""
1752  "{ if (GET_CODE (operands[2]) != CONST_INT
1753	 || INTVAL (operands[2]) != 1) FAIL; } ")
1754
1755;; combined left/right shift
1756
1757(define_split
1758  [(set (match_operand:SI 0 "register_operand" "")
1759	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1760			   (match_operand:SI 2 "const_int_operand" "n"))
1761		(match_operand:SI 3 "const_int_operand" "n")))]
1762  "(unsigned)INTVAL (operands[2]) < 32"
1763  [(use (reg:SI 0))]
1764  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1765   DONE;")
1766
1767(define_split
1768  [(set (match_operand:SI 0 "register_operand" "")
1769	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
1770			   (match_operand:SI 2 "const_int_operand" "n"))
1771		(match_operand:SI 3 "const_int_operand" "n")))
1772   (clobber (reg:SI 18))]
1773  "(unsigned)INTVAL (operands[2]) < 32"
1774  [(use (reg:SI 0))]
1775  "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
1776   DONE;")
1777
1778(define_insn ""
1779  [(set (match_operand:SI 0 "register_operand" "=r")
1780	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1781			   (match_operand:SI 2 "const_int_operand" "n"))
1782		(match_operand:SI 3 "const_int_operand" "n")))
1783   (clobber (reg:SI 18))]
1784  "shl_and_kind (operands[2], operands[3], 0) == 1"
1785 "#"
1786  [(set (attr "length")
1787	(cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1788	       (const_string "4")
1789	       (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1790	       (const_string "6")
1791	       (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1792	       (const_string "8")
1793	       (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
1794	       (const_string "10")
1795	       (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
1796	       (const_string "12")
1797	       (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
1798	       (const_string "14")
1799	       (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
1800	       (const_string "16")]
1801	      (const_string "18")))
1802   (set_attr "type" "arith")])
1803
1804(define_insn ""
1805  [(set (match_operand:SI 0 "register_operand" "=z")
1806	(and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1807			   (match_operand:SI 2 "const_int_operand" "n"))
1808		(match_operand:SI 3 "const_int_operand" "n")))
1809   (clobber (reg:SI 18))]
1810  "shl_and_kind (operands[2], operands[3], 0) == 2"
1811 "#"
1812  [(set (attr "length")
1813	(cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
1814	       (const_string "4")
1815	       (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
1816	       (const_string "6")
1817	       (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
1818	       (const_string "8")]
1819	      (const_string "10")))
1820   (set_attr "type" "arith")])
1821
1822;; shift left / and combination with a scratch register: The combine pass
1823;; does not accept the individual instructions, even though they are
1824;; cheap.  But it needs a precise description so that it is usable after
1825;; reload.
1826(define_insn "and_shl_scratch"
1827  [(set (match_operand:SI 0 "register_operand" "=r,&r")
1828	(lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1829						     (match_operand:SI 2 "const_int_operand" "N,n"))
1830					(match_operand:SI 3 "" "0,r"))
1831				(match_operand:SI 4 "const_int_operand" "n,n"))
1832		     (match_operand:SI 5 "const_int_operand" "n,n")))
1833   (clobber (reg:SI 18))]
1834  ""
1835  "#"
1836  [(set (attr "length")
1837	(cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
1838	       (const_string "4")
1839	       (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
1840	       (const_string "6")
1841	       (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
1842	       (const_string "8")
1843	       (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
1844	       (const_string "10")]
1845	      (const_string "12")))
1846   (set_attr "type" "arith")])
1847
1848(define_split
1849  [(set (match_operand:SI 0 "register_operand" "=r,&r")
1850	(lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
1851						     (match_operand:SI 2 "const_int_operand" "N,n"))
1852					(match_operand:SI 3 "register_operand" "0,r"))
1853				(match_operand:SI 4 "const_int_operand" "n,n"))
1854		     (match_operand:SI 5 "const_int_operand" "n,n")))
1855   (clobber (reg:SI 18))]
1856  ""
1857  [(use (reg:SI 0))]
1858  "
1859{
1860  rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
1861
1862  if (INTVAL (operands[2]))
1863    {
1864      gen_shifty_op (LSHIFTRT, operands);
1865    }
1866  emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
1867  operands[2] = operands[4];
1868  gen_shifty_op (ASHIFT, operands);
1869  if (INTVAL (operands[5]))
1870    {
1871      operands[2] = operands[5];
1872      gen_shifty_op (LSHIFTRT, operands);
1873    }
1874  DONE;
1875}")
1876
1877;; signed left/right shift combination.
1878(define_split
1879  [(set (match_operand:SI 0 "register_operand" "=r")
1880        (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
1881				    (match_operand:SI 2 "const_int_operand" "n"))
1882			 (match_operand:SI 3 "const_int_operand" "n")
1883			 (const_int 0)))
1884   (clobber (reg:SI 18))]
1885  ""
1886  [(use (reg:SI 0))]
1887  "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
1888   DONE;")
1889
1890(define_insn "shl_sext_ext"
1891  [(set (match_operand:SI 0 "register_operand" "=r")
1892        (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1893				    (match_operand:SI 2 "const_int_operand" "n"))
1894			 (match_operand:SI 3 "const_int_operand" "n")
1895			 (const_int 0)))
1896   (clobber (reg:SI 18))]
1897  "(unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
1898  "#"
1899  [(set (attr "length")
1900	(cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
1901	       (const_string "2")
1902	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
1903	       (const_string "4")
1904	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1905	       (const_string "6")
1906	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1907	       (const_string "8")
1908	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1909	       (const_string "10")
1910	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1911	       (const_string "12")
1912	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
1913	       (const_string "14")
1914	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
1915	       (const_string "16")]
1916	      (const_string "18")))
1917    (set_attr "type" "arith")])
1918
1919(define_insn "shl_sext_sub"
1920  [(set (match_operand:SI 0 "register_operand" "=z")
1921        (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
1922				    (match_operand:SI 2 "const_int_operand" "n"))
1923			 (match_operand:SI 3 "const_int_operand" "n")
1924			 (const_int 0)))
1925   (clobber (reg:SI 18))]
1926  "(shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
1927  "#"
1928  [(set (attr "length")
1929	(cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
1930	       (const_string "6")
1931	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
1932	       (const_string "8")
1933	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
1934	       (const_string "10")
1935	       (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
1936	       (const_string "12")]
1937	      (const_string "14")))
1938    (set_attr "type" "arith")])
1939
1940;; These patterns are found in expansions of DImode shifts by 16, and
1941;; allow the xtrct instruction to be generated from C source.
1942
1943(define_insn "xtrct_left"
1944  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1945        (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
1946			   (const_int 16))
1947 	        (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
1948			     (const_int 16))))]
1949  ""
1950  "xtrct	%1,%0"
1951  [(set_attr "type" "arith")])
1952
1953(define_insn "xtrct_right"
1954  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1955        (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
1956			     (const_int 16))
1957 	        (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
1958			   (const_int 16))))]
1959  ""
1960  "xtrct	%2,%0"
1961  [(set_attr "type" "arith")])
1962
1963;; -------------------------------------------------------------------------
1964;; Unary arithmetic
1965;; -------------------------------------------------------------------------
1966
1967(define_insn "negc"
1968  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1969	(neg:SI (plus:SI (reg:SI 18)
1970			 (match_operand:SI 1 "arith_reg_operand" "r"))))
1971   (set (reg:SI 18)
1972	(ne:SI (ior:SI (reg:SI 18) (match_dup 1))
1973	       (const_int 0)))]
1974  ""
1975  "negc	%1,%0"
1976  [(set_attr "type" "arith")])
1977
1978(define_expand "negdi2"
1979  [(set (match_operand:DI 0 "arith_reg_operand" "")
1980	(neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
1981   (clobber (reg:SI 18))]
1982  ""
1983  "
1984{
1985  int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
1986  int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
1987
1988  rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
1989  rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
1990
1991  rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
1992  rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
1993
1994  emit_insn (gen_clrt ());
1995  emit_insn (gen_negc (low_dst, low_src));
1996  emit_insn (gen_negc (high_dst, high_src));
1997  DONE;
1998}")
1999
2000(define_insn "negsi2"
2001  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2002	(neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2003  ""
2004  "neg	%1,%0"
2005  [(set_attr "type" "arith")])
2006
2007(define_insn "one_cmplsi2"
2008  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2009	(not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2010  ""
2011  "not	%1,%0"
2012  [(set_attr "type" "arith")])
2013
2014;; -------------------------------------------------------------------------
2015;; Zero extension instructions
2016;; -------------------------------------------------------------------------
2017
2018(define_insn "zero_extendhisi2"
2019  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2020	(zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2021  ""
2022  "extu.w	%1,%0"
2023  [(set_attr "type" "arith")])
2024
2025(define_insn "zero_extendqisi2"
2026  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2027	(zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2028  ""
2029  "extu.b	%1,%0"
2030  [(set_attr "type" "arith")])
2031
2032(define_insn "zero_extendqihi2"
2033  [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2034	(zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
2035  ""
2036  "extu.b	%1,%0"
2037  [(set_attr "type" "arith")])
2038
2039;; -------------------------------------------------------------------------
2040;; Sign extension instructions
2041;; -------------------------------------------------------------------------
2042
2043;; ??? This should be a define expand.
2044;; ??? Or perhaps it should be dropped?
2045
2046/* There is no point in defining extendsidi2; convert_move generates good
2047   code for that.  */
2048
2049(define_insn "extendhisi2"
2050  [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2051	(sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
2052  ""
2053  "@
2054	exts.w	%1,%0
2055   	mov.w	%1,%0"
2056  [(set_attr "type" "arith,load")])
2057
2058(define_insn "extendqisi2"
2059  [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2060	(sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2061  ""
2062  "@
2063	exts.b	%1,%0
2064	mov.b	%1,%0"
2065  [(set_attr "type" "arith,load")])
2066
2067(define_insn "extendqihi2"
2068  [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2069	(sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
2070  ""
2071  "@
2072	exts.b	%1,%0
2073	mov.b	%1,%0"
2074  [(set_attr "type" "arith,load")])
2075
2076;; -------------------------------------------------------------------------
2077;; Move instructions
2078;; -------------------------------------------------------------------------
2079
2080;; define push and pop so it is easy for sh.c
2081
2082(define_expand "push"
2083  [(set (mem:SI (pre_dec:SI (reg:SI 15)))
2084	(match_operand:SI 0 "register_operand" "r,l,x"))]
2085  ""
2086  "")
2087
2088(define_expand "pop"
2089  [(set (match_operand:SI 0 "register_operand" "=r,l,x")
2090	(mem:SI (post_inc:SI (reg:SI 15))))]
2091  ""
2092  "")
2093
2094(define_expand "push_e"
2095  [(parallel [(set (mem:SF (pre_dec:SI (reg:SI 15)))
2096		   (match_operand:SF 0 "" ""))
2097	      (use (reg:PSI 48))
2098	      (clobber (scratch:SI))])]
2099  ""
2100  "")
2101
2102(define_insn "push_fpul"
2103  [(set (mem:SF (pre_dec:SI (reg:SI 15))) (reg:SF 22))]
2104  "TARGET_SH3E"
2105  "sts.l	fpul,@-r15"
2106  [(set_attr "type" "store")
2107   (set_attr "hit_stack" "yes")])
2108
2109;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
2110;; so use that.
2111(define_expand "push_4"
2112  [(parallel [(set (mem:DF (pre_dec:SI (reg:SI 15))) (match_operand:DF 0 "" ""))
2113	      (use (reg:PSI 48))
2114	      (clobber (scratch:SI))])]
2115  ""
2116  "")
2117
2118(define_expand "pop_e"
2119  [(parallel [(set (match_operand:SF 0 "" "")
2120	      (mem:SF (post_inc:SI (reg:SI 15))))
2121	      (use (reg:PSI 48))
2122	      (clobber (scratch:SI))])]
2123  ""
2124  "")
2125
2126(define_insn "pop_fpul"
2127  [(set (reg:SF 22) (mem:SF (post_inc:SI (reg:SI 15))))]
2128  "TARGET_SH3E"
2129  "lds.l	@r15+,fpul"
2130  [(set_attr "type" "load")
2131   (set_attr "hit_stack" "yes")])
2132
2133(define_expand "pop_4"
2134  [(parallel [(set (match_operand:DF 0 "" "")
2135		   (mem:DF (post_inc:SI (reg:SI 15))))
2136	      (use (reg:PSI 48))
2137	      (clobber (scratch:SI))])]
2138  ""
2139  "")
2140
2141;; These two patterns can happen as the result of optimization, when
2142;; comparisons get simplified to a move of zero or 1 into the T reg.
2143;; They don't disappear completely, because the T reg is a fixed hard reg.
2144
2145(define_insn "clrt"
2146  [(set (reg:SI 18) (const_int 0))]
2147  ""
2148  "clrt")
2149
2150(define_insn "sett"
2151  [(set (reg:SI 18) (const_int 1))]
2152  ""
2153  "sett")
2154
2155;; t/r must come after r/r, lest reload will try to reload stuff like
2156;; (set (subreg:SI (mem:QI (plus:SI (reg:SI 15 r15) (const_int 12)) 0) 0)
2157;; (made from (set (subreg:SI (reg:QI 73) 0) ) into T.
2158(define_insn "movsi_i"
2159  [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,r")
2160	(match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,i"))]
2161  "
2162   ! TARGET_SH3E
2163   && (register_operand (operands[0], SImode)
2164       || register_operand (operands[1], SImode))"
2165  "@
2166	mov.l	%1,%0
2167	mov	%1,%0
2168	cmp/pl	%1
2169	mov.l	%1,%0
2170	sts	%1,%0
2171	movt	%0
2172	mov.l	%1,%0
2173	sts.l	%1,%0
2174	sts.l	%1,%0
2175	lds	%1,%0
2176	lds.l	%1,%0
2177	lds.l	%1,%0
2178	fake	%1,%0"
2179  [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,pcload_si")
2180   (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*")])
2181
2182;; t/r must come after r/r, lest reload will try to reload stuff like
2183;; (subreg:SI (reg:SF 38 fr14) 0) into T (compiling stdlib/strtod.c -m3e -O2)
2184;; ??? This allows moves from macl to fpul to be recognized, but these moves
2185;; will require a reload.
2186(define_insn "movsi_ie"
2187  [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,m,<,<,xl,x,l,y,r,y,r,y")
2188	(match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,xl,t,r,x,l,r,>,>,>,i,r,y,y"))]
2189  "TARGET_SH3E
2190   && (register_operand (operands[0], SImode)
2191       || register_operand (operands[1], SImode))"
2192  "@
2193	mov.l	%1,%0
2194	mov	%1,%0
2195	cmp/pl	%1
2196	mov.l	%1,%0
2197	sts	%1,%0
2198	movt	%0
2199	mov.l	%1,%0
2200	sts.l	%1,%0
2201	sts.l	%1,%0
2202	lds	%1,%0
2203	lds.l	%1,%0
2204	lds.l	%1,%0
2205	lds.l	%1,%0
2206	fake	%1,%0
2207	lds	%1,%0
2208	sts	%1,%0
2209	! move optimized away"
2210  [(set_attr "type" "pcload_si,move,*,load_si,move,move,store,store,pstore,move,load,pload,load,pcload_si,gp_fpul,gp_fpul,nil")
2211   (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
2212
2213(define_insn "movsi_i_lowpart"
2214  [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,r,m,r"))
2215	(match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,xl,t,r,i"))]
2216   "register_operand (operands[0], SImode)
2217    || register_operand (operands[1], SImode)"
2218  "@
2219	mov.l	%1,%0
2220	mov	%1,%0
2221	mov.l	%1,%0
2222	sts	%1,%0
2223	movt	%0
2224	mov.l	%1,%0
2225	fake	%1,%0"
2226  [(set_attr "type" "pcload,move,load,move,move,store,pcload")])
2227(define_expand "movsi"
2228  [(set (match_operand:SI 0 "general_movdst_operand" "")
2229	(match_operand:SI 1 "general_movsrc_operand" ""))]
2230  ""
2231  "{ if (prepare_move_operands (operands, SImode)) DONE; }")
2232
2233(define_expand "ic_invalidate_line"
2234  [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
2235				(match_dup 1)] 12)
2236	      (clobber (scratch:SI))])]
2237  "TARGET_HARD_SH4"
2238  "
2239{
2240  operands[0] = force_reg (Pmode, operands[0]);
2241  operands[1] = force_reg (Pmode, GEN_INT (0xf0000008));
2242}")
2243
2244;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
2245;; 0xf0000008, we get the low-oder bits *1*00 (binary), ;; which fits
2246;; the requirement *0*00 for associative address writes.  The alignment of
2247;; %0 implies that its least significant bit is cleared,
2248;; thus we clear the V bit of a matching entry if there is one.
2249(define_insn "ic_invalidate_line_i"
2250  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r,r")
2251		     (match_operand:SI 1 "register_operand" "r,r")] 12)
2252   (clobber (match_scratch:SI 2 "=&r,1"))]
2253  "TARGET_HARD_SH4"
2254  "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%r1,%r2\;mov.l\\t%0,@%2"
2255  [(set_attr "length" "8")])
2256
2257(define_insn "movqi_i"
2258  [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
2259	(match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
2260  "arith_reg_operand (operands[0], QImode)
2261   || arith_reg_operand (operands[1], QImode)"
2262  "@
2263	mov	%1,%0
2264	mov.b	%1,%0
2265	mov.b	%1,%0
2266	movt	%0
2267	sts	%1,%0
2268	lds	%1,%0"
2269 [(set_attr "type" "move,load,store,move,move,move")])
2270
2271(define_expand "movqi"
2272  [(set (match_operand:QI 0 "general_operand" "")
2273	(match_operand:QI 1 "general_operand"  ""))]
2274  ""
2275  "{ if (prepare_move_operands (operands, QImode)) DONE; }")
2276
2277(define_insn "movhi_i"
2278  [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
2279	(match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
2280  "arith_reg_operand (operands[0], HImode)
2281   || arith_reg_operand (operands[1], HImode)"
2282  "@
2283	mov.w	%1,%0
2284	mov	%1,%0
2285	mov.w	%1,%0
2286	movt	%0
2287	mov.w	%1,%0
2288	sts	%1,%0
2289	lds	%1,%0
2290	fake	%1,%0"
2291  [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
2292
2293(define_expand "movhi"
2294  [(set (match_operand:HI 0 "general_movdst_operand" "")
2295	(match_operand:HI 1 "general_movsrc_operand"  ""))]
2296  ""
2297  "{ if (prepare_move_operands (operands, HImode)) DONE; }")
2298
2299;; ??? This should be a define expand.
2300
2301;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
2302;; compiled with -m2 -ml -O3 -funroll-loops
2303(define_insn ""
2304  [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
2305	(match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
2306  "arith_reg_operand (operands[0], DImode)
2307   || arith_reg_operand (operands[1], DImode)"
2308  "* return output_movedouble (insn, operands, DImode);"
2309  [(set_attr "length" "4")
2310   (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
2311
2312;; If the output is a register and the input is memory or a register, we have
2313;; to be careful and see which word needs to be loaded first.  
2314
2315(define_split
2316  [(set (match_operand:DI 0 "general_movdst_operand" "")
2317	(match_operand:DI 1 "general_movsrc_operand" ""))]
2318  "reload_completed"
2319  [(set (match_dup 2) (match_dup 3))
2320   (set (match_dup 4) (match_dup 5))]
2321  "
2322{
2323  int regno;
2324
2325  if ((GET_CODE (operands[0]) == MEM
2326       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2327      || (GET_CODE (operands[1]) == MEM
2328	  && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
2329    FAIL;
2330
2331  if (GET_CODE (operands[0]) == REG)
2332    regno = REGNO (operands[0]);
2333  else if (GET_CODE (operands[0]) == SUBREG)
2334    regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
2335  else if (GET_CODE (operands[0]) == MEM)
2336    regno = -1;
2337
2338  if (regno == -1
2339      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
2340    {
2341      operands[2] = operand_subword (operands[0], 0, 0, DImode);
2342      operands[3] = operand_subword (operands[1], 0, 0, DImode);
2343      operands[4] = operand_subword (operands[0], 1, 0, DImode);
2344      operands[5] = operand_subword (operands[1], 1, 0, DImode);
2345    }
2346  else
2347    {
2348      operands[2] = operand_subword (operands[0], 1, 0, DImode);
2349      operands[3] = operand_subword (operands[1], 1, 0, DImode);
2350      operands[4] = operand_subword (operands[0], 0, 0, DImode);
2351      operands[5] = operand_subword (operands[1], 0, 0, DImode);
2352    }
2353
2354  if (operands[2] == 0 || operands[3] == 0
2355      || operands[4] == 0 || operands[5] == 0)
2356    FAIL;
2357}")
2358
2359(define_expand "movdi"
2360  [(set (match_operand:DI 0 "general_movdst_operand" "")
2361	(match_operand:DI 1 "general_movsrc_operand" ""))]
2362  ""
2363  "{ if ( prepare_move_operands (operands, DImode)) DONE; }")
2364
2365;; ??? This should be a define expand.
2366
2367(define_insn "movdf_k"
2368  [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
2369	(match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
2370  "(! TARGET_SH4 || reload_completed
2371    /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
2372    || GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3
2373    || GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3)
2374   && (arith_reg_operand (operands[0], DFmode)
2375       || arith_reg_operand (operands[1], DFmode))"
2376  "* return output_movedouble (insn, operands, DFmode);"
2377  [(set_attr "length" "4")
2378   (set_attr "type" "move,pcload,load,store")])
2379
2380;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
2381;; However, the d/F/c/z alternative cannot be split directly; it is converted
2382;; with special code in machine_dependent_reorg into a load of the R0_REG and
2383;; the d/m/c/X alternative, which is split later into single-precision
2384;; instructions.  And when not optimizing, no splits are done before fixing
2385;; up pcloads, so we need usable length information for that.
2386(define_insn "movdf_i4"
2387  [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
2388	(match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
2389   (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
2390   (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
2391  "TARGET_SH4
2392   && (arith_reg_operand (operands[0], DFmode)
2393       || arith_reg_operand (operands[1], DFmode))"
2394  "@
2395	fmov	%1,%0
2396	#
2397	#
2398	fmov.d	%1,%0
2399	fmov.d	%1,%0
2400	#
2401	#
2402	#
2403	#
2404	#"
2405  [(set_attr_alternative "length"
2406     [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
2407      (const_int 4)
2408      (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
2409      (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
2410      (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
2411      (const_int 4)
2412      (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
2413      (const_int 8) (const_int 8)])
2414   (set_attr "type" "fmove,move,pcload,load,store,pcload,load,store,load,load")])
2415
2416;; Moving DFmode between fp/general registers through memory
2417;; (the top of the stack) is faster than moving through fpul even for
2418;; little endian.  Because the type of an instruction is important for its
2419;; scheduling,  it is beneficial to split these operations, rather than
2420;; emitting them in one single chunk, even if this will expose a stack
2421;; use that will prevent scheduling of other stack accesses beyond this
2422;; instruction.
2423(define_split
2424  [(set (match_operand:DF 0 "register_operand" "")
2425	(match_operand:DF 1 "register_operand" ""))
2426   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2427   (clobber (match_scratch:SI 3 "=X"))]
2428  "TARGET_SH4 && reload_completed
2429   && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
2430  [(const_int 0)]
2431  "
2432{
2433  rtx insn, tos;
2434
2435  tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
2436  insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
2437  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
2438  tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
2439  insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
2440  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
2441  DONE;
2442}")
2443
2444;; local-alloc sometimes allocates scratch registers even when not required,
2445;; so we must be prepared to handle these.
2446
2447;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
2448(define_split
2449  [(set (match_operand:DF 0 "general_movdst_operand" "")
2450	(match_operand:DF 1 "general_movsrc_operand"  ""))
2451   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2452   (clobber (match_scratch:SI 3 "X"))]
2453  "TARGET_SH4
2454   && reload_completed
2455   && true_regnum (operands[0]) < 16
2456   && true_regnum (operands[1]) < 16"
2457  [(set (match_dup 0) (match_dup 1))]
2458  "
2459{
2460  /* If this was a reg <-> mem operation with base + index reg addressing,
2461     we have to handle this in a special way.  */
2462  rtx mem = operands[0];
2463  int store_p = 1;
2464  if (! memory_operand (mem, DFmode))
2465    {
2466      mem = operands[1];
2467      store_p = 0;
2468    }
2469  if (GET_CODE (mem) == SUBREG && SUBREG_WORD (mem) == 0)
2470    mem = SUBREG_REG (mem);
2471  if (GET_CODE (mem) == MEM)
2472    {
2473      rtx addr = XEXP (mem, 0);
2474      if (GET_CODE (addr) == PLUS
2475	  && GET_CODE (XEXP (addr, 0)) == REG
2476	  && GET_CODE (XEXP (addr, 1)) == REG)
2477	{
2478	  int offset;
2479	  rtx reg0 = gen_rtx (REG, Pmode, 0);
2480	  rtx regop = operands[store_p], word0 ,word1;
2481
2482	  if (GET_CODE (regop) == SUBREG)
2483	    regop = alter_subreg (regop);
2484	  if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
2485	    offset = 2;
2486	  else
2487	    offset = 4;
2488	  mem = copy_rtx (mem);
2489	  PUT_MODE (mem, SImode);
2490	  word0 = gen_rtx(SUBREG, SImode, regop, 0);
2491	  emit_insn (store_p
2492		     ? gen_movsi_ie (mem, word0) : gen_movsi_ie (word0, mem));
2493	  emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
2494	  mem = copy_rtx (mem);
2495	  word1 = gen_rtx(SUBREG, SImode, regop, 1);
2496	  emit_insn (store_p
2497		     ? gen_movsi_ie (mem, word1) : gen_movsi_ie (word1, mem));
2498	  emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
2499	  DONE;
2500	}
2501    }
2502}")
2503
2504;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
2505(define_split
2506  [(set (match_operand:DF 0 "register_operand" "")
2507	(match_operand:DF 1 "memory_operand"  ""))
2508   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2509   (clobber (reg:SI 0))]
2510  "TARGET_SH4 && reload_completed"
2511  [(parallel [(set (match_dup 0) (match_dup 1))
2512	      (use (match_dup 2))
2513	      (clobber (scratch:SI))])]
2514  "")
2515
2516(define_expand "reload_indf"
2517  [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
2518		   (match_operand:DF 1 "immediate_operand" "FQ"))
2519	      (use (reg:PSI 48))
2520	      (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
2521  ""
2522  "")
2523
2524(define_expand "reload_outdf"
2525  [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
2526		   (match_operand:DF 1 "register_operand" "af,r"))
2527	      (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
2528  ""
2529  "")
2530
2531;; Simplify no-op moves.
2532(define_split
2533  [(set (match_operand:SF 0 "register_operand" "")
2534	(match_operand:SF 1 "register_operand" ""))
2535   (use (match_operand:PSI 2 "fpscr_operand" ""))
2536   (clobber (match_scratch:SI 3 "X"))]
2537  "TARGET_SH3E && reload_completed
2538   && true_regnum (operands[0]) == true_regnum (operands[1])"
2539  [(set (match_dup 0) (match_dup 0))]
2540  "")
2541
2542;; fmovd substitute post-reload splits
2543(define_split
2544  [(set (match_operand:DF 0 "register_operand" "")
2545	(match_operand:DF 1 "register_operand" ""))
2546   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2547   (clobber (match_scratch:SI 3 "X"))]
2548  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2549   && true_regnum (operands[0]) >= FIRST_FP_REG
2550   && true_regnum (operands[1]) >= FIRST_FP_REG"
2551  [(const_int 0)]
2552  "
2553{
2554  int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
2555  emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
2556			   gen_rtx (REG, SFmode, src), operands[2]));
2557  emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
2558			   gen_rtx (REG, SFmode, src + 1), operands[2]));
2559  DONE;
2560}")
2561
2562(define_split
2563  [(set (match_operand:DF 0 "register_operand" "")
2564	(mem:DF (match_operand:SI 1 "register_operand" "")))
2565   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2566   (clobber (match_scratch:SI 3 "X"))]
2567  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2568   && true_regnum (operands[0]) >= FIRST_FP_REG
2569   && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
2570  [(const_int 0)]
2571  "
2572{
2573  int regno = true_regnum (operands[0]);
2574  rtx insn;
2575  rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
2576
2577  insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
2578					   regno + !! TARGET_LITTLE_ENDIAN),
2579				  mem2, operands[2]));
2580  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
2581  insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
2582					   regno + ! TARGET_LITTLE_ENDIAN),
2583				  gen_rtx (MEM, SFmode, operands[1]),
2584				  operands[2]));
2585  DONE;
2586}")
2587
2588(define_split
2589  [(set (match_operand:DF 0 "register_operand" "")
2590	(match_operand:DF 1 "memory_operand" ""))
2591   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2592   (clobber (match_scratch:SI 3 "X"))]
2593  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2594   && true_regnum (operands[0]) >= FIRST_FP_REG"
2595  [(const_int 0)]
2596  "
2597{
2598  int regno = true_regnum (operands[0]);
2599  rtx addr, insn, adjust = NULL_RTX;
2600  rtx mem2 = copy_rtx (operands[1]);
2601  rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
2602  rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
2603
2604  PUT_MODE (mem2, SFmode);
2605  operands[1] = copy_rtx (mem2);
2606  addr = XEXP (mem2, 0);
2607  if (GET_CODE (addr) != POST_INC)
2608    {
2609      /* If we have to modify the stack pointer, the value that we have
2610	 read with post-increment might be modified by an interrupt,
2611	 so write it back.  */
2612      if (REGNO (addr) == STACK_POINTER_REGNUM)
2613	adjust = gen_push_e (reg0);
2614      else
2615	adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
2616      XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
2617    }
2618  addr = XEXP (addr, 0);
2619  insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
2620  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
2621  insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
2622  if (adjust)
2623    emit_insn (adjust);
2624  else
2625    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
2626  DONE;
2627}")
2628
2629(define_split
2630  [(set (match_operand:DF 0 "memory_operand" "")
2631	(match_operand:DF 1 "register_operand" ""))
2632   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2633   (clobber (match_scratch:SI 3 "X"))]
2634  "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
2635   && true_regnum (operands[1]) >= FIRST_FP_REG"
2636  [(const_int 0)]
2637  "
2638{
2639  int regno = true_regnum (operands[1]);
2640  rtx insn, addr, adjust = NULL_RTX;
2641
2642  operands[0] = copy_rtx (operands[0]);
2643  PUT_MODE (operands[0], SFmode);
2644  insn = emit_insn (gen_movsf_ie (operands[0],
2645				  gen_rtx (REG, SFmode,
2646					   regno + ! TARGET_LITTLE_ENDIAN),
2647				  operands[2]));
2648  operands[0] = copy_rtx (operands[0]);
2649  addr = XEXP (operands[0], 0);
2650  if (GET_CODE (addr) != PRE_DEC)
2651    {
2652      adjust = gen_addsi3 (addr, addr, GEN_INT (4));
2653      emit_insn_before (adjust, insn);
2654      XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
2655    }
2656  addr = XEXP (addr, 0);
2657  if (! adjust)
2658    REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
2659  insn = emit_insn (gen_movsf_ie (operands[0],
2660				  gen_rtx (REG, SFmode,
2661					   regno + !! TARGET_LITTLE_ENDIAN),
2662				  operands[2]));
2663  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
2664  DONE;
2665}")
2666
2667;; The '&' for operand 2 is not really true, but push_secondary_reload
2668;; insists on it.
2669;; Operand 1 must accept FPUL_REGS in case fpul is reloaded to memory,
2670;; to avoid a bogus tertiary reload.
2671;; We need a tertiary reload when a floating point register is reloaded
2672;; to memory, so the predicate for operand 0 must accept this, while the 
2673;; constraint of operand 1 must reject the secondary reload register.
2674;; Thus, the secondary reload register for this case has to be GENERAL_REGS,
2675;; too.
2676;; By having the predicate for operand 0 reject any register, we make
2677;; sure that the ordinary moves that just need an intermediate register
2678;; won't get a bogus tertiary reload.
2679;; We use tertiary_reload_operand instead of memory_operand here because
2680;; memory_operand rejects operands that are not directly addressible, e.g.:
2681;; (mem:SF (plus:SI (reg:SI 14 r14)
2682;;         (const_int 132)))
2683
2684(define_expand "reload_outsf"
2685  [(parallel [(set (match_operand:SF 2 "register_operand" "=&r")
2686		   (match_operand:SF 1 "register_operand" "y"))
2687	      (clobber (scratch:SI))])
2688   (parallel [(set (match_operand:SF 0 "tertiary_reload_operand" "=m")
2689		   (match_dup 2))
2690	      (clobber (scratch:SI))])]
2691  ""
2692  "")
2693
2694;; If the output is a register and the input is memory or a register, we have
2695;; to be careful and see which word needs to be loaded first.  
2696
2697(define_split
2698  [(set (match_operand:DF 0 "general_movdst_operand" "")
2699	(match_operand:DF 1 "general_movsrc_operand" ""))]
2700  "reload_completed"
2701  [(set (match_dup 2) (match_dup 3))
2702   (set (match_dup 4) (match_dup 5))]
2703  "
2704{
2705  int regno;
2706
2707  if ((GET_CODE (operands[0]) == MEM
2708       && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
2709      || (GET_CODE (operands[1]) == MEM
2710	  && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
2711    FAIL;
2712
2713  if (GET_CODE (operands[0]) == REG)
2714    regno = REGNO (operands[0]);
2715  else if (GET_CODE (operands[0]) == SUBREG)
2716    regno = REGNO (SUBREG_REG (operands[0])) + SUBREG_WORD (operands[0]);
2717  else if (GET_CODE (operands[0]) == MEM)
2718    regno = -1;
2719
2720  if (regno == -1
2721      || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
2722    {
2723      operands[2] = operand_subword (operands[0], 0, 0, DFmode);
2724      operands[3] = operand_subword (operands[1], 0, 0, DFmode);
2725      operands[4] = operand_subword (operands[0], 1, 0, DFmode);
2726      operands[5] = operand_subword (operands[1], 1, 0, DFmode);
2727    }
2728  else
2729    {
2730      operands[2] = operand_subword (operands[0], 1, 0, DFmode);
2731      operands[3] = operand_subword (operands[1], 1, 0, DFmode);
2732      operands[4] = operand_subword (operands[0], 0, 0, DFmode);
2733      operands[5] = operand_subword (operands[1], 0, 0, DFmode);
2734    }
2735
2736  if (operands[2] == 0 || operands[3] == 0
2737      || operands[4] == 0 || operands[5] == 0)
2738    FAIL;
2739}")
2740
2741;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
2742;; used only once, let combine add in the index again.
2743
2744(define_split
2745  [(set (match_operand:SI 0 "register_operand" "")
2746	(match_operand:SI 1 "" ""))
2747   (clobber (match_operand 2 "register_operand" ""))]
2748  "! reload_in_progress && ! reload_completed"
2749  [(use (reg:SI 0))]
2750  "
2751{
2752  rtx addr, reg, const_int;
2753
2754  if (GET_CODE (operands[1]) != MEM)
2755    FAIL;
2756  addr = XEXP (operands[1], 0);
2757  if (GET_CODE (addr) != PLUS)
2758    FAIL;
2759  reg = XEXP (addr, 0);
2760  const_int = XEXP (addr, 1);
2761  if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
2762    FAIL;
2763  emit_move_insn (operands[2], const_int);
2764  emit_move_insn (operands[0],
2765		  change_address (operands[1], VOIDmode,
2766				  gen_rtx (PLUS, SImode, reg, operands[2])));
2767  DONE;
2768}")
2769
2770(define_split
2771  [(set (match_operand:SI 1 "" "")
2772	(match_operand:SI 0 "register_operand" ""))
2773   (clobber (match_operand 2 "register_operand" ""))]
2774  "! reload_in_progress && ! reload_completed"
2775  [(use (reg:SI 0))]
2776  "
2777{
2778  rtx addr, reg, const_int;
2779
2780  if (GET_CODE (operands[1]) != MEM)
2781    FAIL;
2782  addr = XEXP (operands[1], 0);
2783  if (GET_CODE (addr) != PLUS)
2784    FAIL;
2785  reg = XEXP (addr, 0);
2786  const_int = XEXP (addr, 1);
2787  if (GET_CODE (reg) != REG || GET_CODE (const_int) != CONST_INT)
2788    FAIL;
2789  emit_move_insn (operands[2], const_int);
2790  emit_move_insn (change_address (operands[1], VOIDmode,
2791				  gen_rtx (PLUS, SImode, reg, operands[2])),
2792		  operands[0]);
2793  DONE;
2794}")
2795
2796(define_expand "movdf"
2797  [(set (match_operand:DF 0 "general_movdst_operand" "")
2798	(match_operand:DF 1 "general_movsrc_operand" ""))]
2799  ""
2800  "
2801{
2802  if (prepare_move_operands (operands, DFmode)) DONE;
2803  if (TARGET_SH4)
2804    {
2805      if (no_new_pseudos)
2806	{
2807	  /* ??? FIXME: This is only a stopgap fix.  There is no guarantee
2808	     that fpscr is in the right state. */
2809	  emit_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
2810	  DONE;
2811	}
2812      emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
2813      /* We need something to tag possible REG_LIBCALL notes on to.  */
2814      if (TARGET_FPU_SINGLE && rtx_equal_function_value_matters
2815	  && GET_CODE (operands[0]) == REG)
2816	emit_insn (gen_mov_nop (operands[0]));
2817      DONE;
2818    }
2819}")
2820
2821
2822(define_insn "movsf_i"
2823  [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
2824	(match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,mr,r,r,l"))]
2825  "
2826   (! TARGET_SH3E
2827    /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
2828    || GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3
2829    || GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3)
2830   && (arith_reg_operand (operands[0], SFmode)
2831       || arith_reg_operand (operands[1], SFmode))"
2832  "@
2833	mov	%1,%0
2834	mov	%1,%0
2835	mov.l	%1,%0
2836	mov.l	%1,%0
2837	mov.l	%1,%0
2838	lds	%1,%0
2839	sts	%1,%0"
2840  [(set_attr "type" "move,move,pcload,load,store,move,move")])
2841
2842;; We may not split the ry/yr/XX alternatives to movsi_ie, since
2843;; update_flow_info would not know where to put REG_EQUAL notes
2844;; when the destination changes mode.
2845(define_insn "movsf_ie"
2846  [(set (match_operand:SF 0 "general_movdst_operand"
2847	 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,y")
2848	(match_operand:SF 1 "general_movsrc_operand"
2849	  "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y"))
2850   (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
2851   (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X"))]
2852
2853  "TARGET_SH3E
2854   && (arith_reg_operand (operands[0], SFmode)
2855       || arith_reg_operand (operands[1], SFmode))"
2856  "@
2857	fmov	%1,%0
2858	mov	%1,%0
2859	fldi0	%0
2860	fldi1	%0
2861	#
2862	fmov.s	%1,%0
2863	fmov.s	%1,%0
2864	mov.l	%1,%0
2865	mov.l	%1,%0
2866	mov.l	%1,%0
2867	fsts	fpul,%0
2868	flds	%1,fpul
2869	lds.l	%1,%0
2870	#
2871	sts	%1,%0
2872	lds	%1,%0
2873	! move optimized away"
2874  [(set_attr "type" "fmove,move,fmove,fmove,pcload,load,store,pcload,load,store,fmove,fmove,load,*,gp_fpul,gp_fpul,nil")
2875   (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,0")])
2876
2877(define_split
2878  [(set (match_operand:SF 0 "register_operand" "")
2879	(match_operand:SF 1 "register_operand" ""))
2880   (use (match_operand:PSI 2 "fpscr_operand" "c"))
2881   (clobber (reg:SI 22))]
2882  ""
2883  [(parallel [(set (reg:SF 22) (match_dup 1))
2884	      (use (match_dup 2))
2885	      (clobber (scratch:SI))])
2886   (parallel [(set (match_dup 0) (reg:SF 22))
2887	      (use (match_dup 2))
2888	      (clobber (scratch:SI))])]
2889  "")
2890
2891(define_expand "movsf"
2892  [(set (match_operand:SF 0 "general_movdst_operand" "")
2893        (match_operand:SF 1 "general_movsrc_operand" ""))]
2894  ""
2895  "
2896{
2897  if (prepare_move_operands (operands, SFmode))
2898    DONE;
2899  if (TARGET_SH3E)
2900    {
2901      if (no_new_pseudos)
2902	{
2903	  /* ??? FIXME: This is only a stopgap fix.  There is no guarantee
2904	     that fpscr is in the right state. */
2905	  emit_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
2906	  DONE;
2907	}
2908      emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
2909      /* We need something to tag possible REG_LIBCALL notes on to.  */
2910      if (! TARGET_FPU_SINGLE && rtx_equal_function_value_matters
2911	  && GET_CODE (operands[0]) == REG)
2912	emit_insn (gen_mov_nop (operands[0]));
2913      DONE;
2914    }
2915}")
2916
2917(define_insn "mov_nop"
2918  [(set (match_operand 0 "register_operand" "") (match_dup 0))]
2919  "TARGET_SH3E"
2920  ""
2921  [(set_attr "length" "0")
2922   (set_attr "type" "nil")])
2923
2924(define_expand "reload_insf"
2925  [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
2926		   (match_operand:SF 1 "immediate_operand" "FQ"))
2927	      (use (reg:PSI 48))
2928	      (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
2929  ""
2930  "")
2931
2932(define_expand "reload_insi"
2933  [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
2934		   (match_operand:SF 1 "immediate_operand" "FQ"))
2935	      (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
2936  ""
2937  "")
2938
2939(define_insn "*movsi_y"
2940  [(set (match_operand:SI 0 "register_operand" "=y,y")
2941	(match_operand:SI 1 "immediate_operand" "Qi,I"))
2942   (clobber (match_scratch:SI 3 "=&z,r"))]
2943  "TARGET_SH3E
2944   && (reload_in_progress || reload_completed)"
2945  "#"
2946  [(set_attr "length" "4")
2947   (set_attr "type" "pcload,move")])
2948
2949(define_split
2950  [(set (match_operand:SI 0 "register_operand" "y")
2951	(match_operand:SI 1 "immediate_operand" "I"))
2952   (clobber (match_operand:SI 2 "register_operand" "r"))]
2953  ""
2954  [(set (match_dup 2) (match_dup 1))
2955   (set (match_dup 0) (match_dup 2))]
2956  "")
2957
2958(define_split
2959  [(set (match_operand:SI 0 "register_operand" "y")
2960	(match_operand:SI 1 "memory_operand" ">"))
2961   (clobber (reg:SI 0))]
2962  ""
2963  [(set (match_dup 0) (match_dup 1))]
2964  "")
2965
2966;; ------------------------------------------------------------------------
2967;; Define the real conditional branch instructions.
2968;; ------------------------------------------------------------------------
2969
2970(define_insn "branch_true"
2971  [(set (pc) (if_then_else (ne (reg:SI 18) (const_int 0))
2972			   (label_ref (match_operand 0 "" ""))
2973			   (pc)))]
2974  ""
2975  "* return output_branch (1, insn, operands);"
2976  [(set_attr "type" "cbranch")])
2977
2978(define_insn "branch_false"
2979  [(set (pc) (if_then_else (eq (reg:SI 18) (const_int 0))
2980			   (label_ref (match_operand 0 "" ""))
2981			   (pc)))]
2982  ""
2983  "* return output_branch (0, insn, operands);"
2984  [(set_attr "type" "cbranch")])
2985
2986;; Patterns to prevent reorg from re-combining a condbranch with a branch
2987;; which destination is too far away.
2988;; The const_int_operand is distinct for each branch target; it avoids
2989;; unwanted matches with redundant_insn.
2990(define_insn "block_branch_redirect"
2991  [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] 4))]
2992  ""
2993  ""
2994  [(set_attr "length" "0")])
2995
2996;; This one has the additional purpose to record a possible scratch register
2997;; for the following branch.
2998(define_insn "indirect_jump_scratch"
2999  [(set (match_operand 0 "register_operand" "r")
3000	(unspec [(match_operand 1 "const_int_operand" "")] 4))]
3001  ""
3002  ""
3003  [(set_attr "length" "0")])
3004
3005;; Conditional branch insns
3006
3007(define_expand "beq"
3008  [(set (pc)
3009	(if_then_else (ne (reg:SI 18) (const_int 0))
3010		      (label_ref (match_operand 0 "" ""))
3011		      (pc)))]
3012  ""
3013  "from_compare (operands, EQ);")
3014
3015(define_expand "bne"
3016  [(set (pc)
3017	(if_then_else (eq (reg:SI 18) (const_int 0))
3018		      (label_ref (match_operand 0 "" ""))
3019		      (pc)))]
3020  ""
3021  "from_compare (operands, EQ);")
3022
3023(define_expand "bgt"
3024  [(set (pc)
3025	(if_then_else (ne (reg:SI 18) (const_int 0))
3026		      (label_ref (match_operand 0 "" ""))
3027		      (pc)))]
3028  ""
3029  "from_compare (operands, GT);")
3030
3031(define_expand "blt"
3032  [(set (pc)
3033	(if_then_else (eq (reg:SI 18) (const_int 0))
3034		      (label_ref (match_operand 0 "" ""))
3035		      (pc)))]
3036  ""
3037  "
3038{
3039  if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3040    {
3041      rtx tmp = sh_compare_op0;
3042      sh_compare_op0 = sh_compare_op1;
3043      sh_compare_op1 = tmp;
3044      emit_insn (gen_bgt (operands[0]));
3045      DONE;
3046    }
3047  from_compare (operands, GE);
3048}")
3049
3050(define_expand "ble"
3051  [(set (pc)
3052	(if_then_else (eq (reg:SI 18) (const_int 0))
3053		      (label_ref (match_operand 0 "" ""))
3054		      (pc)))]
3055  ""
3056  "
3057{
3058  if (TARGET_SH3E
3059      && TARGET_IEEE
3060      && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3061    {
3062      rtx tmp = sh_compare_op0;
3063      sh_compare_op0 = sh_compare_op1;
3064      sh_compare_op1 = tmp;
3065      emit_insn (gen_bge (operands[0]));
3066      DONE;
3067    }
3068  from_compare (operands, GT);
3069}")
3070
3071(define_expand "bge"
3072  [(set (pc)
3073	(if_then_else (ne (reg:SI 18) (const_int 0))
3074		      (label_ref (match_operand 0 "" ""))
3075		      (pc)))]
3076  ""
3077  "
3078{
3079  if (TARGET_SH3E
3080      && ! TARGET_IEEE
3081      && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3082    {
3083      rtx tmp = sh_compare_op0;
3084      sh_compare_op0 = sh_compare_op1;
3085      sh_compare_op1 = tmp;
3086      emit_insn (gen_ble (operands[0]));
3087      DONE;
3088    }
3089  from_compare (operands, GE);
3090}")
3091
3092(define_expand "bgtu"
3093  [(set (pc)
3094	(if_then_else (ne (reg:SI 18) (const_int 0))
3095		      (label_ref (match_operand 0 "" ""))
3096		      (pc)))]
3097  ""
3098  "from_compare (operands, GTU); ")
3099
3100(define_expand "bltu"
3101  [(set (pc)
3102		  (if_then_else (eq (reg:SI 18) (const_int 0))
3103				(label_ref (match_operand 0 "" ""))
3104				(pc)))]
3105  ""
3106  "from_compare (operands, GEU);")
3107
3108(define_expand "bgeu"
3109  [(set (pc)
3110	(if_then_else (ne (reg:SI 18) (const_int 0))
3111		      (label_ref (match_operand 0 "" ""))
3112		      (pc)))]
3113  ""
3114  "from_compare (operands, GEU);")
3115
3116(define_expand "bleu"
3117  [(set (pc)
3118	(if_then_else (eq (reg:SI 18) (const_int 0))
3119		      (label_ref (match_operand 0 "" ""))
3120		      (pc)))]
3121  ""
3122  "from_compare (operands, GTU);")
3123
3124;; ------------------------------------------------------------------------
3125;; Jump and linkage insns
3126;; ------------------------------------------------------------------------
3127
3128(define_insn "jump"
3129  [(set (pc)
3130	(label_ref (match_operand 0 "" "")))]
3131  ""
3132  "*
3133{
3134  /* The length is 16 if the delay slot is unfilled.  */
3135  if (get_attr_length(insn) > 4)
3136    return output_far_jump(insn, operands[0]);
3137  else
3138    return   \"bra	%l0%#\";
3139}"
3140  [(set_attr "type" "jump")
3141   (set_attr "needs_delay_slot" "yes")])
3142
3143(define_insn "calli"
3144  [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
3145	 (match_operand 1 "" ""))
3146   (use (reg:SI 48))
3147   (clobber (reg:SI 17))]
3148  ""
3149  "jsr	@%0%#"
3150  [(set_attr "type" "call")
3151   (set_attr "needs_delay_slot" "yes")])
3152
3153(define_insn "call_valuei"
3154  [(set (match_operand 0 "" "=rf")
3155	(call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
3156	      (match_operand 2 "" "")))
3157   (use (reg:SI 48))
3158   (clobber (reg:SI 17))]
3159  ""
3160  "jsr	@%1%#"
3161  [(set_attr "type" "call")
3162   (set_attr "needs_delay_slot" "yes")])
3163
3164(define_expand "call"
3165  [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
3166			    (match_operand 1 "" ""))
3167	      (use (reg:SI 48))
3168	      (clobber (reg:SI 17))])]
3169  ""
3170  "operands[0] = force_reg (SImode, XEXP (operands[0], 0));")
3171
3172(define_expand "call_value"
3173  [(parallel [(set (match_operand 0 "arith_reg_operand" "")
3174		   (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
3175				 (match_operand 2 "" "")))
3176	      (use (reg:SI 48))
3177	      (clobber (reg:SI 17))])]
3178  ""
3179  "operands[1] = force_reg (SImode, XEXP (operands[1], 0));")
3180
3181(define_insn "indirect_jump"
3182  [(set (pc)
3183	(match_operand:SI 0 "arith_reg_operand" "r"))]
3184  ""
3185  "jmp	@%0%#"
3186  [(set_attr "needs_delay_slot" "yes")
3187   (set_attr "type" "jump_ind")])
3188
3189;; The use of operand 1 / 2 helps us distinguish case table jumps
3190;; which can be present in structured code from indirect jumps which can not
3191;; be present in structured code.  This allows -fprofile-arcs to work.
3192
3193;; For SH1 processors.
3194(define_insn "casesi_jump_1"
3195  [(set (pc)
3196	(match_operand:SI 0 "register_operand" "r"))
3197   (use (label_ref (match_operand 1 "" "")))]
3198  ""
3199  "jmp  @%0%#"
3200  [(set_attr "needs_delay_slot" "yes")
3201   (set_attr "type" "jump_ind")])
3202
3203;; For all later processors.
3204(define_insn "casesi_jump_2"
3205  [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
3206		      (label_ref (match_operand 1 "" ""))))
3207   (use (label_ref (match_operand 2 "" "")))]
3208  "! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn"
3209  "braf	%0%#"
3210  [(set_attr "needs_delay_slot" "yes")
3211   (set_attr "type" "jump_ind")])
3212
3213;; Call subroutine returning any type.
3214;; ??? This probably doesn't work.
3215
3216(define_expand "untyped_call"
3217  [(parallel [(call (match_operand 0 "" "")
3218		    (const_int 0))
3219	      (match_operand 1 "" "")
3220	      (match_operand 2 "" "")])]
3221  "TARGET_SH3E"
3222  "
3223{
3224  int i;
3225
3226  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx, const0_rtx));
3227
3228  for (i = 0; i < XVECLEN (operands[2], 0); i++)
3229    {
3230      rtx set = XVECEXP (operands[2], 0, i);
3231      emit_move_insn (SET_DEST (set), SET_SRC (set));
3232    }
3233
3234  /* The optimizer does not know that the call sets the function value
3235     registers we stored in the result block.  We avoid problems by
3236     claiming that all hard registers are used and clobbered at this
3237     point.  */
3238  emit_insn (gen_blockage ());
3239
3240  DONE;
3241}")
3242
3243;; ------------------------------------------------------------------------
3244;; Misc insns
3245;; ------------------------------------------------------------------------
3246
3247(define_insn "dect"
3248  [(set (reg:SI 18)
3249	(eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
3250   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
3251  "TARGET_SH2"
3252  "dt	%0"
3253  [(set_attr "type" "arith")])
3254
3255(define_insn "nop"
3256  [(const_int 0)]
3257  ""
3258  "nop")
3259
3260;; Load address of a label. This is only generated by the casesi expand,
3261;; and by machine_dependent_reorg (fixing up fp moves).
3262;; This must use unspec, because this only works for labels that are
3263;; within range,
3264
3265(define_insn "mova"
3266  [(set (reg:SI 0)
3267	(unspec [(label_ref (match_operand 0 "" ""))] 1))]
3268  ""
3269  "mova	%O0,r0"
3270  [(set_attr "in_delay_slot" "no")
3271   (set_attr "type" "arith")])
3272
3273;; case instruction for switch statements.
3274
3275;; Operand 0 is index
3276;; operand 1 is the minimum bound
3277;; operand 2 is the maximum bound - minimum bound + 1
3278;; operand 3 is CODE_LABEL for the table;
3279;; operand 4 is the CODE_LABEL to go to if index out of range.
3280
3281(define_expand "casesi"
3282  [(match_operand:SI 0 "arith_reg_operand" "")
3283   (match_operand:SI 1 "arith_reg_operand" "")
3284   (match_operand:SI 2 "arith_reg_operand" "")
3285   (match_operand 3 "" "") (match_operand 4 "" "")]
3286  ""
3287  "
3288{
3289  rtx reg = gen_reg_rtx (SImode);
3290  rtx reg2 = gen_reg_rtx (SImode);
3291  operands[1] = copy_to_mode_reg (SImode, operands[1]);
3292  operands[2] = copy_to_mode_reg (SImode, operands[2]);
3293  /* If optimizing, casesi_worker depends on the mode of the instruction
3294     before label it 'uses' - operands[3].  */
3295  emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
3296			   reg));
3297  emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
3298  if (TARGET_SH2)
3299    emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
3300  else
3301    emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
3302  /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
3303     operands[3], but to lab.  We will fix this up in
3304     machine_dependent_reorg.  */
3305  emit_barrier ();
3306  DONE;
3307}")
3308
3309(define_expand "casesi_0"
3310  [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
3311   (set (match_dup 4) (minus:SI (match_dup 4)
3312				(match_operand:SI 1 "arith_operand" "")))
3313   (set (reg:SI 18)
3314	(gtu:SI (match_dup 4)
3315		(match_operand:SI 2 "arith_reg_operand" "")))
3316   (set (pc)
3317	(if_then_else (ne (reg:SI 18)
3318			  (const_int 0))
3319		      (label_ref (match_operand 3 "" ""))
3320		      (pc)))]
3321  ""
3322  "")
3323
3324;; ??? reload might clobber r0 if we use it explicitly in the RTL before
3325;; reload; using a R0_REGS pseudo reg is likely to give poor code.
3326;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
3327
3328(define_insn "casesi_worker_0"
3329  [(set (match_operand:SI 0 "register_operand" "=r,r")
3330	(unspec [(match_operand 1 "register_operand" "0,r")
3331		 (label_ref (match_operand 2 "" ""))] 2))
3332   (clobber (match_scratch:SI 3 "=X,1"))
3333   (clobber (match_scratch:SI 4 "=&z,z"))]
3334  ""
3335  "#")
3336
3337(define_split
3338  [(set (match_operand:SI 0 "register_operand" "")
3339	(unspec [(match_operand 1 "register_operand" "")
3340		 (label_ref (match_operand 2 "" ""))] 2))
3341   (clobber (match_scratch:SI 3 ""))
3342   (clobber (match_scratch:SI 4 ""))]
3343  "! TARGET_SH2 && reload_completed"
3344  [(set (reg:SI 0) (unspec [(label_ref (match_dup 2))] 1))
3345   (parallel [(set (match_dup 0)
3346	      (unspec [(reg:SI 0) (match_dup 1) (label_ref (match_dup 2))] 2))
3347	      (clobber (match_dup 3))])
3348   (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI 0)))]
3349  "LABEL_NUSES (operands[2])++;")
3350
3351(define_split
3352  [(set (match_operand:SI 0 "register_operand" "")
3353	(unspec [(match_operand 1 "register_operand" "")
3354		 (label_ref (match_operand 2 "" ""))] 2))
3355   (clobber (match_scratch:SI 3 ""))
3356   (clobber (match_scratch:SI 4 ""))]
3357  "TARGET_SH2 && reload_completed"
3358  [(set (reg:SI 0) (unspec [(label_ref (match_dup 2))] 1))
3359   (parallel [(set (match_dup 0)
3360	      (unspec [(reg:SI 0) (match_dup 1) (label_ref (match_dup 2))] 2))
3361	      (clobber (match_dup 3))])]
3362  "LABEL_NUSES (operands[2])++;")
3363
3364(define_insn "*casesi_worker"
3365  [(set (match_operand:SI 0 "register_operand" "=r,r")
3366	(unspec [(reg:SI 0) (match_operand 1 "register_operand" "0,r")
3367		 (label_ref (match_operand 2 "" ""))] 2))
3368   (clobber (match_scratch:SI 3 "=X,1"))]
3369  ""
3370  "*
3371{
3372  rtx diff_vec = PATTERN (next_real_insn (operands[2]));
3373
3374  if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3375    abort ();
3376
3377  switch (GET_MODE (diff_vec))
3378    {
3379    case SImode:
3380      return \"shll2	%1\;mov.l	@(r0,%1),%0\";
3381    case HImode:
3382      return \"add	%1,%1\;mov.w	@(r0,%1),%0\";
3383    case QImode:
3384      if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3385	return \"mov.b	@(r0,%1),%0\;extu.b	%0,%0\";
3386      return \"mov.b	@(r0,%1),%0\";
3387    default:
3388      abort ();
3389    }
3390}"
3391  [(set_attr "length" "4")])
3392
3393;; ??? This is not the proper place to invoke another compiler pass;
3394;; Alas, there is no proper place to put it.
3395;; ??? This is also an odd place for the call to emit_fpscr_use.  It
3396;; would be all right if it were for an define_expand for return, but
3397;; that doesn't mix with emitting a prologue.
3398(define_insn "return"
3399  [(return)]
3400  "emit_fpscr_use (),
3401   remove_dead_before_cse (),
3402   reload_completed"
3403  "%@	%#"
3404  [(set_attr "type" "return")
3405   (set_attr "needs_delay_slot" "yes")])
3406
3407(define_expand "prologue"
3408  [(const_int 0)]
3409  ""
3410  "sh_expand_prologue (); DONE;")
3411
3412(define_expand "epilogue"
3413  [(return)]
3414  ""
3415  "sh_expand_epilogue ();")
3416
3417(define_insn "blockage"
3418  [(unspec_volatile [(const_int 0)] 0)]
3419  ""
3420  ""
3421  [(set_attr "length" "0")])
3422
3423;; ------------------------------------------------------------------------
3424;; Scc instructions
3425;; ------------------------------------------------------------------------
3426
3427(define_insn "movt"
3428  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3429	(eq:SI (reg:SI 18) (const_int 1)))]
3430  ""
3431  "movt	%0"
3432  [(set_attr "type" "arith")])
3433
3434(define_expand "seq"
3435  [(set (match_operand:SI 0 "arith_reg_operand" "")
3436	(match_dup 1))]
3437  ""
3438  "operands[1] = prepare_scc_operands (EQ);")
3439
3440(define_expand "slt"
3441  [(set (match_operand:SI 0 "arith_reg_operand" "")
3442	(match_dup 1))]
3443  ""
3444  "operands[1] = prepare_scc_operands (LT);")
3445
3446(define_expand "sle"
3447  [(match_operand:SI 0 "arith_reg_operand" "")]
3448  ""
3449  "
3450{
3451  rtx tmp = sh_compare_op0;
3452  sh_compare_op0 = sh_compare_op1;
3453  sh_compare_op1 = tmp;
3454  emit_insn (gen_sge (operands[0]));
3455  DONE;
3456}")
3457
3458(define_expand "sgt"
3459  [(set (match_operand:SI 0 "arith_reg_operand" "")
3460	(match_dup 1))]
3461  ""
3462  "operands[1] = prepare_scc_operands (GT);")
3463
3464(define_expand "sge"
3465  [(set (match_operand:SI 0 "arith_reg_operand" "")
3466	(match_dup 1))]
3467  ""
3468  "
3469{
3470  if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
3471    {
3472      if (TARGET_IEEE)
3473	{
3474	  rtx t_reg = gen_rtx (REG, SImode, T_REG);
3475	  rtx lab = gen_label_rtx ();
3476	  prepare_scc_operands (EQ);
3477	  emit_jump_insn (gen_branch_true (lab));
3478	  prepare_scc_operands (GT);
3479	  emit_label (lab);
3480	  emit_insn (gen_movt (operands[0]));
3481	}
3482      else
3483	emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
3484      DONE;
3485    }
3486  operands[1] = prepare_scc_operands (GE);
3487}")
3488
3489(define_expand "sgtu"
3490  [(set (match_operand:SI 0 "arith_reg_operand" "")
3491	(match_dup 1))]
3492  ""
3493  "operands[1] = prepare_scc_operands (GTU);")
3494
3495(define_expand "sltu"
3496  [(set (match_operand:SI 0 "arith_reg_operand" "")
3497	(match_dup 1))]
3498  ""
3499  "operands[1] = prepare_scc_operands (LTU);")
3500
3501(define_expand "sleu"
3502  [(set (match_operand:SI 0 "arith_reg_operand" "")
3503	(match_dup 1))]
3504  ""
3505  "operands[1] = prepare_scc_operands (LEU);")
3506
3507(define_expand "sgeu"
3508  [(set (match_operand:SI 0 "arith_reg_operand" "")
3509	(match_dup 1))]
3510  ""
3511  "operands[1] = prepare_scc_operands (GEU);")
3512
3513;; sne moves the complement of the T reg to DEST like this:
3514;;      cmp/eq ...
3515;;      mov    #-1,temp
3516;;      negc   temp,dest
3517;;   This is better than xoring compare result with 1 because it does
3518;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
3519;;   loop.
3520
3521(define_expand "sne"
3522  [(set (match_dup 2) (const_int -1))
3523   (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3524		   (neg:SI (plus:SI (match_dup 1)
3525				    (match_dup 2))))
3526	      (set (reg:SI 18)
3527		   (ne:SI (ior:SI (match_dup 1) (match_dup 2))
3528			  (const_int 0)))])]  
3529  ""
3530  "
3531{
3532   operands[1] = prepare_scc_operands (EQ);
3533   operands[2] = gen_reg_rtx (SImode);
3534}")
3535
3536;; Use the same trick for FP sle / sge
3537(define_expand "movnegt"
3538  [(set (match_dup 2) (const_int -1))
3539   (parallel [(set (match_operand 0 "" "")
3540		   (neg:SI (plus:SI (match_dup 1)
3541				    (match_dup 2))))
3542	      (set (reg:SI 18)
3543		   (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
3544			  (const_int 0)))])]  
3545  ""
3546  "operands[2] = gen_reg_rtx (SImode);")
3547
3548;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
3549;; This prevents a regression that occurred when we switched from xor to
3550;; mov/neg for sne.
3551
3552(define_split
3553  [(set (match_operand:SI 0 "arith_reg_operand" "")
3554	(plus:SI (reg:SI 18)
3555		 (const_int -1)))]
3556  ""
3557  [(set (match_dup 0) (eq:SI (reg:SI 18) (const_int 1)))
3558   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
3559  "")
3560
3561;; -------------------------------------------------------------------------
3562;; Instructions to cope with inline literal tables
3563;; -------------------------------------------------------------------------
3564
3565; 2 byte integer in line
3566
3567(define_insn "consttable_2"
3568 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 2)]
3569 ""
3570 "*
3571{
3572  assemble_integer (operands[0], 2, 1);
3573  return \"\";
3574}"
3575 [(set_attr "length" "2")
3576 (set_attr "in_delay_slot" "no")])
3577
3578; 4 byte integer in line
3579
3580(define_insn "consttable_4"
3581 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 4)]
3582 ""
3583 "*
3584{
3585  assemble_integer (operands[0], 4, 1);
3586  return \"\";
3587}"
3588 [(set_attr "length" "4")
3589  (set_attr "in_delay_slot" "no")])
3590
3591; 8 byte integer in line
3592
3593(define_insn "consttable_8"
3594 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")] 6)]
3595 ""
3596 "*
3597{
3598  assemble_integer (operands[0], 8, 1);
3599  return \"\";
3600}"
3601 [(set_attr "length" "8")
3602  (set_attr "in_delay_slot" "no")])
3603
3604; 4 byte floating point
3605
3606(define_insn "consttable_sf"
3607 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")] 4)]
3608 ""
3609 "*
3610{
3611  union real_extract u;
3612  bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
3613  assemble_real (u.d, SFmode);
3614  return \"\";
3615}"
3616 [(set_attr "length" "4")
3617  (set_attr "in_delay_slot" "no")])
3618
3619; 8 byte floating point
3620
3621(define_insn "consttable_df"
3622 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")] 6)]
3623 ""
3624 "*
3625{
3626  union real_extract u;
3627  bcopy ((char *) &CONST_DOUBLE_LOW (operands[0]), (char *) &u, sizeof u);
3628  assemble_real (u.d, DFmode);
3629  return \"\";
3630}"
3631 [(set_attr "length" "8")
3632  (set_attr "in_delay_slot" "no")])
3633
3634;; Alignment is needed for some constant tables; it may also be added for
3635;; Instructions at the start of loops, or after unconditional branches.
3636;; ??? We would get more accurate lengths if we did instruction
3637;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
3638;; here is too conservative.
3639
3640; align to a two byte boundary
3641
3642(define_expand "align_2"
3643 [(unspec_volatile [(const_int 1)] 1)]
3644 ""
3645 "")
3646
3647; align to a four byte boundary
3648;; align_4 and align_log are instructions for the starts of loops, or
3649;; after unconditional branches, which may take up extra room.
3650
3651(define_expand "align_4"
3652 [(unspec_volatile [(const_int 2)] 1)]
3653 ""
3654 "")
3655
3656; align to a cache line boundary
3657
3658(define_insn "align_log"
3659 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 1)]
3660 ""
3661 ""
3662 [(set_attr "length" "0")
3663  (set_attr "in_delay_slot" "no")])
3664
3665; emitted at the end of the literal table, used to emit the
3666; 32bit branch labels if needed.
3667
3668(define_insn "consttable_end"
3669  [(unspec_volatile [(const_int 0)] 11)]
3670  ""
3671  "* return output_jump_label_table ();"
3672  [(set_attr "in_delay_slot" "no")])
3673
3674;; -------------------------------------------------------------------------
3675;; Misc
3676;; -------------------------------------------------------------------------
3677
3678;; String/block move insn.
3679
3680(define_expand "movstrsi"
3681  [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
3682		   (mem:BLK (match_operand:BLK 1 "" "")))
3683	      (use (match_operand:SI 2 "nonmemory_operand" ""))
3684	      (use (match_operand:SI 3 "immediate_operand" ""))
3685	      (clobber (reg:SI 17))
3686	      (clobber (reg:SI 4))
3687	      (clobber (reg:SI 5))
3688	      (clobber (reg:SI 0))])]
3689  ""
3690  "
3691{
3692  if(expand_block_move (operands))
3693     DONE;
3694  else FAIL;
3695}")
3696
3697(define_insn "block_move_real"
3698  [(parallel [(set (mem:BLK (reg:SI 4))
3699		   (mem:BLK (reg:SI 5)))
3700	      (use (match_operand:SI 0 "arith_reg_operand" "r"))
3701	      (clobber (reg:SI 17))
3702	      (clobber (reg:SI 0))])]
3703  "! TARGET_HARD_SH4"
3704  "jsr	@%0%#"
3705  [(set_attr "type" "sfunc")
3706   (set_attr "needs_delay_slot" "yes")])
3707
3708(define_insn "block_lump_real"
3709  [(parallel [(set (mem:BLK (reg:SI 4))
3710		   (mem:BLK (reg:SI 5)))
3711	      (use (match_operand:SI 0 "arith_reg_operand" "r"))
3712	      (use (reg:SI 6))
3713	      (clobber (reg:SI 17))
3714	      (clobber (reg:SI 4))
3715	      (clobber (reg:SI 5))
3716	      (clobber (reg:SI 6))
3717	      (clobber (reg:SI 0))])]
3718  "! TARGET_HARD_SH4"
3719  "jsr	@%0%#"
3720  [(set_attr "type" "sfunc")
3721   (set_attr "needs_delay_slot" "yes")])
3722
3723(define_insn "block_move_real_i4"
3724  [(parallel [(set (mem:BLK (reg:SI 4))
3725		   (mem:BLK (reg:SI 5)))
3726	      (use (match_operand:SI 0 "arith_reg_operand" "r"))
3727	      (clobber (reg:SI 17))
3728	      (clobber (reg:SI 0))
3729	      (clobber (reg:SI 1))
3730	      (clobber (reg:SI 2))])]
3731  "TARGET_HARD_SH4"
3732  "jsr	@%0%#"
3733  [(set_attr "type" "sfunc")
3734   (set_attr "needs_delay_slot" "yes")])
3735
3736(define_insn "block_lump_real_i4"
3737  [(parallel [(set (mem:BLK (reg:SI 4))
3738		   (mem:BLK (reg:SI 5)))
3739	      (use (match_operand:SI 0 "arith_reg_operand" "r"))
3740	      (use (reg:SI 6))
3741	      (clobber (reg:SI 17))
3742	      (clobber (reg:SI 4))
3743	      (clobber (reg:SI 5))
3744	      (clobber (reg:SI 6))
3745	      (clobber (reg:SI 0))
3746	      (clobber (reg:SI 1))
3747	      (clobber (reg:SI 2))
3748	      (clobber (reg:SI 3))])]
3749  "TARGET_HARD_SH4"
3750  "jsr	@%0%#"
3751  [(set_attr "type" "sfunc")
3752   (set_attr "needs_delay_slot" "yes")])
3753
3754;; -------------------------------------------------------------------------
3755;; Floating point instructions.
3756;; -------------------------------------------------------------------------
3757
3758;; ??? All patterns should have a type attribute.
3759
3760(define_expand "fpu_switch0"
3761  [(set (match_operand:SI 0 "" "") (symbol_ref "__fpscr_values"))
3762   (set (match_dup 2) (match_dup 1))]
3763  ""
3764  "
3765{
3766  operands[1] = gen_rtx (MEM, PSImode, operands[0]);
3767  RTX_UNCHANGING_P (operands[1]) = 1;
3768  operands[2] = get_fpscr_rtx ();
3769}")
3770
3771(define_expand "fpu_switch1"
3772  [(set (match_operand:SI 0 "" "") (symbol_ref "__fpscr_values"))
3773   (set (match_dup 1) (plus:SI (match_dup 0) (const_int 4)))
3774   (set (match_dup 3) (match_dup 2))]
3775  ""
3776  "
3777{
3778  operands[1] = gen_reg_rtx (SImode);
3779  operands[2] = gen_rtx (MEM, PSImode, operands[1]);
3780  RTX_UNCHANGING_P (operands[2]) = 1;
3781  operands[3] = get_fpscr_rtx ();
3782}")
3783
3784(define_expand "movpsi"
3785  [(set (match_operand:PSI 0 "register_operand" "")
3786	(match_operand:PSI 1 "general_movsrc_operand" ""))]
3787  ""
3788  "")
3789
3790;; The c / m alternative is a fake to guide reload to load directly into
3791;; fpscr, since reload doesn't know how to use post-increment.
3792;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
3793;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
3794;; predicate after reload.
3795;; The gp_fpul type for r/!c might look a bit odd, but it actually schedules
3796;; like a gpr <-> fpul move.
3797(define_insn "fpu_switch"
3798  [(set (match_operand:PSI 0 "register_operand" "c,c,r,c,c,r,m,r")
3799	(match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
3800  "! reload_completed
3801   || true_regnum (operands[0]) != FPSCR_REG || GET_CODE (operands[1]) != MEM
3802   || GET_CODE (XEXP (operands[1], 0)) != PLUS"
3803  "@
3804	! precision stays the same
3805	lds.l	%1,fpscr
3806	mov.l	%1,%0
3807	#
3808	lds	%1,fpscr
3809	mov	%1,%0
3810	mov.l	%1,%0
3811	sts	fpscr,%0"
3812  [(set_attr "length" "0,2,2,4,2,2,2,2")
3813   (set_attr "type" "dfp_conv,dfp_conv,load,dfp_conv,dfp_conv,move,store,gp_fpul")])
3814
3815(define_split
3816  [(set (reg:PSI 48) (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
3817  "find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
3818  [(set (match_dup 0) (match_dup 0))]
3819  "
3820{
3821  rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3822					gen_rtx (MEM, PSImode,
3823						 gen_rtx (POST_INC, Pmode,
3824							  operands[0]))));
3825  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
3826}")
3827
3828(define_split
3829  [(set (reg:PSI 48) (mem:PSI (match_operand:SI 0 "register_operand" "r")))]
3830  ""
3831  [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
3832  "
3833{
3834  rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3835					gen_rtx (MEM, PSImode,
3836						 gen_rtx (POST_INC, Pmode,
3837							  operands[0]))));
3838  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
3839}")
3840
3841;; ??? This uses the fp unit, but has no type indicating that.
3842;; If we did that, this would either give a bogus latency or introduce
3843;; a bogus FIFO constraint.
3844;; Since this insn is currently only used for prologues/epilogues,
3845;; it is probably best to claim no function unit, which matches the
3846;; current setting.
3847(define_insn "toggle_sz"
3848  [(set (reg:PSI 48) (xor:PSI (reg:PSI 48) (const_int 1048576)))]
3849  "TARGET_SH4"
3850  "fschg")
3851
3852(define_expand "addsf3"
3853  [(match_operand:SF 0 "arith_reg_operand" "")
3854   (match_operand:SF 1 "arith_reg_operand" "")
3855   (match_operand:SF 2 "arith_reg_operand" "")]
3856  "TARGET_SH3E"
3857  "{ expand_sf_binop (&gen_addsf3_i, operands); DONE; }")
3858
3859(define_insn "addsf3_i"
3860  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3861	(plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
3862		 (match_operand:SF 2 "arith_reg_operand" "f")))
3863   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3864  "TARGET_SH3E"
3865  "fadd	%2,%0"
3866  [(set_attr "type" "fp")])
3867
3868(define_expand "subsf3"
3869  [(match_operand:SF 0 "fp_arith_reg_operand" "")
3870   (match_operand:SF 1 "fp_arith_reg_operand" "")
3871   (match_operand:SF 2 "fp_arith_reg_operand" "")]
3872  "TARGET_SH3E"
3873  "{ expand_sf_binop (&gen_subsf3_i, operands); DONE; }")
3874
3875(define_insn "subsf3_i"
3876  [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
3877	(minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
3878		 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
3879   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3880  "TARGET_SH3E"
3881  "fsub	%2,%0"
3882  [(set_attr "type" "fp")])
3883
3884;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
3885;; register in feeding fp instructions.  Thus, we cannot generate fmac for
3886;; mixed-precision SH4 targets.  To allow it to be still generated for the
3887;; SH3E, we use a separate insn for SH3E mulsf3.
3888
3889(define_expand "mulsf3"
3890  [(match_operand:SF 0 "arith_reg_operand" "")
3891   (match_operand:SF 1 "arith_reg_operand" "")
3892   (match_operand:SF 2 "arith_reg_operand" "")]
3893  "TARGET_SH3E"
3894  "
3895{
3896  if (TARGET_SH4)
3897    expand_sf_binop (&gen_mulsf3_i4, operands);
3898  else
3899    emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
3900  DONE;
3901}")
3902
3903(define_insn "mulsf3_i4"
3904  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3905	(mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
3906		 (match_operand:SF 2 "arith_reg_operand" "f")))
3907   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3908  "TARGET_SH3E"
3909  "fmul	%2,%0"
3910  [(set_attr "type" "fp")])
3911
3912(define_insn "mulsf3_ie"
3913  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3914	(mult:SF (match_operand:SF 1 "arith_reg_operand" "%0")
3915		 (match_operand:SF 2 "arith_reg_operand" "f")))]
3916  "TARGET_SH3E && ! TARGET_SH4"
3917  "fmul	%2,%0"
3918  [(set_attr "type" "fp")])
3919
3920(define_insn "*macsf3"
3921  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3922	(plus:SF (mult:SF (match_operand:SF 1 "arith_reg_operand" "%w")
3923			  (match_operand:SF 2 "arith_reg_operand" "f"))
3924		 (match_operand:SF 3 "arith_reg_operand" "0")))
3925   (use (match_operand:PSI 4 "fpscr_operand" "c"))]
3926  "TARGET_SH3E && ! TARGET_SH4"
3927  "fmac	fr0,%2,%0"
3928  [(set_attr "type" "fp")])
3929
3930(define_expand "divsf3"
3931  [(match_operand:SF 0 "arith_reg_operand" "")
3932   (match_operand:SF 1 "arith_reg_operand" "")
3933   (match_operand:SF 2 "arith_reg_operand" "")]
3934  "TARGET_SH3E"
3935  "{ expand_sf_binop (&gen_divsf3_i, operands); DONE; }")
3936
3937(define_insn "divsf3_i"
3938  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3939	(div:SF (match_operand:SF 1 "arith_reg_operand" "0")
3940		 (match_operand:SF 2 "arith_reg_operand" "f")))
3941   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
3942  "TARGET_SH3E"
3943  "fdiv	%2,%0"
3944  [(set_attr "type" "fdiv")])
3945
3946(define_expand "floatsisf2"
3947  [(set (reg:SI 22)
3948	(match_operand:SI 1 "arith_reg_operand" ""))
3949   (parallel [(set (match_operand:SF 0 "arith_reg_operand" "")
3950		   (float:SF (reg:SI 22)))
3951	      (use (match_dup 2))])]
3952  "TARGET_SH3E"
3953  "
3954{
3955  if (TARGET_SH4)
3956    {
3957      emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 22),
3958			  operands[1]));
3959      emit_sf_insn (gen_floatsisf2_i4 (operands[0], get_fpscr_rtx ()));
3960      DONE;
3961    }
3962  operands[2] = get_fpscr_rtx ();
3963}")
3964
3965(define_insn "floatsisf2_i4"
3966  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3967	(float:SF (reg:SI 22)))
3968   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
3969  "TARGET_SH3E"
3970  "float	fpul,%0"
3971  [(set_attr "type" "fp")])
3972
3973(define_insn "*floatsisf2_ie"
3974  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
3975	(float:SF (reg:SI 22)))]
3976  "TARGET_SH3E && ! TARGET_SH4"
3977  "float	fpul,%0"
3978  [(set_attr "type" "fp")])
3979
3980(define_expand "fix_truncsfsi2"
3981  [(set (reg:SI 22)
3982	(fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
3983   (set (match_operand:SI 0 "arith_reg_operand" "=r")
3984	(reg:SI 22))]
3985  "TARGET_SH3E"
3986  "
3987{
3988  if (TARGET_SH4)
3989    {
3990      emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[1], get_fpscr_rtx ()));
3991      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
3992			  gen_rtx (REG, SImode, 22)));
3993      DONE;
3994    }
3995}")
3996
3997(define_insn "fix_truncsfsi2_i4"
3998  [(set (reg:SI 22)
3999	(fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))
4000   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
4001  "TARGET_SH4"
4002  "ftrc	%0,fpul"
4003  [(set_attr "type" "fp")])
4004
4005(define_insn "fix_truncsfsi2_i4_2"
4006  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4007	(fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
4008   (use (reg:SI 48))
4009   (clobber (reg:SI 22))]
4010  "TARGET_SH4"
4011  "#"
4012  [(set_attr "length" "4")])
4013
4014(define_split
4015  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4016	(fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
4017   (use (match_operand:PSI 2 "fpscr_operand" "c"))
4018   (clobber (reg:SI 22))]
4019  "TARGET_SH4"
4020  [(parallel [(set (reg:SI 22) (fix:SI (match_dup 1)))
4021	      (use (match_dup 2))])
4022   (set (match_dup 0) (reg:SI 22))])
4023
4024(define_insn "*fixsfsi"
4025  [(set (reg:SI 22)
4026	(fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))]
4027  "TARGET_SH3E && ! TARGET_SH4"
4028  "ftrc	%0,fpul"
4029  [(set_attr "type" "fp")])
4030
4031(define_insn "cmpgtsf_t"
4032  [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
4033			   (match_operand:SF 1 "arith_reg_operand" "f")))]
4034  "TARGET_SH3E && ! TARGET_SH4"
4035  "fcmp/gt	%1,%0"
4036  [(set_attr "type" "fp")])
4037
4038(define_insn "cmpeqsf_t"
4039  [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
4040			   (match_operand:SF 1 "arith_reg_operand" "f")))]
4041  "TARGET_SH3E && ! TARGET_SH4"
4042  "fcmp/eq	%1,%0"
4043  [(set_attr "type" "fp")])
4044
4045(define_insn "ieee_ccmpeqsf_t"
4046  [(set (reg:SI 18) (ior:SI (reg:SI 18)
4047			    (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
4048				   (match_operand:SF 1 "arith_reg_operand" "f"))))]
4049  "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
4050  "* return output_ieee_ccmpeq (insn, operands);"
4051  [(set_attr "length" "4")])
4052
4053
4054(define_insn "cmpgtsf_t_i4"
4055  [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f")
4056			   (match_operand:SF 1 "arith_reg_operand" "f")))
4057   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4058  "TARGET_SH4"
4059  "fcmp/gt	%1,%0"
4060  [(set_attr "type" "fp")])
4061
4062(define_insn "cmpeqsf_t_i4"
4063  [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
4064			   (match_operand:SF 1 "arith_reg_operand" "f")))
4065   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4066  "TARGET_SH4"
4067  "fcmp/eq	%1,%0"
4068  [(set_attr "type" "fp")])
4069
4070(define_insn "*ieee_ccmpeqsf_t_4"
4071  [(set (reg:SI 18) (ior:SI (reg:SI 18)
4072			    (eq:SI (match_operand:SF 0 "arith_reg_operand" "f")
4073				   (match_operand:SF 1 "arith_reg_operand" "f"))))
4074   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4075  "TARGET_IEEE && TARGET_SH4"
4076  "* return output_ieee_ccmpeq (insn, operands);"
4077  [(set_attr "length" "4")])
4078
4079(define_expand "cmpsf"
4080  [(set (reg:SI 18) (compare (match_operand:SF 0 "arith_operand" "")
4081			     (match_operand:SF 1 "arith_operand" "")))]
4082  "TARGET_SH3E"
4083  "
4084{
4085  sh_compare_op0 = operands[0];
4086  sh_compare_op1 = operands[1];
4087  DONE;
4088}")
4089
4090(define_expand "negsf2"
4091  [(match_operand:SF 0 "arith_reg_operand" "")
4092   (match_operand:SF 1 "arith_reg_operand" "")]
4093  "TARGET_SH3E"
4094  "{ expand_sf_unop (&gen_negsf2_i, operands); DONE; }")
4095
4096(define_insn "negsf2_i"
4097  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
4098	(neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))
4099   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4100  "TARGET_SH3E"
4101  "fneg	%0"
4102  [(set_attr "type" "fmove")])
4103
4104(define_expand "sqrtsf2"
4105  [(match_operand:SF 0 "arith_reg_operand" "")
4106   (match_operand:SF 1 "arith_reg_operand" "")]
4107  "TARGET_SH3E"
4108  "{ expand_sf_unop (&gen_sqrtsf2_i, operands); DONE; }")
4109
4110(define_insn "sqrtsf2_i"
4111  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
4112	(sqrt:SF (match_operand:SF 1 "arith_reg_operand" "0")))
4113   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4114  "TARGET_SH3E"
4115  "fsqrt	%0"
4116  [(set_attr "type" "fdiv")])
4117
4118(define_expand "abssf2"
4119  [(match_operand:SF 0 "arith_reg_operand" "")
4120   (match_operand:SF 1 "arith_reg_operand" "")]
4121  "TARGET_SH3E"
4122  "{ expand_sf_unop (&gen_abssf2_i, operands); DONE; }")
4123
4124(define_insn "abssf2_i"
4125  [(set (match_operand:SF 0 "arith_reg_operand" "=f")
4126	(abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))
4127   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4128  "TARGET_SH3E"
4129  "fabs	%0"
4130  [(set_attr "type" "fmove")])
4131
4132(define_expand "adddf3"
4133  [(match_operand:DF 0 "arith_reg_operand" "")
4134   (match_operand:DF 1 "arith_reg_operand" "")
4135   (match_operand:DF 2 "arith_reg_operand" "")]
4136  "TARGET_SH4"
4137  "{ expand_df_binop (&gen_adddf3_i, operands); DONE; }")
4138
4139(define_insn "adddf3_i"
4140  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4141	(plus:DF (match_operand:DF 1 "arith_reg_operand" "%0")
4142		 (match_operand:DF 2 "arith_reg_operand" "f")))
4143   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4144  "TARGET_SH4"
4145  "fadd	%2,%0"
4146  [(set_attr "type" "dfp_arith")])
4147
4148(define_expand "subdf3"
4149  [(match_operand:DF 0 "arith_reg_operand" "")
4150   (match_operand:DF 1 "arith_reg_operand" "")
4151   (match_operand:DF 2 "arith_reg_operand" "")]
4152  "TARGET_SH4"
4153  "{ expand_df_binop (&gen_subdf3_i, operands); DONE; }")
4154
4155(define_insn "subdf3_i"
4156  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4157	(minus:DF (match_operand:DF 1 "arith_reg_operand" "0")
4158		  (match_operand:DF 2 "arith_reg_operand" "f")))
4159   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4160  "TARGET_SH4"
4161  "fsub	%2,%0"
4162  [(set_attr "type" "dfp_arith")])
4163
4164(define_expand "muldf3"
4165  [(match_operand:DF 0 "arith_reg_operand" "")
4166   (match_operand:DF 1 "arith_reg_operand" "")
4167   (match_operand:DF 2 "arith_reg_operand" "")]
4168  "TARGET_SH4"
4169  "{ expand_df_binop (&gen_muldf3_i, operands); DONE; }")
4170
4171(define_insn "muldf3_i"
4172  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4173	(mult:DF (match_operand:DF 1 "arith_reg_operand" "%0")
4174		 (match_operand:DF 2 "arith_reg_operand" "f")))
4175   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4176  "TARGET_SH4"
4177  "fmul	%2,%0"
4178  [(set_attr "type" "dfp_arith")])
4179
4180(define_expand "divdf3"
4181  [(match_operand:DF 0 "arith_reg_operand" "")
4182   (match_operand:DF 1 "arith_reg_operand" "")
4183   (match_operand:DF 2 "arith_reg_operand" "")]
4184  "TARGET_SH4"
4185  "{ expand_df_binop (&gen_divdf3_i, operands); DONE; }")
4186
4187(define_insn "divdf3_i"
4188  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4189	(div:DF (match_operand:DF 1 "arith_reg_operand" "0")
4190		(match_operand:DF 2 "arith_reg_operand" "f")))
4191   (use (match_operand:PSI 3 "fpscr_operand" "c"))]
4192  "TARGET_SH4"
4193  "fdiv	%2,%0"
4194  [(set_attr "type" "dfdiv")])
4195
4196(define_expand "floatsidf2"
4197  [(match_operand:DF 0 "arith_reg_operand" "")
4198   (match_operand:SI 1 "arith_reg_operand" "")]
4199  "TARGET_SH4"
4200  "
4201{
4202  emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 22), operands[1]));
4203  emit_df_insn (gen_floatsidf2_i (operands[0], get_fpscr_rtx ()));
4204  DONE;
4205}")
4206
4207(define_insn "floatsidf2_i"
4208  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4209	(float:DF (reg:SI 22)))
4210   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
4211  "TARGET_SH4"
4212  "float	fpul,%0"
4213  [(set_attr "type" "dfp_conv")])
4214
4215(define_expand "fix_truncdfsi2"
4216  [(match_operand:SI 0 "arith_reg_operand" "=r")
4217   (match_operand:DF 1 "arith_reg_operand" "f")]
4218  "TARGET_SH4"
4219  "
4220{
4221  emit_df_insn (gen_fix_truncdfsi2_i (operands[1], get_fpscr_rtx ()));
4222  emit_insn (gen_rtx (SET, VOIDmode, operands[0], gen_rtx (REG, SImode, 22)));
4223  DONE;
4224}")
4225
4226(define_insn "fix_truncdfsi2_i"
4227  [(set (reg:SI 22)
4228	(fix:SI (match_operand:DF 0 "arith_reg_operand" "f")))
4229   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
4230  "TARGET_SH4"
4231  "ftrc	%0,fpul"
4232  [(set_attr "type" "dfp_conv")])
4233
4234(define_insn "fix_truncdfsi2_i4"
4235  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4236	(fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
4237   (use (match_operand:PSI 2 "fpscr_operand" "c"))
4238   (clobber (reg:SI 22))]
4239  "TARGET_SH4"
4240  "#"
4241  [(set_attr "length" "4")])
4242
4243(define_split
4244  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4245	(fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
4246   (use (match_operand:PSI 2 "fpscr_operand" "c"))
4247   (clobber (reg:SI 22))]
4248  "TARGET_SH4"
4249  [(parallel [(set (reg:SI 22) (fix:SI (match_dup 1)))
4250	      (use (match_dup 2))])
4251   (set (match_dup 0) (reg:SI 22))])
4252
4253(define_insn "cmpgtdf_t"
4254  [(set (reg:SI 18) (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
4255			   (match_operand:DF 1 "arith_reg_operand" "f")))
4256   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4257  "TARGET_SH4"
4258  "fcmp/gt	%1,%0"
4259  [(set_attr "type" "dfp_cmp")])
4260
4261(define_insn "cmpeqdf_t"
4262  [(set (reg:SI 18) (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
4263			   (match_operand:DF 1 "arith_reg_operand" "f")))
4264   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4265  "TARGET_SH4"
4266  "fcmp/eq	%1,%0"
4267  [(set_attr "type" "dfp_cmp")])
4268
4269(define_insn "*ieee_ccmpeqdf_t"
4270  [(set (reg:SI 18) (ior:SI (reg:SI 18)
4271			    (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
4272				   (match_operand:DF 1 "arith_reg_operand" "f"))))
4273   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4274  "TARGET_IEEE && TARGET_SH4"
4275  "* return output_ieee_ccmpeq (insn, operands);"
4276  [(set_attr "length" "4")])
4277
4278(define_expand "cmpdf"
4279  [(set (reg:SI 18) (compare (match_operand:DF 0 "arith_operand" "")
4280			     (match_operand:DF 1 "arith_operand" "")))]
4281  "TARGET_SH4"
4282  "
4283{
4284  sh_compare_op0 = operands[0];
4285  sh_compare_op1 = operands[1];
4286  DONE;
4287}")
4288
4289(define_expand "negdf2"
4290  [(match_operand:DF 0 "arith_reg_operand" "")
4291   (match_operand:DF 1 "arith_reg_operand" "")]
4292  "TARGET_SH4"
4293  "{ expand_df_unop (&gen_negdf2_i, operands); DONE; }")
4294
4295(define_insn "negdf2_i"
4296  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4297	(neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4298   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4299  "TARGET_SH4"
4300  "fneg	%0"
4301  [(set_attr "type" "fmove")])
4302
4303(define_expand "sqrtdf2"
4304  [(match_operand:DF 0 "arith_reg_operand" "")
4305   (match_operand:DF 1 "arith_reg_operand" "")]
4306  "TARGET_SH4"
4307  "{ expand_df_unop (&gen_sqrtdf2_i, operands); DONE; }")
4308
4309(define_insn "sqrtdf2_i"
4310  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4311	(sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4312   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4313  "TARGET_SH4"
4314  "fsqrt	%0"
4315  [(set_attr "type" "dfdiv")])
4316
4317(define_expand "absdf2"
4318  [(match_operand:DF 0 "arith_reg_operand" "")
4319   (match_operand:DF 1 "arith_reg_operand" "")]
4320  "TARGET_SH4"
4321  "{ expand_df_unop (&gen_absdf2_i, operands); DONE; }")
4322
4323(define_insn "absdf2_i"
4324  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4325	(abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
4326   (use (match_operand:PSI 2 "fpscr_operand" "c"))]
4327  "TARGET_SH4"
4328  "fabs	%0"
4329  [(set_attr "type" "fmove")])
4330
4331(define_expand "extendsfdf2"
4332  [(match_operand:DF 0 "arith_reg_operand" "")
4333   (match_operand:SF 1 "arith_reg_operand" "")]
4334  "TARGET_SH4"
4335  "
4336{
4337  emit_sf_insn (gen_movsf_ie (gen_rtx (REG, SFmode, 22), operands[1],
4338			      get_fpscr_rtx ()));
4339  emit_df_insn (gen_extendsfdf2_i4 (operands[0], get_fpscr_rtx ()));
4340  DONE;
4341}")
4342
4343(define_insn "extendsfdf2_i4"
4344  [(set (match_operand:DF 0 "arith_reg_operand" "=f")
4345	(float_extend:DF (reg:SF 22)))
4346   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
4347  "TARGET_SH4"
4348  "fcnvsd  fpul,%0"
4349  [(set_attr "type" "fp")])
4350
4351(define_expand "truncdfsf2"
4352  [(match_operand:SF 0 "arith_reg_operand" "")
4353   (match_operand:DF 1 "arith_reg_operand" "")]
4354  "TARGET_SH4"
4355  "
4356{
4357  emit_df_insn (gen_truncdfsf2_i4 (operands[1], get_fpscr_rtx ()));
4358  emit_sf_insn (gen_movsf_ie (operands[0], gen_rtx (REG, SFmode, 22),
4359			   get_fpscr_rtx ()));
4360  DONE;
4361}")
4362
4363(define_insn "truncdfsf2_i4"
4364  [(set (reg:SF 22)
4365	(float_truncate:SF (match_operand:DF 0 "arith_reg_operand" "f")))
4366   (use (match_operand:PSI 1 "fpscr_operand" "c"))]
4367  "TARGET_SH4"
4368  "fcnvds  %0,fpul"
4369  [(set_attr "type" "fp")])
4370
4371;; Bit field extract patterns.  These give better code for packed bitfields,
4372;; because they allow auto-increment addresses to be generated.
4373
4374(define_expand "insv"
4375  [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
4376			 (match_operand:SI 1 "immediate_operand" "")
4377			 (match_operand:SI 2 "immediate_operand" ""))
4378	(match_operand:SI 3 "general_operand" ""))]
4379  "! TARGET_LITTLE_ENDIAN"
4380  "
4381{
4382  rtx addr_target, orig_address, shift_reg;
4383  HOST_WIDE_INT size;
4384
4385  /* ??? expmed doesn't care for non-register predicates.  */
4386  if (! memory_operand (operands[0], VOIDmode)
4387      || ! immediate_operand (operands[1], VOIDmode)
4388      || ! immediate_operand (operands[2], VOIDmode)
4389      || ! general_operand (operands[3], VOIDmode))
4390    FAIL;
4391  /* If this isn't a 16 / 24 / 32 bit field, or if
4392     it doesn't start on a byte boundary, then fail.  */
4393  size = INTVAL (operands[1]);
4394  if (size < 16 || size > 32 || size % 8 != 0
4395      || (INTVAL (operands[2]) % 8) != 0)
4396    FAIL;
4397
4398  size /= 8;
4399  orig_address = XEXP (operands[0], 0);
4400  shift_reg = gen_reg_rtx (SImode);
4401  emit_insn (gen_movsi (shift_reg, operands[3]));
4402  addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
4403
4404  operands[0] = change_address (operands[0], QImode, addr_target);
4405  emit_insn (gen_movqi (operands[0], gen_rtx (SUBREG, QImode, shift_reg, 0)));
4406
4407  while (size -= 1)
4408    {
4409      emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
4410      emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
4411      emit_insn (gen_movqi (operands[0],
4412			    gen_rtx (SUBREG, QImode, shift_reg, 0)));
4413    }
4414
4415  DONE;
4416}")
4417
4418;; -------------------------------------------------------------------------
4419;; Peepholes
4420;; -------------------------------------------------------------------------
4421
4422;; This matches cases where a stack pointer increment at the start of the
4423;; epilogue combines with a stack slot read loading the return value.
4424
4425(define_peephole
4426  [(set (match_operand:SI 0 "arith_reg_operand" "")
4427	(mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
4428   (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
4429  "REGNO (operands[1]) != REGNO (operands[0])"
4430  "mov.l	@%1+,%0")
4431
4432;; See the comment on the dt combiner pattern above.
4433
4434(define_peephole
4435  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4436	(plus:SI (match_dup 0)
4437		 (const_int -1)))
4438   (set (reg:SI 18)
4439	(eq:SI (match_dup 0)
4440	       (const_int 0)))]
4441  "TARGET_SH2"
4442  "dt	%0")
4443
4444;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
4445;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
4446;; reload when the constant is too large for a reg+offset address.
4447
4448;; ??? We would get much better code if this was done in reload.  This would
4449;; require modifying find_reloads_address to recognize that if the constant
4450;; is out-of-range for an immediate add, then we get better code by reloading
4451;; the constant into a register than by reloading the sum into a register,
4452;; since the former is one instruction shorter if the address does not need
4453;; to be offsettable.  Unfortunately this does not work, because there is
4454;; only one register, r0, that can be used as an index register.  This register
4455;; is also the function return value register.  So, if we try to force reload
4456;; to use double-reg addresses, then we end up with some instructions that
4457;; need to use r0 twice.  The only way to fix this is to change the calling
4458;; convention so that r0 is not used to return values.
4459
4460(define_peephole
4461  [(set (match_operand:SI 0 "register_operand" "=r")
4462	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4463   (set (mem:SI (match_dup 0))
4464	(match_operand:SI 2 "general_movsrc_operand" ""))]
4465  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4466  "mov.l	%2,@(%0,%1)")
4467
4468(define_peephole
4469  [(set (match_operand:SI 0 "register_operand" "=r")
4470	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4471   (set (match_operand:SI 2 "general_movdst_operand" "")
4472	(mem:SI (match_dup 0)))]
4473  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4474  "mov.l	@(%0,%1),%2")
4475
4476(define_peephole
4477  [(set (match_operand:SI 0 "register_operand" "=r")
4478	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4479   (set (mem:HI (match_dup 0))
4480	(match_operand:HI 2 "general_movsrc_operand" ""))]
4481  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4482  "mov.w	%2,@(%0,%1)")
4483
4484(define_peephole
4485  [(set (match_operand:SI 0 "register_operand" "=r")
4486	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4487   (set (match_operand:HI 2 "general_movdst_operand" "")
4488	(mem:HI (match_dup 0)))]
4489  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4490  "mov.w	@(%0,%1),%2")
4491
4492(define_peephole
4493  [(set (match_operand:SI 0 "register_operand" "=r")
4494	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4495   (set (mem:QI (match_dup 0))
4496	(match_operand:QI 2 "general_movsrc_operand" ""))]
4497  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4498  "mov.b	%2,@(%0,%1)")
4499
4500(define_peephole
4501  [(set (match_operand:SI 0 "register_operand" "=r")
4502	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4503   (set (match_operand:QI 2 "general_movdst_operand" "")
4504	(mem:QI (match_dup 0)))]
4505  "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
4506  "mov.b	@(%0,%1),%2")
4507
4508(define_peephole
4509  [(set (match_operand:SI 0 "register_operand" "=r")
4510	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4511   (set (mem:SF (match_dup 0))
4512	(match_operand:SF 2 "general_movsrc_operand" ""))]
4513  "REGNO (operands[0]) == 0
4514   && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
4515       || (GET_CODE (operands[2]) == SUBREG
4516	   && REGNO (SUBREG_REG (operands[2])) < 16))
4517   && reg_unused_after (operands[0], insn)"
4518  "mov.l	%2,@(%0,%1)")
4519
4520(define_peephole
4521  [(set (match_operand:SI 0 "register_operand" "=r")
4522	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4523   (set (match_operand:SF 2 "general_movdst_operand" "")
4524
4525	(mem:SF (match_dup 0)))]
4526  "REGNO (operands[0]) == 0
4527   && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
4528       || (GET_CODE (operands[2]) == SUBREG
4529	   && REGNO (SUBREG_REG (operands[2])) < 16))
4530   && reg_unused_after (operands[0], insn)"
4531  "mov.l	@(%0,%1),%2")
4532
4533(define_peephole
4534  [(set (match_operand:SI 0 "register_operand" "=r")
4535	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4536   (set (mem:SF (match_dup 0))
4537	(match_operand:SF 2 "general_movsrc_operand" ""))]
4538  "REGNO (operands[0]) == 0
4539   && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
4540       || (GET_CODE (operands[2]) == SUBREG
4541	   && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
4542   && reg_unused_after (operands[0], insn)"
4543  "fmov{.s|}	%2,@(%0,%1)")
4544
4545(define_peephole
4546  [(set (match_operand:SI 0 "register_operand" "=r")
4547	(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
4548   (set (match_operand:SF 2 "general_movdst_operand" "")
4549
4550	(mem:SF (match_dup 0)))]
4551  "REGNO (operands[0]) == 0
4552   && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG)
4553       || (GET_CODE (operands[2]) == SUBREG
4554	   && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG))
4555   && reg_unused_after (operands[0], insn)"
4556  "fmov{.s|}	@(%0,%1),%2")
4557
4558;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
4559(define_insn "sp_switch_1"
4560  [(const_int 1)]
4561  ""
4562  "*
4563{
4564  rtx xoperands[1];
4565
4566  xoperands[0] = sp_switch;
4567  output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
4568  output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
4569  return \"mov r0,r15\";
4570}"
4571  [(set_attr "length" "10")])
4572
4573;; Switch back to the original stack for interrupt functions with the
4574;; sp_switch attribute.  */
4575(define_insn "sp_switch_2"
4576  [(const_int 2)]
4577  ""
4578  "mov.l @r15+,r15\;mov.l @r15+,r0"
4579  [(set_attr "length" "4")])
4580