Remove obsolete ECOFF support.
[official-gcc.git] / gcc / config / fr30 / fr30.md
blob383a7ee74e52e2a543093b073fb7919bbd77c2d2
1 ;; FR30 machine description.
2 ;; Copyright (C) 1998-2017 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 3, 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 COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;;{{{ Attributes 
25 (define_attr "length" "" (const_int 2))
27 ;; Used to distinguish between small memory model targets and big mode targets.
29 (define_attr "size" "small,big"
30   (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
31                        (const_string "small")
32                        (const_string "big"))))
35 ;; Define an attribute to be used by the delay slot code.
36 ;; An instruction by default is considered to be 'delayable'
37 ;; that is, it can be placed into a delay slot, but it is not
38 ;; itself a delayed branch type instruction.  An instruction
39 ;; whose type is 'delayed' is one which has a delay slot, and
40 ;; an instruction whose delay_type is 'other' is one which does
41 ;; not have a delay slot, nor can it be placed into a delay slot.
43 (define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
45 ;;}}} \f
46 ;;{{{ Delay Slot Specifications 
48 (define_delay (eq_attr "delay_type" "delayed")
49   [(and (eq_attr "delay_type" "delayable")
50         (eq_attr "length" "2"))
51    (nil)
52    (nil)]
55 (include "predicates.md")
56 (include "constraints.md")
58 ;;}}}
59 ;;{{{ Moves 
61 ;;{{{ Comment 
63 ;; Wrap moves in define_expand to prevent memory->memory moves from being
64 ;; generated at the RTL level, which generates better code for most machines
65 ;; which can't do mem->mem moves.
67 ;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
68 ;; than M, the effect of this instruction is to store the specified value in
69 ;; the part of the register that corresponds to mode M.  The effect on the rest
70 ;; of the register is undefined.
72 ;; This class of patterns is special in several ways.  First of all, each of
73 ;; these names *must* be defined, because there is no other way to copy a datum
74 ;; from one place to another.
76 ;; Second, these patterns are not used solely in the RTL generation pass.  Even
77 ;; the reload pass can generate move insns to copy values from stack slots into
78 ;; temporary registers.  When it does so, one of the operands is a hard
79 ;; register and the other is an operand that can need to be reloaded into a
80 ;; register.
82 ;; Therefore, when given such a pair of operands, the pattern must
83 ;; generate RTL which needs no reloading and needs no temporary
84 ;; registers--no registers other than the operands.  For example, if
85 ;; you support the pattern with a `define_expand', then in such a
86 ;; case the `define_expand' mustn't call `force_reg' or any other such
87 ;; function which might generate new pseudo registers.
89 ;; This requirement exists even for subword modes on a RISC machine
90 ;; where fetching those modes from memory normally requires several
91 ;; insns and some temporary registers.  Look in `spur.md' to see how
92 ;; the requirement can be satisfied.
94 ;; During reload a memory reference with an invalid address may be passed as an
95 ;; operand.  Such an address will be replaced with a valid address later in the
96 ;; reload pass.  In this case, nothing may be done with the address except to
97 ;; use it as it stands.  If it is copied, it will not be replaced with a valid
98 ;; address.  No attempt should be made to make such an address into a valid
99 ;; address and no routine (such as `change_address') that will do so may be
100 ;; called.  Note that `general_operand' will fail when applied to such an
101 ;; address.
103 ;; The global variable `reload_in_progress' (which must be explicitly declared
104 ;; if required) can be used to determine whether such special handling is
105 ;; required.
107 ;; The variety of operands that have reloads depends on the rest of
108 ;; the machine description, but typically on a RISC machine these can
109 ;; only be pseudo registers that did not get hard registers, while on
110 ;; other machines explicit memory references will get optional
111 ;; reloads.
113 ;; If a scratch register is required to move an object to or from memory, it
114 ;; can be allocated using `gen_reg_rtx' prior to reload.  But this is
115 ;; impossible during and after reload.  If there are cases needing scratch
116 ;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
117 ;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
118 ;; patterns `reload_inM' or `reload_outM' to handle them.
120 ;; The constraints on a `moveM' must permit moving any hard register to any
121 ;; other hard register provided that `TARGET_HARD_REGNO_MODE_OK' permits mode
122 ;; M in both registers and `REGISTER_MOVE_COST' applied to their classes
123 ;; returns a value of 2.
125 ;; It is obligatory to support floating point `moveM' instructions
126 ;; into and out of any registers that can hold fixed point values,
127 ;; because unions and structures (which have modes `SImode' or
128 ;; `DImode') can be in those registers and they may have floating
129 ;; point members.
131 ;; There may also be a need to support fixed point `moveM' instructions
132 ;; in and out of floating point registers.  Unfortunately, I have
133 ;; forgotten why this was so, and I don't know whether it is still true.
134 ;; If `TARGET_HARD_REGNO_MODE_OK' rejects fixed point values in floating
135 ;; point registers, then the constraints of the fixed point `moveM'
136 ;; instructions must be designed to avoid ever trying to reload into a
137 ;; floating point register.
139 ;;}}}
140 ;;{{{ Push and Pop  
142 ;; Push a register onto the stack
143 (define_insn "movsi_push"
144   [(set (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 (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 "const_int_operand" ""))]
293    "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128
294     && (GET_CODE (operands[0]) != SUBREG
295         || SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[0], 0))))"
296    [(set (match_dup 0) (match_dup 1))
297     (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
298    "{
299    operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
300    operands[2] = gen_lowpart (QImode, operands[0]);
301    }"
304 ;; If we are loading a large negative constant, one which does
305 ;; not have any of its bottom 24 bit set, then we can save time
306 ;; and space by loading the byte value and shifting it into place.
307 (define_split
308   [(set (match_operand:SI 0 "register_operand"  "")
309         (match_operand:SI 1 "const_int_operand" ""))]
310    "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
311    [(set (match_dup 0) (match_dup 2))
312     (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
313                (clobber (reg:CC 16))])]
314    "{
315    HOST_WIDE_INT val = INTVAL (operands[1]);
316    operands[2] = GEN_INT (val >> 24);
317    }"
320 ;; If we are loading a large positive constant, one which has bits
321 ;; in the top byte set, but whose set bits all lie within an 8 bit
322 ;; range, then we can save time and space by loading the byte value
323 ;; and shifting it into place.
324 (define_split
325   [(set (match_operand:SI 0 "register_operand"  "")
326         (match_operand:SI 1 "const_int_operand" ""))]
327    "(INTVAL (operands[1]) > 0x00ffffff)
328    && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
329    [(set (match_dup 0) (match_dup 2))
330     (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
331                (clobber (reg:CC 16))])]
332    "{
333    HOST_WIDE_INT val = INTVAL (operands[1]);
334    int shift = exact_log2 (val & ( - val));
335    operands[2] = GEN_INT (val >> shift);
336    operands[3] = GEN_INT (shift);
337    }"
340 ;; When TARGET_SMALL_MODEL is defined we assume that all symbolic
341 ;; values are addresses which will fit in 20 bits.
343 (define_insn "movsi_internal"
344   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,V,r,m")
345         (match_operand:SI 1 "general_operand"       "L,M,n,i,rde,r,rm,r"))]
346   ""
347   "*
348   {
349     switch (which_alternative)
350     {
351     case 0: return   \"ldi:8 \\t#%1, %0\";
352     case 1: return   \"ldi:20\\t#%1, %0\";
353     case 2: return   \"ldi:32\\t#%1, %0\";
354     case 3: if (TARGET_SMALL_MODEL)
355               return \"ldi:20\\t%1, %0\";
356             else
357               return \"ldi:32\\t%1, %0\";
358     case 4: return   \"mov   \\t%1, %0\";
359     case 5: return   \"st    \\t%1, %0\";
360     case 6: return   \"ld    \\t%1, %0\";
361     case 7: return   \"st    \\t%1, %0\";
362     default: gcc_unreachable ();
363    }
364   }"
365   [(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 4)
366                                (eq_attr "alternative" "2") (const_int 6)
367                                (eq_attr "alternative" "3") 
368                                         (if_then_else (eq_attr "size" "small")
369                                                       (const_int 4)
370                                                       (const_int 6))]
371                               (const_int 2)))]
374 ;;}}}
375 ;;{{{ 8 Byte Moves
377 ;; Note - the FR30 does not have an 8 byte load/store instruction
378 ;; but we have to support this pattern because some other patterns
379 ;; (e.g. muldisi2) can produce a DImode result.
380 ;; (This code is stolen from the M32R port.)
382 (define_expand "movdi"
383   [(set (match_operand:DI 0 "nonimmediate_operand" "")
384         (match_operand:DI 1 "general_operand" ""))]
385   ""
386   "
387   /* Everything except mem = const or mem = mem can be done easily.  */
389   if (GET_CODE (operands[0]) == MEM)
390     operands[1] = force_reg (DImode, operands[1]);
391   "
394 ;; We use an insn and a split so that we can generate
395 ;; RTL rather than text from fr30_move_double().
397 (define_insn "*movdi_insn"
398   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
399         (match_operand:DI 1 "di_operand"               "r,m,r,nF"))]
400   "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
401   "#"
402   [(set_attr "length" "4,8,12,12")]
405 (define_split
406   [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
407         (match_operand:DI 1 "di_operand" ""))]
408   "reload_completed"
409   [(match_dup 2)]
410   "operands[2] = fr30_move_double (operands);"
413 ;;}}}
414 ;;{{{ Load & Store Multiple Registers 
416 ;; The load multiple and store multiple patterns are implemented
417 ;; as peepholes because the only time they are expected to occur
418 ;; is during function prologues and epilogues.
420 (define_peephole
421   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
422         (match_operand:SI 0 "high_register_operand" "h"))
423    (set (mem:SI (pre_dec:SI (reg:SI 15)))
424         (match_operand:SI 1 "high_register_operand" "h"))
425    (set (mem:SI (pre_dec:SI (reg:SI 15)))
426         (match_operand:SI 2 "high_register_operand" "h"))
427    (set (mem:SI (pre_dec:SI (reg:SI 15)))
428         (match_operand:SI 3 "high_register_operand" "h"))]
429   "fr30_check_multiple_regs (operands, 4, 1)"
430   "stm1 (%0, %1, %2, %3)"
431   [(set_attr "delay_type" "other")]
434 (define_peephole
435   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
436         (match_operand:SI 0 "high_register_operand" "h"))
437    (set (mem:SI (pre_dec:SI (reg:SI 15)))
438         (match_operand:SI 1 "high_register_operand" "h"))
439    (set (mem:SI (pre_dec:SI (reg:SI 15)))
440         (match_operand:SI 2 "high_register_operand" "h"))]
441   "fr30_check_multiple_regs (operands, 3, 1)"
442   "stm1 (%0, %1, %2)"
443   [(set_attr "delay_type" "other")]
446 (define_peephole
447   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
448         (match_operand:SI 0 "high_register_operand" "h"))
449    (set (mem:SI (pre_dec:SI (reg:SI 15)))
450         (match_operand:SI 1 "high_register_operand" "h"))]
451   "fr30_check_multiple_regs (operands, 2, 1)"
452   "stm1 (%0, %1)"
453   [(set_attr "delay_type" "other")]
456 (define_peephole
457   [(set (match_operand:SI 0 "high_register_operand" "h")
458         (mem:SI (post_inc:SI (reg:SI 15))))
459    (set (match_operand:SI 1 "high_register_operand" "h")
460         (mem:SI (post_inc:SI (reg:SI 15))))
461    (set (match_operand:SI 2 "high_register_operand" "h")
462         (mem:SI (post_inc:SI (reg:SI 15))))
463    (set (match_operand:SI 3 "high_register_operand" "h")
464         (mem:SI (post_inc:SI (reg:SI 15))))]
465   "fr30_check_multiple_regs (operands, 4, 0)"
466   "ldm1 (%0, %1, %2, %3)"
467   [(set_attr "delay_type" "other")]
470 (define_peephole
471   [(set (match_operand:SI 0 "high_register_operand" "h")
472         (mem:SI (post_inc:SI (reg:SI 15))))
473    (set (match_operand:SI 1 "high_register_operand" "h")
474         (mem:SI (post_inc:SI (reg:SI 15))))
475    (set (match_operand:SI 2 "high_register_operand" "h")
476         (mem:SI (post_inc:SI (reg:SI 15))))]
477   "fr30_check_multiple_regs (operands, 3, 0)"
478   "ldm1 (%0, %1, %2)"
479   [(set_attr "delay_type" "other")]
482 (define_peephole
483   [(set (match_operand:SI 0 "high_register_operand" "h")
484         (mem:SI (post_inc:SI (reg:SI 15))))
485    (set (match_operand:SI 1 "high_register_operand" "h")
486         (mem:SI (post_inc:SI (reg:SI 15))))]
487   "fr30_check_multiple_regs (operands, 2, 0)"
488   "ldm1 (%0, %1)"
489   [(set_attr "delay_type" "other")]
492 (define_peephole
493   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
494         (match_operand:SI 0 "low_register_operand" "l"))
495    (set (mem:SI (pre_dec:SI (reg:SI 15)))
496         (match_operand:SI 1 "low_register_operand" "l"))
497    (set (mem:SI (pre_dec:SI (reg:SI 15)))
498         (match_operand:SI 2 "low_register_operand" "l"))
499    (set (mem:SI (pre_dec:SI (reg:SI 15)))
500         (match_operand:SI 3 "low_register_operand" "l"))]
501   "fr30_check_multiple_regs (operands, 4, 1)"
502   "stm0 (%0, %1, %2, %3)"
503   [(set_attr "delay_type" "other")]
506 (define_peephole
507   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
508         (match_operand:SI 0 "low_register_operand" "l"))
509    (set (mem:SI (pre_dec:SI (reg:SI 15)))
510         (match_operand:SI 1 "low_register_operand" "l"))
511    (set (mem:SI (pre_dec:SI (reg:SI 15)))
512         (match_operand:SI 2 "low_register_operand" "l"))]
513   "fr30_check_multiple_regs (operands, 3, 1)"
514   "stm0 (%0, %1, %2)"
515   [(set_attr "delay_type" "other")]
518 (define_peephole
519   [(set (mem:SI (pre_dec:SI (reg:SI 15)))
520         (match_operand:SI 0 "low_register_operand" "l"))
521    (set (mem:SI (pre_dec:SI (reg:SI 15)))
522         (match_operand:SI 1 "low_register_operand" "l"))]
523   "fr30_check_multiple_regs (operands, 2, 1)"
524   "stm0 (%0, %1)"
525   [(set_attr "delay_type" "other")]
528 ;;}}}
529 ;;{{{ Floating Point Moves 
531 ;; Note - Patterns for SF mode moves are compulsory, but
532 ;; patterns for DF are optional, as GCC can synthesize them.
534 (define_expand "movsf"
535   [(set (match_operand:SF 0 "general_operand" "")
536         (match_operand:SF 1 "general_operand" ""))]
537   ""
538   "{
539   if (!reload_in_progress && !reload_completed
540       && memory_operand (operands[0], SFmode)
541       && memory_operand (operands[1], SFmode))
542     operands[1] = copy_to_mode_reg (SFmode, operands[1]);
543   }"
546 (define_insn "*movsf_internal"
547   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r")
548         (match_operand:SF 1 "general_operand"      "Fn,i,rde,r,rm"))]
549   ""
550   "*
551   {
552     switch (which_alternative)
553     {
554     case 0: return   \"ldi:32\\t%1, %0\";
555     case 1: if (TARGET_SMALL_MODEL)
556               return \"ldi:20\\t%1, %0\";
557             else
558               return \"ldi:32\\t%1, %0\";
559     case 2: return   \"mov   \\t%1, %0\";
560     case 3: return   \"st    \\t%1, %0\";
561     case 4: return   \"ld    \\t%1, %0\";
562     default: gcc_unreachable ();               
563     }
564   }"
565   [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6)
566                                (eq_attr "alternative" "1") 
567                                         (if_then_else (eq_attr "size" "small")
568                                                       (const_int 4)
569                                                       (const_int 6))]
570                               (const_int 2)))]
573 (define_insn "*movsf_constant_store"
574   [(set (match_operand:SF 0 "memory_operand"    "=m")
575         (match_operand:SF 1 "immediate_operand" "F"))]
576   ""
577   "*
578   {
579   const char *    ldi_instr;
580   const char *    tmp_reg;
581   static char     buffer[100];
583   ldi_instr = fr30_const_double_is_zero (operands[1]) ? \"ldi:8\" : \"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 (i.e. outside +/- 16) constants.  We need to be able to
648 ;; handle this because reload assumes that it can generate add
649 ;; instructions with arbitrary 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 (INTVAL (operands[2]) >= -16
662            && INTVAL (operands[2]) <= 15
663            && (!REG_P (operands[1])
664                || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
665                || REGNO (operands[1]) == STACK_POINTER_REGNUM))
666     emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
667   else
668     emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
669   DONE;
670   }"
673 (define_insn "addsi_regs"
674   [(set (match_operand:SI 0 "register_operand"          "=r")
675         (plus:SI (match_operand:SI 1 "register_operand" "%0")
676                  (match_operand:SI 2 "register_operand"  "r")))]
677   ""
678   "addn %2, %0"
681 ;; Do not allow an eliminable register in the source register.  It
682 ;; might be eliminated in favor of the stack pointer, probably
683 ;; increasing the offset, and so rendering the instruction illegal.
684 (define_insn "addsi_small_int"
685   [(set (match_operand:SI 0 "register_operand"              "=r,r")
686         (plus:SI (match_operand:SI 1 "register_operand"      "0,0")
687                  (match_operand:SI 2 "add_immediate_operand" "I,J")))]
688   "!REG_P (operands[1])
689    || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
690    || REGNO (operands[1]) == STACK_POINTER_REGNUM"
691   "@
692    addn %2, %0
693    addn2        %2, %0"
696 (define_expand "addsi_big_int"
697   [(set (match_operand:SI 0 "register_operand"           "")
698         (plus:SI (match_operand:SI 1 "register_operand"  "")
699                  (match_operand:SI 2 "immediate_operand" "")))]
700   ""
701   "{
702   /* Cope with the possibility that ops 0 and 1 are the same register.  */
703   if (rtx_equal_p (operands[0], operands[1]))
704     {
705       if (reload_in_progress || reload_completed)
706         {
707           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
708           
709           emit_insn (gen_movsi (reg, operands[2]));
710           emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
711         }
712       else
713         {
714           operands[2] = force_reg (SImode, operands[2]);
715           emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
716         }
717     }
718   else
719     {
720       emit_insn (gen_movsi (operands[0], operands[2]));
721       emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
722     }
723   DONE;
724   }"
727 (define_insn "*addsi_for_reload"
728   [(set (match_operand:SI 0 "register_operand"         "=&r,r,r")
729         (plus:SI (match_operand:SI 1 "register_operand"  "r,r,r")
730                  (match_operand:SI 2 "immediate_operand" "L,M,n")))]
731   "reload_in_progress || reload_completed"
732   "@
733   ldi:8\\t#%2, %0  \\n\\taddn\\t%1, %0
734   ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
735   ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
736   [(set_attr "length" "4,6,8")]
739 ;;}}}
740 ;;{{{ Subtraction 
742 (define_insn "subsi3"
743   [(set (match_operand:SI 0 "register_operand"       "=r")
744         (minus:SI (match_operand:SI 1 "register_operand" "0")
745                   (match_operand:SI 2 "register_operand" "r")))]
746   ""
747   "subn %2, %0"
750 ;;}}}
751 ;;{{{ Multiplication 
753 ;; Signed multiplication producing 64-bit results from 32-bit inputs
754 (define_insn "mulsidi3"
755   [(set (match_operand:DI 0 "register_operand"                             "=r")
756            (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
757                     (sign_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
758    (clobber (reg:CC 16))]
759   ""
760   "mul  %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
761   [(set_attr "length" "6")]
764 ;; Unsigned multiplication producing 64-bit results from 32-bit inputs
765 (define_insn "umulsidi3"
766   [(set (match_operand:DI 0 "register_operand"                             "=r")
767            (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
768                     (zero_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
769    (clobber (reg:CC 16))]
770   ""
771   "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
772   [(set_attr "length" "6")]
775 ;; Signed multiplication producing 32-bit result from 16-bit inputs
776 (define_insn "mulhisi3"
777   [(set (match_operand:SI 0 "register_operand"                             "=r")
778            (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
779                     (sign_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
780    (clobber (reg:CC 16))]
781   ""
782   "mulh %2, %1\\n\\tmov\\tmdl, %0"
783   [(set_attr "length" "4")]
786 ;; Unsigned multiplication producing 32-bit result from 16-bit inputs
787 (define_insn "umulhisi3"
788   [(set (match_operand:SI 0 "register_operand"                             "=r")
789            (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
790                     (zero_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
791    (clobber (reg:CC 16))]
792   ""
793   "muluh        %2, %1\\n\\tmov\\tmdl, %0"
794   [(set_attr "length" "4")]
797 ;; Signed multiplication producing 32-bit result from 32-bit inputs
798 (define_insn "mulsi3"
799   [(set (match_operand:SI 0 "register_operand"             "=r")
800            (mult:SI (match_operand:SI 1 "register_operand" "%r")
801                     (match_operand:SI 2 "register_operand"  "r")))
802    (clobber (reg:CC 16))]
803   ""
804   "mul  %2, %1\\n\\tmov\\tmdl, %0"
805   [(set_attr "length" "4")]
808 ;;}}}
809 ;;}}} \f
810 ;;{{{ Shifts 
812 ;; Arithmetic Shift Left
813 (define_insn "ashlsi3"
814   [(set (match_operand:SI 0 "register_operand"            "=r,r,r")
815         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,0")
816                    (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
817    (clobber (reg:CC 16))]
818   ""
819   "@
820   lsl   %2, %0
821   lsl   %2, %0
822   lsl2  %x2, %0"
825 ;; Arithmetic Shift Right
826 (define_insn "ashrsi3"
827   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
828         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
829                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
830    (clobber (reg:CC 16))]
831   ""
832   "@
833   asr   %2, %0
834   asr   %2, %0
835   asr2  %x2, %0"
838 ;; Logical Shift Right
839 (define_insn "lshrsi3"
840   [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
841         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
842                      (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
843    (clobber (reg:CC 16))]
844   ""
845   "@
846   lsr   %2, %0
847   lsr   %2, %0
848   lsr2  %x2, %0"
851 ;;}}} \f
852 ;;{{{ Logical Operations 
854 ;; Logical AND, 32-bit integers
855 (define_insn "andsi3"
856   [(set (match_operand:SI 0 "register_operand"         "=r")
857         (and:SI (match_operand:SI 1 "register_operand" "%r")
858                 (match_operand:SI 2 "register_operand"  "0")))
859    (clobber (reg:CC 16))]
860   ""
861   "and  %1, %0"
864 ;; Inclusive OR, 32-bit integers
865 (define_insn "iorsi3"
866   [(set (match_operand:SI 0 "register_operand"         "=r")
867         (ior:SI (match_operand:SI 1 "register_operand" "%r")
868                 (match_operand:SI 2 "register_operand"  "0")))
869    (clobber (reg:CC 16))]
870   ""
871   "or   %1, %0"
874 ;; Exclusive OR, 32-bit integers
875 (define_insn "xorsi3"
876   [(set (match_operand:SI 0 "register_operand"         "=r")
877         (xor:SI (match_operand:SI 1 "register_operand" "%r")
878                 (match_operand:SI 2 "register_operand"  "0")))
879    (clobber (reg:CC 16))]
880   ""
881   "eor  %1, %0"
884 ;; One's complement, 32-bit integers
885 (define_expand "one_cmplsi2"
886   [(set (match_operand:SI 0 "register_operand"         "")
887         (not:SI (match_operand:SI 1 "register_operand" "")))]
888   ""
889   "{
890   if (rtx_equal_p (operands[0], operands[1]))
891     {
892       if (reload_in_progress || reload_completed)
893         {
894           rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
895           
896           emit_insn (gen_movsi (reg, constm1_rtx));
897           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
898         }
899       else
900         {
901           rtx reg = gen_reg_rtx (SImode);
902         
903           emit_insn (gen_movsi (reg, constm1_rtx));
904           emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
905         }
906     }
907   else
908     {
909       emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
910       emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
911     }
912   DONE;
913   }"
916 ;;}}} \f
917 ;;{{{ Comparisons 
919 ;; The actual comparisons, generated by the cbranch and/or cstore expanders
921 (define_insn "*cmpsi_internal"
922   [(set (reg:CC 16)
923         (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")
924                     (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
925   ""
926   "@
927   cmp   %1, %0
928   cmp   %1, %0
929   cmp2  %1, %0"
932 ;;}}} \f
933 ;;{{{ Branches 
935 ;; Define_expands called by the machine independent part of the compiler
936 ;; to allocate a new comparison register
938 (define_expand "cbranchsi4"
939   [(set (reg:CC 16)
940         (compare:CC (match_operand:SI 1 "register_operand"  "")
941                     (match_operand:SI 2 "nonmemory_operand" "")))
942    (set (pc)
943         (if_then_else (match_operator 0 "ordered_comparison_operator"
944                        [(reg:CC 16) (const_int 0)])
945                       (label_ref (match_operand 3 "" ""))
946                       (pc)))]
947   ""
948   ""
952 ;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
953 ;; swapped.  If they are swapped, it reverses the sense of the branch.
955 ;; This pattern matches the (branch-if-true) branches generated above.
956 ;; It generates two different instruction sequences depending upon how
957 ;; far away the destination is.
959 ;; The calculation for the instruction length is derived as follows:
960 ;; The branch instruction has a 9-bit signed displacement so we have
961 ;; this inequality for the displacement:
963 ;;               -256 <= pc < 256
964 ;; or
965 ;;         -256 + 256 <= pc + 256 < 256 + 256
966 ;; i.e.
967 ;;                  0 <= pc + 256 < 512 
969 ;; if we consider the displacement as an unsigned value, then negative
970 ;; displacements become very large positive displacements, and the
971 ;; inequality becomes:
973 ;;              pc + 256 < 512
975 ;; In order to allow for the fact that the real branch instruction works
976 ;; from pc + 2, we increase the offset to 258.
978 ;; Note - we do not have to worry about whether the branch is delayed or
979 ;; not, as branch shortening happens after delay slot reorganization.
981 (define_insn "*branch_true"
982   [(set (pc)
983         (if_then_else (match_operator 0 "comparison_operator"
984                                       [(reg:CC 16)
985                                        (const_int 0)])
986                       (label_ref (match_operand 1 "" ""))
987                       (pc)))]
988   ""
989   "*
990   {
991     if (get_attr_length (insn) == 2)
992       return \"b%b0%#\\t%l1\";
993     else
994       {
995         static char   buffer [100];
996         const char *  tmp_reg; 
997         const char *  ldi_insn;
998         
999         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1000         
1001         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1003         /* The code produced here is, for say the EQ case:
1005                Bne  1f
1006                LDI  <label>, r0
1007                JMP  r0
1008              1:                                         */
1009              
1010         sprintf (buffer,
1011           \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1012           ldi_insn, tmp_reg, tmp_reg);
1014         return buffer;
1015     }
1016   }"
1017   [(set (attr "length") (if_then_else
1018                           (ltu
1019                             (plus
1020                               (minus
1021                                 (match_dup 1)
1022                                 (pc))
1023                               (const_int 254))
1024                             (const_int 506))
1025                           (const_int 2)
1026                           (if_then_else (eq_attr "size" "small")
1027                                         (const_int 8)
1028                                         (const_int 10))))
1029    (set_attr "delay_type" "delayed")]
1033 ;; This pattern is a duplicate of the previous one, except that the
1034 ;; branch occurs if the test is false, so the %B operator is used.
1035 (define_insn "*branch_false"
1036   [(set (pc)
1037         (if_then_else (match_operator 0 "comparison_operator"
1038                                       [(reg:CC 16)
1039                                        (const_int 0)])
1040                       (pc)
1041                       (label_ref (match_operand 1 "" ""))))]
1042   ""
1043   "*
1044   {
1045     if (get_attr_length (insn) == 2)
1046       return \"b%B0%#\\t%l1 \";
1047     else
1048       {
1049         static char   buffer [100];
1050         const char *  tmp_reg; 
1051         const char *  ldi_insn;
1052         
1053         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1054         
1055         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1057         sprintf (buffer,
1058           \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1059           ldi_insn, tmp_reg, tmp_reg);
1061         return buffer;
1062       }
1063   }"
1064   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1065                                                  (const_int 254))
1066                                            (const_int 506))
1067                                       (const_int 2)
1068                                       (if_then_else (eq_attr "size" "small")
1069                                                     (const_int 8)
1070                                                     (const_int 10))))
1071    (set_attr "delay_type" "delayed")]
1074 ;;}}} \f
1075 ;;{{{ Calls & Jumps 
1077 ;; Subroutine call instruction returning no value.  Operand 0 is the function
1078 ;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1079 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1080 ;; registers used as operands.
1082 (define_insn "call"
1083   [(call (match_operand 0 "call_operand" "Qm")
1084          (match_operand 1 ""             "g"))
1085    (clobber (reg:SI 17))]
1086   ""
1087   "call%#\\t%0"
1088   [(set_attr "delay_type" "delayed")]
1091 ;; Subroutine call instruction returning a value.  Operand 0 is the hard
1092 ;; register in which the value is returned.  There are three more operands, the
1093 ;; same as the three operands of the `call' instruction (but with numbers
1094 ;; increased by one).
1096 ;; Subroutines that return `BLKmode' objects use the `call' insn.
1098 (define_insn "call_value"
1099   [(set (match_operand 0 "register_operand"  "=r")
1100         (call (match_operand 1 "call_operand" "Qm")
1101               (match_operand 2 ""             "g")))
1102    (clobber (reg:SI 17))]
1103   ""
1104   "call%#\\t%1"
1105   [(set_attr "delay_type" "delayed")]
1108 ;; Normal unconditional jump.
1109 ;; For a description of the computation of the length 
1110 ;; attribute see the branch patterns above.
1112 ;; Although this instruction really clobbers r0, flow
1113 ;; relies on jump being simplejump_p in several places
1114 ;; and as r0 is fixed, this doesn't change anything
1115 (define_insn "jump"
1116   [(set (pc) (label_ref (match_operand 0 "" "")))]
1117   ""
1118   "*
1119   {
1120     if (get_attr_length (insn) == 2)
1121        return \"bra%#\\t%0\";
1122     else
1123       {
1124         static char   buffer [100];
1125         const char *  tmp_reg; 
1126         const char *  ldi_insn;
1127         
1128         tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1130         ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1132         sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1133           ldi_insn, tmp_reg, tmp_reg);
1135         return buffer;
1136       }
1137   }"
1138   [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1139                                                 (const_int 254))
1140                                           (const_int 506))
1141                                      (const_int 2)
1142                                      (if_then_else (eq_attr "size" "small")
1143                                                    (const_int 6)
1144                                                    (const_int 8))))
1145    (set_attr "delay_type" "delayed")]
1148 ;; Indirect jump through a register
1149 (define_insn "indirect_jump"
1150   [(set (pc) (match_operand 0 "pmode_register_operand" "r"))]
1151   ""
1152   "jmp%#\\t@%0"
1153   [(set_attr "delay_type" "delayed")]
1156 (define_insn "tablejump"
1157   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1158    (use (label_ref (match_operand 1 "" "")))]
1159   ""
1160   "jmp%#\\t@%0"
1161   [(set_attr "delay_type" "delayed")]
1164 ;;}}} \f
1165 ;;{{{ Function Prologues and Epilogues 
1167 ;; Called after register allocation to add any instructions needed for the
1168 ;; prologue.  Using a prologue insn is favored compared to putting all of the
1169 ;; instructions in output_function_prologue(), since it allows the scheduler
1170 ;; to intermix instructions with the saves of the caller saved registers.  In
1171 ;; some cases, it might be necessary to emit a barrier instruction as the last
1172 ;; insn to prevent such scheduling.
1173 (define_expand "prologue"
1174   [(clobber (const_int 0))]
1175   ""
1176   "{
1177   fr30_expand_prologue ();
1178   DONE;
1179   }"
1182 ;; Called after register allocation to add any instructions needed for the
1183 ;; epilogue.  Using an epilogue insn is favored compared to putting all of the
1184 ;; instructions in output_function_epilogue(), since it allows the scheduler
1185 ;; to intermix instructions with the restores of the caller saved registers.
1186 ;; In some cases, it might be necessary to emit a barrier instruction as the
1187 ;; first insn to prevent such scheduling.
1188 (define_expand "epilogue"
1189   [(return)]
1190   ""
1191   "{
1192   fr30_expand_epilogue ();
1193   DONE;
1194   }"
1197 (define_insn "return_from_func"
1198   [(return)
1199    (use (reg:SI 17))]
1200   "reload_completed"
1201   "ret%#"
1202   [(set_attr "delay_type" "delayed")]
1205 (define_insn "leave_func"
1206   [(set (reg:SI 15) (plus:SI (reg:SI 14) (const_int 4)))
1207    (set (reg:SI 14) (mem:SI (minus:SI (reg:SI 15) (const_int 4))))]
1208   "reload_completed"
1209   "leave"
1212 (define_expand "enter_func"
1213   [(parallel
1214   [(set (mem:SI (minus:SI (match_dup 1)
1215                           (const_int 4)))
1216         (match_dup 2))
1217    (set (match_dup 2)
1218         (minus:SI (match_dup 1)
1219                   (const_int 4)))
1220    (set (match_dup 1)
1221         (minus:SI (match_dup 1)
1222                   (match_operand:SI 0 "immediate_operand")))]
1223   )]
1224   ""
1226   operands[1] = stack_pointer_rtx;
1227   operands[2] = hard_frame_pointer_rtx;
1230 (define_insn "*enter_func"
1231   [(set (mem:SI (minus:SI (reg:SI 15)
1232                           (const_int 4)))
1233         (reg:SI 14))
1234    (set (reg:SI 14)
1235         (minus:SI (reg:SI 15)
1236                   (const_int 4)))
1237    (set (reg:SI 15)
1238         (minus:SI (reg:SI 15)
1239                   (match_operand 0 "immediate_operand" "i")))]
1240   "reload_completed"
1241   "enter        #%0"
1242   [(set_attr "delay_type" "other")]
1245 ;;}}} \f
1246 ;;{{{ Miscellaneous 
1248 ;; No operation, needed in case the user uses -g but not -O.
1249 (define_insn "nop"
1250   [(const_int 0)]
1251   ""
1252   "nop"
1255 ;; Pseudo instruction that prevents the scheduler from moving code above this
1256 ;; point.
1257 (define_insn "blockage"
1258   [(unspec_volatile [(const_int 0)] 0)]
1259   ""
1260   ""
1261   [(set_attr "length" "0")]
1263 ;;}}} \f
1264   
1265 ;; Local Variables:
1266 ;; mode: md
1267 ;; folded-file: t
1268 ;; End: