OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [fr30/] [fr30.md] - Blame information for rev 282

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; FR30 machine description.
2
;; Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2007
3
;; Free Software Foundation, Inc.
4
;; Contributed by Cygnus Solutions.
5
 
6
;; This file is part of GCC.
7
 
8
;; GCC is free software; you can redistribute it and/or modify
9
;; it under the terms of the GNU General Public License as published by
10
;; the Free Software Foundation; either version 3, or (at your option)
11
;; any later version.
12
 
13
;; GCC is distributed in the hope that it will be useful,
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
19
;; along with GCC; see the file COPYING3.  If not see
20
;; .
21
 
22
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23
 
24
;;{{{ Attributes
25
 
26
(define_attr "length" "" (const_int 2))
27
 
28
;; Used to distinguish between small memory model targets and big mode targets.
29
 
30
(define_attr "size" "small,big"
31
  (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL")
32
                       (const_string "small")
33
                       (const_string "big"))))
34
 
35
 
36
;; Define an attribute to be used by the delay slot code.
37
;; An instruction by default is considered to be 'delayable'
38
;; that is, it can be placed into a delay slot, but it is not
39
;; itself a delayed branch type instruction.  An instruction
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
42
;; not have a delay slot, nor can it be placed into a delay slot.
43
 
44
(define_attr "delay_type" "delayable,delayed,other" (const_string "delayable"))
45
 
46
;;}}} 
47
;;{{{ Delay Slot Specifications
48
 
49
(define_delay (eq_attr "delay_type" "delayed")
50
  [(and (eq_attr "delay_type" "delayable")
51
        (eq_attr "length" "2"))
52
   (nil)
53
   (nil)]
54
)
55
 
56
(include "predicates.md")
57
 
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"
151
  [(set:SI (match_operand:SI 0 "register_operand" "=a")
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
290
  [(set (match_operand:SI 0 "register_operand"  "")
291
        (match_operand:SI 1 "const_int_operand" ""))]
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))))"
295
   [(set:SI (match_dup 0) (match_dup 1))
296
    (set:SI (match_dup 0) (sign_extend:SI (match_dup 2)))]
297
   "{
298
   operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
299
   operands[2] = gen_lowpart (QImode, operands[0]);
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
307
  [(set (match_operand:SI 0 "register_operand"  "")
308
        (match_operand:SI 1 "const_int_operand" ""))]
309
   "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)"
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
320
;; in the top byte set, but whose set bits all lie within an 8 bit
321
;; range, then we can save time and space by loading the byte value
322
;; and shifting it into place.
323
(define_split
324
  [(set (match_operand:SI 0 "register_operand"  "")
325
        (match_operand:SI 1 "const_int_operand" ""))]
326
   "(INTVAL (operands[1]) > 0x00ffffff)
327
   && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)"
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"
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"))]
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\";
360
    case 7: return   \"st    \\t%1, %0\";
361
    default: gcc_unreachable ();
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
 
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
378
;; (e.g. muldisi2) can produce a DImode result.
379
;; (This code is stolen from the M32R port.)
380
 
381
(define_expand "movdi"
382
  [(set (match_operand:DI 0 "nonimmediate_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
 
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")
398
        (match_operand:DI 1 "di_operand"               "r,m,r,nF"))]
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" "")
406
        (match_operand:DI 1 "di_operand" ""))]
407
  "reload_completed"
408
  [(match_dup 2)]
409
  "operands[2] = fr30_move_double (operands);"
410
)
411
 
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
531
;; patterns for DF are optional, as GCC can synthesize them.
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\";
561
    default: gcc_unreachable ();
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"
573
  [(set (match_operand:SF 0 "memory_operand"    "=m")
574
        (match_operand:SF 1 "immediate_operand" "F"))]
575
  ""
576
  "*
577
  {
578
  const char *    ldi_instr;
579
  const char *    tmp_reg;
580
  static char     buffer[100];
581
 
582
  ldi_instr = fr30_const_double_is_zero (operands[1])
583
            ? ldi_instr = \"ldi:8\" : \"ldi:32\";
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
;;}}} 
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
;;}}} 
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
647
;; large (i.e. outside +/- 16) constants.  We need to be able to
648
;; handle this because reload assumes that it can generate add
649
;; instructions with arbitrary sized constants.
650
(define_expand "addsi3"
651
  [(set (match_operand:SI 0 "register_operand"           "")
652
        (plus:SI (match_operand:SI 1 "register_operand"  "")
653
                 (match_operand:SI 2 "nonmemory_operand" "")))]
654
  ""
655
  "{
656
  if (   GET_CODE (operands[2]) == REG
657
      || GET_CODE (operands[2]) == SUBREG)
658
    emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2]));
659
  else if (GET_CODE (operands[2]) != CONST_INT)
660
    emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
661
  else if (INTVAL (operands[2]) >= -16
662
           && INTVAL (operands[2]) <= 15
663
           && (!REG_P (operands[1])
664
               || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
665
               || REGNO (operands[1]) == STACK_POINTER_REGNUM))
666
    emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2]));
667
  else
668
    emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2]));
669
  DONE;
670
  }"
671
)
672
 
673
(define_insn "addsi_regs"
674
  [(set (match_operand:SI 0 "register_operand"          "=r")
675
        (plus:SI (match_operand:SI 1 "register_operand" "%0")
676
                 (match_operand:SI 2 "register_operand"  "r")))]
677
  ""
678
  "addn %2, %0"
679
)
680
 
681
;; Do not allow an eliminable register in the source register.  It
682
;; might be eliminated in favor of the stack pointer, probably
683
;; increasing the offset, and so rendering the instruction illegal.
684
(define_insn "addsi_small_int"
685
  [(set (match_operand:SI 0 "register_operand"              "=r,r")
686
        (plus:SI (match_operand:SI 1 "register_operand"      "0,0")
687
                 (match_operand:SI 2 "add_immediate_operand" "I,J")))]
688
  "!REG_P (operands[1])
689
   || !REGNO_PTR_FRAME_P (REGNO (operands[1]))
690
   || REGNO (operands[1]) == STACK_POINTER_REGNUM"
691
  "@
692
   addn %2, %0
693
   addn2        %2, %0"
694
)
695
 
696
(define_expand "addsi_big_int"
697
  [(set (match_operand:SI 0 "register_operand"           "")
698
        (plus:SI (match_operand:SI 1 "register_operand"  "")
699
                 (match_operand:SI 2 "immediate_operand" "")))]
700
  ""
701
  "{
702
  /* Cope with the possibility that ops 0 and 1 are the same register.  */
703
  if (rtx_equal_p (operands[0], operands[1]))
704
    {
705
      if (reload_in_progress || reload_completed)
706
        {
707
          rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
708
 
709
          emit_insn (gen_movsi (reg, operands[2]));
710
          emit_insn (gen_addsi_regs (operands[0], operands[0], reg));
711
        }
712
      else
713
        {
714
          operands[2] = force_reg (SImode, operands[2]);
715
          emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2]));
716
        }
717
    }
718
  else
719
    {
720
      emit_insn (gen_movsi (operands[0], operands[2]));
721
      emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1]));
722
    }
723
  DONE;
724
  }"
725
)
726
 
727
(define_insn "*addsi_for_reload"
728
  [(set (match_operand:SI 0 "register_operand"         "=&r,r,r")
729
        (plus:SI (match_operand:SI 1 "register_operand"  "r,r,r")
730
                 (match_operand:SI 2 "immediate_operand" "L,M,n")))]
731
  "reload_in_progress || reload_completed"
732
  "@
733
  ldi:8\\t#%2, %0  \\n\\taddn\\t%1, %0
734
  ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0
735
  ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0"
736
  [(set_attr "length" "4,6,8")]
737
)
738
 
739
;;}}}
740
;;{{{ Subtraction
741
 
742
(define_insn "subsi3"
743
  [(set (match_operand:SI 0 "register_operand"       "=r")
744
        (minus:SI (match_operand:SI 1 "register_operand" "0")
745
                  (match_operand:SI 2 "register_operand" "r")))]
746
  ""
747
  "subn %2, %0"
748
)
749
 
750
;;}}}
751
;;{{{ Multiplication
752
 
753
;; Signed multiplication producing 64-bit results from 32-bit inputs
754
(define_insn "mulsidi3"
755
  [(set (match_operand:DI 0 "register_operand"                             "=r")
756
           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
757
                    (sign_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
758
   (clobber (reg:CC 16))]
759
  ""
760
  "mul  %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
761
  [(set_attr "length" "6")]
762
)
763
 
764
;; Unsigned multiplication producing 64-bit results from 32-bit inputs
765
(define_insn "umulsidi3"
766
  [(set (match_operand:DI 0 "register_operand"                             "=r")
767
           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
768
                    (zero_extend:DI (match_operand:SI 2 "register_operand"  "r"))))
769
   (clobber (reg:CC 16))]
770
  ""
771
  "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0"
772
  [(set_attr "length" "6")]
773
)
774
 
775
;; Signed multiplication producing 32-bit result from 16-bit inputs
776
(define_insn "mulhisi3"
777
  [(set (match_operand:SI 0 "register_operand"                             "=r")
778
           (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
779
                    (sign_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
780
   (clobber (reg:CC 16))]
781
  ""
782
  "mulh %2, %1\\n\\tmov\\tmdl, %0"
783
  [(set_attr "length" "4")]
784
)
785
 
786
;; Unsigned multiplication producing 32-bit result from 16-bit inputs
787
(define_insn "umulhisi3"
788
  [(set (match_operand:SI 0 "register_operand"                             "=r")
789
           (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r"))
790
                    (zero_extend:SI (match_operand:HI 2 "register_operand"  "r"))))
791
   (clobber (reg:CC 16))]
792
  ""
793
  "muluh        %2, %1\\n\\tmov\\tmdl, %0"
794
  [(set_attr "length" "4")]
795
)
796
 
797
;; Signed multiplication producing 32-bit result from 32-bit inputs
798
(define_insn "mulsi3"
799
  [(set (match_operand:SI 0 "register_operand"             "=r")
800
           (mult:SI (match_operand:SI 1 "register_operand" "%r")
801
                    (match_operand:SI 2 "register_operand"  "r")))
802
   (clobber (reg:CC 16))]
803
  ""
804
  "mul  %2, %1\\n\\tmov\\tmdl, %0"
805
  [(set_attr "length" "4")]
806
)
807
 
808
;;}}}
809
;;}}} 
810
;;{{{ Shifts
811
 
812
;; Arithmetic Shift Left
813
(define_insn "ashlsi3"
814
  [(set (match_operand:SI 0 "register_operand"            "=r,r,r")
815
        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,0")
816
                   (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
817
   (clobber (reg:CC 16))]
818
  ""
819
  "@
820
  lsl   %2, %0
821
  lsl   %2, %0
822
  lsl2  %x2, %0"
823
)
824
 
825
;; Arithmetic Shift Right
826
(define_insn "ashrsi3"
827
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
828
        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
829
                     (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
830
   (clobber (reg:CC 16))]
831
  ""
832
  "@
833
  asr   %2, %0
834
  asr   %2, %0
835
  asr2  %x2, %0"
836
)
837
 
838
;; Logical Shift Right
839
(define_insn "lshrsi3"
840
  [(set (match_operand:SI 0 "register_operand"              "=r,r,r")
841
        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,0")
842
                     (match_operand:SI 2 "nonmemory_operand" "r,I,K")))
843
   (clobber (reg:CC 16))]
844
  ""
845
  "@
846
  lsr   %2, %0
847
  lsr   %2, %0
848
  lsr2  %x2, %0"
849
)
850
 
851
;;}}} 
852
;;{{{ Logical Operations
853
 
854
;; Logical AND, 32-bit integers
855
(define_insn "andsi3"
856
  [(set (match_operand:SI 0 "register_operand"         "=r")
857
        (and:SI (match_operand:SI 1 "register_operand" "%r")
858
                (match_operand:SI 2 "register_operand"  "0")))
859
   (clobber (reg:CC 16))]
860
  ""
861
  "and  %1, %0"
862
)
863
 
864
;; Inclusive OR, 32-bit integers
865
(define_insn "iorsi3"
866
  [(set (match_operand:SI 0 "register_operand"         "=r")
867
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
868
                (match_operand:SI 2 "register_operand"  "0")))
869
   (clobber (reg:CC 16))]
870
  ""
871
  "or   %1, %0"
872
)
873
 
874
;; Exclusive OR, 32-bit integers
875
(define_insn "xorsi3"
876
  [(set (match_operand:SI 0 "register_operand"         "=r")
877
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
878
                (match_operand:SI 2 "register_operand"  "0")))
879
   (clobber (reg:CC 16))]
880
  ""
881
  "eor  %1, %0"
882
)
883
 
884
;; One's complement, 32-bit integers
885
(define_expand "one_cmplsi2"
886
  [(set (match_operand:SI 0 "register_operand"         "")
887
        (not:SI (match_operand:SI 1 "register_operand" "")))]
888
  ""
889
  "{
890
  if (rtx_equal_p (operands[0], operands[1]))
891
    {
892
      if (reload_in_progress || reload_completed)
893
        {
894
          rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/);
895
 
896
          emit_insn (gen_movsi (reg, constm1_rtx));
897
          emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
898
        }
899
      else
900
        {
901
          rtx reg = gen_reg_rtx (SImode);
902
 
903
          emit_insn (gen_movsi (reg, constm1_rtx));
904
          emit_insn (gen_xorsi3 (operands[0], operands[0], reg));
905
        }
906
    }
907
  else
908
    {
909
      emit_insn (gen_movsi_internal (operands[0], constm1_rtx));
910
      emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0]));
911
    }
912
  DONE;
913
  }"
914
)
915
 
916
;;}}} 
917
;;{{{ Comparisons
918
 
919
;; The actual comparisons, generated by the cbranch and/or cstore expanders
920
 
921
(define_insn "*cmpsi_internal"
922
  [(set (reg:CC 16)
923
        (compare:CC (match_operand:SI 0 "register_operand"  "r,r,r")
924
                    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
925
  ""
926
  "@
927
  cmp   %1, %0
928
  cmp   %1, %0
929
  cmp2  %1, %0"
930
)
931
 
932
;;}}} 
933
;;{{{ Branches
934
 
935
;; Define_expands called by the machine independent part of the compiler
936
;; to allocate a new comparison register
937
 
938
(define_expand "cbranchsi4"
939
  [(set (reg:CC 16)
940
        (compare:CC (match_operand:SI 1 "register_operand"  "")
941
                    (match_operand:SI 2 "nonmemory_operand" "")))
942
   (set (pc)
943
        (if_then_else (match_operator:CC 0 "ordered_comparison_operator"
944
                       [(reg:CC 16) (const_int 0)])
945
                      (label_ref (match_operand 3 "" ""))
946
                      (pc)))]
947
  ""
948
  ""
949
)
950
 
951
 
952
;; Actual branches.  We must allow for the (label_ref) and the (pc) to be
953
;; swapped.  If they are swapped, it reverses the sense of the branch.
954
 
955
;; This pattern matches the (branch-if-true) branches generated above.
956
;; It generates two different instruction sequences depending upon how
957
;; far away the destination is.
958
 
959
;; The calculation for the instruction length is derived as follows:
960
;; The branch instruction has a 9-bit signed displacement so we have
961
;; this inequality for the displacement:
962
;;
963
;;               -256 <= pc < 256
964
;; or
965
;;         -256 + 256 <= pc + 256 < 256 + 256
966
;; i.e.
967
;;                  0 <= pc + 256 < 512
968
;;
969
;; if we consider the displacement as an unsigned value, then negative
970
;; displacements become very large positive displacements, and the
971
;; inequality becomes:
972
;;
973
;;              pc + 256 < 512
974
;;
975
;; In order to allow for the fact that the real branch instruction works
976
;; from pc + 2, we increase the offset to 258.
977
;;
978
;; Note - we do not have to worry about whether the branch is delayed or
979
;; not, as branch shortening happens after delay slot reorganization.
980
 
981
(define_insn "*branch_true"
982
  [(set (pc)
983
        (if_then_else (match_operator:CC 0 "comparison_operator"
984
                                         [(reg:CC 16)
985
                                          (const_int 0)])
986
                      (label_ref (match_operand 1 "" ""))
987
                      (pc)))]
988
  ""
989
  "*
990
  {
991
    if (get_attr_length (insn) == 2)
992
      return \"b%b0%#\\t%l1\";
993
    else
994
      {
995
        static char   buffer [100];
996
        const char *  tmp_reg;
997
        const char *  ldi_insn;
998
 
999
        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1000
 
1001
        ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1002
 
1003
        /* The code produced here is, for say the EQ case:
1004
 
1005
               Bne  1f
1006
               LDI  
1007
               JMP  r0
1008
             1:                                         */
1009
 
1010
        sprintf (buffer,
1011
          \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1012
          ldi_insn, tmp_reg, tmp_reg);
1013
 
1014
        return buffer;
1015
    }
1016
  }"
1017
  [(set (attr "length") (if_then_else
1018
                          (ltu
1019
                            (plus
1020
                              (minus
1021
                                (match_dup 1)
1022
                                (pc))
1023
                              (const_int 254))
1024
                            (const_int 506))
1025
                          (const_int 2)
1026
                          (if_then_else (eq_attr "size" "small")
1027
                                        (const_int 8)
1028
                                        (const_int 10))))
1029
   (set_attr "delay_type" "delayed")]
1030
)
1031
 
1032
 
1033
;; This pattern is a duplicate of the previous one, except that the
1034
;; branch occurs if the test is false, so the %B operator is used.
1035
(define_insn "*branch_false"
1036
  [(set (pc)
1037
        (if_then_else (match_operator:CC 0 "comparison_operator"
1038
                                         [(reg:CC 16)
1039
                                          (const_int 0)])
1040
                      (pc)
1041
                      (label_ref (match_operand 1 "" ""))))]
1042
  ""
1043
  "*
1044
  {
1045
    if (get_attr_length (insn) == 2)
1046
      return \"b%B0%#\\t%l1 \";
1047
    else
1048
      {
1049
        static char   buffer [100];
1050
        const char *  tmp_reg;
1051
        const char *  ldi_insn;
1052
 
1053
        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1054
 
1055
        ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1056
 
1057
        sprintf (buffer,
1058
          \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\",
1059
          ldi_insn, tmp_reg, tmp_reg);
1060
 
1061
        return buffer;
1062
      }
1063
  }"
1064
  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc))
1065
                                                 (const_int 254))
1066
                                           (const_int 506))
1067
                                      (const_int 2)
1068
                                      (if_then_else (eq_attr "size" "small")
1069
                                                    (const_int 8)
1070
                                                    (const_int 10))))
1071
   (set_attr "delay_type" "delayed")]
1072
)
1073
 
1074
;;}}} 
1075
;;{{{ Calls & Jumps
1076
 
1077
;; Subroutine call instruction returning no value.  Operand 0 is the function
1078
;; to call; operand 1 is the number of bytes of arguments pushed (in mode
1079
;; `SImode', except it is normally a `const_int'); operand 2 is the number of
1080
;; registers used as operands.
1081
 
1082
(define_insn "call"
1083
  [(call (match_operand 0 "call_operand" "Qm")
1084
         (match_operand 1 ""             "g"))
1085
   (clobber (reg:SI 17))]
1086
  ""
1087
  "call%#\\t%0"
1088
  [(set_attr "delay_type" "delayed")]
1089
)
1090
 
1091
;; Subroutine call instruction returning a value.  Operand 0 is the hard
1092
;; register in which the value is returned.  There are three more operands, the
1093
;; same as the three operands of the `call' instruction (but with numbers
1094
;; increased by one).
1095
 
1096
;; Subroutines that return `BLKmode' objects use the `call' insn.
1097
 
1098
(define_insn "call_value"
1099
  [(set (match_operand 0 "register_operand"  "=r")
1100
        (call (match_operand 1 "call_operand" "Qm")
1101
              (match_operand 2 ""             "g")))
1102
   (clobber (reg:SI 17))]
1103
  ""
1104
  "call%#\\t%1"
1105
  [(set_attr "delay_type" "delayed")]
1106
)
1107
 
1108
;; Normal unconditional jump.
1109
;; For a description of the computation of the length
1110
;; attribute see the branch patterns above.
1111
;;
1112
;; Although this instruction really clobbers r0, flow
1113
;; relies on jump being simplejump_p in several places
1114
;; and as r0 is fixed, this doesn't change anything
1115
(define_insn "jump"
1116
  [(set (pc) (label_ref (match_operand 0 "" "")))]
1117
  ""
1118
  "*
1119
  {
1120
    if (get_attr_length (insn) == 2)
1121
       return \"bra%#\\t%0\";
1122
    else
1123
      {
1124
        static char   buffer [100];
1125
        const char *  tmp_reg;
1126
        const char *  ldi_insn;
1127
 
1128
        tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER];
1129
 
1130
        ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\";
1131
 
1132
        sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\",
1133
          ldi_insn, tmp_reg, tmp_reg);
1134
 
1135
        return buffer;
1136
      }
1137
  }"
1138
  [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc))
1139
                                                (const_int 254))
1140
                                          (const_int 506))
1141
                                     (const_int 2)
1142
                                     (if_then_else (eq_attr "size" "small")
1143
                                                   (const_int 6)
1144
                                                   (const_int 8))))
1145
   (set_attr "delay_type" "delayed")]
1146
)
1147
 
1148
;; Indirect jump through a register
1149
(define_insn "indirect_jump"
1150
  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
1151
  "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
1152
  "jmp%#\\t@%0"
1153
  [(set_attr "delay_type" "delayed")]
1154
)
1155
 
1156
(define_insn "tablejump"
1157
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1158
   (use (label_ref (match_operand 1 "" "")))]
1159
  ""
1160
  "jmp%#\\t@%0"
1161
  [(set_attr "delay_type" "delayed")]
1162
)
1163
 
1164
;;}}} 
1165
;;{{{ Function Prologues and Epilogues
1166
 
1167
;; Called after register allocation to add any instructions needed for the
1168
;; prologue.  Using a prologue insn is favored compared to putting all of the
1169
;; instructions in output_function_prologue(), since it allows the scheduler
1170
;; to intermix instructions with the saves of the caller saved registers.  In
1171
;; some cases, it might be necessary to emit a barrier instruction as the last
1172
;; insn to prevent such scheduling.
1173
(define_expand "prologue"
1174
  [(clobber (const_int 0))]
1175
  ""
1176
  "{
1177
  fr30_expand_prologue ();
1178
  DONE;
1179
  }"
1180
)
1181
 
1182
;; Called after register allocation to add any instructions needed for the
1183
;; epilogue.  Using an epilogue insn is favored compared to putting all of the
1184
;; instructions in output_function_epilogue(), since it allows the scheduler
1185
;; to intermix instructions with the restores of the caller saved registers.
1186
;; In some cases, it might be necessary to emit a barrier instruction as the
1187
;; first insn to prevent such scheduling.
1188
(define_expand "epilogue"
1189
  [(return)]
1190
  ""
1191
  "{
1192
  fr30_expand_epilogue ();
1193
  DONE;
1194
  }"
1195
)
1196
 
1197
(define_insn "return_from_func"
1198
  [(return)
1199
   (use (reg:SI 17))]
1200
  "reload_completed"
1201
  "ret%#"
1202
  [(set_attr "delay_type" "delayed")]
1203
)
1204
 
1205
(define_insn "leave_func"
1206
  [(set (reg:SI 15) (reg:SI 14))
1207
   (set (reg:SI 14) (mem:SI (post_inc:SI (reg:SI 15))))]
1208
  "reload_completed"
1209
  "leave"
1210
)
1211
 
1212
(define_expand "enter_func"
1213
  [(parallel
1214
  [(set:SI (mem:SI (minus:SI (match_dup 1)
1215
                             (const_int 4)))
1216
           (match_dup 2))
1217
   (set:SI (match_dup 2)
1218
           (minus:SI (match_dup 1)
1219
                     (const_int 4)))
1220
   (set:SI (match_dup 1)
1221
           (minus:SI (match_dup 1)
1222
                     (match_operand:SI 0 "immediate_operand")))]
1223
  )]
1224
  ""
1225
{
1226
  operands[1] = stack_pointer_rtx;
1227
  operands[2] = hard_frame_pointer_rtx;
1228
})
1229
 
1230
(define_insn "*enter_func"
1231
  [(set:SI (mem:SI (minus:SI (reg:SI 15)
1232
                             (const_int 4)))
1233
           (reg:SI 14))
1234
   (set:SI (reg:SI 14)
1235
           (minus:SI (reg:SI 15)
1236
                     (const_int 4)))
1237
   (set:SI (reg:SI 15)
1238
           (minus:SI (reg:SI 15)
1239
                     (match_operand 0 "immediate_operand" "i")))]
1240
  "reload_completed"
1241
  "enter        #%0"
1242
  [(set_attr "delay_type" "other")]
1243
)
1244
 
1245
;;}}} 
1246
;;{{{ Miscellaneous
1247
 
1248
;; No operation, needed in case the user uses -g but not -O.
1249
(define_insn "nop"
1250
  [(const_int 0)]
1251
  ""
1252
  "nop"
1253
)
1254
 
1255
;; Pseudo instruction that prevents the scheduler from moving code above this
1256
;; point.
1257
(define_insn "blockage"
1258
  [(unspec_volatile [(const_int 0)] 0)]
1259
  ""
1260
  ""
1261
  [(set_attr "length" "0")]
1262
)
1263
;;}}} 
1264
 
1265
;; Local Variables:
1266
;; mode: md
1267
;; folded-file: t
1268
;; End:

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.