Mark ChangeLog
[official-gcc.git] / gcc / config / fr30 / fr30.md
blob296cdb27eb25cb16806b3020cc27bb6693fb2715
1 ;;{{{ Comment 
3 ;; FR30 machine description.
4 ;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
5 ;; Contributed by Cygnus Solutions.
7 ;; This file is part of GNU CC.
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 ;;}}} \f
27 ;;{{{ Attributes 
29 (define_attr "length" "" (const_int 2))
31 ;; Used to distinguish between small memory model targets and big mode targets.
33 (define_attr "size" "small,big"
34   (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
35                        (const_string "small")
36                        (const_string "big"))))
39 ;; Define an attribute to be used by the delay slot code.
40 ;; An instruction by default is considered to be 'delyabable'
41 ;; that is, it can be placed into a delay slot, but it is not
42 ;; itself an delyaed branch type instruction.  An instruction
43 ;; whoes type is 'delayed' is one which has a delay slot, and
44 ;; an instruction whoes delay_type is 'other' is one which does
45 ;; not have a delay slot, nor can it be placed into a delay slot.
47 (define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
49 ;;}}} \f
50 ;;{{{ Delay Slot Specifications 
52 (define_delay (eq_attr "delay_type" "delayed")
53   [(and (eq_attr "delay_type" "delayable")
54         (eq_attr "length" "2"))
55    (nil)
56    (nil)]
59 ;;}}}
60 ;;{{{ Moves 
62 ;;{{{ Comment 
64 ;; Wrap moves in define_expand to prevent memory->memory moves from being
65 ;; generated at the RTL level, which generates better code for most machines
66 ;; which can't do mem->mem moves.
68 ;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
69 ;; than M, the effect of this instruction is to store the specified value in
70 ;; the part of the register that corresponds to mode M.  The effect on the rest
71 ;; of the register is undefined.
73 ;; This class of patterns is special in several ways.  First of all, each of
74 ;; these names *must* be defined, because there is no other way to copy a datum
75 ;; from one place to another.
77 ;; Second, these patterns are not used solely in the RTL generation pass.  Even
78 ;; the reload pass can generate move insns to copy values from stack slots into
79 ;; temporary registers.  When it does so, one of the operands is a hard
80 ;; register and the other is an operand that can need to be reloaded into a
81 ;; register.
83 ;; Therefore, when given such a pair of operands, the pattern must
84 ;; generate RTL which needs no reloading and needs no temporary
85 ;; registers--no registers other than the operands.  For example, if
86 ;; you support the pattern with a `define_expand', then in such a
87 ;; case the `define_expand' mustn't call `force_reg' or any other such
88 ;; function which might generate new pseudo registers.
90 ;; This requirement exists even for subword modes on a RISC machine
91 ;; where fetching those modes from memory normally requires several
92 ;; insns and some temporary registers.  Look in `spur.md' to see how
93 ;; the requirement can be satisfied.
95 ;; During reload a memory reference with an invalid address may be passed as an
96 ;; operand.  Such an address will be replaced with a valid address later in the
97 ;; reload pass.  In this case, nothing may be done with the address except to
98 ;; use it as it stands.  If it is copied, it will not be replaced with a valid
99 ;; address.  No attempt should be made to make such an address into a valid
100 ;; address and no routine (such as `change_address') that will do so may be
101 ;; called.  Note that `general_operand' will fail when applied to such an
102 ;; address.
104 ;; The global variable `reload_in_progress' (which must be explicitly declared
105 ;; if required) can be used to determine whether such special handling is
106 ;; required.
108 ;; The variety of operands that have reloads depends on the rest of
109 ;; the machine description, but typically on a RISC machine these can
110 ;; only be pseudo registers that did not get hard registers, while on
111 ;; other machines explicit memory references will get optional
112 ;; reloads.
114 ;; If a scratch register is required to move an object to or from memory, it
115 ;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
116 ;; impossible during and after reload.  If there are cases needing scratch
117 ;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
118 ;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
119 ;; patterns `reload_inM' or `reload_outM' to handle them.
121 ;; The constraints on a `moveM' must permit moving any hard register to any
122 ;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in
123 ;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a
124 ;; value of 2.
126 ;; It is obligatory to support floating point `moveM' instructions
127 ;; into and out of any registers that can hold fixed point values,
128 ;; because unions and structures (which have modes `SImode' or
129 ;; `DImode') can be in those registers and they may have floating
130 ;; point members.
132 ;; There may also be a need to support fixed point `moveM' instructions in and
133 ;; out of floating point registers.  Unfortunately, I have forgotten why this
134 ;; was so, and I don't know whether it is still true.  If `HARD_REGNO_MODE_OK'
135 ;; rejects fixed point values in floating point registers, then the constraints
136 ;; of the fixed point `moveM' instructions must be designed to avoid ever
137 ;; trying to reload into a floating point register.
139 ;;}}}
140 ;;{{{ Push and Pop  
142 ;; Push a register onto the stack
143 (define_insn "movsi_push"
144   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
145         (match_operand:SI 0 "register_operand" "a"))]
146   ""
147   "st   %0, @-r15"
150 ;; Pop a register off the stack
151 (define_insn "movsi_pop"
152   [(set:SI (match_operand:SI 0 "register_operand" "=a")
153         (mem:SI (post_inc:SI (reg:SI 15))))]
154   ""
155   "ld   @r15+, %0"
158 ;;}}}
159 ;;{{{ 1 Byte Moves 
161 (define_expand "movqi"
162   [(set (match_operand:QI 0 "general_operand" "")
163         (match_operand:QI 1 "general_operand" ""))]
164   ""
165   "
167   if (!reload_in_progress
168       && !reload_completed
169       && GET_CODE (operands[0]) == MEM
170       && (GET_CODE (operands[1]) == MEM
171          || immediate_operand (operands[1], QImode)))
172     operands[1] = copy_to_mode_reg (QImode, operands[1]);
175 (define_insn "movqi_unsigned_register_load"
176   [(set (match_operand:SI 0 "register_operand"              "=r")
177         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
178   ""
179   "ldub %1, %0"
182 (define_expand "movqi_signed_register_load"
183   [(set (match_operand:SI 0 "register_operand"               "")
184         (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))]
185   ""
186   "
187   emit_insn (gen_movqi_unsigned_register_load (operands[0], operands[1]));
188   emit_insn (gen_extendqisi2 (operands[0], operands[0]));
189   DONE;
190   "
193 (define_insn "*movqi_internal"
194   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,red,m,r")
195         (match_operand:QI 1 "general_operand"       "i,red,r,rm"))]
196   ""
197   "@
198    ldi:8\\t#%A1, %0
199    mov  \\t%1, %0
200    stb  \\t%1, %0
201    ldub \\t%1, %0"
204 ;;}}}
205 ;;{{{ 2 Byte Moves 
207 (define_expand "movhi"
208   [(set (match_operand:HI 0 "general_operand" "")
209         (match_operand:HI 1 "general_operand" ""))]
210   ""
211   "
213   if (!reload_in_progress
214       && !reload_completed
215       && GET_CODE (operands[0]) == MEM
216       && (GET_CODE (operands[1]) == MEM
217          || immediate_operand (operands[1], HImode)))
218     operands[1] = copy_to_mode_reg (HImode, operands[1]);
221 (define_insn "movhi_unsigned_register_load"
222   [(set (match_operand:SI 0 "register_operand" "=r")
223         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
224   ""
225   "lduh %1, %0"
228 (define_expand "movhi_signed_register_load"
229   [(set (match_operand:SI 0 "register_operand" "")
230         (sign_extend:SI (match_operand:HI 1 "memory_operand" "")))]
231   ""
232   "
233   emit_insn (gen_movhi_unsigned_register_load (operands[0], operands[1]));
234   emit_insn (gen_extendhisi2 (operands[0], operands[0]));
235   DONE;
236   "
239 (define_insn "*movhi_internal"
240   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,red,m,r")
241         (match_operand:HI 1 "general_operand"       "L,M,n,red,r,rm"))]
242   ""
243   "@
244    ldi:8 \\t#%1, %0
245    ldi:20\\t#%1, %0
246    ldi:32\\t#%1, %0
247    mov   \\t%1, %0
248    sth   \\t%1, %0
249    lduh  \\t%1, %0"
250   [(set_attr "length" "*,4,6,*,*,*")]
253 ;;}}}
254 ;;{{{ 4 Byte Moves 
256 ;; If the destination is a MEM and the source is a
257 ;; MEM or an CONST_INT move the source into a register.
258 (define_expand "movsi"
259   [(set (match_operand:SI 0 "nonimmediate_operand" "")
260         (match_operand:SI 1 "general_operand" ""))]
261   ""
262   "{
263   if (!reload_in_progress
264       && !reload_completed
265       && GET_CODE(operands[0]) == MEM
266       && (GET_CODE (operands[1]) == MEM
267           || immediate_operand (operands[1], SImode)))
268      operands[1] = copy_to_mode_reg (SImode, operands[1]);
269   }"
272 ;; We can do some clever tricks when loading certain immediate
273 ;; values.  We implement these tricks as define_splits, rather
274 ;; than putting the code into the define_expand "movsi" above,
275 ;; because if we put them there, they will be evaluated at RTL
276 ;; generation time and then the combiner pass will come along
277 ;; and replace the multiple insns that have been generated with
278 ;; the original, slower, load insns.  (The combiner pass only
279 ;; cares about reducing the number of instructions, it does not
280 ;; care about instruction lengths or speeds).  Splits are
281 ;; evaluated after the combine pass and before the scheduling
282 ;; passes, so that they are the perfect place to put this
283 ;; intelligence.
285 ;; XXX we probably ought to implement these for QI and HI mode
286 ;; loads as well.
288 ;; If we are loading a small negative constant we can save space
289 ;; and time by loading the positive value and then sign extending it.
290 (define_split
291   [(set (match_operand:SI 0 "register_operand"  "")
292         (match_operand:SI 1 "immediate_operand" ""))]
293    "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128"
294    [(set:SI (match_dup 0) (match_dup 2))
295     (set:SI (match_dup 0) (sign_extend:SI (subreg:QI (match_dup 0) 0)))]
296    "{
297    operands[2] = GEN_INT (INTVAL (operands[1]) & 0xff);
298    }"
301 ;; If we are loading a large negative constant, one which does
302 ;; not have any of its bottom 24 bit set, then we can save time
303 ;; and space by loading the byte value and shifting it into place.
304 (define_split
305   [(set (match_operand:SI 0 "register_operand"  "")
306         (match_operand:SI 1 "immediate_operand" ""))]
307    "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
308    [(set:SI (match_dup 0) (match_dup 2))
309     (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
310                (clobber (reg:CC 16))])]
311    "{
312    HOST_WIDE_INT val = INTVAL (operands[1]);
313    operands[2] = GEN_INT (val >> 24);
314    }"
317 ;; If we are loading a large positive constant, one which has bits
318 ;; in the top byte set, but whoes set bits all lie within an 8 bit
319 ;; range, then we can save time and space by loading the byte value
320 ;; and shifting it into place.
321 (define_split
322   [(set (match_operand:SI 0 "register_operand"  "")
323         (match_operand:SI 1 "immediate_operand" ""))]
324    "(INTVAL (operands[1]) > 0x00ffffff)
325    && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
326    [(set:SI (match_dup 0) (match_dup 2))
327     (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
328                (clobber (reg:CC 16))])]
329    "{
330    HOST_WIDE_INT val = INTVAL (operands[1]);
331    int shift = exact_log2 (val & ( - val));
332    operands[2] = GEN_INT (val >> shift);
333    operands[3] = GEN_INT (shift);
334    }"
337 ;; When TARGET_SMALL_MODEL is defined we assume that all symbolic
338 ;; values are addresses which will fit in 20 bits.
340 (define_insn "movsi_internal"
341   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,m,r")
342         (match_operand:SI 1 "general_operand"       "L,M,n,i,rde,r,rm"))]
343   ""
344   "*
345   {
346     switch (which_alternative)
347     {
348     case 0: return   \"ldi:8 \\t#%1, %0\";
349     case 1: return   \"ldi:20\\t#%1, %0\";
350     case 2: return   \"ldi:32\\t#%1, %0\";
351     case 3: if (TARGET_SMALL_MODEL)
352               return \"ldi:20\\t%1, %0\";
353             else
354               return \"ldi:32\\t%1, %0\";
355     case 4: return   \"mov   \\t%1, %0\";
356     case 5: return   \"st    \\t%1, %0\";
357     case 6: return   \"ld    \\t%1, %0\";
358     default: abort ();         
359     }
360   }"
361   [(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 4)
362                                (eq_attr "alternative" "2") (const_int 6)
363                                (eq_attr "alternative" "3") 
364                                         (if_then_else (eq_attr "size" "small")
365                                                       (const_int 4)
366                                                       (const_int 6))]
367                               (const_int 2)))]
370 ;;}}}
371 ;;{{{ 8 Byte Moves
373 ;; Note - the FR30 does not have an 8 byte load/store instruction
374 ;; but we have to support this pattern because some other patterns
375 ;; (eg muldisi2) can produce a DImode result.
376 ;; (This code is stolen from the M32R port.)
378 (define_expand "movdi"
379   [(set (match_operand:DI 0 "general_operand" "")
380         (match_operand:DI 1 "general_operand" ""))]
381   ""
382   "
383   /* Everything except mem = const or mem = mem can be done easily.  */
384   
385   if (GET_CODE (operands[0]) == MEM)
386     operands[1] = force_reg (DImode, operands[1]);
387   ")
389 ;; We use an insn and a split so that we can generate
390 ;; RTL rather than text from fr30_move_double().
392 (define_insn "*movdi_insn"
393   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
394         (match_operand:DI 1 "di_operand"               "r,m,r,nF"))]
395   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
396   "#"
397   [(set_attr "length" "4,8,12,12")]
400 (define_split
401   [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
402         (match_operand:DI 1 "di_operand" ""))]
403   "reload_completed"
404   [(match_dup 2)]
405   "operands[2] = fr30_move_double (operands);")
407 ;;}}}
408 ;;{{{ Load & Store Multiple Registers 
410 ;; The load multiple and store multiple patterns are implemented
411 ;; as peepholes because the only time they are expected to occur
412 ;; is during function prologues and epilogues.
414 (define_peephole
415   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
416            (match_operand:SI 0 "high_register_operand" "h"))
417    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
418            (match_operand:SI 1 "high_register_operand" "h"))
419    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
420            (match_operand:SI 2 "high_register_operand" "h"))
421    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
422            (match_operand:SI 3 "high_register_operand" "h"))]
423   "fr30_check_multiple_regs (operands, 4, 1)"
424   "stm1 (%0, %1, %2, %3)"
425   [(set_attr "delay_type" "other")]
428 (define_peephole
429   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
430            (match_operand:SI 0 "high_register_operand" "h"))
431    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
432            (match_operand:SI 1 "high_register_operand" "h"))
433    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
434            (match_operand:SI 2 "high_register_operand" "h"))]
435   "fr30_check_multiple_regs (operands, 3, 1)"
436   "stm1 (%0, %1, %2)"
437   [(set_attr "delay_type" "other")]
440 (define_peephole
441   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
442            (match_operand:SI 0 "high_register_operand" "h"))
443    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
444            (match_operand:SI 1 "high_register_operand" "h"))]
445   "fr30_check_multiple_regs (operands, 2, 1)"
446   "stm1 (%0, %1)"
447   [(set_attr "delay_type" "other")]
450 (define_peephole
451   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
452            (mem:SI (post_inc:SI (reg:SI 15))))
453    (set:SI (match_operand:SI 1 "high_register_operand" "h")
454            (mem:SI (post_inc:SI (reg:SI 15))))
455    (set:SI (match_operand:SI 2 "high_register_operand" "h")
456            (mem:SI (post_inc:SI (reg:SI 15))))
457    (set:SI (match_operand:SI 3 "high_register_operand" "h")
458            (mem:SI (post_inc:SI (reg:SI 15))))]
459   "fr30_check_multiple_regs (operands, 4, 0)"
460   "ldm1 (%0, %1, %2, %3)"
461   [(set_attr "delay_type" "other")]
464 (define_peephole
465   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
466            (mem:SI (post_inc:SI (reg:SI 15))))
467    (set:SI (match_operand:SI 1 "high_register_operand" "h")
468            (mem:SI (post_inc:SI (reg:SI 15))))
469    (set:SI (match_operand:SI 2 "high_register_operand" "h")
470            (mem:SI (post_inc:SI (reg:SI 15))))]
471   "fr30_check_multiple_regs (operands, 3, 0)"
472   "ldm1 (%0, %1, %2)"
473   [(set_attr "delay_type" "other")]
476 (define_peephole
477   [(set:SI (match_operand:SI 0 "high_register_operand" "h")
478            (mem:SI (post_inc:SI (reg:SI 15))))
479    (set:SI (match_operand:SI 1 "high_register_operand" "h")
480            (mem:SI (post_inc:SI (reg:SI 15))))]
481   "fr30_check_multiple_regs (operands, 2, 0)"
482   "ldm1 (%0, %1)"
483   [(set_attr "delay_type" "other")]
486 (define_peephole
487   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
488            (match_operand:SI 0 "low_register_operand" "l"))
489    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
490            (match_operand:SI 1 "low_register_operand" "l"))
491    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
492            (match_operand:SI 2 "low_register_operand" "l"))
493    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
494            (match_operand:SI 3 "low_register_operand" "l"))]
495   "fr30_check_multiple_regs (operands, 4, 1)"
496   "stm0 (%0, %1, %2, %3)"
497   [(set_attr "delay_type" "other")]
500 (define_peephole
501   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
502            (match_operand:SI 0 "low_register_operand" "l"))
503    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
504            (match_operand:SI 1 "low_register_operand" "l"))
505    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
506            (match_operand:SI 2 "low_register_operand" "l"))]
507   "fr30_check_multiple_regs (operands, 3, 1)"
508   "stm0 (%0, %1, %2)"
509   [(set_attr "delay_type" "other")]
512 (define_peephole
513   [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
514            (match_operand:SI 0 "low_register_operand" "l"))
515    (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
516            (match_operand:SI 1 "low_register_operand" "l"))]
517   "fr30_check_multiple_regs (operands, 2, 1)"
518   "stm0 (%0, %1)"
519   [(set_attr "delay_type" "other")]
522 ;;}}}
523 ;;{{{ Floating Point Moves 
525 ;; Note - Patterns for SF mode moves are compulsory, but
526 ;; patterns for DF are optional, as GCC can synthesise them.
528 (define_expand "movsf"
529   [(set (match_operand:SF 0 "general_operand" "")
530         (match_operand:SF 1 "general_operand" ""))]
531   ""
532   "{
533   if (!reload_in_progress && !reload_completed
534       && memory_operand (operands[0], SFmode)
535       && memory_operand (operands[1], SFmode))
536     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
537   }"
540 (define_insn "*movsf_internal"
541   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r")
542         (match_operand:SF 1 "general_operand"      "Fn,i,rde,r,rm"))]
543   ""
544   "*
545   {
546     switch (which_alternative)
547     {
548     case 0: return   \"ldi:32\\t%1, %0\";
549     case 1: if (TARGET_SMALL_MODEL)
550               return \"ldi:20\\t%1, %0\";
551             else
552               return \"ldi:32\\t%1, %0\";
553     case 2: return   \"mov   \\t%1, %0\";
554     case 3: return   \"st    \\t%1, %0\";
555     case 4: return   \"ld    \\t%1, %0\";
556     default: abort ();         
557     }
558   }"
559   [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6)
560                                (eq_attr "alternative" "1") 
561                                         (if_then_else (eq_attr "size" "small")
562                                                       (const_int 4)
563                                                       (const_int 6))]
564                               (const_int 2)))]
567 (define_insn "*movsf_constant_store"
568   [(set (match_operand:SF 0 "memory_operand"    "=m")
569         (match_operand:SF 1 "immediate_operand" "F"))]
570   ""
571   "*
572   {
573   char *          ldi_instr;
574   const char *    tmp_reg;
575   static char     buffer[100];
576   REAL_VALUE_TYPE d;
578   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[1]);
579   
580   if (REAL_VALUES_EQUAL (d, dconst0))
581     ldi_instr = \"ldi:8\";
582   else
583     ldi_instr = \"ldi:32\";
585   tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
586   
587   sprintf (buffer, \"%s\\t#%%1, %s\\t;\\n\\tst\\t%s, %%0\\t; Created by movsf_constant_store\",
588     ldi_instr, tmp_reg, tmp_reg);
590   return buffer;
591   }"
592   [(set_attr "length" "8")]
595 ;;}}}
597 ;;}}} \f
598 ;;{{{ Conversions 
600 ;; Signed conversions from a smaller integer to a larger integer
602 (define_insn "extendqisi2"
603   [(set (match_operand:SI 0 "register_operand"                "=r")
604         (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
605   ""
606   "extsb        %0"
609 (define_insn "extendhisi2"
610   [(set (match_operand:SI 0 "register_operand"                "=r")
611         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
612   ""
613   "extsh        %0"
616 ;; Unsigned conversions from a smaller integer to a larger integer
618 (define_insn "zero_extendqisi2"
619   [(set (match_operand:SI 0 "register_operand"                "=r")
620         (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
621   ""
622   "extub        %0"
625 (define_insn "zero_extendhisi2"
626   [(set (match_operand:SI 0 "register_operand"                "=r")
627         (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
628   ""
629   "extuh        %0"
632 ;;}}} \f
633 ;;{{{ Arithmetic 
635 ;;{{{ Addition 
637 ;; This is a special pattern just for adjusting the stack size.
638 (define_insn "add_to_stack"
639   [(set (reg:SI 15)
640         (plus:SI (reg:SI 15)
641                  (match_operand:SI 0 "stack_add_operand" "i")))]
642   ""
643   "addsp        %0"
646 ;; We need some trickery to be able to handle the addition of
647 ;; large (ie outside +/- 16) constants.  We need to be able to
648 ;; handle this because reload assumes that it can generate add
649 ;; instructions with arbitary sized constants.
650 (define_expand "addsi3"
651   [(set (match_operand:SI 0 "register_operand"           "")
652         (plus:SI (match_operand:SI 1 "register_operand"  "")
653                  (match_operand:SI 2 "nonmemory_operand" "")))]
654   ""
655   "{
656   if (   GET_CODE (operands[2]) == REG
657       || GET_CODE (operands[2]) == SUBREG)
658     emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
659   else if (GET_CODE (operands[2]) != CONST_INT)
660     emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
661   else if (   (REGNO (operands[1]) != FRAME_POINTER_REGNUM)
662            && (REGNO (operands[1]) != ARG_POINTER_REGNUM)
663            && (INTVAL (operands[2]) >= -16)
664            && (INTVAL (operands[2]) <= 15))
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   }"
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"
680 ;; Do not allow an eliminable register in the source register.  It
681 ;; might be eliminated in favour 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   "   (REGNO (operands[1]) != FRAME_POINTER_REGNUM)
688    && (REGNO (operands[1]) != ARG_POINTER_REGNUM)"
689   "@
690    addn %2, %0
691    addn2        %2, %0"
694 (define_expand "addsi_big_int"
695   [(set (match_operand:SI 0 "register_operand"           "")
696         (plus:SI (match_operand:SI 1 "register_operand"  "")
697                  (match_operand:SI 2 "immediate_operand" "")))]
698   ""
699   "{
700   /* Cope with the possibility that ops 0 and 1 are the same register.  */
701   if (REGNO (operands[0]) == REGNO (operands[1]))
702     {
703       if (reload_in_progress || reload_completed)
704         {
705           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
706           
707           emit_insn (gen_movsi (reg, operands[2]));
708           emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
709         }
710       else
711         {
712           operands[2] = force_reg (SImode, operands[2]);
713           emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
714         }
715     }
716   else
717     {
718       emit_insn (gen_movsi (operands[0], operands[2]));
719       emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
720     }
721   DONE;
722   }"
725 (define_insn "*addsi_for_reload"
726   [(set (match_operand:SI 0 "register_operand"         "=&r,r,r")
727         (plus:SI (match_operand:SI 1 "register_operand"  "r,r,r")
728                  (match_operand:SI 2 "immediate_operand" "L,M,n")))]
729   "reload_in_progress || reload_completed"
730   "@
731   ldi:8\\t#%2, %0  \\n\\taddn\\t%1, %0
732   ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
733   ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
734   [(set_attr "length" "4,6,8")]
737 ;;}}}
738 ;;{{{ Subtraction 
740 (define_insn "subsi3"
741   [(set (match_operand:SI 0 "register_operand"       "=r")
742         (minus:SI (match_operand:SI 1 "register_operand" "0")
743                   (match_operand:SI 2 "register_operand" "r")))]
744   ""
745   "subn %2, %0"
748 ;;}}}
749 ;;{{{ Multiplication 
751 ;; Signed multiplication producing 64 bit results from 32 bit inputs
752 (define_insn "mulsidi3"
753   [(set (match_operand:DI 0 "register_operand"                             "=r")
754            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
755                     (sign_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
756    (clobber (reg:CC 16))]
757   ""
758   "mul  %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
759   [(set_attr "length" "6")]
762 ;; Unsigned multiplication producing 64 bit results from 32 bit inputs
763 (define_insn "umulsidi3"
764   [(set (match_operand:DI 0 "register_operand"                             "=r")
765            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
766                     (zero_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
767    (clobber (reg:CC 16))]
768   ""
769   "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
770   [(set_attr "length" "6")]
773 ;; Signed multiplication producing 32 bit result from 16 bit inputs
774 (define_insn "mulhisi3"
775   [(set (match_operand:SI 0 "register_operand"                             "=r")
776            (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
777                     (sign_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
778    (clobber (reg:CC 16))]
779   ""
780   "mulh %2, %1\\n\\tmov\\tmdl, %0"
781   [(set_attr "length" "4")]
784 ;; Unsigned multiplication producing 32 bit result from 16 bit inputs
785 (define_insn "umulhisi3"
786   [(set (match_operand:SI 0 "register_operand"                             "=r")
787            (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
788                     (zero_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
789    (clobber (reg:CC 16))]
790   ""
791   "muluh        %2, %1\\n\\tmov\\tmdl, %0"
792   [(set_attr "length" "4")]
795 ;; Signed multiplication producing 32 bit result from 32 bit inputs
796 (define_insn "mulsi3"
797   [(set (match_operand:SI 0 "register_operand"             "=r")
798            (mult:SI (match_operand:SI 1 "register_operand" "%r")
799                     (match_operand:SI 2 "register_operand"  "r")))
800    (clobber (reg:CC 16))]
801   ""
802   "mul  %2, %1\\n\\tmov\\tmdl, %0"
803   [(set_attr "length" "4")]
806 ;;}}}
807 ;;{{{ Negation 
809 (define_expand "negsi2"
810   [(set (match_operand:SI 0 "register_operand"         "")
811         (neg:SI (match_operand:SI 1 "register_operand" "")))]
812   ""
813   "{
814   if (REGNO (operands[0]) == REGNO (operands[1]))
815     {
816       if (reload_in_progress || reload_completed)
817         {
818           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
819           
820           emit_insn (gen_movsi (reg, GEN_INT (0)));
821           emit_insn (gen_subsi3 (reg, reg, operands[0]));
822           emit_insn (gen_movsi (operands[0], reg));
823         }
824       else
825         {
826           rtx reg = gen_reg_rtx (SImode);
827         
828           emit_insn (gen_movsi (reg, GEN_INT (0)));
829           emit_insn (gen_subsi3 (reg, reg, operands[0]));
830           emit_insn (gen_movsi (operands[0], reg));
831         }
832     }
833   else
834     {
835       emit_insn (gen_movsi_internal (operands[0], GEN_INT (0)));
836       emit_insn (gen_subsi3 (operands[0], operands[0], operands[1]));
837     }
838   DONE;
839   }"
842 ;;}}}
844 ;;}}} \f
845 ;;{{{ Shifts 
847 ;; Arithmetic Shift Left
848 (define_insn "ashlsi3"
849   [(set (match_operand:SI 0 "register_operand"            "=r,r,r")
850         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,0")
851                    (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
852    (clobber (reg:CC 16))]
853   ""
854   "@
855   lsl   %2, %0
856   lsl   %2, %0
857   lsl2  %x2, %0"
860 ;; Arithmetic Shift Right
861 (define_insn "ashrsi3"
862   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
863         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
864                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
865    (clobber (reg:CC 16))]
866   ""
867   "@
868   asr   %2, %0
869   asr   %2, %0
870   asr2  %x2, %0"
873 ;; Logical Shift Right
874 (define_insn "lshrsi3"
875   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
876         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
877                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
878    (clobber (reg:CC 16))]
879   ""
880   "@
881   lsr   %2, %0
882   lsr   %2, %0
883   lsr2  %x2, %0"
886 ;;}}} \f
887 ;;{{{ Logical Operations 
889 ;; Logical AND, 32 bit integers
890 (define_insn "andsi3"
891   [(set (match_operand:SI 0 "register_operand"         "=r")
892         (and:SI (match_operand:SI 1 "register_operand" "%r")
893                 (match_operand:SI 2 "register_operand"  "0")))
894    (clobber (reg:CC 16))]
895   ""
896   "and  %1, %0"
899 ;; Inclusive OR, 32 bit integers
900 (define_insn "iorsi3"
901   [(set (match_operand:SI 0 "register_operand"         "=r")
902         (ior:SI (match_operand:SI 1 "register_operand" "%r")
903                 (match_operand:SI 2 "register_operand"  "0")))
904    (clobber (reg:CC 16))]
905   ""
906   "or   %1, %0"
909 ;; Exclusive OR, 32 bit integers
910 (define_insn "xorsi3"
911   [(set (match_operand:SI 0 "register_operand"         "=r")
912         (xor:SI (match_operand:SI 1 "register_operand" "%r")
913                 (match_operand:SI 2 "register_operand"  "0")))
914    (clobber (reg:CC 16))]
915   ""
916   "eor  %1, %0"
919 ;; One's complement, 32 bit integers
920 (define_expand "one_cmplsi2"
921   [(set (match_operand:SI 0 "register_operand"         "")
922         (not:SI (match_operand:SI 1 "register_operand" "")))]
923   ""
924   "{
925   if (REGNO (operands[0]) == REGNO (operands[1]))
926     {
927       if (reload_in_progress || reload_completed)
928         {
929           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
930           
931           emit_insn (gen_movsi (reg, GEN_INT (-1)));
932           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
933         }
934       else
935         {
936           rtx reg = gen_reg_rtx (SImode);
937         
938           emit_insn (gen_movsi (reg, GEN_INT (-1)));
939           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
940         }
941     }
942   else
943     {
944       emit_insn (gen_movsi_internal (operands[0], GEN_INT (-1)));
945       emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
946     }
947   DONE;
948   }"
951 ;;}}} \f
952 ;;{{{ Comparisons 
954 ;; Note, we store the operands in the comparison insns, and use them later
955 ;; when generating the branch or scc operation.
957 ;; First the routines called by the machine independent part of the compiler
958 (define_expand "cmpsi"
959   [(set (reg:CC 16)
960         (compare:CC (match_operand:SI 0 "register_operand"  "")
961                     (match_operand:SI 1 "nonmemory_operand" "")))]
962   ""
963   "{
964   fr30_compare_op0 = operands[0];
965   fr30_compare_op1 = operands[1];
966   DONE;
967   }"
970 ;; Now, the actual comparisons, generated by the branch and/or scc operations
972 (define_insn "*cmpsi_internal"
973   [(set (reg:CC 16)
974         (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")
975                     (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
976   ""
977   "@
978   cmp   %1, %0
979   cmp   %1, %0
980   cmp2  %1, %0"
983 ;;}}} \f
984 ;;{{{ Branches 
986 ;; Define_expands called by the machine independent part of the compiler
987 ;; to allocate a new comparison register
989 (define_expand "beq"
990   [(set (reg:CC 16)
991         (compare:CC (match_dup 1)
992                     (match_dup 2)))
993    (set (pc)
994         (if_then_else (eq:CC (reg:CC 16)
995                              (const_int 0))
996                       (label_ref (match_operand 0 "" ""))
997                       (pc)))]
998   ""
999   "{
1000   operands[1] = fr30_compare_op0;
1001   operands[2] = fr30_compare_op1;
1002   }"
1005 (define_expand "bne"
1006   [(set (reg:CC 16)
1007         (compare:CC (match_dup 1)
1008                     (match_dup 2)))
1009    (set (pc)
1010         (if_then_else (ne:CC (reg:CC 16)
1011                              (const_int 0))
1012                       (label_ref (match_operand 0 "" ""))
1013                       (pc)))]
1014   ""
1015   "{
1016   operands[1] = fr30_compare_op0;
1017   operands[2] = fr30_compare_op1;
1018   }"
1021 (define_expand "blt"
1022   [(set (reg:CC 16)
1023         (compare:CC (match_dup 1)
1024                     (match_dup 2)))
1025    (set (pc)
1026         (if_then_else (lt:CC (reg:CC 16)
1027                              (const_int 0))
1028                       (label_ref (match_operand 0 "" ""))
1029                       (pc)))]
1030   ""
1031   "{
1032   operands[1] = fr30_compare_op0;
1033   operands[2] = fr30_compare_op1;
1034   }"
1037 (define_expand "ble"
1038   [(set (reg:CC 16)
1039         (compare:CC (match_dup 1)
1040                     (match_dup 2)))
1041    (set (pc)
1042         (if_then_else (le:CC (reg:CC 16)
1043                              (const_int 0))
1044                       (label_ref (match_operand 0 "" ""))
1045                       (pc)))]
1046   ""
1047   "{
1048   operands[1] = fr30_compare_op0;
1049   operands[2] = fr30_compare_op1;
1050   }"
1053 (define_expand "bgt"
1054   [(set (reg:CC 16)
1055         (compare:CC (match_dup 1)
1056                     (match_dup 2)))
1057    (set (pc)
1058         (if_then_else (gt:CC (reg:CC 16)
1059                              (const_int 0))
1060                       (label_ref (match_operand 0 "" ""))
1061                       (pc)))]
1062   ""
1063   "{
1064   operands[1] = fr30_compare_op0;
1065   operands[2] = fr30_compare_op1;
1066   }"
1069 (define_expand "bge"
1070   [(set (reg:CC 16)
1071         (compare:CC (match_dup 1)
1072                     (match_dup 2)))
1073    (set (pc)
1074         (if_then_else (ge:CC (reg:CC 16)
1075                              (const_int 0))
1076                       (label_ref (match_operand 0 "" ""))
1077                       (pc)))]
1078   ""
1079   "{
1080   operands[1] = fr30_compare_op0;
1081   operands[2] = fr30_compare_op1;
1082   }"
1085 (define_expand "bltu"
1086   [(set (reg:CC 16)
1087         (compare:CC (match_dup 1)
1088                     (match_dup 2)))
1089    (set (pc)
1090         (if_then_else (ltu:CC (reg:CC 16)
1091                               (const_int 0))
1092                       (label_ref (match_operand 0 "" ""))
1093                       (pc)))]
1094   ""
1095   "{
1096   operands[1] = fr30_compare_op0;
1097   operands[2] = fr30_compare_op1;
1098   }"
1101 (define_expand "bleu"
1102   [(set (reg:CC 16)
1103         (compare:CC (match_dup 1)
1104                     (match_dup 2)))
1105    (set (pc)
1106         (if_then_else (leu:CC (reg:CC 16)
1107                               (const_int 0))
1108                       (label_ref (match_operand 0 "" ""))
1109                       (pc)))]
1110   ""
1111   "{
1112   operands[1] = fr30_compare_op0;
1113   operands[2] = fr30_compare_op1;
1114   }"
1117 (define_expand "bgtu"
1118   [(set (reg:CC 16)
1119         (compare:CC (match_dup 1)
1120                     (match_dup 2)))
1121    (set (pc)
1122         (if_then_else (gtu:CC (reg:CC 16)
1123                               (const_int 0))
1124                       (label_ref (match_operand 0 "" ""))
1125                       (pc)))]
1126   ""
1127   "{
1128   operands[1] = fr30_compare_op0;
1129   operands[2] = fr30_compare_op1;
1130   }"
1133 (define_expand "bgeu"
1134   [(set (reg:CC 16)
1135         (compare:CC (match_dup 1)
1136                     (match_dup 2)))
1137    (set (pc)
1138         (if_then_else (geu:CC (reg:CC 16)
1139                               (const_int 0))
1140                       (label_ref (match_operand 0 "" ""))
1141                       (pc)))]
1142   ""
1143   "{
1144   operands[1] = fr30_compare_op0;
1145   operands[2] = fr30_compare_op1;
1146   }"
1149 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
1150 ;; swapped.  If they are swapped, it reverses the sense of the branch.
1152 ;; This pattern matches the (branch-if-true) branches generated above.
1153 ;; It generates two different instruction sequences depending upon how
1154 ;; far away the destination is.
1156 ;; The calculation for the instruction length is derived as follows:
1157 ;; The branch instruction has a 9 bit signed displacement so we have
1158 ;; this inequality for the displacement:
1160 ;;               -256 <= pc < 256
1161 ;; or
1162 ;;         -256 + 256 <= pc + 256 < 256 + 256
1163 ;; ie
1164 ;;                  0 <= pc + 256 < 512 
1166 ;; if we consider the displacement as an unsigned value, then negative
1167 ;; displacements become very large positive displacements, and the
1168 ;; inequality becomes:
1170 ;;              pc + 256 < 512
1172 ;; In order to allow for the fact that the real branch instruction works
1173 ;; from pc + 2, we increase the offset to 258.
1175 ;; Note - we do not have to worry about whether the branch is delayed or
1176 ;; not, as branch shortening happens after delay slot reorganisation.
1178 (define_insn "*branch_true"
1179   [(set (pc)
1180         (if_then_else (match_operator:CC 0 "comparison_operator"
1181                                          [(reg:CC 16)
1182                                           (const_int 0)])
1183                       (label_ref (match_operand 1 "" ""))
1184                       (pc)))]
1185   ""
1186   "*
1187   {
1188     if (get_attr_length (insn) == 2)
1189       return \"b%b0%#\\t%l1\";
1190     else
1191       {
1192         static char   buffer [100];
1193         const char *  tmp_reg; 
1194         char *        ldi_insn;
1195         
1196         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1197         
1198         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1200         /* The code produced here is, for say the EQ case:
1202                Bne  1f
1203                LDI  <label>, r0
1204                JMP  r0
1205              1:                                         */
1206              
1207         sprintf (buffer,
1208           \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1209           ldi_insn, tmp_reg, tmp_reg);
1211         return buffer;
1212     }
1213   }"
1214   [(set (attr "length") (if_then_else
1215                           (ltu
1216                             (plus
1217                               (minus
1218                                 (match_dup 1)
1219                                 (pc))
1220                               (const_int 254))
1221                             (const_int 506))
1222                           (const_int 2)
1223                           (if_then_else (eq_attr "size" "small")
1224                                         (const_int 8)
1225                                         (const_int 10))))
1226    (set_attr "delay_type" "delayed")]
1230 ;; This pattern is a duplicate of the previous one, except that the
1231 ;; branch occurs if the test is false, so the %B operator is used.
1232 (define_insn "*branch_false"
1233   [(set (pc)
1234         (if_then_else (match_operator:CC 0 "comparison_operator"
1235                                          [(reg:CC 16)
1236                                           (const_int 0)])
1237                       (pc)
1238                       (label_ref (match_operand 1 "" ""))))]
1239   ""
1240   "*
1241   {
1242     if (get_attr_length (insn) == 2)
1243       return \"b%B0%#\\t%l1 \";
1244     else
1245       {
1246         static char   buffer [100];
1247         const char *  tmp_reg; 
1248         char *        ldi_insn;
1249         
1250         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1251         
1252         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1254         sprintf (buffer,
1255           \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1256           ldi_insn, tmp_reg, tmp_reg);
1258         return buffer;
1259       }
1260   }"
1261   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1262                                                  (const_int 254))
1263                                            (const_int 506))
1264                                       (const_int 2)
1265                                       (if_then_else (eq_attr "size" "small")
1266                                                     (const_int 8)
1267                                                     (const_int 10))))
1268    (set_attr "delay_type" "delayed")]
1271 ;;}}} \f
1272 ;;{{{ Calls & Jumps 
1274 ;; Subroutine call instruction returning no value.  Operand 0 is the function
1275 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1276 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1277 ;; registers used as operands.
1279 (define_insn "call"
1280   [(call (match_operand 0 "call_operand" "Qm")
1281          (match_operand 1 ""             "g"))
1282    (clobber (reg:SI 17))]
1283   ""
1284   "call%#\\t%0"
1285   [(set_attr "delay_type" "delayed")]
1288 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
1289 ;; register in which the value is returned.  There are three more operands, the
1290 ;; same as the three operands of the `call' instruction (but with numbers
1291 ;; increased by one).
1293 ;; Subroutines that return `BLKmode' objects use the `call' insn.
1295 (define_insn "call_value"
1296   [(set (match_operand 0 "register_operand"  "=r")
1297         (call (match_operand 1 "call_operand" "Qm")
1298               (match_operand 2 ""             "g")))
1299    (clobber (reg:SI 17))]
1300   ""
1301   "call%#\\t%1"
1302   [(set_attr "delay_type" "delayed")]
1305 ;; Normal unconditional jump.
1306 ;; For a description of the computation of the length 
1307 ;; attribute see the branch patterns above.
1308 (define_insn "jump"
1309   [(set (pc) (label_ref (match_operand 0 "" "")))
1310    (clobber (reg:SI 0))]
1311   ""
1312   "*
1313   {
1314     if (get_attr_length (insn) == 2)
1315        return \"bra%#\\t%0\";
1316     else
1317       {
1318         static char   buffer [100];
1319         const char *  tmp_reg; 
1320         char *        ldi_insn;
1321         
1322         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1324         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1326         sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1327           ldi_insn, tmp_reg, tmp_reg);
1329         return buffer;
1330       }
1331   }"
1332   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1333                                                 (const_int 254))
1334                                           (const_int 506))
1335                                      (const_int 2)
1336                                      (if_then_else (eq_attr "size" "small")
1337                                                    (const_int 6)
1338                                                    (const_int 8))))
1339    (set_attr "delay_type" "delayed")]
1342 ;; Indirect jump through a register
1343 (define_insn "indirect_jump"
1344   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1345   "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1346   "jmp%#\\t@%0"
1347   [(set_attr "delay_type" "delayed")]
1350 (define_insn "tablejump"
1351   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1352    (use (label_ref (match_operand 1 "" "")))]
1353   ""
1354   "jmp%#\\t@%0"
1355   [(set_attr "delay_type" "delayed")]
1358 ;;}}} \f
1359 ;;{{{ Function Prologues and Epilogues 
1361 ;; Called after register allocation to add any instructions needed for the
1362 ;; prologue.  Using a prologue insn is favored compared to putting all of the
1363 ;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler
1364 ;; to intermix instructions with the saves of the caller saved registers.  In
1365 ;; some cases, it might be necessary to emit a barrier instruction as the last
1366 ;; insn to prevent such scheduling.
1367 (define_expand "prologue"
1368   [(clobber (const_int 0))]
1369   ""
1370   "{
1371   fr30_expand_prologue ();
1372   DONE;
1373   }"
1376 ;; Called after register allocation to add any instructions needed for the
1377 ;; epilogue.  Using a epilogue insn is favored compared to putting all of the
1378 ;; instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler
1379 ;; to intermix instructions with the restores of the caller saved registers.
1380 ;; In some cases, it might be necessary to emit a barrier instruction as the
1381 ;; first insn to prevent such scheduling.
1382 (define_expand "epilogue"
1383   [(return)]
1384   ""
1385   "{
1386   fr30_expand_epilogue ();
1387   DONE;
1388   }"
1391 (define_insn "return_from_func"
1392   [(return)
1393    (use (reg:SI 17))]
1394   "reload_completed"
1395   "ret%#"
1396   [(set_attr "delay_type" "delayed")]
1399 (define_insn "leave_func"
1400   [(set (reg:SI 15) (reg:SI 14))
1401    (set (reg:SI 14) (mem:SI (post_inc:SI (reg:SI 15))))]
1402   "reload_completed"
1403   "leave"
1406 (define_insn "enter_func"
1407   [(set:SI (mem:SI (minus:SI (reg:SI 15)
1408                              (const_int 4)))
1409            (reg:SI 14))
1410    (set:SI (reg:SI 14)
1411            (minus:SI (reg:SI 15)
1412                      (const_int 4)))
1413    (set:SI (reg:SI 15)
1414            (minus:SI (reg:SI 15)
1415                      (match_operand 0 "immediate_operand" "i")))]
1416   "reload_completed"
1417   "enter        #%0"
1418   [(set_attr "delay_type" "other")]
1421 ;;}}} \f
1422 ;;{{{ Miscellaneous 
1424 ;; No operation, needed in case the user uses -g but not -O.
1425 (define_insn "nop"
1426   [(const_int 0)]
1427   ""
1428   "nop"
1431 ;; Pseudo instruction that prevents the scheduler from moving code above this
1432 ;; point.
1433 (define_insn "blockage"
1434   [(unspec_volatile [(const_int 0)] 0)]
1435   ""
1436   ""
1437   [(set_attr "length" "0")]
1439   
1440 ;; Local Variables:
1441 ;; mode: md
1442 ;; folded-file: t
1443 ;; End:
1445 ;;}}} \f