OSDN Git Service

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