OSDN Git Service

ed96bbd7861a3a51f643adac3be3d3a1e225ce6d
[pf3gnuchains/gcc-fork.git] / gcc / config / fr30 / fr30.md
1 ;; FR30 machine description.
2 ;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2007, 2010
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Cygnus Solutions.
5
6 ;; This file is part of GCC.
7
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
12
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
24 ;;{{{ Attributes 
25
26 (define_attr "length" "" (const_int 2))
27
28 ;; Used to distinguish between small memory model targets and big mode targets.
29
30 (define_attr "size" "small,big"
31   (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
32                        (const_string "small")
33                        (const_string "big"))))
34
35
36 ;; Define an attribute to be used by the delay slot code.
37 ;; An instruction by default is considered to be 'delayable'
38 ;; that is, it can be placed into a delay slot, but it is not
39 ;; itself a delayed branch type instruction.  An instruction
40 ;; whose type is 'delayed' is one which has a delay slot, and
41 ;; an instruction whose delay_type is 'other' is one which does
42 ;; not have a delay slot, nor can it be placed into a delay slot.
43
44 (define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
45
46 ;;}}} \f
47 ;;{{{ Delay Slot Specifications 
48
49 (define_delay (eq_attr "delay_type" "delayed")
50   [(and (eq_attr "delay_type" "delayable")
51         (eq_attr "length" "2"))
52    (nil)
53    (nil)]
54 )
55
56 (include "predicates.md")
57
58 ;;}}}
59 ;;{{{ Moves 
60
61 ;;{{{ Comment 
62
63 ;; Wrap moves in define_expand to prevent memory->memory moves from being
64 ;; generated at the RTL level, which generates better code for most machines
65 ;; which can't do mem->mem moves.
66
67 ;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
68 ;; than M, the effect of this instruction is to store the specified value in
69 ;; the part of the register that corresponds to mode M.  The effect on the rest
70 ;; of the register is undefined.
71
72 ;; This class of patterns is special in several ways.  First of all, each of
73 ;; these names *must* be defined, because there is no other way to copy a datum
74 ;; from one place to another.
75
76 ;; Second, these patterns are not used solely in the RTL generation pass.  Even
77 ;; the reload pass can generate move insns to copy values from stack slots into
78 ;; temporary registers.  When it does so, one of the operands is a hard
79 ;; register and the other is an operand that can need to be reloaded into a
80 ;; register.
81
82 ;; Therefore, when given such a pair of operands, the pattern must
83 ;; generate RTL which needs no reloading and needs no temporary
84 ;; registers--no registers other than the operands.  For example, if
85 ;; you support the pattern with a `define_expand', then in such a
86 ;; case the `define_expand' mustn't call `force_reg' or any other such
87 ;; function which might generate new pseudo registers.
88
89 ;; This requirement exists even for subword modes on a RISC machine
90 ;; where fetching those modes from memory normally requires several
91 ;; insns and some temporary registers.  Look in `spur.md' to see how
92 ;; the requirement can be satisfied.
93
94 ;; During reload a memory reference with an invalid address may be passed as an
95 ;; operand.  Such an address will be replaced with a valid address later in the
96 ;; reload pass.  In this case, nothing may be done with the address except to
97 ;; use it as it stands.  If it is copied, it will not be replaced with a valid
98 ;; address.  No attempt should be made to make such an address into a valid
99 ;; address and no routine (such as `change_address') that will do so may be
100 ;; called.  Note that `general_operand' will fail when applied to such an
101 ;; address.
102 ;;
103 ;; The global variable `reload_in_progress' (which must be explicitly declared
104 ;; if required) can be used to determine whether such special handling is
105 ;; required.
106 ;;
107 ;; The variety of operands that have reloads depends on the rest of
108 ;; the machine description, but typically on a RISC machine these can
109 ;; only be pseudo registers that did not get hard registers, while on
110 ;; other machines explicit memory references will get optional
111 ;; reloads.
112 ;;
113 ;; If a scratch register is required to move an object to or from memory, it
114 ;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
115 ;; impossible during and after reload.  If there are cases needing scratch
116 ;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
117 ;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
118 ;; patterns `reload_inM' or `reload_outM' to handle them.
119
120 ;; The constraints on a `moveM' must permit moving any hard register to any
121 ;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in
122 ;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a
123 ;; value of 2.
124
125 ;; It is obligatory to support floating point `moveM' instructions
126 ;; into and out of any registers that can hold fixed point values,
127 ;; because unions and structures (which have modes `SImode' or
128 ;; `DImode') can be in those registers and they may have floating
129 ;; point members.
130
131 ;; There may also be a need to support fixed point `moveM' instructions in and
132 ;; out of floating point registers.  Unfortunately, I have forgotten why this
133 ;; was so, and I don't know whether it is still true.  If `HARD_REGNO_MODE_OK'
134 ;; rejects fixed point values in floating point registers, then the constraints
135 ;; of the fixed point `moveM' instructions must be designed to avoid ever
136 ;; trying to reload into a floating point register.
137
138 ;;}}}
139 ;;{{{ Push and Pop  
140
141 ;; Push a register onto the stack
142 (define_insn "movsi_push"
143   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
144         (match_operand:SI 0 "register_operand" "a"))]
145   ""
146   "st   %0, @-r15"
147 )
148
149 ;; Pop a register off the stack
150 (define_insn "movsi_pop"
151   [(set:SI (match_operand:SI 0 "register_operand" "=a")
152         (mem:SI (post_inc:SI (reg:SI 15))))]
153   ""
154   "ld   @r15+, %0"
155 )
156
157 ;;}}}
158 ;;{{{ 1 Byte Moves 
159
160 (define_expand "movqi"
161   [(set (match_operand:QI 0 "general_operand" "")
162         (match_operand:QI 1 "general_operand" ""))]
163   ""
164   "
165 {
166   if (!reload_in_progress
167       && !reload_completed
168       && GET_CODE (operands[0]) == MEM
169       && (GET_CODE (operands[1]) == MEM
170          || immediate_operand (operands[1], QImode)))
171     operands[1] = copy_to_mode_reg (QImode, operands[1]);
172 }")
173
174 (define_insn "movqi_unsigned_register_load"
175   [(set (match_operand:SI 0 "register_operand"              "=r")
176         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
177   ""
178   "ldub %1, %0"
179 )
180
181 (define_expand "movqi_signed_register_load"
182   [(set (match_operand:SI 0 "register_operand"               "")
183         (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
184   ""
185   "
186   emit_insn (gen_movqi_unsigned_register_load (operands[0], operands[1]));
187   emit_insn (gen_extendqisi2 (operands[0], operands[0]));
188   DONE;
189   "
190 )
191
192 (define_insn "*movqi_internal"
193   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,red,m,r")
194         (match_operand:QI 1 "general_operand"       "i,red,r,rm"))]
195   ""
196   "@
197    ldi:8\\t#%A1, %0
198    mov  \\t%1, %0
199    stb  \\t%1, %0
200    ldub \\t%1, %0"
201 )
202
203 ;;}}}
204 ;;{{{ 2 Byte Moves 
205
206 (define_expand "movhi"
207   [(set (match_operand:HI 0 "general_operand" "")
208         (match_operand:HI 1 "general_operand" ""))]
209   ""
210   "
211 {
212   if (!reload_in_progress
213       && !reload_completed
214       && GET_CODE (operands[0]) == MEM
215       && (GET_CODE (operands[1]) == MEM
216          || immediate_operand (operands[1], HImode)))
217     operands[1] = copy_to_mode_reg (HImode, operands[1]);
218 }")
219
220 (define_insn "movhi_unsigned_register_load"
221   [(set (match_operand:SI 0 "register_operand" "=r")
222         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
223   ""
224   "lduh %1, %0"
225 )
226
227 (define_expand "movhi_signed_register_load"
228   [(set (match_operand:SI 0 "register_operand" "")
229         (sign_extend:SI (match_operand:HI 1 "memory_operand" "")))]
230   ""
231   "
232   emit_insn (gen_movhi_unsigned_register_load (operands[0], operands[1]));
233   emit_insn (gen_extendhisi2 (operands[0], operands[0]));
234   DONE;
235   "
236 )
237
238 (define_insn "*movhi_internal"
239   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,red,m,r")
240         (match_operand:HI 1 "general_operand"       "L,M,n,red,r,rm"))]
241   ""
242   "@
243    ldi:8 \\t#%1, %0
244    ldi:20\\t#%1, %0
245    ldi:32\\t#%1, %0
246    mov   \\t%1, %0
247    sth   \\t%1, %0
248    lduh  \\t%1, %0"
249   [(set_attr "length" "*,4,6,*,*,*")]
250 )
251
252 ;;}}}
253 ;;{{{ 4 Byte Moves 
254
255 ;; If the destination is a MEM and the source is a
256 ;; MEM or an CONST_INT move the source into a register.
257 (define_expand "movsi"
258   [(set (match_operand:SI 0 "nonimmediate_operand" "")
259         (match_operand:SI 1 "general_operand" ""))]
260   ""
261   "{
262   if (!reload_in_progress
263       && !reload_completed
264       && GET_CODE(operands[0]) == MEM
265       && (GET_CODE (operands[1]) == MEM
266           || immediate_operand (operands[1], SImode)))
267      operands[1] = copy_to_mode_reg (SImode, operands[1]);
268   }"
269 )
270
271 ;; We can do some clever tricks when loading certain immediate
272 ;; values.  We implement these tricks as define_splits, rather
273 ;; than putting the code into the define_expand "movsi" above,
274 ;; because if we put them there, they will be evaluated at RTL
275 ;; generation time and then the combiner pass will come along
276 ;; and replace the multiple insns that have been generated with
277 ;; the original, slower, load insns.  (The combiner pass only
278 ;; cares about reducing the number of instructions, it does not
279 ;; care about instruction lengths or speeds).  Splits are
280 ;; evaluated after the combine pass and before the scheduling
281 ;; passes, so that they are the perfect place to put this
282 ;; intelligence.
283 ;;
284 ;; XXX we probably ought to implement these for QI and HI mode
285 ;; loads as well.
286
287 ;; If we are loading a small negative constant we can save space
288 ;; and time by loading the positive value and then sign extending it.
289 (define_split
290   [(set (match_operand:SI 0 "register_operand"  "")
291         (match_operand:SI 1 "const_int_operand" ""))]
292    "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128
293     && (GET_CODE (operands[0]) != SUBREG
294         || SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[0], 0))))"
295    [(set:SI (match_dup 0) (match_dup 1))
296     (set:SI (match_dup 0) (sign_extend:SI (match_dup 2)))]
297    "{
298    operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
299    operands[2] = gen_lowpart (QImode, operands[0]);
300    }"
301 )
302
303 ;; If we are loading a large negative constant, one which does
304 ;; not have any of its bottom 24 bit set, then we can save time
305 ;; and space by loading the byte value and shifting it into place.
306 (define_split
307   [(set (match_operand:SI 0 "register_operand"  "")
308         (match_operand:SI 1 "const_int_operand" ""))]
309    "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
310    [(set:SI (match_dup 0) (match_dup 2))
311     (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
312                (clobber (reg:CC 16))])]
313    "{
314    HOST_WIDE_INT val = INTVAL (operands[1]);
315    operands[2] = GEN_INT (val >> 24);
316    }"
317 )
318
319 ;; If we are loading a large positive constant, one which has bits
320 ;; in the top byte set, but whose set bits all lie within an 8 bit
321 ;; range, then we can save time and space by loading the byte value
322 ;; and shifting it into place.
323 (define_split
324   [(set (match_operand:SI 0 "register_operand"  "")
325         (match_operand:SI 1 "const_int_operand" ""))]
326    "(INTVAL (operands[1]) > 0x00ffffff)
327    && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
328    [(set:SI (match_dup 0) (match_dup 2))
329     (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
330                (clobber (reg:CC 16))])]
331    "{
332    HOST_WIDE_INT val = INTVAL (operands[1]);
333    int shift = exact_log2 (val & ( - val));
334    operands[2] = GEN_INT (val >> shift);
335    operands[3] = GEN_INT (shift);
336    }"
337 )
338
339 ;; When TARGET_SMALL_MODEL is defined we assume that all symbolic
340 ;; values are addresses which will fit in 20 bits.
341
342 (define_insn "movsi_internal"
343   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,V,r,m")
344         (match_operand:SI 1 "general_operand"       "L,M,n,i,rde,r,rm,r"))]
345   ""
346   "*
347   {
348     switch (which_alternative)
349     {
350     case 0: return   \"ldi:8 \\t#%1, %0\";
351     case 1: return   \"ldi:20\\t#%1, %0\";
352     case 2: return   \"ldi:32\\t#%1, %0\";
353     case 3: if (TARGET_SMALL_MODEL)
354               return \"ldi:20\\t%1, %0\";
355             else
356               return \"ldi:32\\t%1, %0\";
357     case 4: return   \"mov   \\t%1, %0\";
358     case 5: return   \"st    \\t%1, %0\";
359     case 6: return   \"ld    \\t%1, %0\";
360     case 7: return   \"st    \\t%1, %0\";
361     default: gcc_unreachable ();
362    }
363   }"
364   [(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 4)
365                                (eq_attr "alternative" "2") (const_int 6)
366                                (eq_attr "alternative" "3") 
367                                         (if_then_else (eq_attr "size" "small")
368                                                       (const_int 4)
369                                                       (const_int 6))]
370                               (const_int 2)))]
371 )
372
373 ;;}}}
374 ;;{{{ 8 Byte Moves
375
376 ;; Note - the FR30 does not have an 8 byte load/store instruction
377 ;; but we have to support this pattern because some other patterns
378 ;; (e.g. muldisi2) can produce a DImode result.
379 ;; (This code is stolen from the M32R port.)
380
381 (define_expand "movdi"
382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
383         (match_operand:DI 1 "general_operand" ""))]
384   ""
385   "
386   /* Everything except mem = const or mem = mem can be done easily.  */
387
388   if (GET_CODE (operands[0]) == MEM)
389     operands[1] = force_reg (DImode, operands[1]);
390   "
391 )
392
393 ;; We use an insn and a split so that we can generate
394 ;; RTL rather than text from fr30_move_double().
395
396 (define_insn "*movdi_insn"
397   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
398         (match_operand:DI 1 "di_operand"               "r,m,r,nF"))]
399   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
400   "#"
401   [(set_attr "length" "4,8,12,12")]
402 )
403
404 (define_split
405   [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
406         (match_operand:DI 1 "di_operand" ""))]
407   "reload_completed"
408   [(match_dup 2)]
409   "operands[2] = fr30_move_double (operands);"
410 )
411
412 ;;}}}
413 ;;{{{ Load & Store Multiple Registers 
414
415 ;; The load multiple and store multiple patterns are implemented
416 ;; as peepholes because the only time they are expected to occur
417 ;; is during function prologues and epilogues.
418
419 (define_peephole
420   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
421            (match_operand:SI 0 "high_register_operand" "h"))
422    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
423            (match_operand:SI 1 "high_register_operand" "h"))
424    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
425            (match_operand:SI 2 "high_register_operand" "h"))
426    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
427            (match_operand:SI 3 "high_register_operand" "h"))]
428   "fr30_check_multiple_regs (operands, 4, 1)"
429   "stm1 (%0, %1, %2, %3)"
430   [(set_attr "delay_type" "other")]
431 )
432
433 (define_peephole
434   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
435            (match_operand:SI 0 "high_register_operand" "h"))
436    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
437            (match_operand:SI 1 "high_register_operand" "h"))
438    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
439            (match_operand:SI 2 "high_register_operand" "h"))]
440   "fr30_check_multiple_regs (operands, 3, 1)"
441   "stm1 (%0, %1, %2)"
442   [(set_attr "delay_type" "other")]
443 )
444
445 (define_peephole
446   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
447            (match_operand:SI 0 "high_register_operand" "h"))
448    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
449            (match_operand:SI 1 "high_register_operand" "h"))]
450   "fr30_check_multiple_regs (operands, 2, 1)"
451   "stm1 (%0, %1)"
452   [(set_attr "delay_type" "other")]
453 )
454
455 (define_peephole
456   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
457            (mem:SI (post_inc:SI (reg:SI 15))))
458    (set:SI (match_operand:SI 1 "high_register_operand" "h")
459            (mem:SI (post_inc:SI (reg:SI 15))))
460    (set:SI (match_operand:SI 2 "high_register_operand" "h")
461            (mem:SI (post_inc:SI (reg:SI 15))))
462    (set:SI (match_operand:SI 3 "high_register_operand" "h")
463            (mem:SI (post_inc:SI (reg:SI 15))))]
464   "fr30_check_multiple_regs (operands, 4, 0)"
465   "ldm1 (%0, %1, %2, %3)"
466   [(set_attr "delay_type" "other")]
467 )
468
469 (define_peephole
470   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
471            (mem:SI (post_inc:SI (reg:SI 15))))
472    (set:SI (match_operand:SI 1 "high_register_operand" "h")
473            (mem:SI (post_inc:SI (reg:SI 15))))
474    (set:SI (match_operand:SI 2 "high_register_operand" "h")
475            (mem:SI (post_inc:SI (reg:SI 15))))]
476   "fr30_check_multiple_regs (operands, 3, 0)"
477   "ldm1 (%0, %1, %2)"
478   [(set_attr "delay_type" "other")]
479 )
480
481 (define_peephole
482   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
483            (mem:SI (post_inc:SI (reg:SI 15))))
484    (set:SI (match_operand:SI 1 "high_register_operand" "h")
485            (mem:SI (post_inc:SI (reg:SI 15))))]
486   "fr30_check_multiple_regs (operands, 2, 0)"
487   "ldm1 (%0, %1)"
488   [(set_attr "delay_type" "other")]
489 )
490
491 (define_peephole
492   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
493            (match_operand:SI 0 "low_register_operand" "l"))
494    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
495            (match_operand:SI 1 "low_register_operand" "l"))
496    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
497            (match_operand:SI 2 "low_register_operand" "l"))
498    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
499            (match_operand:SI 3 "low_register_operand" "l"))]
500   "fr30_check_multiple_regs (operands, 4, 1)"
501   "stm0 (%0, %1, %2, %3)"
502   [(set_attr "delay_type" "other")]
503 )
504
505 (define_peephole
506   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
507            (match_operand:SI 0 "low_register_operand" "l"))
508    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
509            (match_operand:SI 1 "low_register_operand" "l"))
510    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
511            (match_operand:SI 2 "low_register_operand" "l"))]
512   "fr30_check_multiple_regs (operands, 3, 1)"
513   "stm0 (%0, %1, %2)"
514   [(set_attr "delay_type" "other")]
515 )
516
517 (define_peephole
518   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
519            (match_operand:SI 0 "low_register_operand" "l"))
520    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
521            (match_operand:SI 1 "low_register_operand" "l"))]
522   "fr30_check_multiple_regs (operands, 2, 1)"
523   "stm0 (%0, %1)"
524   [(set_attr "delay_type" "other")]
525 )
526
527 ;;}}}
528 ;;{{{ Floating Point Moves 
529
530 ;; Note - Patterns for SF mode moves are compulsory, but
531 ;; patterns for DF are optional, as GCC can synthesize them.
532
533 (define_expand "movsf"
534   [(set (match_operand:SF 0 "general_operand" "")
535         (match_operand:SF 1 "general_operand" ""))]
536   ""
537   "{
538   if (!reload_in_progress && !reload_completed
539       && memory_operand (operands[0], SFmode)
540       && memory_operand (operands[1], SFmode))
541     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
542   }"
543 )
544
545 (define_insn "*movsf_internal"
546   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r")
547         (match_operand:SF 1 "general_operand"      "Fn,i,rde,r,rm"))]
548   ""
549   "*
550   {
551     switch (which_alternative)
552     {
553     case 0: return   \"ldi:32\\t%1, %0\";
554     case 1: if (TARGET_SMALL_MODEL)
555               return \"ldi:20\\t%1, %0\";
556             else
557               return \"ldi:32\\t%1, %0\";
558     case 2: return   \"mov   \\t%1, %0\";
559     case 3: return   \"st    \\t%1, %0\";
560     case 4: return   \"ld    \\t%1, %0\";
561     default: gcc_unreachable ();               
562     }
563   }"
564   [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6)
565                                (eq_attr "alternative" "1") 
566                                         (if_then_else (eq_attr "size" "small")
567                                                       (const_int 4)
568                                                       (const_int 6))]
569                               (const_int 2)))]
570 )
571
572 (define_insn "*movsf_constant_store"
573   [(set (match_operand:SF 0 "memory_operand"    "=m")
574         (match_operand:SF 1 "immediate_operand" "F"))]
575   ""
576   "*
577   {
578   const char *    ldi_instr;
579   const char *    tmp_reg;
580   static char     buffer[100];
581
582   ldi_instr = fr30_const_double_is_zero (operands[1]) ? \"ldi:8\" : \"ldi:32\";
583
584   tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
585   
586   sprintf (buffer, \"%s\\t#%%1, %s\\t;\\n\\tst\\t%s, %%0\\t; Created by movsf_constant_store\",
587     ldi_instr, tmp_reg, tmp_reg);
588
589   return buffer;
590   }"
591   [(set_attr "length" "8")]
592 )
593
594 ;;}}}
595
596 ;;}}} \f
597 ;;{{{ Conversions 
598
599 ;; Signed conversions from a smaller integer to a larger integer
600
601 (define_insn "extendqisi2"
602   [(set (match_operand:SI 0 "register_operand"                "=r")
603         (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
604   ""
605   "extsb        %0"
606 )
607
608 (define_insn "extendhisi2"
609   [(set (match_operand:SI 0 "register_operand"                "=r")
610         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
611   ""
612   "extsh        %0"
613 )
614
615 ;; Unsigned conversions from a smaller integer to a larger integer
616
617 (define_insn "zero_extendqisi2"
618   [(set (match_operand:SI 0 "register_operand"                "=r")
619         (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
620   ""
621   "extub        %0"
622 )
623
624 (define_insn "zero_extendhisi2"
625   [(set (match_operand:SI 0 "register_operand"                "=r")
626         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
627   ""
628   "extuh        %0"
629 )
630
631 ;;}}} \f
632 ;;{{{ Arithmetic 
633
634 ;;{{{ Addition 
635
636 ;; This is a special pattern just for adjusting the stack size.
637 (define_insn "add_to_stack"
638   [(set (reg:SI 15)
639         (plus:SI (reg:SI 15)
640                  (match_operand:SI 0 "stack_add_operand" "i")))]
641   ""
642   "addsp        %0"
643 )
644
645 ;; We need some trickery to be able to handle the addition of
646 ;; large (i.e. outside +/- 16) constants.  We need to be able to
647 ;; handle this because reload assumes that it can generate add
648 ;; instructions with arbitrary sized constants.
649 (define_expand "addsi3"
650   [(set (match_operand:SI 0 "register_operand"           "")
651         (plus:SI (match_operand:SI 1 "register_operand"  "")
652                  (match_operand:SI 2 "nonmemory_operand" "")))]
653   ""
654   "{
655   if (   GET_CODE (operands[2]) == REG
656       || GET_CODE (operands[2]) == SUBREG)
657     emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
658   else if (GET_CODE (operands[2]) != CONST_INT)
659     emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
660   else if (INTVAL (operands[2]) >= -16
661            && INTVAL (operands[2]) <= 15
662            && (!REG_P (operands[1])
663                || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
664                || REGNO (operands[1]) == STACK_POINTER_REGNUM))
665     emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
666   else
667     emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
668   DONE;
669   }"
670 )
671
672 (define_insn "addsi_regs"
673   [(set (match_operand:SI 0 "register_operand"          "=r")
674         (plus:SI (match_operand:SI 1 "register_operand" "%0")
675                  (match_operand:SI 2 "register_operand"  "r")))]
676   ""
677   "addn %2, %0"
678 )
679
680 ;; Do not allow an eliminable register in the source register.  It
681 ;; might be eliminated in favor of the stack pointer, probably
682 ;; increasing the offset, and so rendering the instruction illegal.
683 (define_insn "addsi_small_int"
684   [(set (match_operand:SI 0 "register_operand"              "=r,r")
685         (plus:SI (match_operand:SI 1 "register_operand"      "0,0")
686                  (match_operand:SI 2 "add_immediate_operand" "I,J")))]
687   "!REG_P (operands[1])
688    || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
689    || REGNO (operands[1]) == STACK_POINTER_REGNUM"
690   "@
691    addn %2, %0
692    addn2        %2, %0"
693 )
694
695 (define_expand "addsi_big_int"
696   [(set (match_operand:SI 0 "register_operand"           "")
697         (plus:SI (match_operand:SI 1 "register_operand"  "")
698                  (match_operand:SI 2 "immediate_operand" "")))]
699   ""
700   "{
701   /* Cope with the possibility that ops 0 and 1 are the same register.  */
702   if (rtx_equal_p (operands[0], operands[1]))
703     {
704       if (reload_in_progress || reload_completed)
705         {
706           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
707           
708           emit_insn (gen_movsi (reg, operands[2]));
709           emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
710         }
711       else
712         {
713           operands[2] = force_reg (SImode, operands[2]);
714           emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
715         }
716     }
717   else
718     {
719       emit_insn (gen_movsi (operands[0], operands[2]));
720       emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
721     }
722   DONE;
723   }"
724 )
725
726 (define_insn "*addsi_for_reload"
727   [(set (match_operand:SI 0 "register_operand"         "=&r,r,r")
728         (plus:SI (match_operand:SI 1 "register_operand"  "r,r,r")
729                  (match_operand:SI 2 "immediate_operand" "L,M,n")))]
730   "reload_in_progress || reload_completed"
731   "@
732   ldi:8\\t#%2, %0  \\n\\taddn\\t%1, %0
733   ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
734   ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
735   [(set_attr "length" "4,6,8")]
736 )
737
738 ;;}}}
739 ;;{{{ Subtraction 
740
741 (define_insn "subsi3"
742   [(set (match_operand:SI 0 "register_operand"       "=r")
743         (minus:SI (match_operand:SI 1 "register_operand" "0")
744                   (match_operand:SI 2 "register_operand" "r")))]
745   ""
746   "subn %2, %0"
747 )
748
749 ;;}}}
750 ;;{{{ Multiplication 
751
752 ;; Signed multiplication producing 64-bit results from 32-bit inputs
753 (define_insn "mulsidi3"
754   [(set (match_operand:DI 0 "register_operand"                             "=r")
755            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
756                     (sign_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
757    (clobber (reg:CC 16))]
758   ""
759   "mul  %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
760   [(set_attr "length" "6")]
761 )
762
763 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
764 (define_insn "umulsidi3"
765   [(set (match_operand:DI 0 "register_operand"                             "=r")
766            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
767                     (zero_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
768    (clobber (reg:CC 16))]
769   ""
770   "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
771   [(set_attr "length" "6")]
772 )
773
774 ;; Signed multiplication producing 32-bit result from 16-bit inputs
775 (define_insn "mulhisi3"
776   [(set (match_operand:SI 0 "register_operand"                             "=r")
777            (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
778                     (sign_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
779    (clobber (reg:CC 16))]
780   ""
781   "mulh %2, %1\\n\\tmov\\tmdl, %0"
782   [(set_attr "length" "4")]
783 )
784
785 ;; Unsigned multiplication producing 32-bit result from 16-bit inputs
786 (define_insn "umulhisi3"
787   [(set (match_operand:SI 0 "register_operand"                             "=r")
788            (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
789                     (zero_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
790    (clobber (reg:CC 16))]
791   ""
792   "muluh        %2, %1\\n\\tmov\\tmdl, %0"
793   [(set_attr "length" "4")]
794 )
795
796 ;; Signed multiplication producing 32-bit result from 32-bit inputs
797 (define_insn "mulsi3"
798   [(set (match_operand:SI 0 "register_operand"             "=r")
799            (mult:SI (match_operand:SI 1 "register_operand" "%r")
800                     (match_operand:SI 2 "register_operand"  "r")))
801    (clobber (reg:CC 16))]
802   ""
803   "mul  %2, %1\\n\\tmov\\tmdl, %0"
804   [(set_attr "length" "4")]
805 )
806
807 ;;}}}
808 ;;}}} \f
809 ;;{{{ Shifts 
810
811 ;; Arithmetic Shift Left
812 (define_insn "ashlsi3"
813   [(set (match_operand:SI 0 "register_operand"            "=r,r,r")
814         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,0")
815                    (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
816    (clobber (reg:CC 16))]
817   ""
818   "@
819   lsl   %2, %0
820   lsl   %2, %0
821   lsl2  %x2, %0"
822 )
823
824 ;; Arithmetic Shift Right
825 (define_insn "ashrsi3"
826   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
827         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
828                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
829    (clobber (reg:CC 16))]
830   ""
831   "@
832   asr   %2, %0
833   asr   %2, %0
834   asr2  %x2, %0"
835 )
836
837 ;; Logical Shift Right
838 (define_insn "lshrsi3"
839   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
840         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
841                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
842    (clobber (reg:CC 16))]
843   ""
844   "@
845   lsr   %2, %0
846   lsr   %2, %0
847   lsr2  %x2, %0"
848 )
849
850 ;;}}} \f
851 ;;{{{ Logical Operations 
852
853 ;; Logical AND, 32-bit integers
854 (define_insn "andsi3"
855   [(set (match_operand:SI 0 "register_operand"         "=r")
856         (and:SI (match_operand:SI 1 "register_operand" "%r")
857                 (match_operand:SI 2 "register_operand"  "0")))
858    (clobber (reg:CC 16))]
859   ""
860   "and  %1, %0"
861 )
862
863 ;; Inclusive OR, 32-bit integers
864 (define_insn "iorsi3"
865   [(set (match_operand:SI 0 "register_operand"         "=r")
866         (ior:SI (match_operand:SI 1 "register_operand" "%r")
867                 (match_operand:SI 2 "register_operand"  "0")))
868    (clobber (reg:CC 16))]
869   ""
870   "or   %1, %0"
871 )
872
873 ;; Exclusive OR, 32-bit integers
874 (define_insn "xorsi3"
875   [(set (match_operand:SI 0 "register_operand"         "=r")
876         (xor:SI (match_operand:SI 1 "register_operand" "%r")
877                 (match_operand:SI 2 "register_operand"  "0")))
878    (clobber (reg:CC 16))]
879   ""
880   "eor  %1, %0"
881 )
882
883 ;; One's complement, 32-bit integers
884 (define_expand "one_cmplsi2"
885   [(set (match_operand:SI 0 "register_operand"         "")
886         (not:SI (match_operand:SI 1 "register_operand" "")))]
887   ""
888   "{
889   if (rtx_equal_p (operands[0], operands[1]))
890     {
891       if (reload_in_progress || reload_completed)
892         {
893           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
894           
895           emit_insn (gen_movsi (reg, constm1_rtx));
896           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
897         }
898       else
899         {
900           rtx reg = gen_reg_rtx (SImode);
901         
902           emit_insn (gen_movsi (reg, constm1_rtx));
903           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
904         }
905     }
906   else
907     {
908       emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
909       emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
910     }
911   DONE;
912   }"
913 )
914
915 ;;}}} \f
916 ;;{{{ Comparisons 
917
918 ;; The actual comparisons, generated by the cbranch and/or cstore expanders
919
920 (define_insn "*cmpsi_internal"
921   [(set (reg:CC 16)
922         (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")
923                     (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
924   ""
925   "@
926   cmp   %1, %0
927   cmp   %1, %0
928   cmp2  %1, %0"
929 )
930
931 ;;}}} \f
932 ;;{{{ Branches 
933
934 ;; Define_expands called by the machine independent part of the compiler
935 ;; to allocate a new comparison register
936
937 (define_expand "cbranchsi4"
938   [(set (reg:CC 16)
939         (compare:CC (match_operand:SI 1 "register_operand"  "")
940                     (match_operand:SI 2 "nonmemory_operand" "")))
941    (set (pc)
942         (if_then_else (match_operator:CC 0 "ordered_comparison_operator"
943                        [(reg:CC 16) (const_int 0)])
944                       (label_ref (match_operand 3 "" ""))
945                       (pc)))]
946   ""
947   ""
948 )
949
950
951 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
952 ;; swapped.  If they are swapped, it reverses the sense of the branch.
953
954 ;; This pattern matches the (branch-if-true) branches generated above.
955 ;; It generates two different instruction sequences depending upon how
956 ;; far away the destination is.
957
958 ;; The calculation for the instruction length is derived as follows:
959 ;; The branch instruction has a 9-bit signed displacement so we have
960 ;; this inequality for the displacement:
961 ;;
962 ;;               -256 <= pc < 256
963 ;; or
964 ;;         -256 + 256 <= pc + 256 < 256 + 256
965 ;; i.e.
966 ;;                  0 <= pc + 256 < 512 
967 ;;
968 ;; if we consider the displacement as an unsigned value, then negative
969 ;; displacements become very large positive displacements, and the
970 ;; inequality becomes:
971 ;;
972 ;;              pc + 256 < 512
973 ;;
974 ;; In order to allow for the fact that the real branch instruction works
975 ;; from pc + 2, we increase the offset to 258.
976 ;;
977 ;; Note - we do not have to worry about whether the branch is delayed or
978 ;; not, as branch shortening happens after delay slot reorganization.
979
980 (define_insn "*branch_true"
981   [(set (pc)
982         (if_then_else (match_operator:CC 0 "comparison_operator"
983                                          [(reg:CC 16)
984                                           (const_int 0)])
985                       (label_ref (match_operand 1 "" ""))
986                       (pc)))]
987   ""
988   "*
989   {
990     if (get_attr_length (insn) == 2)
991       return \"b%b0%#\\t%l1\";
992     else
993       {
994         static char   buffer [100];
995         const char *  tmp_reg; 
996         const char *  ldi_insn;
997         
998         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
999         
1000         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1001
1002         /* The code produced here is, for say the EQ case:
1003
1004                Bne  1f
1005                LDI  <label>, r0
1006                JMP  r0
1007              1:                                         */
1008              
1009         sprintf (buffer,
1010           \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1011           ldi_insn, tmp_reg, tmp_reg);
1012  
1013         return buffer;
1014     }
1015   }"
1016   [(set (attr "length") (if_then_else
1017                           (ltu
1018                             (plus
1019                               (minus
1020                                 (match_dup 1)
1021                                 (pc))
1022                               (const_int 254))
1023                             (const_int 506))
1024                           (const_int 2)
1025                           (if_then_else (eq_attr "size" "small")
1026                                         (const_int 8)
1027                                         (const_int 10))))
1028    (set_attr "delay_type" "delayed")]
1029 )
1030
1031
1032 ;; This pattern is a duplicate of the previous one, except that the
1033 ;; branch occurs if the test is false, so the %B operator is used.
1034 (define_insn "*branch_false"
1035   [(set (pc)
1036         (if_then_else (match_operator:CC 0 "comparison_operator"
1037                                          [(reg:CC 16)
1038                                           (const_int 0)])
1039                       (pc)
1040                       (label_ref (match_operand 1 "" ""))))]
1041   ""
1042   "*
1043   {
1044     if (get_attr_length (insn) == 2)
1045       return \"b%B0%#\\t%l1 \";
1046     else
1047       {
1048         static char   buffer [100];
1049         const char *  tmp_reg; 
1050         const char *  ldi_insn;
1051         
1052         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1053         
1054         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1055
1056         sprintf (buffer,
1057           \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1058           ldi_insn, tmp_reg, tmp_reg);
1059  
1060         return buffer;
1061       }
1062   }"
1063   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1064                                                  (const_int 254))
1065                                            (const_int 506))
1066                                       (const_int 2)
1067                                       (if_then_else (eq_attr "size" "small")
1068                                                     (const_int 8)
1069                                                     (const_int 10))))
1070    (set_attr "delay_type" "delayed")]
1071 )
1072
1073 ;;}}} \f
1074 ;;{{{ Calls & Jumps 
1075
1076 ;; Subroutine call instruction returning no value.  Operand 0 is the function
1077 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1078 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1079 ;; registers used as operands.
1080
1081 (define_insn "call"
1082   [(call (match_operand 0 "call_operand" "Qm")
1083          (match_operand 1 ""             "g"))
1084    (clobber (reg:SI 17))]
1085   ""
1086   "call%#\\t%0"
1087   [(set_attr "delay_type" "delayed")]
1088 )
1089
1090 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
1091 ;; register in which the value is returned.  There are three more operands, the
1092 ;; same as the three operands of the `call' instruction (but with numbers
1093 ;; increased by one).
1094
1095 ;; Subroutines that return `BLKmode' objects use the `call' insn.
1096
1097 (define_insn "call_value"
1098   [(set (match_operand 0 "register_operand"  "=r")
1099         (call (match_operand 1 "call_operand" "Qm")
1100               (match_operand 2 ""             "g")))
1101    (clobber (reg:SI 17))]
1102   ""
1103   "call%#\\t%1"
1104   [(set_attr "delay_type" "delayed")]
1105 )
1106
1107 ;; Normal unconditional jump.
1108 ;; For a description of the computation of the length 
1109 ;; attribute see the branch patterns above.
1110 ;;
1111 ;; Although this instruction really clobbers r0, flow
1112 ;; relies on jump being simplejump_p in several places
1113 ;; and as r0 is fixed, this doesn't change anything
1114 (define_insn "jump"
1115   [(set (pc) (label_ref (match_operand 0 "" "")))]
1116   ""
1117   "*
1118   {
1119     if (get_attr_length (insn) == 2)
1120        return \"bra%#\\t%0\";
1121     else
1122       {
1123         static char   buffer [100];
1124         const char *  tmp_reg; 
1125         const char *  ldi_insn;
1126         
1127         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1128
1129         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1130
1131         sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1132           ldi_insn, tmp_reg, tmp_reg);
1133  
1134         return buffer;
1135       }
1136   }"
1137   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1138                                                 (const_int 254))
1139                                           (const_int 506))
1140                                      (const_int 2)
1141                                      (if_then_else (eq_attr "size" "small")
1142                                                    (const_int 6)
1143                                                    (const_int 8))))
1144    (set_attr "delay_type" "delayed")]
1145 )
1146
1147 ;; Indirect jump through a register
1148 (define_insn "indirect_jump"
1149   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1150   "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1151   "jmp%#\\t@%0"
1152   [(set_attr "delay_type" "delayed")]
1153 )
1154
1155 (define_insn "tablejump"
1156   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1157    (use (label_ref (match_operand 1 "" "")))]
1158   ""
1159   "jmp%#\\t@%0"
1160   [(set_attr "delay_type" "delayed")]
1161 )
1162
1163 ;;}}} \f
1164 ;;{{{ Function Prologues and Epilogues 
1165
1166 ;; Called after register allocation to add any instructions needed for the
1167 ;; prologue.  Using a prologue insn is favored compared to putting all of the
1168 ;; instructions in output_function_prologue(), since it allows the scheduler
1169 ;; to intermix instructions with the saves of the caller saved registers.  In
1170 ;; some cases, it might be necessary to emit a barrier instruction as the last
1171 ;; insn to prevent such scheduling.
1172 (define_expand "prologue"
1173   [(clobber (const_int 0))]
1174   ""
1175   "{
1176   fr30_expand_prologue ();
1177   DONE;
1178   }"
1179 )
1180
1181 ;; Called after register allocation to add any instructions needed for the
1182 ;; epilogue.  Using an epilogue insn is favored compared to putting all of the
1183 ;; instructions in output_function_epilogue(), since it allows the scheduler
1184 ;; to intermix instructions with the restores of the caller saved registers.
1185 ;; In some cases, it might be necessary to emit a barrier instruction as the
1186 ;; first insn to prevent such scheduling.
1187 (define_expand "epilogue"
1188   [(return)]
1189   ""
1190   "{
1191   fr30_expand_epilogue ();
1192   DONE;
1193   }"
1194 )
1195
1196 (define_insn "return_from_func"
1197   [(return)
1198    (use (reg:SI 17))]
1199   "reload_completed"
1200   "ret%#"
1201   [(set_attr "delay_type" "delayed")]
1202 )
1203
1204 (define_insn "leave_func"
1205   [(set (reg:SI 15) (plus:SI (reg:SI 14) (const_int 4)))
1206    (set (reg:SI 14) (mem:SI (minus:SI (reg:SI 15) (const_int 4))))]
1207   "reload_completed"
1208   "leave"
1209 )
1210
1211 (define_expand "enter_func"
1212   [(parallel
1213   [(set:SI (mem:SI (minus:SI (match_dup 1)
1214                              (const_int 4)))
1215            (match_dup 2))
1216    (set:SI (match_dup 2)
1217            (minus:SI (match_dup 1)
1218                      (const_int 4)))
1219    (set:SI (match_dup 1)
1220            (minus:SI (match_dup 1)
1221                      (match_operand:SI 0 "immediate_operand")))]
1222   )]
1223   ""
1224 {
1225   operands[1] = stack_pointer_rtx;
1226   operands[2] = hard_frame_pointer_rtx;
1227 })
1228
1229 (define_insn "*enter_func"
1230   [(set:SI (mem:SI (minus:SI (reg:SI 15)
1231                              (const_int 4)))
1232            (reg:SI 14))
1233    (set:SI (reg:SI 14)
1234            (minus:SI (reg:SI 15)
1235                      (const_int 4)))
1236    (set:SI (reg:SI 15)
1237            (minus:SI (reg:SI 15)
1238                      (match_operand 0 "immediate_operand" "i")))]
1239   "reload_completed"
1240   "enter        #%0"
1241   [(set_attr "delay_type" "other")]
1242 )
1243
1244 ;;}}} \f
1245 ;;{{{ Miscellaneous 
1246
1247 ;; No operation, needed in case the user uses -g but not -O.
1248 (define_insn "nop"
1249   [(const_int 0)]
1250   ""
1251   "nop"
1252 )
1253
1254 ;; Pseudo instruction that prevents the scheduler from moving code above this
1255 ;; point.
1256 (define_insn "blockage"
1257   [(unspec_volatile [(const_int 0)] 0)]
1258   ""
1259   ""
1260   [(set_attr "length" "0")]
1261 )
1262 ;;}}} \f
1263   
1264 ;; Local Variables:
1265 ;; mode: md
1266 ;; folded-file: t
1267 ;; End: