Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / gcc / config / arc / arc.md
blobb67984babbb429e94c0f2b0230f45ecab98c0eea
1 ;; 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.
5 ;; This file is part of GCC.
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.
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.
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 ;; <http://www.gnu.org/licenses/>.
21 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 ;; ??? This is an old port, and is undoubtedly suffering from bit rot.
25 ;; Insn type.  Used to default other attribute values.
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"))
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))
39          (eq_attr "type" "store")
40          (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
41                        (const_int 2) (const_int 1))
43          (eq_attr "type" "move,unary,compare")
44          (if_then_else (match_operand 1 "long_immediate_operand" "")
45                        (const_int 2) (const_int 1))
47          (eq_attr "type" "binary,mul")
48          (if_then_else (match_operand 2 "long_immediate_operand" "")
49                        (const_int 2) (const_int 1))
51          (eq_attr "type" "cmove")
52          (if_then_else (match_operand 2 "register_operand" "")
53                        (const_int 1) (const_int 2))
55          (eq_attr "type" "multi") (const_int 2)
56         ]
58         (const_int 1)))
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")])
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.
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.
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")
84          (eq_attr "type" "compare")
85          (const_string "set")
87          (eq_attr "type" "cmove,branch")
88          (const_string "use")
90          (eq_attr "type" "multi,misc")
91          (const_string "clob")
92          ]
94          (const_string "nocond")))
96 ;; Delay slots.
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          ]
103          (if_then_else (eq_attr "length" "1")
104                        (const_string "true")
105                        (const_string "false"))))
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")])
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 \f   
117 ;; Scheduling description for the ARC
119 (define_cpu_unit "branch")
121 (define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
122                          "nothing")
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.
129 (define_insn_reservation "compare" 1 (eq_attr "type" "compare")
130                          "nothing,branch")
132 (define_insn_reservation "branch" 1 (eq_attr "type" "branch")
133                          "branch")
135 ;; 2) References to loaded registers should wait a cycle.
137 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
139 (define_insn_reservation "memory" 2 (eq_attr "type" "load")
140                          "nothing")
142 ;; Move instructions.
144 (define_expand "movqi"
145   [(set (match_operand:QI 0 "general_operand" "")
146         (match_operand:QI 1 "general_operand" ""))]
147   ""
148   "
150   /* Everything except mem = const or mem = mem can be done easily.  */
152   if (GET_CODE (operands[0]) == MEM)
153     operands[1] = force_reg (QImode, operands[1]);
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")])
169 ;; ??? This may never match since there's no cmpqi insn.
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")])
182 (define_expand "movhi"
183   [(set (match_operand:HI 0 "general_operand" "")
184         (match_operand:HI 1 "general_operand" ""))]
185   ""
186   "
188   /* Everything except mem = const or mem = mem can be done easily.  */
190   if (GET_CODE (operands[0]) == MEM)
191     operands[1] = force_reg (HImode, operands[1]);
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")])
206 ;; ??? Will this ever match?
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")])
221 (define_expand "movsi"
222   [(set (match_operand:SI 0 "general_operand" "")
223         (match_operand:SI 1 "general_operand" ""))]
224   ""
225   "
227   /* Everything except mem = const or mem = mem can be done easily.  */
229   if (GET_CODE (operands[0]) == MEM)
230     operands[1] = force_reg (SImode, operands[1]);
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")])
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")])
257 (define_expand "movdi"
258   [(set (match_operand:DI 0 "general_operand" "")
259         (match_operand:DI 1 "general_operand" ""))]
260   ""
261   "
263   /* Everything except mem = const or mem = mem can be done easily.  */
265   if (GET_CODE (operands[0]) == MEM)
266     operands[1] = force_reg (DImode, operands[1]);
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   "*
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     }
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")])
308 ;(define_expand "movdi"
309 ;  [(set (match_operand:DI 0 "general_operand" "")
310 ;       (match_operand:DI 1 "general_operand" ""))]
311 ;  ""
312 ;  "
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]);
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 ;}")
326 ;; Floating point move insns.
328 (define_expand "movsf"
329   [(set (match_operand:SF 0 "general_operand" "")
330         (match_operand:SF 1 "general_operand" ""))]
331   ""
332   "
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]);
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")])
351 (define_expand "movdf"
352   [(set (match_operand:DF 0 "general_operand" "")
353         (match_operand:DF 1 "general_operand" ""))]
354   ""
355   "
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]);
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   "*
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     }
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")])
401 ;(define_expand "movdf"
402 ;  [(set (match_operand:DF 0 "general_operand" "")
403 ;       (match_operand:DF 1 "general_operand" ""))]
404 ;  ""
405 ;  "
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]);
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 ;}")
419 ;; Load/Store with update instructions.
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.
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).
430 ;; We use match_operator here because we need to know whether the memory
431 ;; object is volatile or not.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
577 ;; Conditional move instructions.
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   "
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);
592   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
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 ;  "
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);
608 ;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
609 ;}")
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   "
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);
624   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
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 ;  "
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);
640 ;  operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
641 ;}")
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")])
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 ;  "*
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 ;    }
675 ;  [(set_attr "type" "cmove,cmove")
676 ;   (set_attr "length" "2,4")])
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")])
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 ;  "*
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 ;    }
711 ;  [(set_attr "type" "cmove,cmove")
712 ;   (set_attr "length" "2,4")])
714 ;; Zero extension instructions.
715 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
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")])
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")])
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")])
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")])
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")])
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")])
777 ;; Sign extension instructions.
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")])
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")])
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")])
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")])
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")])
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")])
839 ;; Arithmetic instructions.
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")
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")])
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   "*
868   rtx op2 = operands[2];
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\";
881   [(set_attr "length" "2")])
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")
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")])
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   "*
910   rtx op2 = operands[2];
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\";
923   [(set_attr "length" "2")])
925 ;; Boolean instructions.
927 ;; We don't define the DImode versions as expand_binop does a good enough job.
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")
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")])
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")])
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")])
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")
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")])
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")
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")])
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")])
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")])
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")])
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")])
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")])
1051 ;; Shift instructions.
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   "
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     }
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   "
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     }
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   "
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     }
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")])
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")])
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")])
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")])
1156 ;; Compare instructions.
1157 ;; This controls RTL generation and register allocation.
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.
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   "
1170   arc_compare_op0 = operands[0];
1171   arc_compare_op1 = operands[1];
1172   DONE;
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.
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")])
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")])
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")])
1214 ;; Next come the scc insns.
1216 (define_expand "seq"
1217   [(set (match_operand:SI 0 "register_operand" "=r")
1218         (eq:SI (match_dup 1) (const_int 0)))]
1219   ""
1220   "
1222   operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1225 (define_expand "sne"
1226   [(set (match_operand:SI 0 "register_operand" "=r")
1227         (ne:SI (match_dup 1) (const_int 0)))]
1228   ""
1229   "
1231   operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1234 (define_expand "sgt"
1235   [(set (match_operand:SI 0 "register_operand" "=r")
1236         (gt:SI (match_dup 1) (const_int 0)))]
1237   ""
1238   "
1240   operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1243 (define_expand "sle"
1244   [(set (match_operand:SI 0 "register_operand" "=r")
1245         (le:SI (match_dup 1) (const_int 0)))]
1246   ""
1247   "
1249   operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1252 (define_expand "sge"
1253   [(set (match_operand:SI 0 "register_operand" "=r")
1254         (ge:SI (match_dup 1) (const_int 0)))]
1255   ""
1256   "
1258   operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1261 (define_expand "slt"
1262   [(set (match_operand:SI 0 "register_operand" "=r")
1263         (lt:SI (match_dup 1) (const_int 0)))]
1264   ""
1265   "
1267   operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1270 (define_expand "sgtu"
1271   [(set (match_operand:SI 0 "register_operand" "=r")
1272         (gtu:SI (match_dup 1) (const_int 0)))]
1273   ""
1274   "
1276   operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1279 (define_expand "sleu"
1280   [(set (match_operand:SI 0 "register_operand" "=r")
1281         (leu:SI (match_dup 1) (const_int 0)))]
1282   ""
1283   "
1285   operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1288 (define_expand "sgeu"
1289   [(set (match_operand:SI 0 "register_operand" "=r")
1290         (geu:SI (match_dup 1) (const_int 0)))]
1291   ""
1292   "
1294   operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1297 (define_expand "sltu"
1298   [(set (match_operand:SI 0 "register_operand" "=r")
1299         (ltu:SI (match_dup 1) (const_int 0)))]
1300   ""
1301   "
1303   operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
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")])
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")])
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")])
1333 ;; These control RTL generation for conditional jump insns
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   "
1343   operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
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   "
1354   operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
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   "
1365   operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
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   "
1376   operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
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   "
1387   operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
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   "
1398   operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
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   "
1409   operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
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   "
1420   operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
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   "
1431   operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
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   "
1442   operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1445 ;; Now match both normal and inverted jump.
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   "*
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\";
1464   [(set_attr "type" "branch")])
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   "*
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\";
1483   [(set_attr "type" "branch")])
1485 ;; Unconditional and other jump instructions.
1487 (define_insn "jump"
1488   [(set (pc) (label_ref (match_operand 0 "" "")))]
1489   ""
1490   "b%* %l0"
1491   [(set_attr "type" "uncond_branch")])
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")])
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.
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   "
1527   operands[5] = gen_reg_rtx (SImode);
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   "*
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 \"\";
1549   [(set_attr "type" "uncond_branch")
1550    (set_attr "length" "6")])
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")])
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   "")
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")])
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")])
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   "")
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")])
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")])
1620 (define_insn "nop"
1621   [(const_int 0)]
1622   ""
1623   "nop"
1624   [(set_attr "type" "misc")])
1626 ;; Special pattern to flush the icache.
1627 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
1629 (define_insn "flush_icache"
1630   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1631   ""
1632   "* return \"\";"
1633   [(set_attr "type" "misc")])
1635 ;; Split up troublesome insns for better scheduling.
1637 ;; Peepholes go at the end.