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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [config/] [arc/] [arc.md] - Blame information for rev 859

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

Line No. Rev Author Line
1 282 jeremybenn
;; Machine description of the Argonaut ARC cpu for GNU C compiler
2
;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007, 2008
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_clobber (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_clobber (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 cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
589
                                XEXP (operands[1], 1));
590
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
591
}")
592
 
593
(define_expand "movsfcc"
594
  [(set (match_operand:SF 0 "register_operand" "")
595
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
596
                         (match_operand:SF 2 "nonmemory_operand" "")
597
                         (match_operand:SF 3 "register_operand" "")))]
598
  ""
599
  "
600
{
601
  enum rtx_code code = GET_CODE (operands[1]);
602
  rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
603
                                XEXP (operands[1], 1));
604
  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
605
}")
606
 
607
(define_insn "*movsicc_insn"
608
  [(set (match_operand:SI 0 "register_operand" "=r")
609
        (if_then_else:SI (match_operand 1 "comparison_operator" "")
610
                         (match_operand:SI 2 "nonmemory_operand" "rJi")
611
                         (match_operand:SI 3 "register_operand" "0")))]
612
  ""
613
  "mov.%d1 %0,%S2"
614
  [(set_attr "type" "cmove")])
615
 
616
(define_insn "*movsfcc_insn"
617
  [(set (match_operand:SF 0 "register_operand" "=r,r")
618
        (if_then_else:SF (match_operand 1 "comparison_operator" "")
619
                         (match_operand:SF 2 "nonmemory_operand" "r,E")
620
                         (match_operand:SF 3 "register_operand" "0,0")))]
621
  ""
622
  "@
623
   mov.%d1 %0,%2
624
   mov.%d1 %0,%2 ; %A2"
625
  [(set_attr "type" "cmove,cmove")])
626
 
627
 
628
;; Zero extension instructions.
629
;; ??? We don't support volatile memrefs here, but I'm not sure why.
630
 
631
(define_insn "zero_extendqihi2"
632
  [(set (match_operand:HI 0 "register_operand" "=r,r")
633
        (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
634
  ""
635
  "@
636
   extb%? %0,%1
637
   ldb%U1 %0,%1"
638
  [(set_attr "type" "unary,load")])
639
 
640
(define_insn "*zero_extendqihi2_set_cc_insn"
641
  [(set (reg:CCZN 61) (compare:CCZN
642
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
643
                       (const_int 0)))
644
   (set (match_operand:HI 0 "register_operand" "=r")
645
        (zero_extend:HI (match_dup 1)))]
646
  ""
647
  "extb%?.f %0,%1"
648
  [(set_attr "type" "unary")
649
   (set_attr "cond" "set_zn")])
650
 
651
(define_insn "zero_extendqisi2"
652
  [(set (match_operand:SI 0 "register_operand" "=r,r")
653
        (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
654
  ""
655
  "@
656
   extb%? %0,%1
657
   ldb%U1 %0,%1"
658
  [(set_attr "type" "unary,load")])
659
 
660
(define_insn "*zero_extendqisi2_set_cc_insn"
661
  [(set (reg:CCZN 61) (compare:CCZN
662
                       (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
663
                       (const_int 0)))
664
   (set (match_operand:SI 0 "register_operand" "=r")
665
        (zero_extend:SI (match_dup 1)))]
666
  ""
667
  "extb%?.f %0,%1"
668
  [(set_attr "type" "unary")
669
   (set_attr "cond" "set_zn")])
670
 
671
(define_insn "zero_extendhisi2"
672
  [(set (match_operand:SI 0 "register_operand" "=r,r")
673
        (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
674
  ""
675
  "@
676
   extw%? %0,%1
677
   ldw%U1 %0,%1"
678
  [(set_attr "type" "unary,load")])
679
 
680
(define_insn "*zero_extendhisi2_set_cc_insn"
681
  [(set (reg:CCZN 61) (compare:CCZN
682
                       (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
683
                       (const_int 0)))
684
   (set (match_operand:SI 0 "register_operand" "=r")
685
        (zero_extend:SI (match_dup 1)))]
686
  ""
687
  "extw%?.f %0,%1"
688
  [(set_attr "type" "unary")
689
   (set_attr "cond" "set_zn")])
690
 
691
;; Sign extension instructions.
692
 
693
(define_insn "extendqihi2"
694
  [(set (match_operand:HI 0 "register_operand" "=r,r")
695
        (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
696
  ""
697
  "@
698
   sexb%? %0,%1
699
   ldb.x%U1 %0,%1"
700
  [(set_attr "type" "unary,load")])
701
 
702
(define_insn "*extendqihi2_set_cc_insn"
703
  [(set (reg:CCZN 61) (compare:CCZN
704
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
705
                       (const_int 0)))
706
   (set (match_operand:HI 0 "register_operand" "=r")
707
        (sign_extend:HI (match_dup 1)))]
708
  ""
709
  "sexb%?.f %0,%1"
710
  [(set_attr "type" "unary")
711
   (set_attr "cond" "set_zn")])
712
 
713
(define_insn "extendqisi2"
714
  [(set (match_operand:SI 0 "register_operand" "=r,r")
715
        (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
716
  ""
717
  "@
718
   sexb%? %0,%1
719
   ldb.x%U1 %0,%1"
720
  [(set_attr "type" "unary,load")])
721
 
722
(define_insn "*extendqisi2_set_cc_insn"
723
  [(set (reg:CCZN 61) (compare:CCZN
724
                       (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
725
                       (const_int 0)))
726
   (set (match_operand:SI 0 "register_operand" "=r")
727
        (sign_extend:SI (match_dup 1)))]
728
  ""
729
  "sexb%?.f %0,%1"
730
  [(set_attr "type" "unary")
731
   (set_attr "cond" "set_zn")])
732
 
733
(define_insn "extendhisi2"
734
  [(set (match_operand:SI 0 "register_operand" "=r,r")
735
        (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
736
  ""
737
  "@
738
   sexw%? %0,%1
739
   ldw.x%U1 %0,%1"
740
  [(set_attr "type" "unary,load")])
741
 
742
(define_insn "*extendhisi2_set_cc_insn"
743
  [(set (reg:CCZN 61) (compare:CCZN
744
                       (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
745
                       (const_int 0)))
746
   (set (match_operand:SI 0 "register_operand" "=r")
747
        (sign_extend:SI (match_dup 1)))]
748
  ""
749
  "sexw%?.f %0,%1"
750
  [(set_attr "type" "unary")
751
   (set_attr "cond" "set_zn")])
752
 
753
;; Arithmetic instructions.
754
 
755
(define_insn "addsi3"
756
  [(set (match_operand:SI 0 "register_operand" "=r")
757
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
758
                 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
759
  ""
760
  "add%? %0,%1,%2")
761
 
762
(define_insn "*addsi3_set_cc_insn"
763
  [(set (reg:CC 61) (compare:CC
764
                     (plus:SI (match_operand:SI 1 "register_operand" "%r")
765
                              (match_operand:SI 2 "nonmemory_operand" "rIJ"))
766
                     (const_int 0)))
767
   (set (match_operand:SI 0 "register_operand" "=r")
768
        (plus:SI (match_dup 1)
769
                 (match_dup 2)))]
770
  ""
771
  "add%?.f %0,%1,%2"
772
  [(set_attr "cond" "set")])
773
 
774
(define_insn "adddi3"
775
  [(set (match_operand:DI 0 "register_operand" "=r")
776
        (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
777
                 (match_operand:DI 2 "nonmemory_operand" "ri")))
778
   (clobber (reg:CC 61))]
779
  ""
780
  "*
781
{
782
  rtx op2 = operands[2];
783
 
784
  if (GET_CODE (op2) == CONST_INT)
785
    {
786
      int sign = INTVAL (op2);
787
      if (sign < 0)
788
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
789
      else
790
        return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
791
    }
792
  else
793
    return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
794
}"
795
  [(set_attr "length" "2")])
796
 
797
(define_insn "subsi3"
798
  [(set (match_operand:SI 0 "register_operand" "=r")
799
        (minus:SI (match_operand:SI 1 "register_operand" "r")
800
                  (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
801
  ""
802
  "sub%? %0,%1,%2")
803
 
804
(define_insn "*subsi3_set_cc_insn"
805
  [(set (reg:CC 61) (compare:CC
806
                     (minus:SI (match_operand:SI 1 "register_operand" "%r")
807
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
808
                     (const_int 0)))
809
   (set (match_operand:SI 0 "register_operand" "=r")
810
        (minus:SI (match_dup 1)
811
                  (match_dup 2)))]
812
  ""
813
  "sub%?.f %0,%1,%2"
814
  [(set_attr "cond" "set")])
815
 
816
(define_insn "subdi3"
817
  [(set (match_operand:DI 0 "register_operand" "=r")
818
        (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
819
                  (match_operand:DI 2 "nonmemory_operand" "ri")))
820
   (clobber (reg:CC 61))]
821
  ""
822
  "*
823
{
824
  rtx op2 = operands[2];
825
 
826
  if (GET_CODE (op2) == CONST_INT)
827
    {
828
      int sign = INTVAL (op2);
829
      if (sign < 0)
830
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
831
      else
832
        return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
833
    }
834
  else
835
    return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
836
}"
837
  [(set_attr "length" "2")])
838
 
839
;; Boolean instructions.
840
;;
841
;; We don't define the DImode versions as expand_binop does a good enough job.
842
 
843
(define_insn "andsi3"
844
  [(set (match_operand:SI 0 "register_operand" "=r")
845
        (and:SI (match_operand:SI 1 "register_operand" "%r")
846
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
847
  ""
848
  "and%? %0,%1,%2")
849
 
850
(define_insn "*andsi3_set_cc_insn"
851
  [(set (reg:CCZN 61) (compare:CCZN
852
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
853
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
854
                       (const_int 0)))
855
   (set (match_operand:SI 0 "register_operand" "=r")
856
        (and:SI (match_dup 1)
857
                (match_dup 2)))]
858
  ""
859
  "and%?.f %0,%1,%2"
860
  [(set_attr "cond" "set_zn")])
861
 
862
(define_insn "*bicsi3_insn"
863
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
864
        (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
865
                (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
866
  ""
867
  "bic%? %0,%1,%2"
868
  [(set_attr "length" "1,2,1,2")])
869
 
870
(define_insn "*bicsi3_set_cc_insn"
871
  [(set (reg:CCZN 61) (compare:CCZN
872
                       (and:SI (match_operand:SI 1 "register_operand" "%r")
873
                               (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
874
                       (const_int 0)))
875
   (set (match_operand:SI 0 "register_operand" "=r")
876
        (and:SI (match_dup 1)
877
                (not:SI (match_dup 2))))]
878
  ""
879
  "bic%?.f %0,%1,%2"
880
  [(set_attr "cond" "set_zn")])
881
 
882
(define_insn "iorsi3"
883
  [(set (match_operand:SI 0 "register_operand" "=r")
884
        (ior:SI (match_operand:SI 1 "register_operand" "%r")
885
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
886
  ""
887
  "or%? %0,%1,%2")
888
 
889
(define_insn "*iorsi3_set_cc_insn"
890
  [(set (reg:CCZN 61) (compare:CCZN
891
                       (ior:SI (match_operand:SI 1 "register_operand" "%r")
892
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
893
                       (const_int 0)))
894
   (set (match_operand:SI 0 "register_operand" "=r")
895
        (ior:SI (match_dup 1)
896
                (match_dup 2)))]
897
  ""
898
  "or%?.f %0,%1,%2"
899
  [(set_attr "cond" "set_zn")])
900
 
901
(define_insn "xorsi3"
902
  [(set (match_operand:SI 0 "register_operand" "=r")
903
        (xor:SI (match_operand:SI 1 "register_operand" "%r")
904
                (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
905
  ""
906
  "xor%? %0,%1,%2")
907
 
908
(define_insn "*xorsi3_set_cc_insn"
909
  [(set (reg:CCZN 61) (compare:CCZN
910
                       (xor:SI (match_operand:SI 1 "register_operand" "%r")
911
                               (match_operand:SI 2 "nonmemory_operand" "rIJ"))
912
                       (const_int 0)))
913
   (set (match_operand:SI 0 "register_operand" "=r")
914
        (xor:SI (match_dup 1)
915
                (match_dup 2)))]
916
  ""
917
  "xor%?.f %0,%1,%2"
918
  [(set_attr "cond" "set_zn")])
919
 
920
(define_insn "negsi2"
921
  [(set (match_operand:SI 0 "register_operand" "=r")
922
        (neg:SI (match_operand:SI 1 "register_operand" "r")))]
923
  ""
924
  "sub%? %0,0,%1"
925
  [(set_attr "type" "unary")])
926
 
927
(define_insn "*negsi2_set_cc_insn"
928
  [(set (reg:CC 61) (compare:CC
929
                     (neg:SI (match_operand:SI 1 "register_operand" "r"))
930
                     (const_int 0)))
931
   (set (match_operand:SI 0 "register_operand" "=r")
932
        (neg:SI (match_dup 1)))]
933
  ""
934
  "sub%?.f %0,0,%1"
935
  [(set_attr "type" "unary")
936
   (set_attr "cond" "set")])
937
 
938
(define_insn "negdi2"
939
  [(set (match_operand:DI 0 "register_operand" "=r")
940
        (neg:DI (match_operand:DI 1 "register_operand" "r")))
941
   (clobber (reg:SI 61))]
942
  ""
943
  "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
944
  [(set_attr "type" "unary")
945
   (set_attr "length" "2")])
946
 
947
(define_insn "one_cmplsi2"
948
  [(set (match_operand:SI 0 "register_operand" "=r")
949
        (not:SI (match_operand:SI 1 "register_operand" "r")))]
950
  ""
951
  "xor%? %0,%1,-1"
952
  [(set_attr "type" "unary")])
953
 
954
(define_insn "*one_cmplsi2_set_cc_insn"
955
  [(set (reg:CCZN 61) (compare:CCZN
956
                       (not:SI (match_operand:SI 1 "register_operand" "r"))
957
                       (const_int 0)))
958
   (set (match_operand:SI 0 "register_operand" "=r")
959
        (not:SI (match_dup 1)))]
960
  ""
961
  "xor%?.f %0,%1,-1"
962
  [(set_attr "type" "unary")
963
   (set_attr "cond" "set_zn")])
964
 
965
;; Shift instructions.
966
 
967
(define_expand "ashlsi3"
968
  [(set (match_operand:SI 0 "register_operand" "")
969
        (ashift:SI (match_operand:SI 1 "register_operand" "")
970
                   (match_operand:SI 2 "nonmemory_operand" "")))]
971
  ""
972
  "
973
{
974
  if (! TARGET_SHIFTER)
975
    {
976
      emit_insn (gen_rtx_PARALLEL
977
                 (VOIDmode,
978
                  gen_rtvec (2,
979
                             gen_rtx_SET (VOIDmode, operands[0],
980
                                          gen_rtx_ASHIFT (SImode, operands[1],
981
                                                          operands[2])),
982
                             gen_rtx_CLOBBER (VOIDmode,
983
                                              gen_rtx_SCRATCH (SImode)))));
984
      DONE;
985
    }
986
}")
987
 
988
(define_expand "ashrsi3"
989
  [(set (match_operand:SI 0 "register_operand" "")
990
        (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
991
                     (match_operand:SI 2 "nonmemory_operand" "")))]
992
  ""
993
  "
994
{
995
  if (! TARGET_SHIFTER)
996
    {
997
      emit_insn (gen_rtx_PARALLEL
998
                 (VOIDmode,
999
                  gen_rtvec (2,
1000
                             gen_rtx_SET (VOIDmode, operands[0],
1001
                                          gen_rtx_ASHIFTRT (SImode,
1002
                                                            operands[1],
1003
                                                            operands[2])),
1004
                             gen_rtx_CLOBBER (VOIDmode,
1005
                                              gen_rtx_SCRATCH (SImode)))));
1006
      DONE;
1007
    }
1008
}")
1009
 
1010
(define_expand "lshrsi3"
1011
  [(set (match_operand:SI 0 "register_operand" "")
1012
        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1013
                     (match_operand:SI 2 "nonmemory_operand" "")))]
1014
  ""
1015
  "
1016
{
1017
  if (! TARGET_SHIFTER)
1018
    {
1019
      emit_insn (gen_rtx_PARALLEL
1020
                 (VOIDmode,
1021
                  gen_rtvec (2,
1022
                             gen_rtx_SET (VOIDmode, operands[0],
1023
                                          gen_rtx_LSHIFTRT (SImode,
1024
                                                            operands[1],
1025
                                                            operands[2])),
1026
                             gen_rtx_CLOBBER (VOIDmode,
1027
                                              gen_rtx_SCRATCH (SImode)))));
1028
      DONE;
1029
    }
1030
}")
1031
 
1032
(define_insn "*ashlsi3_insn"
1033
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1034
        (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1035
                   (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1036
  "TARGET_SHIFTER"
1037
  "asl%? %0,%1,%2"
1038
  [(set_attr "type" "shift")
1039
   (set_attr "length" "1,2,1,2")])
1040
 
1041
(define_insn "*ashrsi3_insn"
1042
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1043
        (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1044
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1045
  "TARGET_SHIFTER"
1046
  "asr%? %0,%1,%2"
1047
  [(set_attr "type" "shift")
1048
   (set_attr "length" "1,2,1,2")])
1049
 
1050
(define_insn "*lshrsi3_insn"
1051
  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1052
        (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1053
                     (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1054
  "TARGET_SHIFTER"
1055
  "lsr%? %0,%1,%2"
1056
  [(set_attr "type" "shift")
1057
   (set_attr "length" "1,2,1,2")])
1058
 
1059
(define_insn "*shift_si3"
1060
  [(set (match_operand:SI 0 "register_operand" "=r")
1061
        (match_operator:SI 3 "shift_operator"
1062
                           [(match_operand:SI 1 "register_operand" "0")
1063
                            (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1064
   (clobber (match_scratch:SI 4 "=&r"))]
1065
  "! TARGET_SHIFTER"
1066
  "* return output_shift (operands);"
1067
  [(set_attr "type" "shift")
1068
   (set_attr "length" "8")])
1069
 
1070
;; Compare instructions.
1071
;; This controls RTL generation and register allocation.
1072
 
1073
;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1074
;; This assumes sub.f 0,symbol,0 is a valid insn.
1075
;; Note that "sub.f 0,r0,1" is an 8 byte insn.  To avoid unnecessarily
1076
;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1077
;; if it's a small constant.
1078
 
1079
(define_insn "*cmpsi_cc_insn"
1080
  [(set (reg:CC 61)
1081
        (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1082
                    (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1083
  ""
1084
  "@
1085
   sub.f 0,%0,%1
1086
   sub.f %1,%0,%1
1087
   sub.f 0,%0,%1"
1088
  [(set_attr "type" "compare,compare,compare")])
1089
 
1090
(define_insn "*cmpsi_cczn_insn"
1091
  [(set (reg:CCZN 61)
1092
        (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1093
                      (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1094
  ""
1095
  "@
1096
   sub.f 0,%0,%1
1097
   sub.f %1,%0,%1
1098
   sub.f 0,%0,%1"
1099
  [(set_attr "type" "compare,compare,compare")])
1100
 
1101
(define_insn "*cmpsi_ccznc_insn"
1102
  [(set (reg:CCZNC 61)
1103
        (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1104
                       (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1105
  ""
1106
  "@
1107
   sub.f 0,%0,%1
1108
   sub.f %1,%0,%1
1109
   sub.f 0,%0,%1"
1110
  [(set_attr "type" "compare,compare,compare")])
1111
 
1112
;; Next come the scc insn and its expander.
1113
 
1114
(define_expand "cstoresi4"
1115
  [(set (match_dup 4)
1116
        (match_op_dup 5
1117
         [(match_operand:SI 2 "register_operand" "")
1118
          (match_operand:SI 3 "nonmemory_operand" "")]))
1119
   (set (match_operand:SI 0 "register_operand")
1120
        (match_operator:SI 1 "ordered_comparison_operator"
1121
         [(match_dup 4)
1122
          (const_int 0)]))]
1123
  ""
1124
  "
1125
{
1126
  operands[4] = gen_compare_reg (GET_CODE (operands[1]),
1127
                                 operands[2], operands[3]);
1128
  operands[5] = gen_rtx_fmt_ee (COMPARE,
1129
                                GET_MODE (operands[4]),
1130
                                operands[2], operands[3]);
1131
}")
1132
 
1133
(define_insn "*scc_insn"
1134
  [(set (match_operand:SI 0 "register_operand" "=r")
1135
        (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1136
  ""
1137
  "mov %0,1\;sub.%D1 %0,%0,%0"
1138
  [(set_attr "type" "unary")
1139
   (set_attr "length" "2")])
1140
 
1141
;; ??? Look up negscc insn.  See pa.md for example.
1142
(define_insn "*neg_scc_insn"
1143
  [(set (match_operand:SI 0 "register_operand" "=r")
1144
        (neg:SI (match_operator:SI 1 "comparison_operator"
1145
                 [(reg 61) (const_int 0)])))]
1146
  ""
1147
  "mov %0,-1\;sub.%D1 %0,%0,%0"
1148
  [(set_attr "type" "unary")
1149
   (set_attr "length" "2")])
1150
 
1151
(define_insn "*not_scc_insn"
1152
  [(set (match_operand:SI 0 "register_operand" "=r")
1153
        (not:SI (match_operator:SI 1 "comparison_operator"
1154
                 [(reg 61) (const_int 0)])))]
1155
  ""
1156
  "mov %0,1\;sub.%d1 %0,%0,%0"
1157
  [(set_attr "type" "unary")
1158
   (set_attr "length" "2")])
1159
 
1160
;; These control RTL generation for conditional jump insns
1161
 
1162
(define_expand "cbranchsi4"
1163
  [(set (match_dup 4)
1164
        (match_op_dup 5
1165
         [(match_operand:SI 1 "register_operand" "")
1166
          (match_operand:SI 2 "nonmemory_operand" "")]))
1167
   (set (pc)
1168
        (if_then_else
1169
              (match_operator 0 "ordered_comparison_operator"
1170
               [(match_dup 4)
1171
                (const_int 0)])
1172
              (label_ref (match_operand 3 "" ""))
1173
              (pc)))]
1174
  ""
1175
  "
1176
{
1177
  operands[4] = gen_compare_reg (GET_CODE (operands[0]),
1178
                                 operands[1], operands[2]);
1179
  operands[5] = gen_rtx_fmt_ee (COMPARE,
1180
                                GET_MODE (operands[4]),
1181
                                operands[1], operands[2]);
1182
}")
1183
 
1184
;; Now match both normal and inverted jump.
1185
 
1186
(define_insn "*branch_insn"
1187
  [(set (pc)
1188
        (if_then_else (match_operator 1 "proper_comparison_operator"
1189
                                      [(reg 61) (const_int 0)])
1190
                      (label_ref (match_operand 0 "" ""))
1191
                      (pc)))]
1192
  ""
1193
  "*
1194
{
1195
  if (arc_ccfsm_branch_deleted_p ())
1196
    {
1197
      arc_ccfsm_record_branch_deleted ();
1198
      return \"; branch deleted, next insns conditionalized\";
1199
    }
1200
  else
1201
    return \"%~b%d1%# %l0\";
1202
}"
1203
  [(set_attr "type" "branch")])
1204
 
1205
(define_insn "*rev_branch_insn"
1206
  [(set (pc)
1207
        (if_then_else (match_operator 1 "proper_comparison_operator"
1208
                                      [(reg 61) (const_int 0)])
1209
                      (pc)
1210
                      (label_ref (match_operand 0 "" ""))))]
1211
  "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1212
  "*
1213
{
1214
  if (arc_ccfsm_branch_deleted_p ())
1215
    {
1216
      arc_ccfsm_record_branch_deleted ();
1217
      return \"; branch deleted, next insns conditionalized\";
1218
    }
1219
  else
1220
    return \"%~b%D1%# %l0\";
1221
}"
1222
  [(set_attr "type" "branch")])
1223
 
1224
;; Unconditional and other jump instructions.
1225
 
1226
(define_insn "jump"
1227
  [(set (pc) (label_ref (match_operand 0 "" "")))]
1228
  ""
1229
  "b%* %l0"
1230
  [(set_attr "type" "uncond_branch")])
1231
 
1232
(define_insn "indirect_jump"
1233
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1234
  ""
1235
  "j%* %a0"
1236
  [(set_attr "type" "uncond_branch")])
1237
 
1238
;; Implement a switch statement.
1239
;; This wouldn't be necessary in the non-pic case if we could distinguish
1240
;; label refs of the jump table from other label refs.  The problem is that
1241
;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1242
;; the real address since it's the address of the table.
1243
 
1244
(define_expand "casesi"
1245
  [(set (match_dup 5)
1246
        (minus:SI (match_operand:SI 0 "register_operand" "")
1247
                  (match_operand:SI 1 "nonmemory_operand" "")))
1248
   (set (reg:CC 61)
1249
        (compare:CC (match_dup 5)
1250
                    (match_operand:SI 2 "nonmemory_operand" "")))
1251
   (set (pc)
1252
        (if_then_else (gtu (reg:CC 61)
1253
                           (const_int 0))
1254
                      (label_ref (match_operand 4 "" ""))
1255
                      (pc)))
1256
   (parallel
1257
    [(set (pc)
1258
          (mem:SI (plus:SI (mult:SI (match_dup 5)
1259
                                    (const_int 4))
1260
                           (label_ref (match_operand 3 "" "")))))
1261
     (clobber (match_scratch:SI 6 ""))
1262
     (clobber (match_scratch:SI 7 ""))])]
1263
  ""
1264
  "
1265
{
1266
  operands[5] = gen_reg_rtx (SImode);
1267
}")
1268
 
1269
(define_insn "*casesi_insn"
1270
  [(set (pc)
1271
        (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1272
                                  (const_int 4))
1273
                         (label_ref (match_operand 1 "" "")))))
1274
   (clobber (match_scratch:SI 2 "=r"))
1275
   (clobber (match_scratch:SI 3 "=r"))]
1276
  ""
1277
  "*
1278
{
1279
  output_asm_insn (\"mov %2,%1\", operands);
1280
  if (TARGET_SHIFTER)
1281
    output_asm_insn (\"asl %3,%0,2\", operands);
1282
  else
1283
    output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1284
  output_asm_insn (\"ld %2,[%2,%3]\", operands);
1285
  output_asm_insn (\"j.nd %a2\", operands);
1286
  return \"\";
1287
}"
1288
  [(set_attr "type" "uncond_branch")
1289
   (set_attr "length" "6")])
1290
 
1291
(define_insn "tablejump"
1292
  [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1293
   (use (label_ref (match_operand 1 "" "")))]
1294
  "0 /* disabled -> using casesi now */"
1295
  "j%* %a0"
1296
  [(set_attr "type" "uncond_branch")])
1297
 
1298
(define_expand "call"
1299
  ;; operands[1] is stack_size_rtx
1300
  ;; operands[2] is next_arg_register
1301
  [(parallel [(call (match_operand:SI 0 "call_operand" "")
1302
                    (match_operand 1 "" ""))
1303
             (clobber (reg:SI 31))])]
1304
  ""
1305
  "")
1306
 
1307
(define_insn "*call_via_reg"
1308
  [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1309
         (match_operand 1 "" ""))
1310
   (clobber (reg:SI 31))]
1311
  ""
1312
  "lr blink,[status]\;j.d %0\;add blink,blink,2"
1313
  [(set_attr "type" "call_no_delay_slot")
1314
   (set_attr "length" "3")])
1315
 
1316
(define_insn "*call_via_label"
1317
  [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1318
         (match_operand 1 "" ""))
1319
   (clobber (reg:SI 31))]
1320
  ""
1321
  ; The %~ is necessary in case this insn gets conditionalized and the previous
1322
  ; insn is the cc setter.
1323
  "%~bl%!%* %0"
1324
  [(set_attr "type" "call")
1325
   (set_attr "cond" "canuse")])
1326
 
1327
(define_expand "call_value"
1328
  ;; operand 2 is stack_size_rtx
1329
  ;; operand 3 is next_arg_register
1330
  [(parallel [(set (match_operand 0 "register_operand" "=r")
1331
                   (call (match_operand:SI 1 "call_operand" "")
1332
                         (match_operand 2 "" "")))
1333
             (clobber (reg:SI 31))])]
1334
  ""
1335
  "")
1336
 
1337
(define_insn "*call_value_via_reg"
1338
  [(set (match_operand 0 "register_operand" "=r")
1339
        (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1340
              (match_operand 2 "" "")))
1341
   (clobber (reg:SI 31))]
1342
  ""
1343
  "lr blink,[status]\;j.d %1\;add blink,blink,2"
1344
  [(set_attr "type" "call_no_delay_slot")
1345
   (set_attr "length" "3")])
1346
 
1347
(define_insn "*call_value_via_label"
1348
  [(set (match_operand 0 "register_operand" "=r")
1349
        (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1350
              (match_operand 2 "" "")))
1351
   (clobber (reg:SI 31))]
1352
  ""
1353
  ; The %~ is necessary in case this insn gets conditionalized and the previous
1354
  ; insn is the cc setter.
1355
  "%~bl%!%* %1"
1356
  [(set_attr "type" "call")
1357
   (set_attr "cond" "canuse")])
1358
 
1359
(define_insn "nop"
1360
  [(const_int 0)]
1361
  ""
1362
  "nop"
1363
  [(set_attr "type" "misc")])
1364
 
1365
;; Special pattern to flush the icache.
1366
;; ??? Not sure what to do here.  Some ARC's are known to support this.
1367
 
1368
(define_insn "flush_icache"
1369
  [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1370
  ""
1371
  "* return \"\";"
1372
  [(set_attr "type" "misc")])
1373
 
1374
;; Split up troublesome insns for better scheduling.
1375
 
1376
;; 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.