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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [arc/] [arc.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 of the Argonaut ARC cpu for GNU C compiler
2
;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007
3
;; Free Software Foundation, 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
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
 
23
;; ??? This is an old port, and is undoubtedly suffering from bit rot.
24
 
25
;; Insn type.  Used to default other attribute values.
26
 
27
(define_attr "type"
28
  "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
29
  (const_string "binary"))
30
 
31
;; Length (in # of insns, long immediate constants counted too).
32
;; ??? There's a nasty interaction between the conditional execution fsm
33
;; and insn lengths: insns with shimm values cannot be conditionally executed.
34
(define_attr "length" ""
35
  (cond [(eq_attr "type" "load")
36
         (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
37
                       (const_int 2) (const_int 1))
38
 
39
         (eq_attr "type" "store")
40
         (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
41
                       (const_int 2) (const_int 1))
42
 
43
         (eq_attr "type" "move,unary,compare")
44
         (if_then_else (match_operand 1 "long_immediate_operand" "")
45
                       (const_int 2) (const_int 1))
46
 
47
         (eq_attr "type" "binary,mul")
48
         (if_then_else (match_operand 2 "long_immediate_operand" "")
49
                       (const_int 2) (const_int 1))
50
 
51
         (eq_attr "type" "cmove")
52
         (if_then_else (match_operand 2 "register_operand" "")
53
                       (const_int 1) (const_int 2))
54
 
55
         (eq_attr "type" "multi") (const_int 2)
56
        ]
57
 
58
        (const_int 1)))
59
 
60
;; The length here is the length of a single asm.  Unfortunately it might be
61
;; 1 or 2 so we must allow for 2.  That's ok though.  How often will users
62
;; lament asm's not being put in delay slots?
63
(define_asm_attributes
64
  [(set_attr "length" "2")
65
   (set_attr "type" "multi")])
66
 
67
;; Condition codes: this one is used by final_prescan_insn to speed up
68
;; conditionalizing instructions.  It saves having to scan the rtl to see if
69
;; it uses or alters the condition codes.
70
 
71
;; USE: This insn uses the condition codes (e.g.: a conditional branch).
72
;; CANUSE: This insn can use the condition codes (for conditional execution).
73
;; SET: All condition codes are set by this insn.
74
;; SET_ZN: the Z and N flags are set by this insn.
75
;; SET_ZNC: the Z, N, and C flags are set by this insn.
76
;; CLOB: The condition codes are set to unknown values by this insn.
77
;; NOCOND: This insn can't use and doesn't affect the condition codes.
78
 
79
(define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
80
  (cond [(and (eq_attr "type" "unary,binary,move")
81
              (eq_attr "length" "1"))
82
         (const_string "canuse")
83
 
84
         (eq_attr "type" "compare")
85
         (const_string "set")
86
 
87
         (eq_attr "type" "cmove,branch")
88
         (const_string "use")
89
 
90
         (eq_attr "type" "multi,misc")
91
         (const_string "clob")
92
         ]
93
 
94
         (const_string "nocond")))
95
 
96
;; Delay slots.
97
 
98
(define_attr "in_delay_slot" "false,true"
99
  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
100
         (const_string "false")
101
         ]
102
 
103
         (if_then_else (eq_attr "length" "1")
104
                       (const_string "true")
105
                       (const_string "false"))))
106
 
107
(define_delay (eq_attr "type" "call")
108
  [(eq_attr "in_delay_slot" "true")
109
   (eq_attr "in_delay_slot" "true")
110
   (eq_attr "in_delay_slot" "true")])
111
 
112
(define_delay (eq_attr "type" "branch,uncond_branch")
113
  [(eq_attr "in_delay_slot" "true")
114
   (eq_attr "in_delay_slot" "true")
115
   (eq_attr "in_delay_slot" "true")])
116
 
117
;; Scheduling description for the ARC
118
 
119
(define_cpu_unit "branch")
120
 
121
(define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
122
                         "nothing")
123
 
124
;; 1) A conditional jump cannot immediately follow the insn setting the flags.
125
;; This isn't a complete solution as it doesn't come with guarantees.  That
126
;; is done in the branch patterns and in arc_print_operand.  This exists to
127
;; avoid inserting a nop when we can.
128
 
129
(define_insn_reservation "compare" 1 (eq_attr "type" "compare")
130
                         "nothing,branch")
131
 
132
(define_insn_reservation "branch" 1 (eq_attr "type" "branch")
133
                         "branch")
134
 
135
;; 2) References to loaded registers should wait a cycle.
136
 
137
;; Memory with load-delay of 1 (i.e., 2 cycle load).
138
 
139
(define_insn_reservation "memory" 2 (eq_attr "type" "load")
140
                         "nothing")
141
 
142
;; Move instructions.
143
 
144
(define_expand "movqi"
145
  [(set (match_operand:QI 0 "general_operand" "")
146
        (match_operand:QI 1 "general_operand" ""))]
147
  ""
148
  "
149
{
150
  /* Everything except mem = const or mem = mem can be done easily.  */
151
 
152
  if (GET_CODE (operands[0]) == MEM)
153
    operands[1] = force_reg (QImode, operands[1]);
154
}")
155
 
156
(define_insn "*movqi_insn"
157
  [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
158
        (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
159
;; ??? Needed?
160
  "register_operand (operands[0], QImode)
161
   || register_operand (operands[1], QImode)"
162
  "@
163
   mov%? %0,%1
164
   mov%? %0,%1
165
   ldb%U1%V1 %0,%1
166
   stb%U0%V0 %1,%0"
167
  [(set_attr "type" "move,move,load,store")])
168
 
169
;; ??? This may never match since there's no cmpqi insn.
170
 
171
(define_insn "*movqi_set_cc_insn"
172
  [(set (reg:CCZN 61) (compare:CCZN
173
                       (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
174
                       (const_int 0)))
175
   (set (match_operand:QI 0 "move_dest_operand" "=r")
176
        (match_dup 1))]
177
  ""
178
  "mov%?.f %0,%1"
179
  [(set_attr "type" "move")
180
   (set_attr "cond" "set_zn")])
181
 
182
(define_expand "movhi"
183
  [(set (match_operand:HI 0 "general_operand" "")
184
        (match_operand:HI 1 "general_operand" ""))]
185
  ""
186
  "
187
{
188
  /* Everything except mem = const or mem = mem can be done easily.  */
189
 
190
  if (GET_CODE (operands[0]) == MEM)
191
    operands[1] = force_reg (HImode, operands[1]);
192
}")
193
 
194
(define_insn "*movhi_insn"
195
  [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
196
        (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
197
  "register_operand (operands[0], HImode)
198
   || register_operand (operands[1], HImode)"
199
  "@
200
   mov%? %0,%1
201
   mov%? %0,%1
202
   ldw%U1%V1 %0,%1
203
   stw%U0%V0 %1,%0"
204
  [(set_attr "type" "move,move,load,store")])
205
 
206
;; ??? Will this ever match?
207
 
208
(define_insn "*movhi_set_cc_insn"
209
  [(set (reg:CCZN 61) (compare:CCZN
210
                       (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
211
                       (const_int 0)))
212
   (set (match_operand:HI 0 "move_dest_operand" "=r")
213
        (match_dup 1))]
214
;; ??? Needed?
215
  "register_operand (operands[0], HImode)
216
   || register_operand (operands[1], HImode)"
217
  "mov%?.f %0,%1"
218
  [(set_attr "type" "move")
219
   (set_attr "cond" "set_zn")])
220
 
221
(define_expand "movsi"
222
  [(set (match_operand:SI 0 "general_operand" "")
223
        (match_operand:SI 1 "general_operand" ""))]
224
  ""
225
  "
226
{
227
  /* Everything except mem = const or mem = mem can be done easily.  */
228
 
229
  if (GET_CODE (operands[0]) == MEM)
230
    operands[1] = force_reg (SImode, operands[1]);
231
}")
232
 
233
(define_insn "*movsi_insn"
234
  [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
235
        (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
236
  "register_operand (operands[0], SImode)
237
   || register_operand (operands[1], SImode)"
238
  "@
239
   mov%? %0,%1
240
   mov%? %0,%S1
241
   ld%U1%V1 %0,%1
242
   st%U0%V0 %1,%0"
243
  [(set_attr "type" "move,move,load,store")])
244
 
245
(define_insn "*movsi_set_cc_insn"
246
  [(set (reg:CCZN 61) (compare:CCZN
247
                       (match_operand:SI 1 "move_src_operand" "rIJi")
248
                       (const_int 0)))
249
   (set (match_operand:SI 0 "move_dest_operand" "=r")
250
        (match_dup 1))]
251
  "register_operand (operands[0], SImode)
252
   || register_operand (operands[1], SImode)"
253
  "mov%?.f %0,%S1"
254
  [(set_attr "type" "move")
255
   (set_attr "cond" "set_zn")])
256
 
257
(define_expand "movdi"
258
  [(set (match_operand:DI 0 "general_operand" "")
259
        (match_operand:DI 1 "general_operand" ""))]
260
  ""
261
  "
262
{
263
  /* Everything except mem = const or mem = mem can be done easily.  */
264
 
265
  if (GET_CODE (operands[0]) == MEM)
266
    operands[1] = force_reg (DImode, operands[1]);
267
}")
268
 
269
(define_insn "*movdi_insn"
270
  [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
271
        (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
272
  "register_operand (operands[0], DImode)
273
   || register_operand (operands[1], DImode)"
274
  "*
275
{
276
  switch (which_alternative)
277
    {
278
    case 0 :
279
      /* We normally copy the low-numbered register first.  However, if
280
         the first register operand 0 is the same as the second register of
281
         operand 1, we must copy in the opposite order.  */
282
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
283
        return \"mov %R0,%R1\;mov %0,%1\";
284
      else
285
        return \"mov %0,%1\;mov %R0,%R1\";
286
    case 1 :
287
      return \"mov %0,%L1\;mov %R0,%H1\";
288
    case 2 :
289
      /* If the low-address word is used in the address, we must load it
290
         last.  Otherwise, load it first.  Note that we cannot have
291
         auto-increment in that case since the address register is known to be
292
         dead.  */
293
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
294
                             operands [1], 0))
295
          return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
296
      else
297
          return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
298
    case 3 :
299
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
300
    default:
301
      gcc_unreachable ();
302
    }
303
}"
304
  [(set_attr "type" "move,move,load,store")
305
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
306
   (set_attr "length" "2,4,2,2")])
307
 
308
;(define_expand "movdi"
309
;  [(set (match_operand:DI 0 "general_operand" "")
310
;       (match_operand:DI 1 "general_operand" ""))]
311
;  ""
312
;  "
313
;{
314
;  /* Flow doesn't understand that this is effectively a DFmode move.
315
;     It doesn't know that all of `operands[0]' is set.  */
316
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
317
;
318
;  /* Emit insns that movsi_insn can handle.  */
319
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
320
;                       operand_subword (operands[1], 0, 0, DImode)));
321
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
322
;                       operand_subword (operands[1], 1, 0, DImode)));
323
;  DONE;
324
;}")
325
 
326
;; Floating point move insns.
327
 
328
(define_expand "movsf"
329
  [(set (match_operand:SF 0 "general_operand" "")
330
        (match_operand:SF 1 "general_operand" ""))]
331
  ""
332
  "
333
{
334
  /* Everything except mem = const or mem = mem can be done easily.  */
335
  if (GET_CODE (operands[0]) == MEM)
336
    operands[1] = force_reg (SFmode, operands[1]);
337
}")
338
 
339
(define_insn "*movsf_insn"
340
  [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
341
        (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
342
  "register_operand (operands[0], SFmode)
343
   || register_operand (operands[1], SFmode)"
344
  "@
345
   mov%? %0,%1
346
   mov%? %0,%1 ; %A1
347
   ld%U1%V1 %0,%1
348
   st%U0%V0 %1,%0"
349
  [(set_attr "type" "move,move,load,store")])
350
 
351
(define_expand "movdf"
352
  [(set (match_operand:DF 0 "general_operand" "")
353
        (match_operand:DF 1 "general_operand" ""))]
354
  ""
355
  "
356
{
357
  /* Everything except mem = const or mem = mem can be done easily.  */
358
  if (GET_CODE (operands[0]) == MEM)
359
    operands[1] = force_reg (DFmode, operands[1]);
360
}")
361
 
362
(define_insn "*movdf_insn"
363
  [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
364
        (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
365
  "register_operand (operands[0], DFmode)
366
   || register_operand (operands[1], DFmode)"
367
  "*
368
{
369
  switch (which_alternative)
370
    {
371
    case 0 :
372
      /* We normally copy the low-numbered register first.  However, if
373
         the first register operand 0 is the same as the second register of
374
         operand 1, we must copy in the opposite order.  */
375
      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
376
        return \"mov %R0,%R1\;mov %0,%1\";
377
      else
378
        return \"mov %0,%1\;mov %R0,%R1\";
379
    case 1 :
380
      return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
381
    case 2 :
382
      /* If the low-address word is used in the address, we must load it
383
         last.  Otherwise, load it first.  Note that we cannot have
384
         auto-increment in that case since the address register is known to be
385
         dead.  */
386
      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
387
                             operands [1], 0))
388
        return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
389
      else
390
        return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
391
    case 3 :
392
      return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
393
    default:
394
      gcc_unreachable ();
395
    }
396
}"
397
  [(set_attr "type" "move,move,load,store")
398
   ;; ??? The ld/st values could be 4 if it's [reg,bignum].
399
   (set_attr "length" "2,4,2,2")])
400
 
401
;(define_expand "movdf"
402
;  [(set (match_operand:DF 0 "general_operand" "")
403
;       (match_operand:DF 1 "general_operand" ""))]
404
;  ""
405
;  "
406
;{
407
;  /* Flow doesn't understand that this is effectively a DFmode move.
408
;     It doesn't know that all of `operands[0]' is set.  */
409
;  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
410
;
411
;  /* Emit insns that movsi_insn can handle.  */
412
;  emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
413
;                       operand_subword (operands[1], 0, 0, DFmode)));
414
;  emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
415
;                       operand_subword (operands[1], 1, 0, DFmode)));
416
;  DONE;
417
;}")
418
 
419
;; Load/Store with update instructions.
420
;;
421
;; Some of these we can get by using pre-decrement or pre-increment, but the
422
;; hardware can also do cases where the increment is not the size of the
423
;; object.
424
;;
425
;; In all these cases, we use operands 0 and 1 for the register being
426
;; incremented because those are the operands that local-alloc will
427
;; tie and these are the pair most likely to be tieable (and the ones
428
;; that will benefit the most).
429
;;
430
;; We use match_operator here because we need to know whether the memory
431
;; object is volatile or not.
432
 
433
(define_insn "*loadqi_update"
434
  [(set (match_operand:QI 3 "register_operand" "=r,r")
435
        (match_operator:QI 4 "load_update_operand"
436
         [(match_operand:SI 1 "register_operand" "0,0")
437
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
438
   (set (match_operand:SI 0 "register_operand" "=r,r")
439
        (plus:SI (match_dup 1) (match_dup 2)))]
440
  ""
441
  "ldb.a%V4 %3,[%0,%2]"
442
  [(set_attr "type" "load,load")
443
   (set_attr "length" "1,2")])
444
 
445
(define_insn "*load_zeroextendqisi_update"
446
  [(set (match_operand:SI 3 "register_operand" "=r,r")
447
        (zero_extend:SI (match_operator:QI 4 "load_update_operand"
448
                         [(match_operand:SI 1 "register_operand" "0,0")
449
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
450
   (set (match_operand:SI 0 "register_operand" "=r,r")
451
        (plus:SI (match_dup 1) (match_dup 2)))]
452
  ""
453
  "ldb.a%V4 %3,[%0,%2]"
454
  [(set_attr "type" "load,load")
455
   (set_attr "length" "1,2")])
456
 
457
(define_insn "*load_signextendqisi_update"
458
  [(set (match_operand:SI 3 "register_operand" "=r,r")
459
        (sign_extend:SI (match_operator:QI 4 "load_update_operand"
460
                         [(match_operand:SI 1 "register_operand" "0,0")
461
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
462
   (set (match_operand:SI 0 "register_operand" "=r,r")
463
        (plus:SI (match_dup 1) (match_dup 2)))]
464
  ""
465
  "ldb.x.a%V4 %3,[%0,%2]"
466
  [(set_attr "type" "load,load")
467
   (set_attr "length" "1,2")])
468
 
469
(define_insn "*storeqi_update"
470
  [(set (match_operator:QI 4 "store_update_operand"
471
         [(match_operand:SI 1 "register_operand" "0")
472
          (match_operand:SI 2 "short_immediate_operand" "I")])
473
        (match_operand:QI 3 "register_operand" "r"))
474
   (set (match_operand:SI 0 "register_operand" "=r")
475
        (plus:SI (match_dup 1) (match_dup 2)))]
476
  ""
477
  "stb.a%V4 %3,[%0,%2]"
478
  [(set_attr "type" "store")
479
   (set_attr "length" "1")])
480
 
481
(define_insn "*loadhi_update"
482
  [(set (match_operand:HI 3 "register_operand" "=r,r")
483
        (match_operator:HI 4 "load_update_operand"
484
         [(match_operand:SI 1 "register_operand" "0,0")
485
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
486
   (set (match_operand:SI 0 "register_operand" "=r,r")
487
        (plus:SI (match_dup 1) (match_dup 2)))]
488
  ""
489
  "ldw.a%V4 %3,[%0,%2]"
490
  [(set_attr "type" "load,load")
491
   (set_attr "length" "1,2")])
492
 
493
(define_insn "*load_zeroextendhisi_update"
494
  [(set (match_operand:SI 3 "register_operand" "=r,r")
495
        (zero_extend:SI (match_operator:HI 4 "load_update_operand"
496
                         [(match_operand:SI 1 "register_operand" "0,0")
497
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
498
   (set (match_operand:SI 0 "register_operand" "=r,r")
499
        (plus:SI (match_dup 1) (match_dup 2)))]
500
  ""
501
  "ldw.a%V4 %3,[%0,%2]"
502
  [(set_attr "type" "load,load")
503
   (set_attr "length" "1,2")])
504
 
505
(define_insn "*load_signextendhisi_update"
506
  [(set (match_operand:SI 3 "register_operand" "=r,r")
507
        (sign_extend:SI (match_operator:HI 4 "load_update_operand"
508
                         [(match_operand:SI 1 "register_operand" "0,0")
509
                          (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
510
   (set (match_operand:SI 0 "register_operand" "=r,r")
511
        (plus:SI (match_dup 1) (match_dup 2)))]
512
  ""
513
  "ldw.x.a%V4 %3,[%0,%2]"
514
  [(set_attr "type" "load,load")
515
   (set_attr "length" "1,2")])
516
 
517
(define_insn "*storehi_update"
518
  [(set (match_operator:HI 4 "store_update_operand"
519
         [(match_operand:SI 1 "register_operand" "0")
520
          (match_operand:SI 2 "short_immediate_operand" "I")])
521
        (match_operand:HI 3 "register_operand" "r"))
522
   (set (match_operand:SI 0 "register_operand" "=r")
523
        (plus:SI (match_dup 1) (match_dup 2)))]
524
  ""
525
  "stw.a%V4 %3,[%0,%2]"
526
  [(set_attr "type" "store")
527
   (set_attr "length" "1")])
528
 
529
(define_insn "*loadsi_update"
530
  [(set (match_operand:SI 3 "register_operand" "=r,r")
531
        (match_operator:SI 4 "load_update_operand"
532
         [(match_operand:SI 1 "register_operand" "0,0")
533
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
534
   (set (match_operand:SI 0 "register_operand" "=r,r")
535
        (plus:SI (match_dup 1) (match_dup 2)))]
536
  ""
537
  "ld.a%V4 %3,[%0,%2]"
538
  [(set_attr "type" "load,load")
539
   (set_attr "length" "1,2")])
540
 
541
(define_insn "*storesi_update"
542
  [(set (match_operator:SI 4 "store_update_operand"
543
         [(match_operand:SI 1 "register_operand" "0")
544
          (match_operand:SI 2 "short_immediate_operand" "I")])
545
        (match_operand:SI 3 "register_operand" "r"))
546
   (set (match_operand:SI 0 "register_operand" "=r")
547
        (plus:SI (match_dup 1) (match_dup 2)))]
548
  ""
549
  "st.a%V4 %3,[%0,%2]"
550
  [(set_attr "type" "store")
551
   (set_attr "length" "1")])
552
 
553
(define_insn "*loadsf_update"
554
  [(set (match_operand:SF 3 "register_operand" "=r,r")
555
        (match_operator:SF 4 "load_update_operand"
556
         [(match_operand:SI 1 "register_operand" "0,0")
557
          (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
558
   (set (match_operand:SI 0 "register_operand" "=r,r")
559
        (plus:SI (match_dup 1) (match_dup 2)))]
560
  ""
561
  "ld.a%V4 %3,[%0,%2]"
562
  [(set_attr "type" "load,load")
563
   (set_attr "length" "1,2")])
564
 
565
(define_insn "*storesf_update"
566
  [(set (match_operator:SF 4 "store_update_operand"
567
         [(match_operand:SI 1 "register_operand" "0")
568
          (match_operand:SI 2 "short_immediate_operand" "I")])
569
        (match_operand:SF 3 "register_operand" "r"))
570
   (set (match_operand:SI 0 "register_operand" "=r")
571
        (plus:SI (match_dup 1) (match_dup 2)))]
572
  ""
573
  "st.a%V4 %3,[%0,%2]"
574
  [(set_attr "type" "store")
575
   (set_attr "length" "1")])
576
 
577
;; Conditional move instructions.
578
 
579
(define_expand "movsicc"
580
  [(set (match_operand:SI 0 "register_operand" "")
581
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
582
                         (match_operand:SI 2 "nonmemory_operand" "")
583
                         (match_operand:SI 3 "register_operand" "")))]
584
  ""
585
  "
586
{
587
  enum rtx_code code = GET_CODE (operands[1]);
588
  rtx ccreg
589
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
590
                   61);
591
 
592
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
593
}")
594
 
595
;(define_expand "movdicc"
596
;  [(set (match_operand:DI 0 "register_operand" "")
597
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
598
;                        (match_operand:DI 2 "nonmemory_operand" "")
599
;                        (match_operand:DI 3 "register_operand" "")))]
600
;  "0 /* ??? this would work better if we had cmpdi */"
601
;  "
602
;{
603
;  enum rtx_code code = GET_CODE (operands[1]);
604
;  rtx ccreg
605
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
606
;                  61);
607
;
608
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
609
;}")
610
 
611
(define_expand "movsfcc"
612
  [(set (match_operand:SF 0 "register_operand" "")
613
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
614
                         (match_operand:SF 2 "nonmemory_operand" "")
615
                         (match_operand:SF 3 "register_operand" "")))]
616
  ""
617
  "
618
{
619
  enum rtx_code code = GET_CODE (operands[1]);
620
  rtx ccreg
621
    = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
622
                   61);
623
 
624
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
625
}")
626
 
627
;(define_expand "movdfcc"
628
;  [(set (match_operand:DF 0 "register_operand" "")
629
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
630
;                        (match_operand:DF 2 "nonmemory_operand" "")
631
;                        (match_operand:DF 3 "register_operand" "")))]
632
;  "0 /* ??? can generate less efficient code if constants involved */"
633
;  "
634
;{
635
; enum rtx_code code = GET_CODE (operands[1]);
636
; rtx ccreg
637
;   = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
638
;                  61);
639
;
640
;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
641
;}")
642
 
643
(define_insn "*movsicc_insn"
644
  [(set (match_operand:SI 0 "register_operand" "=r")
645
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
646
                         (match_operand:SI 2 "nonmemory_operand" "rJi")
647
                         (match_operand:SI 3 "register_operand" "0")))]
648
  ""
649
  "mov.%d1 %0,%S2"
650
  [(set_attr "type" "cmove")])
651
 
652
; ??? This doesn't properly handle constants.
653
;(define_insn "*movdicc_insn"
654
;  [(set (match_operand:DI 0 "register_operand" "=r,r")
655
;       (if_then_else:DI (match_operand 1 "comparison_operator" "")
656
;                        (match_operand:DI 2 "nonmemory_operand" "r,Ji")
657
;                        (match_operand:DI 3 "register_operand" "0,0")))]
658
;  "0"
659
;  "*
660
;{
661
;  switch (which_alternative)
662
;    {
663
;    case 0 :
664
;      /* We normally copy the low-numbered register first.  However, if
665
;        the first register operand 0 is the same as the second register of
666
;        operand 1, we must copy in the opposite order.  */
667
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
668
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
669
;      else
670
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
671
;    case 1 :
672
;      return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
673
;    }
674
;}"
675
;  [(set_attr "type" "cmove,cmove")
676
;   (set_attr "length" "2,4")])
677
 
678
(define_insn "*movsfcc_insn"
679
  [(set (match_operand:SF 0 "register_operand" "=r,r")
680
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
681
                         (match_operand:SF 2 "nonmemory_operand" "r,E")
682
                         (match_operand:SF 3 "register_operand" "0,0")))]
683
  ""
684
  "@
685
   mov.%d1 %0,%2
686
   mov.%d1 %0,%2 ; %A2"
687
  [(set_attr "type" "cmove,cmove")])
688
 
689
;(define_insn "*movdfcc_insn"
690
;  [(set (match_operand:DF 0 "register_operand" "=r,r")
691
;       (if_then_else:DF (match_operand 1 "comparison_operator" "")
692
;                        (match_operand:DF 2 "nonmemory_operand" "r,E")
693
;                        (match_operand:DF 3 "register_operand" "0,0")))]
694
;  "0"
695
;  "*
696
;{
697
;  switch (which_alternative)
698
;    {
699
;    case 0 :
700
;      /* We normally copy the low-numbered register first.  However, if
701
;        the first register operand 0 is the same as the second register of
702
;        operand 1, we must copy in the opposite order.  */
703
;      if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
704
;       return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
705
;      else
706
;       return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
707
;    case 1 :
708
;      return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
709
;    }
710
;}"
711
;  [(set_attr "type" "cmove,cmove")
712
;   (set_attr "length" "2,4")])
713
 
714
;; Zero extension instructions.
715
;; ??? We don't support volatile memrefs here, but I'm not sure why.
716
 
717
(define_insn "zero_extendqihi2"
718
  [(set (match_operand:HI 0 "register_operand" "=r,r")
719
        (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
720
  ""
721
  "@
722
   extb%? %0,%1
723
   ldb%U1 %0,%1"
724
  [(set_attr "type" "unary,load")])
725
 
726
(define_insn "*zero_extendqihi2_set_cc_insn"
727
  [(set (reg:CCZN 61) (compare:CCZN
728
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
729
                       (const_int 0)))
730
   (set (match_operand:HI 0 "register_operand" "=r")
731
        (zero_extend:HI (match_dup 1)))]
732
  ""
733
  "extb%?.f %0,%1"
734
  [(set_attr "type" "unary")
735
   (set_attr "cond" "set_zn")])
736
 
737
(define_insn "zero_extendqisi2"
738
  [(set (match_operand:SI 0 "register_operand" "=r,r")
739
        (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
740
  ""
741
  "@
742
   extb%? %0,%1
743
   ldb%U1 %0,%1"
744
  [(set_attr "type" "unary,load")])
745
 
746
(define_insn "*zero_extendqisi2_set_cc_insn"
747
  [(set (reg:CCZN 61) (compare:CCZN
748
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
749
                       (const_int 0)))
750
   (set (match_operand:SI 0 "register_operand" "=r")
751
        (zero_extend:SI (match_dup 1)))]
752
  ""
753
  "extb%?.f %0,%1"
754
  [(set_attr "type" "unary")
755
   (set_attr "cond" "set_zn")])
756
 
757
(define_insn "zero_extendhisi2"
758
  [(set (match_operand:SI 0 "register_operand" "=r,r")
759
        (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
760
  ""
761
  "@
762
   extw%? %0,%1
763
   ldw%U1 %0,%1"
764
  [(set_attr "type" "unary,load")])
765
 
766
(define_insn "*zero_extendhisi2_set_cc_insn"
767
  [(set (reg:CCZN 61) (compare:CCZN
768
                       (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
769
                       (const_int 0)))
770
   (set (match_operand:SI 0 "register_operand" "=r")
771
        (zero_extend:SI (match_dup 1)))]
772
  ""
773
  "extw%?.f %0,%1"
774
  [(set_attr "type" "unary")
775
   (set_attr "cond" "set_zn")])
776
 
777
;; Sign extension instructions.
778
 
779
(define_insn "extendqihi2"
780
  [(set (match_operand:HI 0 "register_operand" "=r,r")
781
        (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
782
  ""
783
  "@
784
   sexb%? %0,%1
785
   ldb.x%U1 %0,%1"
786
  [(set_attr "type" "unary,load")])
787
 
788
(define_insn "*extendqihi2_set_cc_insn"
789
  [(set (reg:CCZN 61) (compare:CCZN
790
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
791
                       (const_int 0)))
792
   (set (match_operand:HI 0 "register_operand" "=r")
793
        (sign_extend:HI (match_dup 1)))]
794
  ""
795
  "sexb%?.f %0,%1"
796
  [(set_attr "type" "unary")
797
   (set_attr "cond" "set_zn")])
798
 
799
(define_insn "extendqisi2"
800
  [(set (match_operand:SI 0 "register_operand" "=r,r")
801
        (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
802
  ""
803
  "@
804
   sexb%? %0,%1
805
   ldb.x%U1 %0,%1"
806
  [(set_attr "type" "unary,load")])
807
 
808
(define_insn "*extendqisi2_set_cc_insn"
809
  [(set (reg:CCZN 61) (compare:CCZN
810
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
811
                       (const_int 0)))
812
   (set (match_operand:SI 0 "register_operand" "=r")
813
        (sign_extend:SI (match_dup 1)))]
814
  ""
815
  "sexb%?.f %0,%1"
816
  [(set_attr "type" "unary")
817
   (set_attr "cond" "set_zn")])
818
 
819
(define_insn "extendhisi2"
820
  [(set (match_operand:SI 0 "register_operand" "=r,r")
821
        (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
822
  ""
823
  "@
824
   sexw%? %0,%1
825
   ldw.x%U1 %0,%1"
826
  [(set_attr "type" "unary,load")])
827
 
828
(define_insn "*extendhisi2_set_cc_insn"
829
  [(set (reg:CCZN 61) (compare:CCZN
830
                       (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
831
                       (const_int 0)))
832
   (set (match_operand:SI 0 "register_operand" "=r")
833
        (sign_extend:SI (match_dup 1)))]
834
  ""
835
  "sexw%?.f %0,%1"
836
  [(set_attr "type" "unary")
837
   (set_attr "cond" "set_zn")])
838
 
839
;; Arithmetic instructions.
840
 
841
(define_insn "addsi3"
842
  [(set (match_operand:SI 0 "register_operand" "=r")
843
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
844
                 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
845
  ""
846
  "add%? %0,%1,%2")
847
 
848
(define_insn "*addsi3_set_cc_insn"
849
  [(set (reg:CC 61) (compare:CC
850
                     (plus:SI (match_operand:SI 1 "register_operand" "%r")
851
                              (match_operand:SI 2 "nonmemory_operand" "rIJ"))
852
                     (const_int 0)))
853
   (set (match_operand:SI 0 "register_operand" "=r")
854
        (plus:SI (match_dup 1)
855
                 (match_dup 2)))]
856
  ""
857
  "add%?.f %0,%1,%2"
858
  [(set_attr "cond" "set")])
859
 
860
(define_insn "adddi3"
861
  [(set (match_operand:DI 0 "register_operand" "=r")
862
        (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
863
                 (match_operand:DI 2 "nonmemory_operand" "ri")))
864
   (clobber (reg:CC 61))]
865
  ""
866
  "*
867
{
868
  rtx op2 = operands[2];
869
 
870
  if (GET_CODE (op2) == CONST_INT)
871
    {
872
      int sign = INTVAL (op2);
873
      if (sign < 0)
874
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
875
      else
876
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
877
    }
878
  else
879
    return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
880
}"
881
  [(set_attr "length" "2")])
882
 
883
(define_insn "subsi3"
884
  [(set (match_operand:SI 0 "register_operand" "=r")
885
        (minus:SI (match_operand:SI 1 "register_operand" "r")
886
                  (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
887
  ""
888
  "sub%? %0,%1,%2")
889
 
890
(define_insn "*subsi3_set_cc_insn"
891
  [(set (reg:CC 61) (compare:CC
892
                     (minus:SI (match_operand:SI 1 "register_operand" "%r")
893
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
894
                     (const_int 0)))
895
   (set (match_operand:SI 0 "register_operand" "=r")
896
        (minus:SI (match_dup 1)
897
                  (match_dup 2)))]
898
  ""
899
  "sub%?.f %0,%1,%2"
900
  [(set_attr "cond" "set")])
901
 
902
(define_insn "subdi3"
903
  [(set (match_operand:DI 0 "register_operand" "=r")
904
        (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
905
                  (match_operand:DI 2 "nonmemory_operand" "ri")))
906
   (clobber (reg:CC 61))]
907
  ""
908
  "*
909
{
910
  rtx op2 = operands[2];
911
 
912
  if (GET_CODE (op2) == CONST_INT)
913
    {
914
      int sign = INTVAL (op2);
915
      if (sign < 0)
916
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
917
      else
918
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
919
    }
920
  else
921
    return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
922
}"
923
  [(set_attr "length" "2")])
924
 
925
;; Boolean instructions.
926
;;
927
;; We don't define the DImode versions as expand_binop does a good enough job.
928
 
929
(define_insn "andsi3"
930
  [(set (match_operand:SI 0 "register_operand" "=r")
931
        (and:SI (match_operand:SI 1 "register_operand" "%r")
932
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
933
  ""
934
  "and%? %0,%1,%2")
935
 
936
(define_insn "*andsi3_set_cc_insn"
937
  [(set (reg:CCZN 61) (compare:CCZN
938
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
939
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
940
                       (const_int 0)))
941
   (set (match_operand:SI 0 "register_operand" "=r")
942
        (and:SI (match_dup 1)
943
                (match_dup 2)))]
944
  ""
945
  "and%?.f %0,%1,%2"
946
  [(set_attr "cond" "set_zn")])
947
 
948
(define_insn "*bicsi3_insn"
949
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
950
        (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
951
                (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
952
  ""
953
  "bic%? %0,%1,%2"
954
  [(set_attr "length" "1,2,1,2")])
955
 
956
(define_insn "*bicsi3_set_cc_insn"
957
  [(set (reg:CCZN 61) (compare:CCZN
958
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
959
                               (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
960
                       (const_int 0)))
961
   (set (match_operand:SI 0 "register_operand" "=r")
962
        (and:SI (match_dup 1)
963
                (not:SI (match_dup 2))))]
964
  ""
965
  "bic%?.f %0,%1,%2"
966
  [(set_attr "cond" "set_zn")])
967
 
968
(define_insn "iorsi3"
969
  [(set (match_operand:SI 0 "register_operand" "=r")
970
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
971
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
972
  ""
973
  "or%? %0,%1,%2")
974
 
975
(define_insn "*iorsi3_set_cc_insn"
976
  [(set (reg:CCZN 61) (compare:CCZN
977
                       (ior:SI (match_operand:SI 1 "register_operand" "%r")
978
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
979
                       (const_int 0)))
980
   (set (match_operand:SI 0 "register_operand" "=r")
981
        (ior:SI (match_dup 1)
982
                (match_dup 2)))]
983
  ""
984
  "or%?.f %0,%1,%2"
985
  [(set_attr "cond" "set_zn")])
986
 
987
(define_insn "xorsi3"
988
  [(set (match_operand:SI 0 "register_operand" "=r")
989
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
990
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
991
  ""
992
  "xor%? %0,%1,%2")
993
 
994
(define_insn "*xorsi3_set_cc_insn"
995
  [(set (reg:CCZN 61) (compare:CCZN
996
                       (xor:SI (match_operand:SI 1 "register_operand" "%r")
997
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
998
                       (const_int 0)))
999
   (set (match_operand:SI 0 "register_operand" "=r")
1000
        (xor:SI (match_dup 1)
1001
                (match_dup 2)))]
1002
  ""
1003
  "xor%?.f %0,%1,%2"
1004
  [(set_attr "cond" "set_zn")])
1005
 
1006
(define_insn "negsi2"
1007
  [(set (match_operand:SI 0 "register_operand" "=r")
1008
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1009
  ""
1010
  "sub%? %0,0,%1"
1011
  [(set_attr "type" "unary")])
1012
 
1013
(define_insn "*negsi2_set_cc_insn"
1014
  [(set (reg:CC 61) (compare:CC
1015
                     (neg:SI (match_operand:SI 1 "register_operand" "r"))
1016
                     (const_int 0)))
1017
   (set (match_operand:SI 0 "register_operand" "=r")
1018
        (neg:SI (match_dup 1)))]
1019
  ""
1020
  "sub%?.f %0,0,%1"
1021
  [(set_attr "type" "unary")
1022
   (set_attr "cond" "set")])
1023
 
1024
(define_insn "negdi2"
1025
  [(set (match_operand:DI 0 "register_operand" "=r")
1026
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
1027
   (clobber (reg:SI 61))]
1028
  ""
1029
  "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1030
  [(set_attr "type" "unary")
1031
   (set_attr "length" "2")])
1032
 
1033
(define_insn "one_cmplsi2"
1034
  [(set (match_operand:SI 0 "register_operand" "=r")
1035
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
1036
  ""
1037
  "xor%? %0,%1,-1"
1038
  [(set_attr "type" "unary")])
1039
 
1040
(define_insn "*one_cmplsi2_set_cc_insn"
1041
  [(set (reg:CCZN 61) (compare:CCZN
1042
                       (not:SI (match_operand:SI 1 "register_operand" "r"))
1043
                       (const_int 0)))
1044
   (set (match_operand:SI 0 "register_operand" "=r")
1045
        (not:SI (match_dup 1)))]
1046
  ""
1047
  "xor%?.f %0,%1,-1"
1048
  [(set_attr "type" "unary")
1049
   (set_attr "cond" "set_zn")])
1050
 
1051
;; Shift instructions.
1052
 
1053
(define_expand "ashlsi3"
1054
  [(set (match_operand:SI 0 "register_operand" "")
1055
        (ashift:SI (match_operand:SI 1 "register_operand" "")
1056
                   (match_operand:SI 2 "nonmemory_operand" "")))]
1057
  ""
1058
  "
1059
{
1060
  if (! TARGET_SHIFTER)
1061
    {
1062
      emit_insn (gen_rtx_PARALLEL
1063
                 (VOIDmode,
1064
                  gen_rtvec (2,
1065
                             gen_rtx_SET (VOIDmode, operands[0],
1066
                                          gen_rtx_ASHIFT (SImode, operands[1],
1067
                                                          operands[2])),
1068
                             gen_rtx_CLOBBER (VOIDmode,
1069
                                              gen_rtx_SCRATCH (SImode)))));
1070
      DONE;
1071
    }
1072
}")
1073
 
1074
(define_expand "ashrsi3"
1075
  [(set (match_operand:SI 0 "register_operand" "")
1076
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1077
                     (match_operand:SI 2 "nonmemory_operand" "")))]
1078
  ""
1079
  "
1080
{
1081
  if (! TARGET_SHIFTER)
1082
    {
1083
      emit_insn (gen_rtx_PARALLEL
1084
                 (VOIDmode,
1085
                  gen_rtvec (2,
1086
                             gen_rtx_SET (VOIDmode, operands[0],
1087
                                          gen_rtx_ASHIFTRT (SImode,
1088
                                                            operands[1],
1089
                                                            operands[2])),
1090
                             gen_rtx_CLOBBER (VOIDmode,
1091
                                              gen_rtx_SCRATCH (SImode)))));
1092
      DONE;
1093
    }
1094
}")
1095
 
1096
(define_expand "lshrsi3"
1097
  [(set (match_operand:SI 0 "register_operand" "")
1098
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1099
                     (match_operand:SI 2 "nonmemory_operand" "")))]
1100
  ""
1101
  "
1102
{
1103
  if (! TARGET_SHIFTER)
1104
    {
1105
      emit_insn (gen_rtx_PARALLEL
1106
                 (VOIDmode,
1107
                  gen_rtvec (2,
1108
                             gen_rtx_SET (VOIDmode, operands[0],
1109
                                          gen_rtx_LSHIFTRT (SImode,
1110
                                                            operands[1],
1111
                                                            operands[2])),
1112
                             gen_rtx_CLOBBER (VOIDmode,
1113
                                              gen_rtx_SCRATCH (SImode)))));
1114
      DONE;
1115
    }
1116
}")
1117
 
1118
(define_insn "*ashlsi3_insn"
1119
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1120
        (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1121
                   (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1122
  "TARGET_SHIFTER"
1123
  "asl%? %0,%1,%2"
1124
  [(set_attr "type" "shift")
1125
   (set_attr "length" "1,2,1,2")])
1126
 
1127
(define_insn "*ashrsi3_insn"
1128
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1129
        (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1130
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1131
  "TARGET_SHIFTER"
1132
  "asr%? %0,%1,%2"
1133
  [(set_attr "type" "shift")
1134
   (set_attr "length" "1,2,1,2")])
1135
 
1136
(define_insn "*lshrsi3_insn"
1137
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1138
        (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1139
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1140
  "TARGET_SHIFTER"
1141
  "lsr%? %0,%1,%2"
1142
  [(set_attr "type" "shift")
1143
   (set_attr "length" "1,2,1,2")])
1144
 
1145
(define_insn "*shift_si3"
1146
  [(set (match_operand:SI 0 "register_operand" "=r")
1147
        (match_operator:SI 3 "shift_operator"
1148
                           [(match_operand:SI 1 "register_operand" "0")
1149
                            (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1150
   (clobber (match_scratch:SI 4 "=&r"))]
1151
  "! TARGET_SHIFTER"
1152
  "* return output_shift (operands);"
1153
  [(set_attr "type" "shift")
1154
   (set_attr "length" "8")])
1155
 
1156
;; Compare instructions.
1157
;; This controls RTL generation and register allocation.
1158
 
1159
;; We generate RTL for comparisons and branches by having the cmpxx
1160
;; patterns store away the operands.  Then, the scc and bcc patterns
1161
;; emit RTL for both the compare and the branch.
1162
 
1163
(define_expand "cmpsi"
1164
  [(set (reg:CC 61)
1165
        (compare:CC (match_operand:SI 0 "register_operand" "")
1166
                    (match_operand:SI 1 "nonmemory_operand" "")))]
1167
  ""
1168
  "
1169
{
1170
  arc_compare_op0 = operands[0];
1171
  arc_compare_op1 = operands[1];
1172
  DONE;
1173
}")
1174
 
1175
;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1176
;; This assumes sub.f 0,symbol,0 is a valid insn.
1177
;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
1178
;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1179
;; if it's a small constant.
1180
 
1181
(define_insn "*cmpsi_cc_insn"
1182
  [(set (reg:CC 61)
1183
        (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1184
                    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1185
  ""
1186
  "@
1187
   sub.f 0,%0,%1
1188
   sub.f %1,%0,%1
1189
   sub.f 0,%0,%1"
1190
  [(set_attr "type" "compare,compare,compare")])
1191
 
1192
(define_insn "*cmpsi_cczn_insn"
1193
  [(set (reg:CCZN 61)
1194
        (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1195
                      (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1196
  ""
1197
  "@
1198
   sub.f 0,%0,%1
1199
   sub.f %1,%0,%1
1200
   sub.f 0,%0,%1"
1201
  [(set_attr "type" "compare,compare,compare")])
1202
 
1203
(define_insn "*cmpsi_ccznc_insn"
1204
  [(set (reg:CCZNC 61)
1205
        (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1206
                       (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1207
  ""
1208
  "@
1209
   sub.f 0,%0,%1
1210
   sub.f %1,%0,%1
1211
   sub.f 0,%0,%1"
1212
  [(set_attr "type" "compare,compare,compare")])
1213
 
1214
;; Next come the scc insns.
1215
 
1216
(define_expand "seq"
1217
  [(set (match_operand:SI 0 "register_operand" "=r")
1218
        (eq:SI (match_dup 1) (const_int 0)))]
1219
  ""
1220
  "
1221
{
1222
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1223
}")
1224
 
1225
(define_expand "sne"
1226
  [(set (match_operand:SI 0 "register_operand" "=r")
1227
        (ne:SI (match_dup 1) (const_int 0)))]
1228
  ""
1229
  "
1230
{
1231
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1232
}")
1233
 
1234
(define_expand "sgt"
1235
  [(set (match_operand:SI 0 "register_operand" "=r")
1236
        (gt:SI (match_dup 1) (const_int 0)))]
1237
  ""
1238
  "
1239
{
1240
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1241
}")
1242
 
1243
(define_expand "sle"
1244
  [(set (match_operand:SI 0 "register_operand" "=r")
1245
        (le:SI (match_dup 1) (const_int 0)))]
1246
  ""
1247
  "
1248
{
1249
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1250
}")
1251
 
1252
(define_expand "sge"
1253
  [(set (match_operand:SI 0 "register_operand" "=r")
1254
        (ge:SI (match_dup 1) (const_int 0)))]
1255
  ""
1256
  "
1257
{
1258
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1259
}")
1260
 
1261
(define_expand "slt"
1262
  [(set (match_operand:SI 0 "register_operand" "=r")
1263
        (lt:SI (match_dup 1) (const_int 0)))]
1264
  ""
1265
  "
1266
{
1267
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1268
}")
1269
 
1270
(define_expand "sgtu"
1271
  [(set (match_operand:SI 0 "register_operand" "=r")
1272
        (gtu:SI (match_dup 1) (const_int 0)))]
1273
  ""
1274
  "
1275
{
1276
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1277
}")
1278
 
1279
(define_expand "sleu"
1280
  [(set (match_operand:SI 0 "register_operand" "=r")
1281
        (leu:SI (match_dup 1) (const_int 0)))]
1282
  ""
1283
  "
1284
{
1285
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1286
}")
1287
 
1288
(define_expand "sgeu"
1289
  [(set (match_operand:SI 0 "register_operand" "=r")
1290
        (geu:SI (match_dup 1) (const_int 0)))]
1291
  ""
1292
  "
1293
{
1294
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1295
}")
1296
 
1297
(define_expand "sltu"
1298
  [(set (match_operand:SI 0 "register_operand" "=r")
1299
        (ltu:SI (match_dup 1) (const_int 0)))]
1300
  ""
1301
  "
1302
{
1303
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1304
}")
1305
 
1306
(define_insn "*scc_insn"
1307
  [(set (match_operand:SI 0 "register_operand" "=r")
1308
        (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1309
  ""
1310
  "mov %0,1\;sub.%D1 %0,%0,%0"
1311
  [(set_attr "type" "unary")
1312
   (set_attr "length" "2")])
1313
 
1314
;; ??? Look up negscc insn.  See pa.md for example.
1315
(define_insn "*neg_scc_insn"
1316
  [(set (match_operand:SI 0 "register_operand" "=r")
1317
        (neg:SI (match_operator:SI 1 "comparison_operator"
1318
                 [(reg 61) (const_int 0)])))]
1319
  ""
1320
  "mov %0,-1\;sub.%D1 %0,%0,%0"
1321
  [(set_attr "type" "unary")
1322
   (set_attr "length" "2")])
1323
 
1324
(define_insn "*not_scc_insn"
1325
  [(set (match_operand:SI 0 "register_operand" "=r")
1326
        (not:SI (match_operator:SI 1 "comparison_operator"
1327
                 [(reg 61) (const_int 0)])))]
1328
  ""
1329
  "mov %0,1\;sub.%d1 %0,%0,%0"
1330
  [(set_attr "type" "unary")
1331
   (set_attr "length" "2")])
1332
 
1333
;; These control RTL generation for conditional jump insns
1334
 
1335
(define_expand "beq"
1336
  [(set (pc)
1337
        (if_then_else (eq (match_dup 1) (const_int 0))
1338
                      (label_ref (match_operand 0 "" ""))
1339
                      (pc)))]
1340
  ""
1341
  "
1342
{
1343
  operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1344
}")
1345
 
1346
(define_expand "bne"
1347
  [(set (pc)
1348
        (if_then_else (ne (match_dup 1) (const_int 0))
1349
                      (label_ref (match_operand 0 "" ""))
1350
                      (pc)))]
1351
  ""
1352
  "
1353
{
1354
  operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1355
}")
1356
 
1357
(define_expand "bgt"
1358
  [(set (pc)
1359
        (if_then_else (gt (match_dup 1) (const_int 0))
1360
                      (label_ref (match_operand 0 "" ""))
1361
                      (pc)))]
1362
  ""
1363
  "
1364
{
1365
  operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1366
}")
1367
 
1368
(define_expand "ble"
1369
  [(set (pc)
1370
        (if_then_else (le (match_dup 1) (const_int 0))
1371
                      (label_ref (match_operand 0 "" ""))
1372
                      (pc)))]
1373
  ""
1374
  "
1375
{
1376
  operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1377
}")
1378
 
1379
(define_expand "bge"
1380
  [(set (pc)
1381
        (if_then_else (ge (match_dup 1) (const_int 0))
1382
                      (label_ref (match_operand 0 "" ""))
1383
                      (pc)))]
1384
  ""
1385
  "
1386
{
1387
  operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1388
}")
1389
 
1390
(define_expand "blt"
1391
  [(set (pc)
1392
        (if_then_else (lt (match_dup 1) (const_int 0))
1393
                      (label_ref (match_operand 0 "" ""))
1394
                      (pc)))]
1395
  ""
1396
  "
1397
{
1398
  operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1399
}")
1400
 
1401
(define_expand "bgtu"
1402
  [(set (pc)
1403
        (if_then_else (gtu (match_dup 1) (const_int 0))
1404
                      (label_ref (match_operand 0 "" ""))
1405
                      (pc)))]
1406
  ""
1407
  "
1408
{
1409
  operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1410
}")
1411
 
1412
(define_expand "bleu"
1413
  [(set (pc)
1414
        (if_then_else (leu (match_dup 1) (const_int 0))
1415
                      (label_ref (match_operand 0 "" ""))
1416
                      (pc)))]
1417
  ""
1418
  "
1419
{
1420
  operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1421
}")
1422
 
1423
(define_expand "bgeu"
1424
  [(set (pc)
1425
        (if_then_else (geu (match_dup 1) (const_int 0))
1426
                      (label_ref (match_operand 0 "" ""))
1427
                      (pc)))]
1428
  ""
1429
  "
1430
{
1431
  operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1432
}")
1433
 
1434
(define_expand "bltu"
1435
  [(set (pc)
1436
        (if_then_else (ltu (match_dup 1) (const_int 0))
1437
                      (label_ref (match_operand 0 "" ""))
1438
                      (pc)))]
1439
  ""
1440
  "
1441
{
1442
  operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1443
}")
1444
 
1445
;; Now match both normal and inverted jump.
1446
 
1447
(define_insn "*branch_insn"
1448
  [(set (pc)
1449
        (if_then_else (match_operator 1 "proper_comparison_operator"
1450
                                      [(reg 61) (const_int 0)])
1451
                      (label_ref (match_operand 0 "" ""))
1452
                      (pc)))]
1453
  ""
1454
  "*
1455
{
1456
  if (arc_ccfsm_branch_deleted_p ())
1457
    {
1458
      arc_ccfsm_record_branch_deleted ();
1459
      return \"; branch deleted, next insns conditionalized\";
1460
    }
1461
  else
1462
    return \"%~b%d1%# %l0\";
1463
}"
1464
  [(set_attr "type" "branch")])
1465
 
1466
(define_insn "*rev_branch_insn"
1467
  [(set (pc)
1468
        (if_then_else (match_operator 1 "proper_comparison_operator"
1469
                                      [(reg 61) (const_int 0)])
1470
                      (pc)
1471
                      (label_ref (match_operand 0 "" ""))))]
1472
  "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1473
  "*
1474
{
1475
  if (arc_ccfsm_branch_deleted_p ())
1476
    {
1477
      arc_ccfsm_record_branch_deleted ();
1478
      return \"; branch deleted, next insns conditionalized\";
1479
    }
1480
  else
1481
    return \"%~b%D1%# %l0\";
1482
}"
1483
  [(set_attr "type" "branch")])
1484
 
1485
;; Unconditional and other jump instructions.
1486
 
1487
(define_insn "jump"
1488
  [(set (pc) (label_ref (match_operand 0 "" "")))]
1489
  ""
1490
  "b%* %l0"
1491
  [(set_attr "type" "uncond_branch")])
1492
 
1493
(define_insn "indirect_jump"
1494
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1495
  ""
1496
  "j%* %a0"
1497
  [(set_attr "type" "uncond_branch")])
1498
 
1499
;; Implement a switch statement.
1500
;; This wouldn't be necessary in the non-pic case if we could distinguish
1501
;; label refs of the jump table from other label refs.  The problem is that
1502
;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1503
;; the real address since it's the address of the table.
1504
 
1505
(define_expand "casesi"
1506
  [(set (match_dup 5)
1507
        (minus:SI (match_operand:SI 0 "register_operand" "")
1508
                  (match_operand:SI 1 "nonmemory_operand" "")))
1509
   (set (reg:CC 61)
1510
        (compare:CC (match_dup 5)
1511
                    (match_operand:SI 2 "nonmemory_operand" "")))
1512
   (set (pc)
1513
        (if_then_else (gtu (reg:CC 61)
1514
                           (const_int 0))
1515
                      (label_ref (match_operand 4 "" ""))
1516
                      (pc)))
1517
   (parallel
1518
    [(set (pc)
1519
          (mem:SI (plus:SI (mult:SI (match_dup 5)
1520
                                    (const_int 4))
1521
                           (label_ref (match_operand 3 "" "")))))
1522
     (clobber (match_scratch:SI 6 ""))
1523
     (clobber (match_scratch:SI 7 ""))])]
1524
  ""
1525
  "
1526
{
1527
  operands[5] = gen_reg_rtx (SImode);
1528
}")
1529
 
1530
(define_insn "*casesi_insn"
1531
  [(set (pc)
1532
        (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1533
                                  (const_int 4))
1534
                         (label_ref (match_operand 1 "" "")))))
1535
   (clobber (match_scratch:SI 2 "=r"))
1536
   (clobber (match_scratch:SI 3 "=r"))]
1537
  ""
1538
  "*
1539
{
1540
  output_asm_insn (\"mov %2,%1\", operands);
1541
  if (TARGET_SHIFTER)
1542
    output_asm_insn (\"asl %3,%0,2\", operands);
1543
  else
1544
    output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1545
  output_asm_insn (\"ld %2,[%2,%3]\", operands);
1546
  output_asm_insn (\"j.nd %a2\", operands);
1547
  return \"\";
1548
}"
1549
  [(set_attr "type" "uncond_branch")
1550
   (set_attr "length" "6")])
1551
 
1552
(define_insn "tablejump"
1553
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1554
   (use (label_ref (match_operand 1 "" "")))]
1555
  "0 /* disabled -> using casesi now */"
1556
  "j%* %a0"
1557
  [(set_attr "type" "uncond_branch")])
1558
 
1559
(define_expand "call"
1560
  ;; operands[1] is stack_size_rtx
1561
  ;; operands[2] is next_arg_register
1562
  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1563
                    (match_operand 1 "" ""))
1564
             (clobber (reg:SI 31))])]
1565
  ""
1566
  "")
1567
 
1568
(define_insn "*call_via_reg"
1569
  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1570
         (match_operand 1 "" ""))
1571
   (clobber (reg:SI 31))]
1572
  ""
1573
  "lr blink,[status]\;j.d %0\;add blink,blink,2"
1574
  [(set_attr "type" "call_no_delay_slot")
1575
   (set_attr "length" "3")])
1576
 
1577
(define_insn "*call_via_label"
1578
  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1579
         (match_operand 1 "" ""))
1580
   (clobber (reg:SI 31))]
1581
  ""
1582
  ; The %~ is necessary in case this insn gets conditionalized and the previous
1583
  ; insn is the cc setter.
1584
  "%~bl%!%* %0"
1585
  [(set_attr "type" "call")
1586
   (set_attr "cond" "canuse")])
1587
 
1588
(define_expand "call_value"
1589
  ;; operand 2 is stack_size_rtx
1590
  ;; operand 3 is next_arg_register
1591
  [(parallel [(set (match_operand 0 "register_operand" "=r")
1592
                   (call (match_operand:SI 1 "call_operand" "")
1593
                         (match_operand 2 "" "")))
1594
             (clobber (reg:SI 31))])]
1595
  ""
1596
  "")
1597
 
1598
(define_insn "*call_value_via_reg"
1599
  [(set (match_operand 0 "register_operand" "=r")
1600
        (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1601
              (match_operand 2 "" "")))
1602
   (clobber (reg:SI 31))]
1603
  ""
1604
  "lr blink,[status]\;j.d %1\;add blink,blink,2"
1605
  [(set_attr "type" "call_no_delay_slot")
1606
   (set_attr "length" "3")])
1607
 
1608
(define_insn "*call_value_via_label"
1609
  [(set (match_operand 0 "register_operand" "=r")
1610
        (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1611
              (match_operand 2 "" "")))
1612
   (clobber (reg:SI 31))]
1613
  ""
1614
  ; The %~ is necessary in case this insn gets conditionalized and the previous
1615
  ; insn is the cc setter.
1616
  "%~bl%!%* %1"
1617
  [(set_attr "type" "call")
1618
   (set_attr "cond" "canuse")])
1619
 
1620
(define_insn "nop"
1621
  [(const_int 0)]
1622
  ""
1623
  "nop"
1624
  [(set_attr "type" "misc")])
1625
 
1626
;; Special pattern to flush the icache.
1627
;; ??? Not sure what to do here.  Some ARC's are known to support this.
1628
 
1629
(define_insn "flush_icache"
1630
  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1631
  ""
1632
  "* return \"\";"
1633
  [(set_attr "type" "misc")])
1634
 
1635
;; Split up troublesome insns for better scheduling.
1636
 
1637
;; Peepholes go at the end.

powered by: WebSVN 2.1.0

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