OSDN Git Service

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