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