]> gcc.gnu.org Git - gcc.git/blame - gcc/config/fr30/fr30.md
sh.md (movsi_i): Fix type attribute.
[gcc.git] / gcc / config / fr30 / fr30.md
CommitLineData
309dd885 1;; FR30 machine description.
f17178cf
KH
2;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005
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
NC
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 2, or (at your option)
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
7ec022b2 19;; along with GCC; see the file COPYING. If not, write to
39d14dda
KC
20;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21;; Boston, MA 02110-1301, USA.
309dd885
NC
22
23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
309dd885
NC
25;;{{{ Attributes
26
27(define_attr "length" "" (const_int 2))
28
29;; Used to distinguish between small memory model targets and big mode targets.
30
31(define_attr "size" "small,big"
32 (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
33 (const_string "small")
34 (const_string "big"))))
35
36
37;; Define an attribute to be used by the delay slot code.
6fc0bb99 38;; An instruction by default is considered to be 'delayable'
309dd885 39;; that is, it can be placed into a delay slot, but it is not
40b982a9 40;; itself a delayed branch type instruction. An instruction
696e78bf
KH
41;; whose type is 'delayed' is one which has a delay slot, and
42;; an instruction whose delay_type is 'other' is one which does
309dd885
NC
43;; not have a delay slot, nor can it be placed into a delay slot.
44
45(define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
46
47;;}}} \f
48;;{{{ Delay Slot Specifications
49
50(define_delay (eq_attr "delay_type" "delayed")
51 [(and (eq_attr "delay_type" "delayable")
52 (eq_attr "length" "2"))
53 (nil)
54 (nil)]
55)
56
f17178cf
KH
57(include "predicates.md")
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"
144 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
145 (match_operand:SI 0 "register_operand" "a"))]
146 ""
147 "st %0, @-r15"
148)
149
150;; Pop a register off the stack
151(define_insn "movsi_pop"
997718c7 152 [(set:SI (match_operand:SI 0 "register_operand" "=a")
309dd885
NC
153 (mem:SI (post_inc:SI (reg:SI 15))))]
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))))"
5c7666c1
NC
296 [(set:SI (match_dup 0) (match_dup 1))
297 (set:SI (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)"
309dd885
NC
311 [(set:SI (match_dup 0) (match_dup 2))
312 (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (const_int 24)))
313 (clobber (reg:CC 16))])]
314 "{
315 HOST_WIDE_INT val = INTVAL (operands[1]);
316 operands[2] = GEN_INT (val >> 24);
317 }"
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)"
309dd885
NC
329 [(set:SI (match_dup 0) (match_dup 2))
330 (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3)))
331 (clobber (reg:CC 16))])]
332 "{
333 HOST_WIDE_INT val = INTVAL (operands[1]);
334 int shift = exact_log2 (val & ( - val));
335 operands[2] = GEN_INT (val >> shift);
336 operands[3] = GEN_INT (shift);
337 }"
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"
344 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,m,r")
345 (match_operand:SI 1 "general_operand" "L,M,n,i,rde,r,rm"))]
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\";
4e81e7c2 361 default: gcc_unreachable ();
309dd885
NC
362 }
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"
382 [(set (match_operand:DI 0 "general_operand" "")
383 (match_operand:DI 1 "general_operand" ""))]
384 ""
385 "
386 /* Everything except mem = const or mem = mem can be done easily. */
387
388 if (GET_CODE (operands[0]) == MEM)
389 operands[1] = force_reg (DImode, operands[1]);
390 ")
391
392;; We use an insn and a split so that we can generate
393;; RTL rather than text from fr30_move_double().
394
395(define_insn "*movdi_insn"
396 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r")
397 (match_operand:DI 1 "di_operand" "r,m,r,nF"))]
398 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)"
399 "#"
400 [(set_attr "length" "4,8,12,12")]
401)
402
403(define_split
404 [(set (match_operand:DI 0 "nonimmediate_di_operand" "")
405 (match_operand:DI 1 "di_operand" ""))]
406 "reload_completed"
407 [(match_dup 2)]
408 "operands[2] = fr30_move_double (operands);")
409
309dd885
NC
410;;}}}
411;;{{{ Load & Store Multiple Registers
412
413;; The load multiple and store multiple patterns are implemented
414;; as peepholes because the only time they are expected to occur
415;; is during function prologues and epilogues.
416
417(define_peephole
418 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
419 (match_operand:SI 0 "high_register_operand" "h"))
420 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
421 (match_operand:SI 1 "high_register_operand" "h"))
422 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
423 (match_operand:SI 2 "high_register_operand" "h"))
424 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
425 (match_operand:SI 3 "high_register_operand" "h"))]
426 "fr30_check_multiple_regs (operands, 4, 1)"
427 "stm1 (%0, %1, %2, %3)"
428 [(set_attr "delay_type" "other")]
429)
430
431(define_peephole
432 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
433 (match_operand:SI 0 "high_register_operand" "h"))
434 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
435 (match_operand:SI 1 "high_register_operand" "h"))
436 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
437 (match_operand:SI 2 "high_register_operand" "h"))]
438 "fr30_check_multiple_regs (operands, 3, 1)"
439 "stm1 (%0, %1, %2)"
440 [(set_attr "delay_type" "other")]
441)
442
443(define_peephole
444 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
445 (match_operand:SI 0 "high_register_operand" "h"))
446 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
447 (match_operand:SI 1 "high_register_operand" "h"))]
448 "fr30_check_multiple_regs (operands, 2, 1)"
449 "stm1 (%0, %1)"
450 [(set_attr "delay_type" "other")]
451)
452
453(define_peephole
454 [(set:SI (match_operand:SI 0 "high_register_operand" "h")
455 (mem:SI (post_inc:SI (reg:SI 15))))
456 (set:SI (match_operand:SI 1 "high_register_operand" "h")
457 (mem:SI (post_inc:SI (reg:SI 15))))
458 (set:SI (match_operand:SI 2 "high_register_operand" "h")
459 (mem:SI (post_inc:SI (reg:SI 15))))
460 (set:SI (match_operand:SI 3 "high_register_operand" "h")
461 (mem:SI (post_inc:SI (reg:SI 15))))]
462 "fr30_check_multiple_regs (operands, 4, 0)"
463 "ldm1 (%0, %1, %2, %3)"
464 [(set_attr "delay_type" "other")]
465)
466
467(define_peephole
468 [(set:SI (match_operand:SI 0 "high_register_operand" "h")
469 (mem:SI (post_inc:SI (reg:SI 15))))
470 (set:SI (match_operand:SI 1 "high_register_operand" "h")
471 (mem:SI (post_inc:SI (reg:SI 15))))
472 (set:SI (match_operand:SI 2 "high_register_operand" "h")
473 (mem:SI (post_inc:SI (reg:SI 15))))]
474 "fr30_check_multiple_regs (operands, 3, 0)"
475 "ldm1 (%0, %1, %2)"
476 [(set_attr "delay_type" "other")]
477)
478
479(define_peephole
480 [(set:SI (match_operand:SI 0 "high_register_operand" "h")
481 (mem:SI (post_inc:SI (reg:SI 15))))
482 (set:SI (match_operand:SI 1 "high_register_operand" "h")
483 (mem:SI (post_inc:SI (reg:SI 15))))]
484 "fr30_check_multiple_regs (operands, 2, 0)"
485 "ldm1 (%0, %1)"
486 [(set_attr "delay_type" "other")]
487)
488
489(define_peephole
490 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
491 (match_operand:SI 0 "low_register_operand" "l"))
492 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
493 (match_operand:SI 1 "low_register_operand" "l"))
494 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
495 (match_operand:SI 2 "low_register_operand" "l"))
496 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
497 (match_operand:SI 3 "low_register_operand" "l"))]
498 "fr30_check_multiple_regs (operands, 4, 1)"
499 "stm0 (%0, %1, %2, %3)"
500 [(set_attr "delay_type" "other")]
501)
502
503(define_peephole
504 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
505 (match_operand:SI 0 "low_register_operand" "l"))
506 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
507 (match_operand:SI 1 "low_register_operand" "l"))
508 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
509 (match_operand:SI 2 "low_register_operand" "l"))]
510 "fr30_check_multiple_regs (operands, 3, 1)"
511 "stm0 (%0, %1, %2)"
512 [(set_attr "delay_type" "other")]
513)
514
515(define_peephole
516 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
517 (match_operand:SI 0 "low_register_operand" "l"))
518 (set:SI (mem:SI (pre_dec:SI (reg:SI 15)))
519 (match_operand:SI 1 "low_register_operand" "l"))]
520 "fr30_check_multiple_regs (operands, 2, 1)"
521 "stm0 (%0, %1)"
522 [(set_attr "delay_type" "other")]
523)
524
525;;}}}
526;;{{{ Floating Point Moves
527
528;; Note - Patterns for SF mode moves are compulsory, but
05713b80 529;; patterns for DF are optional, as GCC can synthesize them.
309dd885
NC
530
531(define_expand "movsf"
532 [(set (match_operand:SF 0 "general_operand" "")
533 (match_operand:SF 1 "general_operand" ""))]
534 ""
535 "{
536 if (!reload_in_progress && !reload_completed
537 && memory_operand (operands[0], SFmode)
538 && memory_operand (operands[1], SFmode))
539 operands[1] = copy_to_mode_reg (SFmode, operands[1]);
540 }"
541)
542
543(define_insn "*movsf_internal"
544 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r")
545 (match_operand:SF 1 "general_operand" "Fn,i,rde,r,rm"))]
546 ""
547 "*
548 {
549 switch (which_alternative)
550 {
551 case 0: return \"ldi:32\\t%1, %0\";
552 case 1: if (TARGET_SMALL_MODEL)
553 return \"ldi:20\\t%1, %0\";
554 else
555 return \"ldi:32\\t%1, %0\";
556 case 2: return \"mov \\t%1, %0\";
557 case 3: return \"st \\t%1, %0\";
558 case 4: return \"ld \\t%1, %0\";
4e81e7c2 559 default: gcc_unreachable ();
309dd885
NC
560 }
561 }"
562 [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6)
563 (eq_attr "alternative" "1")
564 (if_then_else (eq_attr "size" "small")
565 (const_int 4)
566 (const_int 6))]
567 (const_int 2)))]
568)
569
570(define_insn "*movsf_constant_store"
997718c7 571 [(set (match_operand:SF 0 "memory_operand" "=m")
309dd885
NC
572 (match_operand:SF 1 "immediate_operand" "F"))]
573 ""
574 "*
575 {
1943c2c1 576 const char * ldi_instr;
82a9bba5 577 const char * tmp_reg;
309dd885 578 static char buffer[100];
309dd885 579
3d5ee65b
NC
580 ldi_instr = fr30_const_double_is_zero (operands[1])
581 ? ldi_instr = \"ldi:8\" : \"ldi:32\";
309dd885
NC
582
583 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
584
585 sprintf (buffer, \"%s\\t#%%1, %s\\t;\\n\\tst\\t%s, %%0\\t; Created by movsf_constant_store\",
586 ldi_instr, tmp_reg, tmp_reg);
587
588 return buffer;
589 }"
590 [(set_attr "length" "8")]
591)
592
593;;}}}
594
595;;}}} \f
596;;{{{ Conversions
597
598;; Signed conversions from a smaller integer to a larger integer
599
600(define_insn "extendqisi2"
601 [(set (match_operand:SI 0 "register_operand" "=r")
602 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
603 ""
604 "extsb %0"
605)
606
607(define_insn "extendhisi2"
608 [(set (match_operand:SI 0 "register_operand" "=r")
609 (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
610 ""
611 "extsh %0"
612)
613
614;; Unsigned conversions from a smaller integer to a larger integer
615
616(define_insn "zero_extendqisi2"
617 [(set (match_operand:SI 0 "register_operand" "=r")
618 (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
619 ""
620 "extub %0"
621)
622
623(define_insn "zero_extendhisi2"
624 [(set (match_operand:SI 0 "register_operand" "=r")
625 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
626 ""
627 "extuh %0"
628)
629
630;;}}} \f
631;;{{{ Arithmetic
632
633;;{{{ Addition
634
635;; This is a special pattern just for adjusting the stack size.
636(define_insn "add_to_stack"
637 [(set (reg:SI 15)
638 (plus:SI (reg:SI 15)
639 (match_operand:SI 0 "stack_add_operand" "i")))]
640 ""
641 "addsp %0"
642)
643
644;; We need some trickery to be able to handle the addition of
112cdef5 645;; large (i.e. outside +/- 16) constants. We need to be able to
309dd885 646;; handle this because reload assumes that it can generate add
839a4992 647;; instructions with arbitrary sized constants.
309dd885
NC
648(define_expand "addsi3"
649 [(set (match_operand:SI 0 "register_operand" "")
650 (plus:SI (match_operand:SI 1 "register_operand" "")
651 (match_operand:SI 2 "nonmemory_operand" "")))]
652 ""
653 "{
654 if ( GET_CODE (operands[2]) == REG
655 || GET_CODE (operands[2]) == SUBREG)
656 emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
657 else if (GET_CODE (operands[2]) != CONST_INT)
658 emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
a02ee5b2
RS
659 else if (INTVAL (operands[2]) >= -16
660 && INTVAL (operands[2]) <= 15
661 && (!REGNO_PTR_FRAME_P (REGNO (operands[1]))
662 || REGNO (operands[1]) == STACK_POINTER_REGNUM))
309dd885
NC
663 emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
664 else
665 emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
666 DONE;
667 }"
668)
669
670(define_insn "addsi_regs"
671 [(set (match_operand:SI 0 "register_operand" "=r")
672 (plus:SI (match_operand:SI 1 "register_operand" "%0")
673 (match_operand:SI 2 "register_operand" "r")))]
674 ""
675 "addn %2, %0"
676)
677
aaceac0b 678;; Do not allow an eliminable register in the source register. It
9cd10576 679;; might be eliminated in favor of the stack pointer, probably
aaceac0b 680;; increasing the offset, and so rendering the instruction illegal.
309dd885
NC
681(define_insn "addsi_small_int"
682 [(set (match_operand:SI 0 "register_operand" "=r,r")
683 (plus:SI (match_operand:SI 1 "register_operand" "0,0")
684 (match_operand:SI 2 "add_immediate_operand" "I,J")))]
a02ee5b2
RS
685 "! REGNO_PTR_FRAME_P (REGNO (operands[1]))
686 || REGNO (operands[1]) == STACK_POINTER_REGNUM"
309dd885
NC
687 "@
688 addn %2, %0
689 addn2 %2, %0"
690)
691
692(define_expand "addsi_big_int"
693 [(set (match_operand:SI 0 "register_operand" "")
694 (plus:SI (match_operand:SI 1 "register_operand" "")
695 (match_operand:SI 2 "immediate_operand" "")))]
696 ""
697 "{
698 /* Cope with the possibility that ops 0 and 1 are the same register. */
699 if (REGNO (operands[0]) == REGNO (operands[1]))
700 {
701 if (reload_in_progress || reload_completed)
702 {
703 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
704
705 emit_insn (gen_movsi (reg, operands[2]));
706 emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
707 }
708 else
709 {
710 operands[2] = force_reg (SImode, operands[2]);
711 emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
712 }
713 }
714 else
715 {
716 emit_insn (gen_movsi (operands[0], operands[2]));
717 emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
718 }
719 DONE;
720 }"
721)
722
723(define_insn "*addsi_for_reload"
724 [(set (match_operand:SI 0 "register_operand" "=&r,r,r")
725 (plus:SI (match_operand:SI 1 "register_operand" "r,r,r")
726 (match_operand:SI 2 "immediate_operand" "L,M,n")))]
727 "reload_in_progress || reload_completed"
728 "@
729 ldi:8\\t#%2, %0 \\n\\taddn\\t%1, %0
730 ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
731 ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
732 [(set_attr "length" "4,6,8")]
733)
734
735;;}}}
736;;{{{ Subtraction
737
738(define_insn "subsi3"
739 [(set (match_operand:SI 0 "register_operand" "=r")
997718c7
RH
740 (minus:SI (match_operand:SI 1 "register_operand" "0")
741 (match_operand:SI 2 "register_operand" "r")))]
309dd885
NC
742 ""
743 "subn %2, %0"
744)
745
746;;}}}
747;;{{{ Multiplication
748
a7b376ee 749;; Signed multiplication producing 64-bit results from 32-bit inputs
309dd885
NC
750(define_insn "mulsidi3"
751 [(set (match_operand:DI 0 "register_operand" "=r")
752 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
753 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))
754 (clobber (reg:CC 16))]
755 ""
756 "mul %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
757 [(set_attr "length" "6")]
758)
759
a7b376ee 760;; Unsigned multiplication producing 64-bit results from 32-bit inputs
309dd885
NC
761(define_insn "umulsidi3"
762 [(set (match_operand:DI 0 "register_operand" "=r")
763 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
764 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
765 (clobber (reg:CC 16))]
766 ""
767 "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
768 [(set_attr "length" "6")]
769)
770
a7b376ee 771;; Signed multiplication producing 32-bit result from 16-bit inputs
309dd885
NC
772(define_insn "mulhisi3"
773 [(set (match_operand:SI 0 "register_operand" "=r")
774 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
775 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))
776 (clobber (reg:CC 16))]
777 ""
778 "mulh %2, %1\\n\\tmov\\tmdl, %0"
779 [(set_attr "length" "4")]
780)
781
a7b376ee 782;; Unsigned multiplication producing 32-bit result from 16-bit inputs
309dd885
NC
783(define_insn "umulhisi3"
784 [(set (match_operand:SI 0 "register_operand" "=r")
785 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
786 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))
787 (clobber (reg:CC 16))]
788 ""
789 "muluh %2, %1\\n\\tmov\\tmdl, %0"
790 [(set_attr "length" "4")]
791)
792
a7b376ee 793;; Signed multiplication producing 32-bit result from 32-bit inputs
309dd885
NC
794(define_insn "mulsi3"
795 [(set (match_operand:SI 0 "register_operand" "=r")
796 (mult:SI (match_operand:SI 1 "register_operand" "%r")
797 (match_operand:SI 2 "register_operand" "r")))
798 (clobber (reg:CC 16))]
799 ""
800 "mul %2, %1\\n\\tmov\\tmdl, %0"
801 [(set_attr "length" "4")]
802)
803
804;;}}}
805;;{{{ Negation
806
807(define_expand "negsi2"
808 [(set (match_operand:SI 0 "register_operand" "")
809 (neg:SI (match_operand:SI 1 "register_operand" "")))]
810 ""
811 "{
812 if (REGNO (operands[0]) == REGNO (operands[1]))
813 {
814 if (reload_in_progress || reload_completed)
815 {
816 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
817
a556fd39 818 emit_insn (gen_movsi (reg, const0_rtx));
309dd885
NC
819 emit_insn (gen_subsi3 (reg, reg, operands[0]));
820 emit_insn (gen_movsi (operands[0], reg));
821 }
822 else
823 {
824 rtx reg = gen_reg_rtx (SImode);
825
a556fd39 826 emit_insn (gen_movsi (reg, const0_rtx));
309dd885
NC
827 emit_insn (gen_subsi3 (reg, reg, operands[0]));
828 emit_insn (gen_movsi (operands[0], reg));
829 }
830 }
831 else
832 {
a556fd39 833 emit_insn (gen_movsi_internal (operands[0], const0_rtx));
309dd885
NC
834 emit_insn (gen_subsi3 (operands[0], operands[0], operands[1]));
835 }
836 DONE;
837 }"
838)
839
840;;}}}
841
842;;}}} \f
843;;{{{ Shifts
844
845;; Arithmetic Shift Left
846(define_insn "ashlsi3"
847 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
848 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0")
849 (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
850 (clobber (reg:CC 16))]
851 ""
852 "@
853 lsl %2, %0
854 lsl %2, %0
855 lsl2 %x2, %0"
856)
857
858;; Arithmetic Shift Right
859(define_insn "ashrsi3"
860 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
861 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0")
862 (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
863 (clobber (reg:CC 16))]
864 ""
865 "@
866 asr %2, %0
867 asr %2, %0
868 asr2 %x2, %0"
869)
870
871;; Logical Shift Right
872(define_insn "lshrsi3"
873 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
874 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0")
875 (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
876 (clobber (reg:CC 16))]
877 ""
878 "@
879 lsr %2, %0
880 lsr %2, %0
881 lsr2 %x2, %0"
882)
883
884;;}}} \f
885;;{{{ Logical Operations
886
a7b376ee 887;; Logical AND, 32-bit integers
309dd885
NC
888(define_insn "andsi3"
889 [(set (match_operand:SI 0 "register_operand" "=r")
890 (and:SI (match_operand:SI 1 "register_operand" "%r")
891 (match_operand:SI 2 "register_operand" "0")))
892 (clobber (reg:CC 16))]
893 ""
894 "and %1, %0"
895)
896
a7b376ee 897;; Inclusive OR, 32-bit integers
309dd885
NC
898(define_insn "iorsi3"
899 [(set (match_operand:SI 0 "register_operand" "=r")
900 (ior:SI (match_operand:SI 1 "register_operand" "%r")
901 (match_operand:SI 2 "register_operand" "0")))
902 (clobber (reg:CC 16))]
903 ""
904 "or %1, %0"
905)
906
a7b376ee 907;; Exclusive OR, 32-bit integers
309dd885
NC
908(define_insn "xorsi3"
909 [(set (match_operand:SI 0 "register_operand" "=r")
910 (xor:SI (match_operand:SI 1 "register_operand" "%r")
911 (match_operand:SI 2 "register_operand" "0")))
912 (clobber (reg:CC 16))]
913 ""
914 "eor %1, %0"
915)
916
a7b376ee 917;; One's complement, 32-bit integers
309dd885
NC
918(define_expand "one_cmplsi2"
919 [(set (match_operand:SI 0 "register_operand" "")
920 (not:SI (match_operand:SI 1 "register_operand" "")))]
921 ""
922 "{
923 if (REGNO (operands[0]) == REGNO (operands[1]))
924 {
925 if (reload_in_progress || reload_completed)
926 {
927 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
928
a556fd39 929 emit_insn (gen_movsi (reg, constm1_rtx));
309dd885
NC
930 emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
931 }
932 else
933 {
934 rtx reg = gen_reg_rtx (SImode);
935
a556fd39 936 emit_insn (gen_movsi (reg, constm1_rtx));
309dd885
NC
937 emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
938 }
939 }
940 else
941 {
a556fd39 942 emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
309dd885
NC
943 emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
944 }
945 DONE;
946 }"
947)
948
949;;}}} \f
950;;{{{ Comparisons
951
952;; Note, we store the operands in the comparison insns, and use them later
953;; when generating the branch or scc operation.
954
955;; First the routines called by the machine independent part of the compiler
956(define_expand "cmpsi"
957 [(set (reg:CC 16)
958 (compare:CC (match_operand:SI 0 "register_operand" "")
959 (match_operand:SI 1 "nonmemory_operand" "")))]
960 ""
961 "{
962 fr30_compare_op0 = operands[0];
963 fr30_compare_op1 = operands[1];
964 DONE;
965 }"
966)
967
968;; Now, the actual comparisons, generated by the branch and/or scc operations
969
970(define_insn "*cmpsi_internal"
971 [(set (reg:CC 16)
972 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
973 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
974 ""
975 "@
976 cmp %1, %0
977 cmp %1, %0
978 cmp2 %1, %0"
979)
980
981;;}}} \f
982;;{{{ Branches
983
984;; Define_expands called by the machine independent part of the compiler
985;; to allocate a new comparison register
986
987(define_expand "beq"
988 [(set (reg:CC 16)
989 (compare:CC (match_dup 1)
990 (match_dup 2)))
991 (set (pc)
992 (if_then_else (eq:CC (reg:CC 16)
993 (const_int 0))
994 (label_ref (match_operand 0 "" ""))
995 (pc)))]
996 ""
997 "{
998 operands[1] = fr30_compare_op0;
999 operands[2] = fr30_compare_op1;
1000 }"
1001)
1002
1003(define_expand "bne"
1004 [(set (reg:CC 16)
1005 (compare:CC (match_dup 1)
1006 (match_dup 2)))
1007 (set (pc)
1008 (if_then_else (ne:CC (reg:CC 16)
1009 (const_int 0))
1010 (label_ref (match_operand 0 "" ""))
1011 (pc)))]
1012 ""
1013 "{
1014 operands[1] = fr30_compare_op0;
1015 operands[2] = fr30_compare_op1;
1016 }"
1017)
1018
1019(define_expand "blt"
1020 [(set (reg:CC 16)
1021 (compare:CC (match_dup 1)
1022 (match_dup 2)))
1023 (set (pc)
1024 (if_then_else (lt:CC (reg:CC 16)
1025 (const_int 0))
1026 (label_ref (match_operand 0 "" ""))
1027 (pc)))]
1028 ""
1029 "{
1030 operands[1] = fr30_compare_op0;
1031 operands[2] = fr30_compare_op1;
1032 }"
1033)
1034
1035(define_expand "ble"
1036 [(set (reg:CC 16)
1037 (compare:CC (match_dup 1)
1038 (match_dup 2)))
1039 (set (pc)
1040 (if_then_else (le:CC (reg:CC 16)
1041 (const_int 0))
1042 (label_ref (match_operand 0 "" ""))
1043 (pc)))]
1044 ""
1045 "{
1046 operands[1] = fr30_compare_op0;
1047 operands[2] = fr30_compare_op1;
1048 }"
1049)
1050
1051(define_expand "bgt"
1052 [(set (reg:CC 16)
1053 (compare:CC (match_dup 1)
1054 (match_dup 2)))
1055 (set (pc)
1056 (if_then_else (gt:CC (reg:CC 16)
1057 (const_int 0))
1058 (label_ref (match_operand 0 "" ""))
1059 (pc)))]
1060 ""
1061 "{
1062 operands[1] = fr30_compare_op0;
1063 operands[2] = fr30_compare_op1;
1064 }"
1065)
1066
1067(define_expand "bge"
1068 [(set (reg:CC 16)
1069 (compare:CC (match_dup 1)
1070 (match_dup 2)))
1071 (set (pc)
1072 (if_then_else (ge:CC (reg:CC 16)
1073 (const_int 0))
1074 (label_ref (match_operand 0 "" ""))
1075 (pc)))]
1076 ""
1077 "{
1078 operands[1] = fr30_compare_op0;
1079 operands[2] = fr30_compare_op1;
1080 }"
1081)
1082
1083(define_expand "bltu"
1084 [(set (reg:CC 16)
1085 (compare:CC (match_dup 1)
1086 (match_dup 2)))
1087 (set (pc)
1088 (if_then_else (ltu:CC (reg:CC 16)
1089 (const_int 0))
1090 (label_ref (match_operand 0 "" ""))
1091 (pc)))]
1092 ""
1093 "{
1094 operands[1] = fr30_compare_op0;
1095 operands[2] = fr30_compare_op1;
1096 }"
1097)
1098
1099(define_expand "bleu"
1100 [(set (reg:CC 16)
1101 (compare:CC (match_dup 1)
1102 (match_dup 2)))
1103 (set (pc)
1104 (if_then_else (leu:CC (reg:CC 16)
1105 (const_int 0))
1106 (label_ref (match_operand 0 "" ""))
1107 (pc)))]
1108 ""
1109 "{
1110 operands[1] = fr30_compare_op0;
1111 operands[2] = fr30_compare_op1;
1112 }"
1113)
1114
1115(define_expand "bgtu"
1116 [(set (reg:CC 16)
1117 (compare:CC (match_dup 1)
1118 (match_dup 2)))
1119 (set (pc)
1120 (if_then_else (gtu:CC (reg:CC 16)
1121 (const_int 0))
1122 (label_ref (match_operand 0 "" ""))
1123 (pc)))]
1124 ""
1125 "{
1126 operands[1] = fr30_compare_op0;
1127 operands[2] = fr30_compare_op1;
1128 }"
1129)
1130
1131(define_expand "bgeu"
1132 [(set (reg:CC 16)
1133 (compare:CC (match_dup 1)
1134 (match_dup 2)))
1135 (set (pc)
1136 (if_then_else (geu:CC (reg:CC 16)
1137 (const_int 0))
1138 (label_ref (match_operand 0 "" ""))
1139 (pc)))]
1140 ""
1141 "{
1142 operands[1] = fr30_compare_op0;
1143 operands[2] = fr30_compare_op1;
1144 }"
1145)
1146
1147;; Actual branches. We must allow for the (label_ref) and the (pc) to be
1148;; swapped. If they are swapped, it reverses the sense of the branch.
1149
1150;; This pattern matches the (branch-if-true) branches generated above.
1151;; It generates two different instruction sequences depending upon how
1152;; far away the destination is.
1153
1154;; The calculation for the instruction length is derived as follows:
a7b376ee 1155;; The branch instruction has a 9-bit signed displacement so we have
309dd885
NC
1156;; this inequality for the displacement:
1157;;
1158;; -256 <= pc < 256
1159;; or
1160;; -256 + 256 <= pc + 256 < 256 + 256
112cdef5 1161;; i.e.
309dd885
NC
1162;; 0 <= pc + 256 < 512
1163;;
1164;; if we consider the displacement as an unsigned value, then negative
1165;; displacements become very large positive displacements, and the
1166;; inequality becomes:
1167;;
1168;; pc + 256 < 512
1169;;
1170;; In order to allow for the fact that the real branch instruction works
1171;; from pc + 2, we increase the offset to 258.
1172;;
1173;; Note - we do not have to worry about whether the branch is delayed or
272d0bee 1174;; not, as branch shortening happens after delay slot reorganization.
309dd885
NC
1175
1176(define_insn "*branch_true"
1177 [(set (pc)
1178 (if_then_else (match_operator:CC 0 "comparison_operator"
1179 [(reg:CC 16)
1180 (const_int 0)])
1181 (label_ref (match_operand 1 "" ""))
1182 (pc)))]
1183 ""
1184 "*
1185 {
1186 if (get_attr_length (insn) == 2)
1187 return \"b%b0%#\\t%l1\";
1188 else
1189 {
82a9bba5
NC
1190 static char buffer [100];
1191 const char * tmp_reg;
1943c2c1 1192 const char * ldi_insn;
309dd885
NC
1193
1194 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1195
1196 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1197
1198 /* The code produced here is, for say the EQ case:
1199
1200 Bne 1f
1201 LDI <label>, r0
1202 JMP r0
1203 1: */
1204
1205 sprintf (buffer,
1206 \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1207 ldi_insn, tmp_reg, tmp_reg);
1208
1209 return buffer;
1210 }
1211 }"
1212 [(set (attr "length") (if_then_else
1213 (ltu
1214 (plus
1215 (minus
1216 (match_dup 1)
1217 (pc))
1218 (const_int 254))
1219 (const_int 506))
1220 (const_int 2)
1221 (if_then_else (eq_attr "size" "small")
1222 (const_int 8)
1223 (const_int 10))))
1224 (set_attr "delay_type" "delayed")]
1225)
1226
1227
1228;; This pattern is a duplicate of the previous one, except that the
1229;; branch occurs if the test is false, so the %B operator is used.
1230(define_insn "*branch_false"
1231 [(set (pc)
1232 (if_then_else (match_operator:CC 0 "comparison_operator"
1233 [(reg:CC 16)
1234 (const_int 0)])
1235 (pc)
1236 (label_ref (match_operand 1 "" ""))))]
1237 ""
1238 "*
1239 {
1240 if (get_attr_length (insn) == 2)
1241 return \"b%B0%#\\t%l1 \";
1242 else
1243 {
82a9bba5
NC
1244 static char buffer [100];
1245 const char * tmp_reg;
1943c2c1 1246 const char * ldi_insn;
309dd885
NC
1247
1248 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1249
1250 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1251
1252 sprintf (buffer,
1253 \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1254 ldi_insn, tmp_reg, tmp_reg);
1255
1256 return buffer;
1257 }
1258 }"
1259 [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1260 (const_int 254))
1261 (const_int 506))
1262 (const_int 2)
1263 (if_then_else (eq_attr "size" "small")
1264 (const_int 8)
1265 (const_int 10))))
1266 (set_attr "delay_type" "delayed")]
1267)
1268
1269;;}}} \f
1270;;{{{ Calls & Jumps
1271
1272;; Subroutine call instruction returning no value. Operand 0 is the function
1273;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1274;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1275;; registers used as operands.
1276
1277(define_insn "call"
6e11d5e9 1278 [(call (match_operand 0 "call_operand" "Qm")
309dd885
NC
1279 (match_operand 1 "" "g"))
1280 (clobber (reg:SI 17))]
1281 ""
1282 "call%#\\t%0"
1283 [(set_attr "delay_type" "delayed")]
1284)
1285
1286;; Subroutine call instruction returning a value. Operand 0 is the hard
1287;; register in which the value is returned. There are three more operands, the
1288;; same as the three operands of the `call' instruction (but with numbers
1289;; increased by one).
1290
1291;; Subroutines that return `BLKmode' objects use the `call' insn.
1292
1293(define_insn "call_value"
1294 [(set (match_operand 0 "register_operand" "=r")
6e11d5e9 1295 (call (match_operand 1 "call_operand" "Qm")
309dd885
NC
1296 (match_operand 2 "" "g")))
1297 (clobber (reg:SI 17))]
1298 ""
1299 "call%#\\t%1"
1300 [(set_attr "delay_type" "delayed")]
1301)
1302
1303;; Normal unconditional jump.
1304;; For a description of the computation of the length
1305;; attribute see the branch patterns above.
a29b099d
JJ
1306;;
1307;; Although this instruction really clobbers r0, flow
1308;; relies on jump being simplejump_p in several places
1309;; and as r0 is fixed, this doesn't change anything
309dd885 1310(define_insn "jump"
a29b099d 1311 [(set (pc) (label_ref (match_operand 0 "" "")))]
309dd885
NC
1312 ""
1313 "*
1314 {
1315 if (get_attr_length (insn) == 2)
1316 return \"bra%#\\t%0\";
1317 else
1318 {
82a9bba5
NC
1319 static char buffer [100];
1320 const char * tmp_reg;
1943c2c1 1321 const char * ldi_insn;
309dd885
NC
1322
1323 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1324
1325 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1326
1327 sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1328 ldi_insn, tmp_reg, tmp_reg);
1329
1330 return buffer;
1331 }
1332 }"
1333 [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1334 (const_int 254))
1335 (const_int 506))
1336 (const_int 2)
1337 (if_then_else (eq_attr "size" "small")
1338 (const_int 6)
1339 (const_int 8))))
1340 (set_attr "delay_type" "delayed")]
1341)
1342
1343;; Indirect jump through a register
1344(define_insn "indirect_jump"
1345 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1346 "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1347 "jmp%#\\t@%0"
1348 [(set_attr "delay_type" "delayed")]
1349)
1350
1351(define_insn "tablejump"
1352 [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1353 (use (label_ref (match_operand 1 "" "")))]
1354 ""
1355 "jmp%#\\t@%0"
1356 [(set_attr "delay_type" "delayed")]
1357)
1358
1359;;}}} \f
1360;;{{{ Function Prologues and Epilogues
1361
1362;; Called after register allocation to add any instructions needed for the
1363;; prologue. Using a prologue insn is favored compared to putting all of the
08c148a8 1364;; instructions in output_function_prologue(), since it allows the scheduler
309dd885
NC
1365;; to intermix instructions with the saves of the caller saved registers. In
1366;; some cases, it might be necessary to emit a barrier instruction as the last
1367;; insn to prevent such scheduling.
1368(define_expand "prologue"
82a9bba5 1369 [(clobber (const_int 0))]
309dd885
NC
1370 ""
1371 "{
1372 fr30_expand_prologue ();
1373 DONE;
1374 }"
1375)
1376
1377;; Called after register allocation to add any instructions needed for the
5519a4f9 1378;; epilogue. Using an epilogue insn is favored compared to putting all of the
08c148a8 1379;; instructions in output_function_epilogue(), since it allows the scheduler
309dd885
NC
1380;; to intermix instructions with the restores of the caller saved registers.
1381;; In some cases, it might be necessary to emit a barrier instruction as the
1382;; first insn to prevent such scheduling.
1383(define_expand "epilogue"
1384 [(return)]
1385 ""
1386 "{
1387 fr30_expand_epilogue ();
1388 DONE;
1389 }"
1390)
1391
1392(define_insn "return_from_func"
1393 [(return)
1394 (use (reg:SI 17))]
1395 "reload_completed"
1396 "ret%#"
1397 [(set_attr "delay_type" "delayed")]
1398)
1399
1400(define_insn "leave_func"
1401 [(set (reg:SI 15) (reg:SI 14))
1402 (set (reg:SI 14) (mem:SI (post_inc:SI (reg:SI 15))))]
1403 "reload_completed"
1404 "leave"
1405)
1406
1407(define_insn "enter_func"
1408 [(set:SI (mem:SI (minus:SI (reg:SI 15)
1409 (const_int 4)))
1410 (reg:SI 14))
1411 (set:SI (reg:SI 14)
1412 (minus:SI (reg:SI 15)
1413 (const_int 4)))
1414 (set:SI (reg:SI 15)
1415 (minus:SI (reg:SI 15)
1416 (match_operand 0 "immediate_operand" "i")))]
1417 "reload_completed"
1418 "enter #%0"
1419 [(set_attr "delay_type" "other")]
1420)
1421
1422;;}}} \f
1423;;{{{ Miscellaneous
1424
1425;; No operation, needed in case the user uses -g but not -O.
1426(define_insn "nop"
1427 [(const_int 0)]
1428 ""
1429 "nop"
1430)
1431
1432;; Pseudo instruction that prevents the scheduler from moving code above this
1433;; point.
1434(define_insn "blockage"
1435 [(unspec_volatile [(const_int 0)] 0)]
1436 ""
1437 ""
1438 [(set_attr "length" "0")]
1439)
5c7666c1 1440;;}}} \f
309dd885
NC
1441
1442;; Local Variables:
1443;; mode: md
1444;; folded-file: t
1445;; End:
This page took 1.764965 seconds and 5 git commands to generate.