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

Subversion Repositories openrisc

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
;; Machine description for MorphoRISC1
2
;; Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3
;; Contributed by Red Hat, Inc.
4
 
5
;; This file is part of GCC.
6
 
7
;; GCC is free software; you can redistribute it and/or modify
8
;; it under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
 
12
;; GCC is distributed in the hope that it will be useful,
13
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
;; GNU General Public License for more details.
16
 
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
;; UNSPECs
22
(define_constants
23
  [
24
    (UNSPEC_BLOCKAGE 0)
25
    (UNSPEC_EI 1)
26
    (UNSPEC_DI 2)
27
    (UNSPEC_LOOP 3)
28
  ])
29
 
30
;; Attributes
31
(define_attr "type" "branch,call,load,store,io,arith,complex,unknown"
32
         (const_string "unknown") )
33
 
34
;; If the attribute takes numeric values, no `enum' type will be defined and
35
;; the function to obtain the attribute's value will return `int'.
36
 
37
(define_attr "length" "" (const_int 4))
38
 
39
 
40
;; DFA scheduler.
41
(define_automaton "other")
42
(define_cpu_unit "decode_unit" "other")
43
(define_cpu_unit "memory_unit" "other")
44
(define_cpu_unit "branch_unit" "other")
45
 
46
(define_insn_reservation "mem_access" 2
47
  (ior (eq_attr "type" "load") (eq_attr "type" "store"))
48
  "decode_unit+memory_unit*2")
49
 
50
(define_insn_reservation "io_access" 2
51
  (eq_attr "type" "io")
52
  "decode_unit+memory_unit*2")
53
 
54
(define_insn_reservation "branch_access" 2
55
  (ior (eq_attr "type" "branch")
56
       (eq_attr "type" "call"))
57
  "decode_unit+branch_unit*2")
58
 
59
(define_insn_reservation "arith_access" 1
60
  (eq_attr "type" "arith")
61
  "decode_unit")
62
 
63
(define_bypass 2 "arith_access" "branch_access")
64
(define_bypass 3 "mem_access" "branch_access")
65
(define_bypass 3 "io_access" "branch_access")
66
 
67
 
68
;; Delay Slots
69
 
70
;; The mt does not allow branches in the delay slot.
71
;; The mt does not allow back to back memory or io instruction.
72
;; The compiler does not know what the type of instruction is at
73
;; the destination of the branch.  Thus, only type that will be acceptable
74
;; (safe) is the arith type.
75
 
76
(define_delay (ior (eq_attr "type" "branch")
77
                   (eq_attr "type" "call"))
78
                 [(eq_attr "type" "arith") (nil) (nil)])
79
 
80
 
81
(define_insn "decrement_and_branch_until_zero"
82
   [(set (pc)
83
         (if_then_else
84
          (ne (match_operand:SI 0 "nonimmediate_operand" "+r,*m")
85
              (const_int 0))
86
          (label_ref (match_operand 1 "" ""))
87
          (pc)))
88
    (set (match_dup 0)
89
         (plus:SI (match_dup 0)
90
                  (const_int -1)))
91
    (clobber (match_scratch:SI 2 "=X,&r"))
92
    (clobber (match_scratch:SI 3 "=X,&r"))]
93
  "TARGET_MS1_16_003 || TARGET_MS2"
94
  "@
95
   dbnz\t%0, %l1%#
96
   #"
97
  [(set_attr "length" "4,16")
98
   (set_attr "type" "branch,unknown")]
99
)
100
 
101
;; Split the above to handle the case where operand 0 is in memory
102
;; (a register that couldn't get a hard register).
103
(define_split
104
  [(set (pc)
105
        (if_then_else
106
          (ne (match_operand:SI 0 "memory_operand" "")
107
              (const_int 0))
108
          (label_ref (match_operand 1 "" ""))
109
          (pc)))
110
    (set (match_dup 0)
111
         (plus:SI (match_dup 0)
112
                  (const_int -1)))
113
    (clobber (match_scratch:SI 2 ""))
114
    (clobber (match_scratch:SI 3 ""))]
115
  "TARGET_MS1_16_003 || TARGET_MS2"
116
  [(set (match_dup 2) (match_dup 0))
117
   (set (match_dup 3) (plus:SI (match_dup 2) (const_int -1)))
118
   (set (match_dup 0) (match_dup 3))
119
   (set (pc)
120
        (if_then_else
121
         (ne (match_dup 2)
122
             (const_int 0))
123
         (label_ref (match_dup 1))
124
         (pc)))]
125
  "")
126
 
127
;; This peephole is defined in the vain hope that it might actually trigger one
128
;; day, although I have yet to find a test case that matches it.  The normal
129
;; problem is that GCC likes to move the loading of the constant value -1 out
130
;; of the loop, so it is not here to be matched.
131
 
132
(define_peephole2
133
  [(set (match_operand:SI 0 "register_operand" "")
134
        (plus:SI (match_dup 0) (const_int -1)))
135
   (set (match_operand:SI 1 "register_operand" "")
136
     (const_int -1))
137
   (set (pc) (if_then_else
138
                (ne (match_dup 0) (match_dup 1))
139
                (label_ref (match_operand 2 "" ""))
140
                (pc)))]
141
  "TARGET_MS1_16_003 || TARGET_MS2"
142
  [(parallel [(set (pc)
143
                   (if_then_else
144
                      (ne (match_dup 0) (const_int 0))
145
                      (label_ref (match_dup 2))
146
                      (pc)))
147
              (set (match_dup 0)
148
                   (plus:SI (match_dup 0) (const_int -1)))
149
              (clobber (reg:SI 0))
150
              (clobber (reg:SI 0))])]
151
  "")
152
 
153
 
154
;; Loop instructions.  ms2 has a low overhead looping instructions.
155
;; these take a constant or register loop count and a loop length
156
;; offset.  Unfortunately the loop can only be up to 256 instructions,
157
;; We deal with longer loops by moving the loop end upwards.  To do
158
;; otherwise would force us to to be very pessimistic right up until
159
;; the end.
160
 
161
;; This instruction is a placeholder to make the control flow explicit.
162
(define_insn "loop_end"
163
  [(set (pc) (if_then_else
164
                          (ne (match_operand:SI 0 "register_operand" "")
165
                              (const_int 1))
166
                          (label_ref (match_operand 1 "" ""))
167
                          (pc)))
168
   (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
169
   (unspec [(const_int 0)] UNSPEC_LOOP)]
170
  "TARGET_MS2"
171
  ";loop end %0,%l1"
172
  [(set_attr "length" "0")])
173
 
174
;; This is the real looping instruction.  It is placed just before the
175
;; loop body.  We make it a branch insn, so it stays at the end of the
176
;; block it is in.
177
(define_insn "loop_init"
178
  [(set (match_operand:SI 0 "register_operand" "=r,r")
179
        (match_operand:SI 1 "uns_arith_operand" "r,K"))
180
   (unspec [(label_ref (match_operand 2 "" ""))] UNSPEC_LOOP)]
181
  "TARGET_MS2"
182
  "@
183
   loop  %1,%l2 ;%0%#
184
   loopi %1,%l2 ;%0%#"
185
  [(set_attr "length" "4")
186
   (set_attr "type" "branch")])
187
 
188
; operand 0 is the loop count pseudo register
189
; operand 1 is the number of loop iterations or 0 if it is unknown
190
; operand 2 is the maximum number of loop iterations
191
; operand 3 is the number of levels of enclosed loops
192
; operand 4 is the label to jump to at the top of the loop
193
(define_expand "doloop_end"
194
  [(parallel [(set (pc) (if_then_else
195
                          (ne (match_operand:SI 0 "nonimmediate_operand" "")
196
                              (const_int 0))
197
                          (label_ref (match_operand 4 "" ""))
198
                          (pc)))
199
              (set (match_dup 0)
200
                   (plus:SI (match_dup 0)
201
                            (const_int -1)))
202
              (clobber (match_scratch:SI 5 ""))
203
              (clobber (match_scratch:SI 6 ""))])]
204
  "TARGET_MS1_16_003 || TARGET_MS2"
205
  {mt_add_loop ();})
206
 
207
;; Moves
208
 
209
(define_expand "loadqi"
210
  [
211
   ;; compute shift
212
   (set (match_operand:SI 2 "register_operand" "")
213
        (and:SI (match_dup 1) (const_int 3)))
214
   (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 3)))
215
   (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
216
 
217
   ;; get word that contains byte
218
   (set (match_operand:SI 0 "register_operand" "")
219
        (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
220
                        (const_int -3))))
221
 
222
   ;; align byte
223
   (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
224
  ]
225
  ""
226
  "")
227
 
228
 
229
;; storeqi
230
;; operand 0 byte value to store
231
;; operand 1 address
232
;; operand 2 temp, word containing byte
233
;; operand 3 temp, shift count
234
;; operand 4 temp, mask, aligned and masked byte
235
;; operand 5 (unused)
236
(define_expand "storeqi"
237
  [
238
   ;; compute shift
239
   (set (match_operand:SI 3 "register_operand" "")
240
        (and:SI (match_operand:SI 1 "register_operand" "") (const_int 3)))
241
   (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 3)))
242
   (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
243
 
244
   ;; get word that contains byte
245
   (set (match_operand:SI 2 "register_operand" "")
246
        (mem:SI (and:SI (match_dup 1) (const_int -3))))
247
 
248
   ;; generate mask
249
   (set (match_operand:SI 4 "register_operand" "") (const_int 255))
250
   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
251
   (set (match_dup 4) (not:SI (match_dup 4)))
252
 
253
   ;; clear appropriate bits
254
   (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
255
 
256
   ;; align byte
257
   (set (match_dup 4)
258
        (and:SI (match_operand:SI 0 "register_operand" "") (const_int 255)))
259
   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
260
 
261
   ;; combine
262
   (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
263
   ;; store updated word
264
   (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
265
  ]
266
  ""
267
  "")
268
 
269
 
270
(define_expand "movqi"
271
  [(set (match_operand:QI 0 "general_operand" "")
272
        (match_operand:QI 1 "general_operand" ""))]
273
  ""
274
  "
275
{
276
  if (!reload_in_progress
277
      && !reload_completed
278
      && GET_CODE (operands[0]) == MEM
279
      && GET_CODE (operands[1]) == MEM)
280
    operands[1] = copy_to_mode_reg (QImode, operands[1]);
281
 
282
  if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[0]) == MEM)
283
    {
284
        rtx scratch1 = gen_reg_rtx (SImode);
285
        rtx scratch2 = gen_reg_rtx (SImode);
286
        rtx scratch3 = gen_reg_rtx (SImode);
287
        rtx data     = operands[1];
288
        rtx address  = XEXP (operands[0], 0);
289
        rtx seq;
290
 
291
        if ( GET_CODE (data) != REG )
292
            data = copy_to_mode_reg (QImode, data);
293
 
294
        if ( GET_CODE (address) != REG )
295
          address = copy_to_mode_reg (SImode, address);
296
 
297
        start_sequence ();
298
        emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
299
                                scratch1, scratch2, scratch3));
300
        mt_set_memflags (operands[0]);
301
        seq = get_insns ();
302
        end_sequence ();
303
        emit_insn (seq);
304
        DONE;
305
    }
306
 
307
  if ( (! TARGET_BYTE_ACCESS) && GET_CODE (operands[1]) == MEM)
308
    {
309
        rtx scratch1 = gen_reg_rtx (SImode);
310
        rtx data = operands[0];
311
        rtx address = XEXP (operands[1], 0);
312
        rtx seq;
313
 
314
        if ( GET_CODE (address) != REG )
315
          address = copy_to_mode_reg (SImode, address);
316
 
317
        start_sequence ();
318
        emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
319
        mt_set_memflags (operands[1]);
320
        seq = get_insns ();
321
        end_sequence ();
322
        emit_insn (seq);
323
        DONE;
324
    }
325
 
326
   /* If the load is a pseudo register in a stack slot, some simplification
327
      can be made because the loads are aligned */
328
  if ( (! TARGET_BYTE_ACCESS)
329
        && (reload_in_progress && GET_CODE (operands[1]) == SUBREG
330
          && GET_CODE (SUBREG_REG (operands[1])) == REG
331
          && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
332
    {
333
        rtx data = operands[0];
334
        rtx address = XEXP (operands[1], 0);
335
        rtx seq;
336
 
337
        start_sequence ();
338
        emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
339
        mt_set_memflags (operands[1]);
340
        seq = get_insns ();
341
        end_sequence ();
342
        emit_insn (seq);
343
        DONE;
344
    }
345
}")
346
 
347
(define_insn "*movqi_internal"
348
  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
349
        (match_operand:QI 1 "general_operand" "r,m,r,I"))]
350
  "TARGET_BYTE_ACCESS
351
    && (!memory_operand (operands[0], QImode)
352
        || !memory_operand (operands[1], QImode))"
353
  "@
354
   or  %0, %1, %1
355
   ldb %0, %1
356
   stb %1, %0
357
   addi %0, r0, %1"
358
  [(set_attr "length" "4,4,4,4")
359
   (set_attr "type" "arith,load,store,arith")])
360
 
361
(define_insn "*movqi_internal_nobyte"
362
  [(set (match_operand:QI 0 "register_operand" "=r,r")
363
        (match_operand:QI 1 "arith_operand" "r,I"))]
364
  "!TARGET_BYTE_ACCESS
365
    && (!memory_operand (operands[0], QImode)
366
        || !memory_operand (operands[1], QImode))"
367
  "@
368
   or   %0, %1, %1
369
   addi %0, r0, %1"
370
  [(set_attr "length" "4,4")
371
   (set_attr "type" "arith,arith")])
372
 
373
 
374
;; The MorphoRISC does not have 16-bit loads and stores.
375
;; These operations must be synthesized.  Note that the code
376
;; for loadhi and storehi assumes that the least significant bits
377
;; is ignored.
378
 
379
;; loadhi
380
;; operand 0 location of result
381
;; operand 1 memory address
382
;; operand 2 temp
383
(define_expand "loadhi"
384
  [
385
   ;; compute shift
386
   (set (match_operand:SI 2 "register_operand" "")
387
        (and:SI (match_dup 1) (const_int 2)))
388
   (set (match_dup 2)   (xor:SI (match_dup 2) (const_int 2)))
389
   (set (match_dup 2 )  (ashift:SI (match_dup 2) (const_int 3)))
390
 
391
   ;; get word that contains the 16-bits
392
   (set (match_operand:SI 0 "register_operand" "")
393
        (mem:SI (and:SI (match_operand:SI 1 "register_operand" "")
394
                        (const_int -3))))
395
 
396
   ;; align 16-bit value
397
   (set (match_dup 0)   (ashiftrt:SI (match_dup 0) (match_dup 2)))
398
  ]
399
  ""
400
  "")
401
 
402
;; storehi
403
;; operand 0 byte value to store
404
;; operand 1 address
405
;; operand 2 temp, word containing byte
406
;; operand 3 temp, shift count
407
;; operand 4 temp, mask, aligned and masked byte
408
;; operand 5 (unused)
409
(define_expand "storehi"
410
  [
411
   ;; compute shift
412
   (set (match_operand:SI 3 "register_operand" "")
413
        (and:SI (match_operand:SI 1 "register_operand" "") (const_int 2)))
414
   (set (match_dup 3)   (xor:SI (match_dup 3) (const_int 2)))
415
   (set (match_dup 3)   (ashift:SI (match_dup 3) (const_int 3)))
416
 
417
   ;; get word that contains the 16-bits
418
   (set (match_operand:SI 2 "register_operand" "")
419
        (mem:SI (and:SI (match_dup 1) (const_int -3))))
420
 
421
   ;; generate mask
422
   (set (match_operand:SI 4 "register_operand" "") (const_int 65535))
423
   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
424
   (set (match_dup 4) (not:SI (match_dup 4)))
425
 
426
   ;; clear appropriate bits
427
   (set (match_dup 2) (and:SI (match_dup 2) (match_dup 4)))
428
 
429
   ;; align 16-bit value
430
   (set (match_dup 4)
431
        (and:SI (match_operand:SI 0 "register_operand" "") (const_int 65535)))
432
   (set (match_dup 4) (ashift:SI (match_dup 4) (match_dup 3)))
433
 
434
   ;; combine
435
   (set (match_dup 2) (ior:SI (match_dup 4) (match_dup 2)))
436
   ;; store updated word
437
   (set (mem:SI (and:SI (match_dup 1) (const_int -3))) (match_dup 2))
438
  ]
439
  ""
440
  "")
441
 
442
 
443
(define_expand "movhi"
444
  [(set (match_operand:HI 0 "general_operand" "")
445
        (match_operand:HI 1 "general_operand" ""))]
446
  ""
447
  "
448
{
449
  if (!reload_in_progress
450
      && !reload_completed
451
      && GET_CODE (operands[0]) == MEM
452
      && GET_CODE (operands[1]) == MEM)
453
    operands[1] = copy_to_mode_reg (HImode, operands[1]);
454
 
455
  if ( GET_CODE (operands[0]) == MEM)
456
    {
457
        rtx scratch1 = gen_reg_rtx (SImode);
458
        rtx scratch2 = gen_reg_rtx (SImode);
459
        rtx scratch3 = gen_reg_rtx (SImode);
460
        rtx data     = operands[1];
461
        rtx address  = XEXP (operands[0], 0);
462
        rtx seq;
463
 
464
        if (GET_CODE (data) != REG)
465
          data = copy_to_mode_reg (HImode, data);
466
 
467
        if (GET_CODE (address) != REG)
468
          address = copy_to_mode_reg (SImode, address);
469
 
470
        start_sequence ();
471
        emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
472
                                scratch1, scratch2, scratch3));
473
        mt_set_memflags (operands[0]);
474
        seq = get_insns ();
475
        end_sequence ();
476
        emit_insn (seq);
477
        DONE;
478
    }
479
 
480
  if ( GET_CODE (operands[1]) == MEM)
481
    {
482
        rtx scratch1 = gen_reg_rtx (SImode);
483
        rtx data     = operands[0];
484
        rtx address  = XEXP (operands[1], 0);
485
        rtx seq;
486
 
487
        if (GET_CODE (address) != REG)
488
            address = copy_to_mode_reg (SImode, address);
489
 
490
        start_sequence ();
491
        emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
492
                               scratch1));
493
        mt_set_memflags (operands[1]);
494
        seq = get_insns ();
495
        end_sequence ();
496
        emit_insn (seq);
497
        DONE;
498
    }
499
 
500
   /* If the load is a pseudo register in a stack slot, some simplification
501
      can be made because the loads are aligned */
502
  if ( (reload_in_progress && GET_CODE (operands[1]) == SUBREG
503
          && GET_CODE (SUBREG_REG (operands[1])) == REG
504
          && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
505
    {
506
        rtx data = operands[0];
507
        rtx address = XEXP (operands[1], 0);
508
        rtx seq;
509
 
510
        start_sequence ();
511
        emit_insn (gen_movsi (gen_lowpart (SImode, data), address));
512
        mt_set_memflags (operands[1]);
513
        seq = get_insns ();
514
        end_sequence ();
515
        emit_insn (seq);
516
        DONE;
517
    }
518
}")
519
 
520
(define_insn "*movhi_internal"
521
  [(set (match_operand:HI 0 "register_operand" "=r,r")
522
        (match_operand:HI 1 "arith_operand" "r,I"))]
523
  "!memory_operand (operands[0], HImode) || !memory_operand (operands[1], HImode)"
524
  "@
525
  or    %0, %1, %1
526
  addi  %0, r0, %1"
527
  [(set_attr "length" "4,4")
528
   (set_attr "type" "arith,arith")])
529
 
530
(define_expand "movsi"
531
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
532
        (match_operand:SI 1 "general_operand" ""))]
533
  ""
534
  "
535
{
536
  if (!reload_in_progress  && !reload_completed
537
      && !register_operand (operands[0], SImode)
538
      && !register_operand (operands[1], SImode))
539
    operands[1] = copy_to_mode_reg (SImode, operands[1]);
540
 
541
  /* Take care of constants that don't fit in single instruction */
542
  if ( (reload_in_progress || reload_completed)
543
   && !single_const_operand (operands[1], SImode))
544
    {
545
      emit_insn (gen_movsi_high (operands[0], operands[1]));
546
      emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1]));
547
      DONE;
548
    }
549
 
550
}")
551
 
552
(define_insn "movsi_high"
553
  [(set (match_operand:SI 0 "register_operand" "=r")
554
        (high:SI (match_operand:SI 1 "general_operand" "i")))]
555
  ""
556
  "*
557
{
558
  return \"ldui\\t%0, %H1\";
559
}"
560
  [(set_attr "length" "4")
561
   (set_attr "type" "arith")])
562
 
563
 
564
(define_insn "movsi_lo_sum"
565
  [(set (match_operand:SI 0 "register_operand" "=r")
566
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
567
                   (match_operand:SI 2 "general_operand" "i")))]
568
  ""
569
  "*
570
{
571
  return \"addui\\t%0, %1, %L2\";
572
}"
573
  [(set_attr "length" "4")
574
   (set_attr "type" "arith")])
575
 
576
/* Take care of constants that don't fit in single instruction */
577
(define_split
578
  [(set (match_operand:SI 0 "register_operand" "")
579
        (match_operand:SI 1 "general_operand" ""))]
580
  "(reload_in_progress || reload_completed)
581
   && !single_const_operand (operands[1], SImode)"
582
 
583
  [(set (match_dup 0 )
584
        (high:SI (match_dup 1)))
585
   (set (match_dup 0 )
586
        (lo_sum:SI (match_dup 0)
587
                   (match_dup 1)))]
588
)
589
 
590
 
591
;; The last pattern in movsi (with two instructions)
592
;; is really handled by the emit_insn's in movsi
593
;; and the define_split above.  This provides additional
594
;; instructions to fill delay slots.
595
 
596
;; Note - it is best to only have one movsi pattern and to handle
597
;; all the various contingencies by the use of alternatives.  This
598
;; allows reload the greatest amount of flexibility (since reload will
599
;; only choose amoungst alternatives for a selected insn, it will not
600
;; replace the insn with another one).
601
(define_insn "*movsi_internal"
602
  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r")
603
        (match_operand:SI 1 "general_operand"       "r,m,r,I,P,L,N,i"))]
604
  "(!memory_operand (operands[0], SImode) || !memory_operand (operands[1], SImode))
605
   && !((reload_in_progress || reload_completed)
606
         && !single_const_operand (operands[1], SImode))"
607
  "@
608
  or     %0, %1, %1
609
  ldw    %0, %1
610
  stw    %1, %0
611
  addi   %0, r0, %1
612
  addui  %0, r0, %1
613
  ldui   %0, %H1
614
  nori   %0, r0, %N1
615
  ldui   %0, %H1\;addui %0, %0, %L1"
616
  [(set_attr "length" "4,4,4,4,4,4,4,8")
617
   (set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")]
618
)
619
 
620
;; Floating Point Moves
621
;;
622
;; Note - Patterns for SF mode moves are compulsory, but
623
;; patterns for DF are optional, as GCC can synthesize them.
624
 
625
(define_expand "movsf"
626
  [(set (match_operand:SF 0 "general_operand" "")
627
        (match_operand:SF 1 "general_operand" ""))]
628
  ""
629
  "
630
{
631
  if (!reload_in_progress
632
      && !reload_completed
633
      && GET_CODE (operands[0]) == MEM
634
      && (GET_CODE (operands[1]) == MEM
635
         || GET_CODE (operands[1]) == CONST_DOUBLE))
636
    operands[1] = copy_to_mode_reg (SFmode, operands[1]);
637
 
638
  /* Take care of reg <- SF constant */
639
  if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) )
640
    {
641
      emit_insn (gen_movsf_high (operands[0], operands[1]));
642
      emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1]));
643
      DONE;
644
    }
645
}")
646
 
647
(define_insn "movsf_lo_sum"
648
  [(set (match_operand:SF 0 "register_operand" "=r")
649
        (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
650
                   (match_operand:SF 2 "const_double_operand" "")))]
651
  ""
652
  "*
653
{
654
  REAL_VALUE_TYPE r;
655
  long i;
656
 
657
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
658
  REAL_VALUE_TO_TARGET_SINGLE (r, i);
659
  operands[2] = GEN_INT (i);
660
  return \"addui\\t%0, %1, %L2\";
661
}"
662
  [(set_attr "length" "4")
663
   (set_attr "type" "arith")])
664
 
665
(define_insn "movsf_high"
666
  [(set (match_operand:SF 0 "register_operand" "=r")
667
        (high:SF (match_operand:SF 1 "const_double_operand" "")))]
668
  ""
669
  "*
670
{
671
  REAL_VALUE_TYPE r;
672
  long i;
673
 
674
  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
675
  REAL_VALUE_TO_TARGET_SINGLE (r, i);
676
  operands[1] = GEN_INT (i);
677
  return \"ldui\\t%0, %H1\";
678
}"
679
  [(set_attr "length" "4")
680
   (set_attr "type" "arith")])
681
 
682
 
683
(define_insn "*movsf_internal"
684
  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
685
        (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))]
686
  "!memory_operand (operands[0], SFmode) || !memory_operand (operands[1], SFmode)"
687
  "@
688
  or     %0, %1, %1
689
  ldw    %0, %1
690
  stw    %1, %0"
691
  [(set_attr "length" "4,4,4")
692
   (set_attr "type" "arith,load,store")]
693
)
694
 
695
(define_expand "movdf"
696
  [(set (match_operand:DF 0 "general_operand" "")
697
        (match_operand:DF 1 "general_operand" ""))]
698
  ""
699
  "
700
{
701
  /* One of the ops has to be in a register or 0 */
702
  if (!register_operand (operand0, DFmode)
703
      && !reg_or_0_operand (operand1, DFmode))
704
    operands[1] = copy_to_mode_reg (DFmode, operand1);
705
}")
706
 
707
(define_insn_and_split "*movdf_internal"
708
  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,o")
709
        (match_operand:DF 1 "general_operand"      "rim,r"))]
710
  "! (memory_operand (operands[0], DFmode)
711
         && memory_operand (operands[1], DFmode))"
712
  "#"
713
 
714
  "(reload_completed || reload_in_progress)"
715
 
716
  [(set (match_dup 2) (match_dup 3))
717
   (set (match_dup 4) (match_dup 5))
718
  ]
719
 
720
  "{
721
    /* figure out what precisely to put into operands 2, 3, 4, and 5 */
722
    mt_split_words (SImode, DFmode, operands);
723
  }"
724
)
725
 
726
 
727
;; Reloads
728
 
729
;; Like `movM', but used when a scratch register is required to move between
730
;; operand 0 and operand 1.  Operand 2 describes the scratch register.  See the
731
;; discussion of the `SECONDARY_RELOAD_CLASS' macro.
732
 
733
(define_expand "reload_inqi"
734
  [(set (match_operand:QI 0 "register_operand" "=r")
735
        (match_operand:QI 1 "memory_operand" "m"))
736
   (clobber (match_operand:DI 2 "register_operand" "=&r"))]
737
  "! TARGET_BYTE_ACCESS"
738
  "
739
{
740
  rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
741
  rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
742
  rtx data = operands[0];
743
  rtx address = XEXP (operands[1], 0);
744
  rtx swap, seq;
745
 
746
  /* It is possible that the registers we got for scratch1
747
     might coincide with that of operands[0].  gen_loadqi
748
     requires operand0 and operand2 to be different registers.
749
     The following statement ensure that is always the case. */
750
  if (REGNO(operands[0]) == REGNO(scratch1))
751
    {
752
        swap = scratch1;
753
        scratch1 = scratch2;
754
        scratch2 = swap;
755
    }
756
 
757
  /* need to make sure address is already in register */
758
  if ( GET_CODE (address) != REG )
759
    address = force_operand (address, scratch2);
760
 
761
  start_sequence ();
762
  emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1));
763
  mt_set_memflags (operands[1]);
764
  seq = get_insns ();
765
  end_sequence ();
766
  emit_insn (seq);
767
  DONE;
768
}")
769
 
770
(define_expand "reload_outqi"
771
  [(set (match_operand:QI 0 "memory_operand" "=m")
772
        (match_operand:QI 1 "register_operand" "r"))
773
   (clobber (match_operand:TI 2 "register_operand" "=&r"))]
774
  "! TARGET_BYTE_ACCESS"
775
  "
776
{
777
  rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
778
  rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
779
  rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
780
  rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
781
  rtx data     = operands[1];
782
  rtx address  = XEXP (operands[0], 0);
783
  rtx seq;
784
 
785
  /* need to make sure address is already in register */
786
  if ( GET_CODE (address) != REG )
787
    address = force_operand (address, scratch4);
788
 
789
  start_sequence ();
790
  emit_insn (gen_storeqi (gen_lowpart (SImode, data), address,
791
                          scratch1, scratch2, scratch3));
792
  mt_set_memflags (operands[0]);
793
  seq = get_insns ();
794
  end_sequence ();
795
  emit_insn (seq);
796
  DONE;
797
}")
798
 
799
(define_expand "reload_inhi"
800
  [(set (match_operand:HI 0 "register_operand" "=r")
801
        (match_operand:HI 1 "memory_operand" "m"))
802
   (clobber (match_operand:DI 2 "register_operand" "=&r"))]
803
  ""
804
  "
805
{
806
  rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
807
  rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
808
  rtx data     = operands[0];
809
  rtx address  = XEXP (operands[1], 0);
810
  rtx swap, seq;
811
 
812
  /* It is possible that the registers we got for scratch1
813
     might coincide with that of operands[0].  gen_loadqi
814
     requires operand0 and operand2 to be different registers.
815
     The following statement ensure that is always the case. */
816
  if (REGNO(operands[0]) == REGNO(scratch1))
817
    {
818
        swap = scratch1;
819
        scratch1 = scratch2;
820
        scratch2 = swap;
821
    }
822
 
823
  /* need to make sure address is already in register */
824
  if ( GET_CODE (address) != REG )
825
    address = force_operand (address, scratch2);
826
 
827
  start_sequence ();
828
  emit_insn (gen_loadhi (gen_lowpart (SImode, data), address,
829
                         scratch1));
830
  mt_set_memflags (operands[1]);
831
  seq = get_insns ();
832
  end_sequence ();
833
  emit_insn (seq);
834
  DONE;
835
}")
836
 
837
(define_expand "reload_outhi"
838
  [(set (match_operand:HI 0 "memory_operand" "=m")
839
        (match_operand:HI 1 "register_operand" "r"))
840
   (clobber (match_operand:TI 2 "register_operand" "=&r"))]
841
  ""
842
  "
843
{
844
  rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2]));
845
  rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1);
846
  rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2);
847
  rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3);
848
  rtx data     = operands[1];
849
  rtx address  = XEXP (operands[0], 0);
850
  rtx seq;
851
 
852
  /* need to make sure address is already in register */
853
  if ( GET_CODE (address) != REG )
854
    address = force_operand (address, scratch4);
855
 
856
  start_sequence ();
857
  emit_insn (gen_storehi (gen_lowpart (SImode, data), address,
858
                          scratch1, scratch2, scratch3));
859
  mt_set_memflags (operands[0]);
860
  seq = get_insns ();
861
  end_sequence ();
862
  emit_insn (seq);
863
  DONE;
864
}")
865
 
866
 
867
;; 32 bit Integer arithmetic
868
 
869
;; Addition
870
(define_insn "addsi3"
871
  [(set (match_operand:SI 0 "register_operand" "=r,r")
872
        (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
873
                 (match_operand:SI 2 "arith_operand" "r,I")))]
874
  ""
875
  "@
876
  add %0, %1, %2
877
  addi %0, %1, %2"
878
  [(set_attr "length" "4,4")
879
   (set_attr "type" "arith,arith")])
880
 
881
;; Subtraction
882
(define_insn "subsi3"
883
  [(set (match_operand:SI 0 "register_operand" "=r,r")
884
        (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
885
                  (match_operand:SI 2 "arith_operand" "rJ,I")))]
886
  ""
887
  "@
888
  sub %0, %z1, %z2
889
  subi %0, %z1, %2"
890
  [(set_attr "length" "4,4")
891
   (set_attr "type" "arith,arith")])
892
 
893
;;  Negation
894
(define_insn "negsi2"
895
  [(set (match_operand:SI 0 "register_operand" "=r,r")
896
        (neg:SI (match_operand:SI 1 "arith_operand" "r,I")))]
897
  ""
898
  "@
899
  sub  %0, r0, %1
900
  subi  %0, r0, %1"
901
  [(set_attr "length" "4,4")
902
   (set_attr "type" "arith,arith")])
903
 
904
 
905
;; 32 bit Integer Shifts and Rotates
906
 
907
;; Arithmetic Shift Left
908
(define_insn "ashlsi3"
909
  [(set (match_operand:SI 0 "register_operand" "=r,r")
910
        (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
911
                   (match_operand:SI 2 "arith_operand" "r,K")))]
912
  ""
913
  "@
914
  lsl %0, %1, %2
915
  lsli %0, %1, %2"
916
  [(set_attr "length" "4,4")
917
   (set_attr "type" "arith,arith")])
918
 
919
;; Arithmetic Shift Right
920
(define_insn "ashrsi3"
921
  [(set (match_operand:SI 0 "register_operand" "=r,r")
922
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
923
                     (match_operand:SI 2 "uns_arith_operand" "r,K")))]
924
  ""
925
  "@
926
  asr %0, %1, %2
927
  asri %0, %1, %2"
928
  [(set_attr "length" "4,4")
929
   (set_attr "type" "arith,arith")])
930
 
931
;; Logical Shift Right
932
(define_insn "lshrsi3"
933
  [(set (match_operand:SI 0 "register_operand" "=r,r")
934
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
935
                     (match_operand:SI 2 "uns_arith_operand" "r,K")))]
936
  ""
937
  "@
938
  lsr %0, %1, %2
939
  lsri %0, %1, %2"
940
  [(set_attr "length" "4,4")
941
   (set_attr "type" "arith,arith")])
942
 
943
 
944
;; 32 Bit Integer Logical operations
945
 
946
;; Logical AND, 32 bit integers
947
(define_insn "andsi3"
948
  [(set (match_operand:SI 0 "register_operand" "=r,r")
949
        (and:SI (match_operand:SI 1 "register_operand" "%r,r")
950
                (match_operand:SI 2 "uns_arith_operand" "r,K")))]
951
  ""
952
  "@
953
  and %0, %1, %2
954
  andi %0, %1, %2"
955
  [(set_attr "length" "4,4")
956
   (set_attr "type" "arith,arith")])
957
 
958
;; Inclusive OR, 32 bit integers
959
(define_insn "iorsi3"
960
  [(set (match_operand:SI 0 "register_operand" "=r,r")
961
        (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
962
                (match_operand:SI 2 "uns_arith_operand" "r,K")))]
963
  ""
964
  "@
965
  or %0, %1, %2
966
  ori %0, %1, %2"
967
  [(set_attr "length" "4,4")
968
   (set_attr "type" "arith,arith")])
969
 
970
;; Exclusive OR, 32 bit integers
971
(define_insn "xorsi3"
972
  [(set (match_operand:SI 0 "register_operand" "=r,r")
973
        (xor:SI (match_operand:SI 1 "register_operand" "%r,r")
974
                (match_operand:SI 2 "uns_arith_operand" "r,K")))]
975
  ""
976
  "@
977
  xor %0, %1, %2
978
  xori %0, %1, %2"
979
  [(set_attr "length" "4,4")
980
   (set_attr "type" "arith,arith")])
981
 
982
 
983
;; One's complement, 32 bit integers
984
(define_insn "one_cmplsi2"
985
  [(set (match_operand:SI 0 "register_operand" "=r")
986
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
987
  ""
988
  "nor %0, %1, %1"
989
  [(set_attr "length" "4")
990
   (set_attr "type" "arith")])
991
 
992
 
993
;; Multiply
994
 
995
(define_insn "mulhisi3"
996
  [(set (match_operand:SI 0 "register_operand" "=r,r")
997
     (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
998
              (sign_extend:SI (match_operand:HI 2 "arith_operand" "r,I"))))]
999
  "TARGET_MS1_16_003 || TARGET_MS2"
1000
  "@
1001
  mul %0, %1, %2
1002
  muli %0, %1, %2"
1003
  [(set_attr "length" "4,4")
1004
   (set_attr "type" "arith,arith")])
1005
 
1006
 
1007
;; Comparisons
1008
 
1009
;; Note, we store the operands in the comparison insns, and use them later
1010
;; when generating the branch or scc operation.
1011
 
1012
;; First the routines called by the machine independent part of the compiler
1013
(define_expand "cmpsi"
1014
  [(set (cc0)
1015
        (compare (match_operand:SI 0 "register_operand" "")
1016
                 (match_operand:SI 1 "arith_operand" "")))]
1017
  ""
1018
  "
1019
{
1020
  mt_compare_op0 = operands[0];
1021
  mt_compare_op1 = operands[1];
1022
  DONE;
1023
}")
1024
 
1025
 
1026
;; Branches
1027
 
1028
(define_expand "beq"
1029
  [(use (match_operand 0 "" ""))]
1030
  ""
1031
  "
1032
{
1033
  mt_emit_cbranch (EQ, operands[0], mt_compare_op0, mt_compare_op1);
1034
  DONE;
1035
}")
1036
 
1037
(define_expand "bne"
1038
  [(use (match_operand 0 "" ""))]
1039
  ""
1040
  "
1041
{
1042
  mt_emit_cbranch (NE, operands[0], mt_compare_op0, mt_compare_op1);
1043
  DONE;
1044
}")
1045
 
1046
(define_expand "bge"
1047
  [(use (match_operand 0 "" ""))]
1048
  ""
1049
  "
1050
{
1051
  mt_emit_cbranch (GE, operands[0], mt_compare_op0, mt_compare_op1);
1052
  DONE;
1053
}")
1054
 
1055
(define_expand "bgt"
1056
  [(use (match_operand 0 "" ""))]
1057
  ""
1058
  "
1059
{
1060
  mt_emit_cbranch (GT, operands[0], mt_compare_op0, mt_compare_op1);
1061
  DONE;
1062
}")
1063
 
1064
(define_expand "ble"
1065
  [(use (match_operand 0 "" ""))]
1066
  ""
1067
  "
1068
{
1069
  mt_emit_cbranch (LE, operands[0], mt_compare_op0, mt_compare_op1);
1070
  DONE;
1071
}")
1072
 
1073
(define_expand "blt"
1074
  [(use (match_operand 0 "" ""))]
1075
  ""
1076
  "
1077
{
1078
  mt_emit_cbranch (LT, operands[0], mt_compare_op0, mt_compare_op1);
1079
  DONE;
1080
}")
1081
 
1082
(define_expand "bgeu"
1083
  [(use (match_operand 0 "" ""))]
1084
  ""
1085
  "
1086
{
1087
  mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1088
  DONE;
1089
}")
1090
 
1091
(define_expand "bgtu"
1092
  [(use (match_operand 0 "" ""))]
1093
  ""
1094
  "
1095
{
1096
  mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1097
  DONE;
1098
}")
1099
 
1100
(define_expand "bleu"
1101
  [(use (match_operand 0 "" ""))]
1102
  ""
1103
  "
1104
{
1105
  mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1106
  DONE;
1107
}")
1108
 
1109
(define_expand "bltu"
1110
  [(use (match_operand 0 "" ""))]
1111
  ""
1112
  "
1113
{
1114
  mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1115
  DONE;
1116
}")
1117
 
1118
(define_expand "bunge"
1119
  [(use (match_operand 0 "" ""))]
1120
  ""
1121
  "
1122
{
1123
  mt_emit_cbranch (GEU, operands[0], mt_compare_op0, mt_compare_op1);
1124
  DONE;
1125
}")
1126
 
1127
(define_expand "bungt"
1128
  [(use (match_operand 0 "" ""))]
1129
  ""
1130
  "
1131
{
1132
  mt_emit_cbranch (GTU, operands[0], mt_compare_op0, mt_compare_op1);
1133
  DONE;
1134
}")
1135
 
1136
(define_expand "bunle"
1137
  [(use (match_operand 0 "" ""))]
1138
  ""
1139
  "
1140
{
1141
  mt_emit_cbranch (LEU, operands[0], mt_compare_op0, mt_compare_op1);
1142
  DONE;
1143
}")
1144
 
1145
(define_expand "bunlt"
1146
  [(use (match_operand 0 "" ""))]
1147
  ""
1148
  "
1149
{
1150
  mt_emit_cbranch (LTU, operands[0], mt_compare_op0, mt_compare_op1);
1151
  DONE;
1152
}")
1153
 
1154
(define_insn "*beq_true"
1155
  [(set (pc)
1156
        (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1157
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1158
                      (label_ref (match_operand 2 "" ""))
1159
                      (pc)))]
1160
  ""
1161
  "breq %z0, %z1, %l2%#"
1162
  [(set_attr "length" "4")
1163
   (set_attr "type" "branch")])
1164
 
1165
(define_insn "*beq_false"
1166
  [(set (pc)
1167
        (if_then_else (eq (match_operand:SI 0 "reg_or_0_operand" "rJ")
1168
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1169
                      (pc)
1170
                      (label_ref (match_operand 2 "" ""))))]
1171
  ""
1172
  "brne %z0, %z1, %l2%#"
1173
  [(set_attr "length" "4")
1174
   (set_attr "type" "branch")])
1175
 
1176
 
1177
(define_insn "*bne_true"
1178
  [(set (pc)
1179
        (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1180
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1181
                      (label_ref (match_operand 2 "" ""))
1182
                      (pc)))]
1183
  ""
1184
  "brne %z0, %z1, %l2%#"
1185
  [(set_attr "length" "4")
1186
   (set_attr "type" "branch")])
1187
 
1188
(define_insn "*bne_false"
1189
  [(set (pc)
1190
        (if_then_else (ne (match_operand:SI 0 "reg_or_0_operand" "rJ")
1191
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1192
                      (pc)
1193
                      (label_ref (match_operand 2 "" ""))))]
1194
  ""
1195
  "breq %z0, %z1, %l2%#"
1196
  [(set_attr "length" "4")
1197
   (set_attr "type" "branch")])
1198
 
1199
(define_insn "*blt_true"
1200
  [(set (pc)
1201
        (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1202
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1203
                      (label_ref (match_operand 2 "" ""))
1204
                      (pc)))]
1205
  ""
1206
  "brlt %z0, %z1, %l2%#"
1207
  [(set_attr "length" "4")
1208
   (set_attr "type" "branch")])
1209
 
1210
(define_insn "*blt_false"
1211
  [(set (pc)
1212
        (if_then_else (lt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1213
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1214
                      (pc)
1215
                      (label_ref (match_operand 2 "" ""))))]
1216
  ""
1217
  "brle %z1, %z0,%l2%#"
1218
  [(set_attr "length" "4")
1219
   (set_attr "type" "branch")])
1220
 
1221
(define_insn "*ble_true"
1222
  [(set (pc)
1223
        (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1224
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1225
                      (label_ref (match_operand 2 "" ""))
1226
                      (pc)))]
1227
  ""
1228
  "brle %z0, %z1, %l2%#"
1229
  [(set_attr "length" "4")
1230
   (set_attr "type" "branch")])
1231
 
1232
(define_insn "*ble_false"
1233
  [(set (pc)
1234
        (if_then_else (le (match_operand:SI 0 "reg_or_0_operand" "rJ")
1235
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1236
                      (pc)
1237
                      (label_ref (match_operand 2 "" ""))))]
1238
  ""
1239
  "brlt %z1, %z0,%l2%#"
1240
  [(set_attr "length" "4")
1241
   (set_attr "type" "branch")])
1242
 
1243
(define_insn "*bgt_true"
1244
  [(set (pc)
1245
        (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1246
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1247
                      (label_ref (match_operand 2 "" ""))
1248
                      (pc)))]
1249
  ""
1250
  "brlt %z1, %z0, %l2%#"
1251
  [(set_attr "length" "4")
1252
   (set_attr "type" "branch")])
1253
 
1254
(define_insn "*bgt_false"
1255
  [(set (pc)
1256
        (if_then_else (gt (match_operand:SI 0 "reg_or_0_operand" "rJ")
1257
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1258
                      (pc)
1259
                      (label_ref (match_operand 2 "" ""))))]
1260
  ""
1261
  "brle %z0, %z1, %l2%#"
1262
  [(set_attr "length" "4")
1263
   (set_attr "type" "branch")])
1264
 
1265
(define_insn "*bge_true"
1266
  [(set (pc)
1267
        (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1268
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1269
                      (label_ref (match_operand 2 "" ""))
1270
                      (pc)))]
1271
  ""
1272
  "brle %z1, %z0,%l2%#"
1273
  [(set_attr "length" "4")
1274
   (set_attr "type" "branch")])
1275
 
1276
(define_insn "*bge_false"
1277
  [(set (pc)
1278
        (if_then_else (ge (match_operand:SI 0 "reg_or_0_operand" "rJ")
1279
                          (match_operand:SI 1 "reg_or_0_operand" "rJ"))
1280
                      (pc)
1281
                      (label_ref (match_operand 2 "" ""))))]
1282
  ""
1283
  "brlt %z0, %z1, %l2%#"
1284
  [(set_attr "length" "4")
1285
   (set_attr "type" "branch")])
1286
 
1287
;; No unsigned operators on Morpho mt.  All the unsigned operations are
1288
;; converted to the signed operations above.
1289
 
1290
 
1291
;; Set flag operations
1292
 
1293
;; "seq", "sne", "slt", "sle", "sgt", "sge", "sltu", "sleu",
1294
;; "sgtu", and "sgeu" don't exist as regular instruction on the
1295
;; mt, so these are not defined
1296
 
1297
;; Call and branch instructions
1298
 
1299
(define_expand "call"
1300
  [(parallel [(call (mem:SI (match_operand:SI 0 "register_operand" ""))
1301
                            (match_operand 1 "" ""))
1302
              (clobber (reg:SI 14))])]
1303
  ""
1304
  "
1305
{
1306
    operands[0] = force_reg (SImode, XEXP (operands[0], 0));
1307
}")
1308
 
1309
(define_insn "call_internal"
1310
  [(call (mem:SI (match_operand 0 "register_operand" "r"))
1311
         (match_operand 1 "" ""))
1312
   ;; possibly add a clobber of the reg that gets the return address
1313
   (clobber (reg:SI 14))]
1314
  ""
1315
  "jal r14, %0%#"
1316
  [(set_attr "length" "4")
1317
   (set_attr "type" "call")])
1318
 
1319
(define_expand "call_value"
1320
  [(parallel [(set (match_operand 0 "register_operand" "")
1321
                   (call (mem:SI (match_operand:SI 1 "register_operand" ""))
1322
                                 (match_operand 2 "general_operand" "")))
1323
              (clobber (reg:SI 14))])]
1324
  ""
1325
  "
1326
{
1327
    operands[1] = force_reg (SImode, XEXP (operands[1], 0));
1328
}")
1329
 
1330
 
1331
(define_insn "call_value_internal"
1332
  [(set (match_operand 0 "register_operand" "=r")
1333
        (call (mem:SI (match_operand 1 "register_operand" "r"))
1334
              (match_operand 2 "" "")))
1335
        ;; possibly add a clobber of the reg that gets the return address
1336
        (clobber (reg:SI 14))]
1337
  ""
1338
  "jal r14, %1%#"
1339
  [(set_attr "length" "4")
1340
   (set_attr "type" "call")])
1341
 
1342
;; Subroutine return
1343
(define_insn "return_internal"
1344
  [(const_int 2)
1345
   (return)
1346
   (use (reg:SI 14))]
1347
  ""
1348
  "jal r0, r14%#"
1349
  [(set_attr "length" "4")
1350
   (set_attr "type" "call")])
1351
 
1352
;; Interrupt return
1353
(define_insn "return_interrupt_internal"
1354
  [(const_int 3)
1355
   (return)
1356
   (use (reg:SI 15))]
1357
  ""
1358
  "reti r15%#"
1359
  [(set_attr "length" "4")
1360
   (set_attr "type" "call")])
1361
 
1362
;; Subroutine return
1363
(define_insn "eh_return_internal"
1364
  [(return)
1365
   (use (reg:SI 7))
1366
   (use (reg:SI 8))
1367
   (use (reg:SI 11))
1368
   (use (reg:SI 10))]
1369
  ""
1370
  "jal r0, r11%#"
1371
  [(set_attr "length" "4")
1372
   (set_attr "type" "call")])
1373
 
1374
 
1375
;; Normal unconditional jump
1376
(define_insn "jump"
1377
  [(set (pc) (label_ref (match_operand 0 "" "")))]
1378
  ""
1379
  "jmp %l0%#"
1380
  [(set_attr "length" "4")
1381
   (set_attr "type" "branch")])
1382
 
1383
;; Indirect jump through a register
1384
(define_insn "indirect_jump"
1385
  [(set (pc) (match_operand 0 "register_operand" "r"))]
1386
  ""
1387
  "jal r0,%0%#"
1388
  [(set_attr "length" "4")
1389
   (set_attr "type" "call")])
1390
 
1391
(define_insn "tablejump"
1392
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1393
   (use (label_ref (match_operand 1 "" "")))]
1394
  ""
1395
  "jal r0, %0%#"
1396
  [(set_attr "length" "4")
1397
   (set_attr "type" "call")])
1398
 
1399
 
1400
(define_expand "prologue"
1401
  [(const_int 1)]
1402
  ""
1403
  "
1404
{
1405
  mt_expand_prologue ();
1406
  DONE;
1407
}")
1408
 
1409
(define_expand "epilogue"
1410
  [(const_int 2)]
1411
  ""
1412
  "
1413
{
1414
  mt_expand_epilogue (NORMAL_EPILOGUE);
1415
  DONE;
1416
}")
1417
 
1418
 
1419
(define_expand "eh_return"
1420
  [(use (match_operand:SI 0 "register_operand" "r"))]
1421
  ""
1422
  "
1423
{
1424
  mt_expand_eh_return (operands);
1425
  DONE;
1426
}")
1427
 
1428
 
1429
(define_insn_and_split "eh_epilogue"
1430
  [(unspec [(match_operand 0 "register_operand" "r")] 6)]
1431
  ""
1432
  "#"
1433
  "reload_completed"
1434
  [(const_int 1)]
1435
  "mt_emit_eh_epilogue (operands); DONE;"
1436
)
1437
 
1438
;; No operation, needed in case the user uses -g but not -O.
1439
(define_insn "nop"
1440
  [(const_int 0)]
1441
  ""
1442
  "nop"
1443
  [(set_attr "length" "4")
1444
   (set_attr "type" "arith")])
1445
 
1446
;; ::::::::::::::::::::
1447
;; ::
1448
;; :: UNSPEC_VOLATILE usage
1449
;; ::
1450
;; ::::::::::::::::::::
1451
;;
1452
;;      0        blockage
1453
;;      1       Enable interrupts
1454
;;      2       Disable interrupts
1455
;;
1456
 
1457
;; Pseudo instruction that prevents the scheduler from moving code above this
1458
;; point.
1459
(define_insn "blockage"
1460
  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
1461
  ""
1462
  ""
1463
  [(set_attr "length" "0")])
1464
 
1465
;; Trap instruction to allow usage of the __builtin_trap function
1466
(define_insn "trap"
1467
  [(trap_if (const_int 1) (const_int 0))
1468
   (clobber (reg:SI 14))]
1469
  ""
1470
  "si   r14%#"
1471
  [(set_attr "length" "4")
1472
   (set_attr "type" "branch")])
1473
 
1474
(define_expand "conditional_trap"
1475
  [(trap_if (match_operator 0 "comparison_operator"
1476
                            [(match_dup 2)
1477
                             (match_dup 3)])
1478
            (match_operand 1 "const_int_operand" ""))]
1479
  ""
1480
  "
1481
{
1482
  operands[2] = mt_compare_op0;
1483
  operands[3] = mt_compare_op1;
1484
}")
1485
 
1486
;; Templates to control handling of interrupts
1487
 
1488
;; Enable interrupts template
1489
(define_insn "ei"
1490
  [(unspec_volatile [(const_int 0)] UNSPEC_EI)]
1491
  ""
1492
  "ei"
1493
  [(set_attr "length" "4")])
1494
 
1495
;; Enable interrupts template
1496
(define_insn "di"
1497
  [(unspec_volatile [(const_int 0)] UNSPEC_DI)]
1498
  ""
1499
  "di"
1500
  [(set_attr "length" "4")])

powered by: WebSVN 2.1.0

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