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