]> gcc.gnu.org Git - gcc.git/blame - gcc/config/fr30/fr30.md
fr30.md (cbranchsi4): Remove mode from comparison.
[gcc.git] / gcc / config / fr30 / fr30.md
CommitLineData
309dd885 1;; FR30 machine description.
d652f226 2;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2007, 2010
f17178cf 3;; Free Software Foundation, Inc.
309dd885
NC
4;; Contributed by Cygnus Solutions.
5
7ec022b2 6;; This file is part of GCC.
309dd885 7
7ec022b2 8;; GCC is free software; you can redistribute it and/or modify
309dd885 9;; it under the terms of the GNU General Public License as published by
2f83c7d6 10;; the Free Software Foundation; either version 3, or (at your option)
309dd885
NC
11;; any later version.
12
7ec022b2 13;; GCC is distributed in the hope that it will be useful,
309dd885
NC
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
19;; along with GCC; see the file COPYING3. If not see
20;; <http://www.gnu.org/licenses/>.
309dd885
NC
21
22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
309dd885
NC
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.
6fc0bb99 37;; An instruction by default is considered to be 'delayable'
309dd885 38;; that is, it can be placed into a delay slot, but it is not
40b982a9 39;; itself a delayed branch type instruction. An instruction
696e78bf
KH
40;; whose type is 'delayed' is one which has a delay slot, and
41;; an instruction whose delay_type is 'other' is one which does
309dd885
NC
42;; not have a delay slot, nor can it be placed into a delay slot.
43
44(define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
45
46;;}}} \f
47;;{{{ Delay Slot Specifications
48
49(define_delay (eq_attr "delay_type" "delayed")
50 [(and (eq_attr "delay_type" "delayable")
51 (eq_attr "length" "2"))
52 (nil)
53 (nil)]
54)
55
f17178cf 56(include "predicates.md")
ad1c1eeb 57(include "constraints.md")
f17178cf 58
309dd885
NC
59;;}}}
60;;{{{ Moves
61
62;;{{{ Comment
63
64;; Wrap moves in define_expand to prevent memory->memory moves from being
65;; generated at the RTL level, which generates better code for most machines
66;; which can't do mem->mem moves.
67
68;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider
69;; than M, the effect of this instruction is to store the specified value in
70;; the part of the register that corresponds to mode M. The effect on the rest
71;; of the register is undefined.
72
73;; This class of patterns is special in several ways. First of all, each of
74;; these names *must* be defined, because there is no other way to copy a datum
75;; from one place to another.
76
77;; Second, these patterns are not used solely in the RTL generation pass. Even
78;; the reload pass can generate move insns to copy values from stack slots into
79;; temporary registers. When it does so, one of the operands is a hard
80;; register and the other is an operand that can need to be reloaded into a
81;; register.
82
83;; Therefore, when given such a pair of operands, the pattern must
84;; generate RTL which needs no reloading and needs no temporary
85;; registers--no registers other than the operands. For example, if
86;; you support the pattern with a `define_expand', then in such a
87;; case the `define_expand' mustn't call `force_reg' or any other such
88;; function which might generate new pseudo registers.
89
90;; This requirement exists even for subword modes on a RISC machine
91;; where fetching those modes from memory normally requires several
92;; insns and some temporary registers. Look in `spur.md' to see how
93;; the requirement can be satisfied.
94
95;; During reload a memory reference with an invalid address may be passed as an
96;; operand. Such an address will be replaced with a valid address later in the
97;; reload pass. In this case, nothing may be done with the address except to
98;; use it as it stands. If it is copied, it will not be replaced with a valid
99;; address. No attempt should be made to make such an address into a valid
100;; address and no routine (such as `change_address') that will do so may be
101;; called. Note that `general_operand' will fail when applied to such an
102;; address.
103;;
104;; The global variable `reload_in_progress' (which must be explicitly declared
105;; if required) can be used to determine whether such special handling is
106;; required.
107;;
108;; The variety of operands that have reloads depends on the rest of
109;; the machine description, but typically on a RISC machine these can
110;; only be pseudo registers that did not get hard registers, while on
111;; other machines explicit memory references will get optional
112;; reloads.
113;;
114;; If a scratch register is required to move an object to or from memory, it
115;; can be allocated using `gen_reg_rtx' prior to reload. But this is
116;; impossible during and after reload. If there are cases needing scratch
117;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and
118;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide
119;; patterns `reload_inM' or `reload_outM' to handle them.
120
121;; The constraints on a `moveM' must permit moving any hard register to any
122;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in
123;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a
124;; value of 2.
125
126;; It is obligatory to support floating point `moveM' instructions
127;; into and out of any registers that can hold fixed point values,
128;; because unions and structures (which have modes `SImode' or
129;; `DImode') can be in those registers and they may have floating
130;; point members.
131
132;; There may also be a need to support fixed point `moveM' instructions in and
133;; out of floating point registers. Unfortunately, I have forgotten why this
134;; was so, and I don't know whether it is still true. If `HARD_REGNO_MODE_OK'
135;; rejects fixed point values in floating point registers, then the constraints
136;; of the fixed point `moveM' instructions must be designed to avoid ever
137;; trying to reload into a floating point register.
138
139;;}}}
140;;{{{ Push and Pop
141
142;; Push a register onto the stack
143(define_insn "movsi_push"
a7edae0a
MS
144 [(set (mem:SI (pre_dec:SI (reg:SI 15)))
145 (match_operand:SI 0 "register_operand" "a"))]
309dd885
NC
146 ""
147 "st %0, @-r15"
148)
149
150;; Pop a register off the stack
151(define_insn "movsi_pop"
a7edae0a
MS
152 [(set (match_operand:SI 0 "register_operand" "=a")
153 (mem:SI (post_inc:SI (reg:SI 15))))]
309dd885
NC
154 ""
155 "ld @r15+, %0"
156)
157
158;;}}}
159;;{{{ 1 Byte Moves
160
161(define_expand "movqi"
162 [(set (match_operand:QI 0 "general_operand" "")
163 (match_operand:QI 1 "general_operand" ""))]
164 ""
165 "
166{
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]);
173}")
174
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"
180)
181
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 "
191)
192
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"
202)
203
204;;}}}
205;;{{{ 2 Byte Moves
206
207(define_expand "movhi"
208 [(set (match_operand:HI 0 "general_operand" "")
209 (match_operand:HI 1 "general_operand" ""))]
210 ""
211 "
212{
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]);
219}")
220
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"
226)
227
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 "
237)
238
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,*,*,*")]
251)
252
253;;}}}
254;;{{{ 4 Byte Moves
255
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 }"
270)
271
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.
284;;
285;; XXX we probably ought to implement these for QI and HI mode
286;; loads as well.
287
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
997718c7 291 [(set (match_operand:SI 0 "register_operand" "")
5c7666c1 292 (match_operand:SI 1 "const_int_operand" ""))]
acb188c1
RS
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))))"
a7edae0a
MS
296 [(set (match_dup 0) (match_dup 1))
297 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
309dd885 298 "{
5c7666c1
NC
299 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
300 operands[2] = gen_lowpart (QImode, operands[0]);
309dd885
NC
301 }"
302)
303
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
997718c7 308 [(set (match_operand:SI 0 "register_operand" "")
5c7666c1
NC
309 (match_operand:SI 1 "const_int_operand" ""))]
310 "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
a7edae0a
MS
311 [(set (match_dup 0) (match_dup 2))
312 (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
309dd885
NC
313 (clobber (reg:CC 16))])]
314 "{
315 HOST_WIDE_INT val = INTVAL (operands[1]);
316 operands[2] = GEN_INT (val >> 24);
317 }"
318)
319
320;; If we are loading a large positive constant, one which has bits
696e78bf 321;; in the top byte set, but whose set bits all lie within an 8 bit
309dd885
NC
322;; range, then we can save time and space by loading the byte value
323;; and shifting it into place.
324(define_split
997718c7 325 [(set (match_operand:SI 0 "register_operand" "")
5c7666c1 326 (match_operand:SI 1 "const_int_operand" ""))]
309dd885 327 "(INTVAL (operands[1]) > 0x00ffffff)
5c7666c1 328 && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
a7edae0a
MS
329 [(set (match_dup 0) (match_dup 2))
330 (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
309dd885
NC
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 }"
338)
339
340;; When TARGET_SMALL_MODEL is defined we assume that all symbolic
341;; values are addresses which will fit in 20 bits.
342
343(define_insn "movsi_internal"
08937250
LP
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"))]
309dd885
NC
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\";
08937250
LP
361 case 7: return \"st \\t%1, %0\";
362 default: gcc_unreachable ();
363 }
309dd885
NC
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)))]
372)
373
aeb4f5ef
NC
374;;}}}
375;;{{{ 8 Byte Moves
376
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
112cdef5 379;; (e.g. muldisi2) can produce a DImode result.
aeb4f5ef
NC
380;; (This code is stolen from the M32R port.)
381
382(define_expand "movdi"
ed31d14c
LP
383 [(set (match_operand:DI 0 "nonimmediate_operand" "")
384 (match_operand:DI 1 "general_operand" ""))]
aeb4f5ef
NC
385 ""
386 "
387 /* Everything except mem = const or mem = mem can be done easily. */
ed31d14c 388
aeb4f5ef
NC
389 if (GET_CODE (operands[0]) == MEM)
390 operands[1] = force_reg (DImode, operands[1]);
ed31d14c
LP
391 "
392)
aeb4f5ef
NC
393
394;; We use an insn and a split so that we can generate
395;; RTL rather than text from fr30_move_double().
396
397(define_insn "*movdi_insn"
398 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
ed31d14c 399 (match_operand:DI 1 "di_operand" "r,m,r,nF"))]
aeb4f5ef
NC
400 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
401 "#"
402 [(set_attr "length" "4,8,12,12")]
403)
404
405(define_split
406 [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
ed31d14c 407 (match_operand:DI 1 "di_operand" ""))]
aeb4f5ef
NC
408 "reload_completed"
409 [(match_dup 2)]
ed31d14c
LP
410 "operands[2] = fr30_move_double (operands);"
411)
aeb4f5ef 412
309dd885
NC
413;;}}}
414;;{{{ Load & Store Multiple Registers
415
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.
419
420(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
429 "fr30_check_multiple_regs (operands, 4, 1)"
430 "stm1 (%0, %1, %2, %3)"
431 [(set_attr "delay_type" "other")]
432)
433
434(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
441 "fr30_check_multiple_regs (operands, 3, 1)"
442 "stm1 (%0, %1, %2)"
443 [(set_attr "delay_type" "other")]
444)
445
446(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
451 "fr30_check_multiple_regs (operands, 2, 1)"
452 "stm1 (%0, %1)"
453 [(set_attr "delay_type" "other")]
454)
455
456(define_peephole
a7edae0a
MS
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))))]
309dd885
NC
465 "fr30_check_multiple_regs (operands, 4, 0)"
466 "ldm1 (%0, %1, %2, %3)"
467 [(set_attr "delay_type" "other")]
468)
469
470(define_peephole
a7edae0a
MS
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))))]
309dd885
NC
477 "fr30_check_multiple_regs (operands, 3, 0)"
478 "ldm1 (%0, %1, %2)"
479 [(set_attr "delay_type" "other")]
480)
481
482(define_peephole
a7edae0a
MS
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))))]
309dd885
NC
487 "fr30_check_multiple_regs (operands, 2, 0)"
488 "ldm1 (%0, %1)"
489 [(set_attr "delay_type" "other")]
490)
491
492(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
501 "fr30_check_multiple_regs (operands, 4, 1)"
502 "stm0 (%0, %1, %2, %3)"
503 [(set_attr "delay_type" "other")]
504)
505
506(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
513 "fr30_check_multiple_regs (operands, 3, 1)"
514 "stm0 (%0, %1, %2)"
515 [(set_attr "delay_type" "other")]
516)
517
518(define_peephole
a7edae0a
MS
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"))]
309dd885
NC
523 "fr30_check_multiple_regs (operands, 2, 1)"
524 "stm0 (%0, %1)"
525 [(set_attr "delay_type" "other")]
526)
527
528;;}}}
529;;{{{ Floating Point Moves
530
531;; Note - Patterns for SF mode moves are compulsory, but
05713b80 532;; patterns for DF are optional, as GCC can synthesize them.
309dd885
NC
533
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 }"
544)
545
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\";
4e81e7c2 562 default: gcc_unreachable ();
309dd885
NC
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)))]
571)
572
573(define_insn "*movsf_constant_store"
997718c7 574 [(set (match_operand:SF 0 "memory_operand" "=m")
309dd885
NC
575 (match_operand:SF 1 "immediate_operand" "F"))]
576 ""
577 "*
578 {
1943c2c1 579 const char * ldi_instr;
82a9bba5 580 const char * tmp_reg;
309dd885 581 static char buffer[100];
309dd885 582
02809efd 583 ldi_instr = fr30_const_double_is_zero (operands[1]) ? \"ldi:8\" : \"ldi:32\";
309dd885
NC
584
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);
589
590 return buffer;
591 }"
592 [(set_attr "length" "8")]
593)
594
595;;}}}
596
597;;}}} \f
598;;{{{ Conversions
599
600;; Signed conversions from a smaller integer to a larger integer
601
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"
607)
608
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"
614)
615
616;; Unsigned conversions from a smaller integer to a larger integer
617
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"
623)
624
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"
630)
631
632;;}}} \f
633;;{{{ Arithmetic
634
635;;{{{ Addition
636
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"
644)
645
646;; We need some trickery to be able to handle the addition of
112cdef5 647;; large (i.e. outside +/- 16) constants. We need to be able to
309dd885 648;; handle this because reload assumes that it can generate add
839a4992 649;; instructions with arbitrary sized constants.
309dd885
NC
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]));
a02ee5b2
RS
661 else if (INTVAL (operands[2]) >= -16
662 && INTVAL (operands[2]) <= 15
e2972de5
RIL
663 && (!REG_P (operands[1])
664 || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
a02ee5b2 665 || REGNO (operands[1]) == STACK_POINTER_REGNUM))
309dd885
NC
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 }"
671)
672
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"
679)
680
aaceac0b 681;; Do not allow an eliminable register in the source register. It
9cd10576 682;; might be eliminated in favor of the stack pointer, probably
aaceac0b 683;; increasing the offset, and so rendering the instruction illegal.
309dd885
NC
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")))]
e2972de5
RIL
688 "!REG_P (operands[1])
689 || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
a02ee5b2 690 || REGNO (operands[1]) == STACK_POINTER_REGNUM"
309dd885
NC
691 "@
692 addn %2, %0
693 addn2 %2, %0"
694)
695
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. */
e2972de5 703 if (rtx_equal_p (operands[0], operands[1]))
309dd885
NC
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 }"
725)
726
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")]
737)
738
739;;}}}
740;;{{{ Subtraction
741
742(define_insn "subsi3"
743 [(set (match_operand:SI 0 "register_operand" "=r")
997718c7
RH
744 (minus:SI (match_operand:SI 1 "register_operand" "0")
745 (match_operand:SI 2 "register_operand" "r")))]
309dd885
NC
746 ""
747 "subn %2, %0"
748)
749
750;;}}}
751;;{{{ Multiplication
752
a7b376ee 753;; Signed multiplication producing 64-bit results from 32-bit inputs
309dd885
NC
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")]
762)
763
a7b376ee 764;; Unsigned multiplication producing 64-bit results from 32-bit inputs
309dd885
NC
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")]
773)
774
a7b376ee 775;; Signed multiplication producing 32-bit result from 16-bit inputs
309dd885
NC
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")]
784)
785
a7b376ee 786;; Unsigned multiplication producing 32-bit result from 16-bit inputs
309dd885
NC
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")]
795)
796
a7b376ee 797;; Signed multiplication producing 32-bit result from 32-bit inputs
309dd885
NC
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")]
806)
807
808;;}}}
309dd885
NC
809;;}}} \f
810;;{{{ Shifts
811
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"
823)
824
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"
836)
837
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"
849)
850
851;;}}} \f
852;;{{{ Logical Operations
853
a7b376ee 854;; Logical AND, 32-bit integers
309dd885
NC
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"
862)
863
a7b376ee 864;; Inclusive OR, 32-bit integers
309dd885
NC
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"
872)
873
a7b376ee 874;; Exclusive OR, 32-bit integers
309dd885
NC
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"
882)
883
a7b376ee 884;; One's complement, 32-bit integers
309dd885
NC
885(define_expand "one_cmplsi2"
886 [(set (match_operand:SI 0 "register_operand" "")
887 (not:SI (match_operand:SI 1 "register_operand" "")))]
888 ""
889 "{
e2972de5 890 if (rtx_equal_p (operands[0], operands[1]))
309dd885
NC
891 {
892 if (reload_in_progress || reload_completed)
893 {
894 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
895
a556fd39 896 emit_insn (gen_movsi (reg, constm1_rtx));
309dd885
NC
897 emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
898 }
899 else
900 {
901 rtx reg = gen_reg_rtx (SImode);
902
a556fd39 903 emit_insn (gen_movsi (reg, constm1_rtx));
309dd885
NC
904 emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
905 }
906 }
907 else
908 {
a556fd39 909 emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
309dd885
NC
910 emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
911 }
912 DONE;
913 }"
914)
915
916;;}}} \f
917;;{{{ Comparisons
918
f90b7a5a 919;; The actual comparisons, generated by the cbranch and/or cstore expanders
309dd885
NC
920
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"
930)
931
932;;}}} \f
933;;{{{ Branches
934
935;; Define_expands called by the machine independent part of the compiler
936;; to allocate a new comparison register
937
f90b7a5a 938(define_expand "cbranchsi4"
309dd885 939 [(set (reg:CC 16)
f90b7a5a
PB
940 (compare:CC (match_operand:SI 1 "register_operand" "")
941 (match_operand:SI 2 "nonmemory_operand" "")))
309dd885 942 (set (pc)
baecdd1e 943 (if_then_else (match_operator 0 "ordered_comparison_operator"
f90b7a5a
PB
944 [(reg:CC 16) (const_int 0)])
945 (label_ref (match_operand 3 "" ""))
309dd885
NC
946 (pc)))]
947 ""
309dd885 948 ""
309dd885
NC
949)
950
309dd885
NC
951
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.
954
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.
958
959;; The calculation for the instruction length is derived as follows:
a7b376ee 960;; The branch instruction has a 9-bit signed displacement so we have
309dd885
NC
961;; this inequality for the displacement:
962;;
963;; -256 <= pc < 256
964;; or
965;; -256 + 256 <= pc + 256 < 256 + 256
112cdef5 966;; i.e.
309dd885
NC
967;; 0 <= pc + 256 < 512
968;;
969;; if we consider the displacement as an unsigned value, then negative
970;; displacements become very large positive displacements, and the
971;; inequality becomes:
972;;
973;; pc + 256 < 512
974;;
975;; In order to allow for the fact that the real branch instruction works
976;; from pc + 2, we increase the offset to 258.
977;;
978;; Note - we do not have to worry about whether the branch is delayed or
272d0bee 979;; not, as branch shortening happens after delay slot reorganization.
309dd885
NC
980
981(define_insn "*branch_true"
982 [(set (pc)
baecdd1e
NC
983 (if_then_else (match_operator 0 "comparison_operator"
984 [(reg:CC 16)
985 (const_int 0)])
309dd885
NC
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 {
82a9bba5
NC
995 static char buffer [100];
996 const char * tmp_reg;
1943c2c1 997 const char * ldi_insn;
309dd885
NC
998
999 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1000
1001 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1002
1003 /* The code produced here is, for say the EQ case:
1004
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);
1013
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")]
1030)
1031
1032
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)
baecdd1e
NC
1037 (if_then_else (match_operator 0 "comparison_operator"
1038 [(reg:CC 16)
1039 (const_int 0)])
309dd885
NC
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 {
82a9bba5
NC
1049 static char buffer [100];
1050 const char * tmp_reg;
1943c2c1 1051 const char * ldi_insn;
309dd885
NC
1052
1053 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1054
1055 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1056
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);
1060
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")]
1072)
1073
1074;;}}} \f
1075;;{{{ Calls & Jumps
1076
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.
1081
1082(define_insn "call"
6e11d5e9 1083 [(call (match_operand 0 "call_operand" "Qm")
309dd885
NC
1084 (match_operand 1 "" "g"))
1085 (clobber (reg:SI 17))]
1086 ""
1087 "call%#\\t%0"
1088 [(set_attr "delay_type" "delayed")]
1089)
1090
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).
1095
1096;; Subroutines that return `BLKmode' objects use the `call' insn.
1097
1098(define_insn "call_value"
1099 [(set (match_operand 0 "register_operand" "=r")
6e11d5e9 1100 (call (match_operand 1 "call_operand" "Qm")
309dd885
NC
1101 (match_operand 2 "" "g")))
1102 (clobber (reg:SI 17))]
1103 ""
1104 "call%#\\t%1"
1105 [(set_attr "delay_type" "delayed")]
1106)
1107
1108;; Normal unconditional jump.
1109;; For a description of the computation of the length
1110;; attribute see the branch patterns above.
a29b099d
JJ
1111;;
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
309dd885 1115(define_insn "jump"
a29b099d 1116 [(set (pc) (label_ref (match_operand 0 "" "")))]
309dd885
NC
1117 ""
1118 "*
1119 {
1120 if (get_attr_length (insn) == 2)
1121 return \"bra%#\\t%0\";
1122 else
1123 {
82a9bba5
NC
1124 static char buffer [100];
1125 const char * tmp_reg;
1943c2c1 1126 const char * ldi_insn;
309dd885
NC
1127
1128 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1129
1130 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1131
1132 sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1133 ldi_insn, tmp_reg, tmp_reg);
1134
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")]
1146)
1147
1148;; Indirect jump through a register
1149(define_insn "indirect_jump"
1150 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1151 "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1152 "jmp%#\\t@%0"
1153 [(set_attr "delay_type" "delayed")]
1154)
1155
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")]
1162)
1163
1164;;}}} \f
1165;;{{{ Function Prologues and Epilogues
1166
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
08c148a8 1169;; instructions in output_function_prologue(), since it allows the scheduler
309dd885
NC
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"
82a9bba5 1174 [(clobber (const_int 0))]
309dd885
NC
1175 ""
1176 "{
1177 fr30_expand_prologue ();
1178 DONE;
1179 }"
1180)
1181
1182;; Called after register allocation to add any instructions needed for the
5519a4f9 1183;; epilogue. Using an epilogue insn is favored compared to putting all of the
08c148a8 1184;; instructions in output_function_epilogue(), since it allows the scheduler
309dd885
NC
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 }"
1195)
1196
1197(define_insn "return_from_func"
1198 [(return)
1199 (use (reg:SI 17))]
1200 "reload_completed"
1201 "ret%#"
1202 [(set_attr "delay_type" "delayed")]
1203)
1204
1205(define_insn "leave_func"
0db0c836
NF
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))))]
309dd885
NC
1208 "reload_completed"
1209 "leave"
1210)
1211
e2972de5
RIL
1212(define_expand "enter_func"
1213 [(parallel
a7edae0a
MS
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")))]
e2972de5
RIL
1223 )]
1224 ""
1225{
1226 operands[1] = stack_pointer_rtx;
1227 operands[2] = hard_frame_pointer_rtx;
1228})
1229
1230(define_insn "*enter_func"
a7edae0a
MS
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")))]
309dd885
NC
1240 "reload_completed"
1241 "enter #%0"
1242 [(set_attr "delay_type" "other")]
1243)
1244
1245;;}}} \f
1246;;{{{ Miscellaneous
1247
1248;; No operation, needed in case the user uses -g but not -O.
1249(define_insn "nop"
1250 [(const_int 0)]
1251 ""
1252 "nop"
1253)
1254
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")]
1262)
5c7666c1 1263;;}}} \f
309dd885
NC
1264
1265;; Local Variables:
1266;; mode: md
1267;; folded-file: t
1268;; End:
This page took 2.984389 seconds and 5 git commands to generate.