2009-07-17 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / gcc / config / arc / arc.md
blob09e47daf1d1e67f5cf1516cd9f9e4941a7adf242
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 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);
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   "
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);
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")])
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")])
628 ;; Zero extension instructions.
629 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
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")])
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")])
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")])
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")])
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")])
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")])
691 ;; Sign extension instructions.
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")])
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")])
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")])
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")])
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")])
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")])
753 ;; Arithmetic instructions.
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")
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")])
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   "*
782   rtx op2 = operands[2];
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\";
795   [(set_attr "length" "2")])
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")
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")])
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   "*
824   rtx op2 = operands[2];
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\";
837   [(set_attr "length" "2")])
839 ;; Boolean instructions.
841 ;; We don't define the DImode versions as expand_binop does a good enough job.
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")
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")])
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")])
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")])
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")
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")])
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")
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")])
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")])
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")])
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")])
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")])
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")])
965 ;; Shift instructions.
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   "
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     }
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   "
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     }
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   "
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     }
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")])
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")])
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")])
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")])
1070 ;; Compare instructions.
1071 ;; This controls RTL generation and register allocation.
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.
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")])
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")])
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")])
1112 ;; Next come the scc insn and its expander.
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   "
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]);
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")])
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")])
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")])
1160 ;; These control RTL generation for conditional jump insns
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   "
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]);
1184 ;; Now match both normal and inverted jump.
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   "*
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\";
1203   [(set_attr "type" "branch")])
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   "*
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\";
1222   [(set_attr "type" "branch")])
1224 ;; Unconditional and other jump instructions.
1226 (define_insn "jump"
1227   [(set (pc) (label_ref (match_operand 0 "" "")))]
1228   ""
1229   "b%* %l0"
1230   [(set_attr "type" "uncond_branch")])
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")])
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.
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   "
1266   operands[5] = gen_reg_rtx (SImode);
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   "*
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 \"\";
1288   [(set_attr "type" "uncond_branch")
1289    (set_attr "length" "6")])
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")])
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   "")
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")])
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")])
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   "")
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")])
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")])
1359 (define_insn "nop"
1360   [(const_int 0)]
1361   ""
1362   "nop"
1363   [(set_attr "type" "misc")])
1365 ;; Special pattern to flush the icache.
1366 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
1368 (define_insn "flush_icache"
1369   [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1370   ""
1371   "* return \"\";"
1372   [(set_attr "type" "misc")])
1374 ;; Split up troublesome insns for better scheduling.
1376 ;; Peepholes go at the end.