OSDN Git Service

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