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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [fr30/] [fr30.md] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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