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