1 ;; Machine description of the Argonaut ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
19 ;; Boston, MA 02111-1307, USA.
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.
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)
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 (eg: 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")
87 (eq_attr "type" "cmove,branch")
90 (eq_attr "type" "multi,misc")
94 (const_string "nocond")))
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")
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")])
117 ;; Function units of the ARC
119 ;; (define_function_unit {name} {num-units} {n-users} {test}
120 ;; {ready-delay} {issue-delay} [{conflict-list}])
122 ;; 1) A conditional jump cannot immediately follow the insn setting the flags.
123 ;; This isn't a complete solution as it doesn't come with guarantees. That
124 ;; is done in the branch patterns and in arc_print_operand. This exists to
125 ;; avoid inserting a nop when we can.
126 (define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")])
128 ;; 2) References to loaded registers should wait a cycle.
130 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
131 (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
133 ;; Units that take one cycle do not need to be specified.
135 ;; Move instructions.
137 (define_expand "movqi"
138 [(set (match_operand:QI 0 "general_operand" "")
139 (match_operand:QI 1 "general_operand" ""))]
143 /* Everything except mem = const or mem = mem can be done easily. */
145 if (GET_CODE (operands[0]) == MEM)
146 operands[1] = force_reg (QImode, operands[1]);
149 (define_insn "*movqi_insn"
150 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
151 (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
153 "register_operand (operands[0], QImode)
154 || register_operand (operands[1], QImode)"
160 [(set_attr "type" "move,move,load,store")])
162 ;; ??? This may never match since there's no cmpqi insn.
164 (define_insn "*movqi_set_cc_insn"
165 [(set (reg:CCZN 61) (compare:CCZN
166 (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
168 (set (match_operand:QI 0 "move_dest_operand" "=r")
172 [(set_attr "type" "move")
173 (set_attr "cond" "set_zn")])
175 (define_expand "movhi"
176 [(set (match_operand:HI 0 "general_operand" "")
177 (match_operand:HI 1 "general_operand" ""))]
181 /* Everything except mem = const or mem = mem can be done easily. */
183 if (GET_CODE (operands[0]) == MEM)
184 operands[1] = force_reg (HImode, operands[1]);
187 (define_insn "*movhi_insn"
188 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
189 (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
190 "register_operand (operands[0], HImode)
191 || register_operand (operands[1], HImode)"
197 [(set_attr "type" "move,move,load,store")])
199 ;; ??? Will this ever match?
201 (define_insn "*movhi_set_cc_insn"
202 [(set (reg:CCZN 61) (compare:CCZN
203 (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
205 (set (match_operand:HI 0 "move_dest_operand" "=r")
208 "register_operand (operands[0], HImode)
209 || register_operand (operands[1], HImode)"
211 [(set_attr "type" "move")
212 (set_attr "cond" "set_zn")])
214 (define_expand "movsi"
215 [(set (match_operand:SI 0 "general_operand" "")
216 (match_operand:SI 1 "general_operand" ""))]
220 /* Everything except mem = const or mem = mem can be done easily. */
222 if (GET_CODE (operands[0]) == MEM)
223 operands[1] = force_reg (SImode, operands[1]);
226 (define_insn "*movsi_insn"
227 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
228 (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
229 "register_operand (operands[0], SImode)
230 || register_operand (operands[1], SImode)"
236 [(set_attr "type" "move,move,load,store")])
238 (define_insn "*movsi_set_cc_insn"
239 [(set (reg:CCZN 61) (compare:CCZN
240 (match_operand:SI 1 "move_src_operand" "rIJi")
242 (set (match_operand:SI 0 "move_dest_operand" "=r")
244 "register_operand (operands[0], SImode)
245 || register_operand (operands[1], SImode)"
247 [(set_attr "type" "move")
248 (set_attr "cond" "set_zn")])
250 (define_expand "movdi"
251 [(set (match_operand:DI 0 "general_operand" "")
252 (match_operand:DI 1 "general_operand" ""))]
256 /* Everything except mem = const or mem = mem can be done easily. */
258 if (GET_CODE (operands[0]) == MEM)
259 operands[1] = force_reg (DImode, operands[1]);
262 (define_insn "*movdi_insn"
263 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
264 (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
265 "register_operand (operands[0], DImode)
266 || register_operand (operands[1], DImode)"
269 switch (which_alternative)
272 /* We normally copy the low-numbered register first. However, if
273 the first register operand 0 is the same as the second register of
274 operand 1, we must copy in the opposite order. */
275 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
276 return \"mov %R0,%R1\;mov %0,%1\";
278 return \"mov %0,%1\;mov %R0,%R1\";
280 return \"mov %0,%L1\;mov %R0,%H1\";
282 /* If the low-address word is used in the address, we must load it
283 last. Otherwise, load it first. Note that we cannot have
284 auto-increment in that case since the address register is known to be
286 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
288 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
290 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
292 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
297 [(set_attr "type" "move,move,load,store")
298 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
299 (set_attr "length" "2,4,2,2")])
301 ;(define_expand "movdi"
302 ; [(set (match_operand:DI 0 "general_operand" "")
303 ; (match_operand:DI 1 "general_operand" ""))]
307 ; /* Flow doesn't understand that this is effectively a DFmode move.
308 ; It doesn't know that all of `operands[0]' is set. */
309 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
311 ; /* Emit insns that movsi_insn can handle. */
312 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
313 ; operand_subword (operands[1], 0, 0, DImode)));
314 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
315 ; operand_subword (operands[1], 1, 0, DImode)));
319 ;; Floating point move insns.
321 (define_expand "movsf"
322 [(set (match_operand:SF 0 "general_operand" "")
323 (match_operand:SF 1 "general_operand" ""))]
327 /* Everything except mem = const or mem = mem can be done easily. */
328 if (GET_CODE (operands[0]) == MEM)
329 operands[1] = force_reg (SFmode, operands[1]);
332 (define_insn "*movsf_insn"
333 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
334 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
335 "register_operand (operands[0], SFmode)
336 || register_operand (operands[1], SFmode)"
342 [(set_attr "type" "move,move,load,store")])
344 (define_expand "movdf"
345 [(set (match_operand:DF 0 "general_operand" "")
346 (match_operand:DF 1 "general_operand" ""))]
350 /* Everything except mem = const or mem = mem can be done easily. */
351 if (GET_CODE (operands[0]) == MEM)
352 operands[1] = force_reg (DFmode, operands[1]);
355 (define_insn "*movdf_insn"
356 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
357 (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
358 "register_operand (operands[0], DFmode)
359 || register_operand (operands[1], DFmode)"
362 switch (which_alternative)
365 /* We normally copy the low-numbered register first. However, if
366 the first register operand 0 is the same as the second register of
367 operand 1, we must copy in the opposite order. */
368 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
369 return \"mov %R0,%R1\;mov %0,%1\";
371 return \"mov %0,%1\;mov %R0,%R1\";
373 return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
375 /* If the low-address word is used in the address, we must load it
376 last. Otherwise, load it first. Note that we cannot have
377 auto-increment in that case since the address register is known to be
379 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
381 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
383 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
385 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
390 [(set_attr "type" "move,move,load,store")
391 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
392 (set_attr "length" "2,4,2,2")])
394 ;(define_expand "movdf"
395 ; [(set (match_operand:DF 0 "general_operand" "")
396 ; (match_operand:DF 1 "general_operand" ""))]
400 ; /* Flow doesn't understand that this is effectively a DFmode move.
401 ; It doesn't know that all of `operands[0]' is set. */
402 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
404 ; /* Emit insns that movsi_insn can handle. */
405 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
406 ; operand_subword (operands[1], 0, 0, DFmode)));
407 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
408 ; operand_subword (operands[1], 1, 0, DFmode)));
412 ;; Load/Store with update instructions.
414 ;; Some of these we can get by using pre-decrement or pre-increment, but the
415 ;; hardware can also do cases where the increment is not the size of the
418 ;; In all these cases, we use operands 0 and 1 for the register being
419 ;; incremented because those are the operands that local-alloc will
420 ;; tie and these are the pair most likely to be tieable (and the ones
421 ;; that will benefit the most).
423 ;; We use match_operator here because we need to know whether the memory
424 ;; object is volatile or not.
426 (define_insn "*loadqi_update"
427 [(set (match_operand:QI 3 "register_operand" "=r,r")
428 (match_operator:QI 4 "load_update_operand"
429 [(match_operand:SI 1 "register_operand" "0,0")
430 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
431 (set (match_operand:SI 0 "register_operand" "=r,r")
432 (plus:SI (match_dup 1) (match_dup 2)))]
434 "ldb.a%V4 %3,[%0,%2]"
435 [(set_attr "type" "load,load")
436 (set_attr "length" "1,2")])
438 (define_insn "*load_zeroextendqisi_update"
439 [(set (match_operand:SI 3 "register_operand" "=r,r")
440 (zero_extend:SI (match_operator:QI 4 "load_update_operand"
441 [(match_operand:SI 1 "register_operand" "0,0")
442 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
443 (set (match_operand:SI 0 "register_operand" "=r,r")
444 (plus:SI (match_dup 1) (match_dup 2)))]
446 "ldb.a%V4 %3,[%0,%2]"
447 [(set_attr "type" "load,load")
448 (set_attr "length" "1,2")])
450 (define_insn "*load_signextendqisi_update"
451 [(set (match_operand:SI 3 "register_operand" "=r,r")
452 (sign_extend:SI (match_operator:QI 4 "load_update_operand"
453 [(match_operand:SI 1 "register_operand" "0,0")
454 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
455 (set (match_operand:SI 0 "register_operand" "=r,r")
456 (plus:SI (match_dup 1) (match_dup 2)))]
458 "ldb.x.a%V4 %3,[%0,%2]"
459 [(set_attr "type" "load,load")
460 (set_attr "length" "1,2")])
462 (define_insn "*storeqi_update"
463 [(set (match_operator:QI 4 "store_update_operand"
464 [(match_operand:SI 1 "register_operand" "0")
465 (match_operand:SI 2 "short_immediate_operand" "I")])
466 (match_operand:QI 3 "register_operand" "r"))
467 (set (match_operand:SI 0 "register_operand" "=r")
468 (plus:SI (match_dup 1) (match_dup 2)))]
470 "stb.a%V4 %3,[%0,%2]"
471 [(set_attr "type" "store")
472 (set_attr "length" "1")])
474 (define_insn "*loadhi_update"
475 [(set (match_operand:HI 3 "register_operand" "=r,r")
476 (match_operator:HI 4 "load_update_operand"
477 [(match_operand:SI 1 "register_operand" "0,0")
478 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
479 (set (match_operand:SI 0 "register_operand" "=r,r")
480 (plus:SI (match_dup 1) (match_dup 2)))]
482 "ldw.a%V4 %3,[%0,%2]"
483 [(set_attr "type" "load,load")
484 (set_attr "length" "1,2")])
486 (define_insn "*load_zeroextendhisi_update"
487 [(set (match_operand:SI 3 "register_operand" "=r,r")
488 (zero_extend:SI (match_operator:HI 4 "load_update_operand"
489 [(match_operand:SI 1 "register_operand" "0,0")
490 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
491 (set (match_operand:SI 0 "register_operand" "=r,r")
492 (plus:SI (match_dup 1) (match_dup 2)))]
494 "ldw.a%V4 %3,[%0,%2]"
495 [(set_attr "type" "load,load")
496 (set_attr "length" "1,2")])
498 (define_insn "*load_signextendhisi_update"
499 [(set (match_operand:SI 3 "register_operand" "=r,r")
500 (sign_extend:SI (match_operator:HI 4 "load_update_operand"
501 [(match_operand:SI 1 "register_operand" "0,0")
502 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
503 (set (match_operand:SI 0 "register_operand" "=r,r")
504 (plus:SI (match_dup 1) (match_dup 2)))]
506 "ldw.x.a%V4 %3,[%0,%2]"
507 [(set_attr "type" "load,load")
508 (set_attr "length" "1,2")])
510 (define_insn "*storehi_update"
511 [(set (match_operator:HI 4 "store_update_operand"
512 [(match_operand:SI 1 "register_operand" "0")
513 (match_operand:SI 2 "short_immediate_operand" "I")])
514 (match_operand:HI 3 "register_operand" "r"))
515 (set (match_operand:SI 0 "register_operand" "=r")
516 (plus:SI (match_dup 1) (match_dup 2)))]
518 "stw.a%V4 %3,[%0,%2]"
519 [(set_attr "type" "store")
520 (set_attr "length" "1")])
522 (define_insn "*loadsi_update"
523 [(set (match_operand:SI 3 "register_operand" "=r,r")
524 (match_operator:SI 4 "load_update_operand"
525 [(match_operand:SI 1 "register_operand" "0,0")
526 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
527 (set (match_operand:SI 0 "register_operand" "=r,r")
528 (plus:SI (match_dup 1) (match_dup 2)))]
531 [(set_attr "type" "load,load")
532 (set_attr "length" "1,2")])
534 (define_insn "*storesi_update"
535 [(set (match_operator:SI 4 "store_update_operand"
536 [(match_operand:SI 1 "register_operand" "0")
537 (match_operand:SI 2 "short_immediate_operand" "I")])
538 (match_operand:SI 3 "register_operand" "r"))
539 (set (match_operand:SI 0 "register_operand" "=r")
540 (plus:SI (match_dup 1) (match_dup 2)))]
543 [(set_attr "type" "store")
544 (set_attr "length" "1")])
546 (define_insn "*loadsf_update"
547 [(set (match_operand:SF 3 "register_operand" "=r,r")
548 (match_operator:SF 4 "load_update_operand"
549 [(match_operand:SI 1 "register_operand" "0,0")
550 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
551 (set (match_operand:SI 0 "register_operand" "=r,r")
552 (plus:SI (match_dup 1) (match_dup 2)))]
555 [(set_attr "type" "load,load")
556 (set_attr "length" "1,2")])
558 (define_insn "*storesf_update"
559 [(set (match_operator:SF 4 "store_update_operand"
560 [(match_operand:SI 1 "register_operand" "0")
561 (match_operand:SI 2 "short_immediate_operand" "I")])
562 (match_operand:SF 3 "register_operand" "r"))
563 (set (match_operand:SI 0 "register_operand" "=r")
564 (plus:SI (match_dup 1) (match_dup 2)))]
567 [(set_attr "type" "store")
568 (set_attr "length" "1")])
570 ;; Conditional move instructions.
572 (define_expand "movsicc"
573 [(set (match_operand:SI 0 "register_operand" "")
574 (if_then_else:SI (match_operand 1 "comparison_operator" "")
575 (match_operand:SI 2 "nonmemory_operand" "")
576 (match_operand:SI 3 "register_operand" "")))]
580 enum rtx_code code = GET_CODE (operands[1]);
582 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
585 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
588 ;(define_expand "movdicc"
589 ; [(set (match_operand:DI 0 "register_operand" "")
590 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
591 ; (match_operand:DI 2 "nonmemory_operand" "")
592 ; (match_operand:DI 3 "register_operand" "")))]
593 ; "0 /* ??? this would work better if we had cmpdi */"
596 ; enum rtx_code code = GET_CODE (operands[1]);
598 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
601 ; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
604 (define_expand "movsfcc"
605 [(set (match_operand:SF 0 "register_operand" "")
606 (if_then_else:SF (match_operand 1 "comparison_operator" "")
607 (match_operand:SF 2 "nonmemory_operand" "")
608 (match_operand:SF 3 "register_operand" "")))]
612 enum rtx_code code = GET_CODE (operands[1]);
614 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
617 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
620 ;(define_expand "movdfcc"
621 ; [(set (match_operand:DF 0 "register_operand" "")
622 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
623 ; (match_operand:DF 2 "nonmemory_operand" "")
624 ; (match_operand:DF 3 "register_operand" "")))]
625 ; "0 /* ??? can generate less efficient code if constants involved */"
628 ; enum rtx_code code = GET_CODE (operands[1]);
630 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
633 ; operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
636 (define_insn "*movsicc_insn"
637 [(set (match_operand:SI 0 "register_operand" "=r")
638 (if_then_else:SI (match_operand 1 "comparison_operator" "")
639 (match_operand:SI 2 "nonmemory_operand" "rJi")
640 (match_operand:SI 3 "register_operand" "0")))]
643 [(set_attr "type" "cmove")])
645 ; ??? This doesn't properly handle constants.
646 ;(define_insn "*movdicc_insn"
647 ; [(set (match_operand:DI 0 "register_operand" "=r,r")
648 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
649 ; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
650 ; (match_operand:DI 3 "register_operand" "0,0")))]
654 ; switch (which_alternative)
657 ; /* We normally copy the low-numbered register first. However, if
658 ; the first register operand 0 is the same as the second register of
659 ; operand 1, we must copy in the opposite order. */
660 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
661 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
663 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
665 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
668 ; [(set_attr "type" "cmove,cmove")
669 ; (set_attr "length" "2,4")])
671 (define_insn "*movsfcc_insn"
672 [(set (match_operand:SF 0 "register_operand" "=r,r")
673 (if_then_else:SF (match_operand 1 "comparison_operator" "")
674 (match_operand:SF 2 "nonmemory_operand" "r,E")
675 (match_operand:SF 3 "register_operand" "0,0")))]
680 [(set_attr "type" "cmove,cmove")])
682 ;(define_insn "*movdfcc_insn"
683 ; [(set (match_operand:DF 0 "register_operand" "=r,r")
684 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
685 ; (match_operand:DF 2 "nonmemory_operand" "r,E")
686 ; (match_operand:DF 3 "register_operand" "0,0")))]
690 ; switch (which_alternative)
693 ; /* We normally copy the low-numbered register first. However, if
694 ; the first register operand 0 is the same as the second register of
695 ; operand 1, we must copy in the opposite order. */
696 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
697 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
699 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
701 ; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
704 ; [(set_attr "type" "cmove,cmove")
705 ; (set_attr "length" "2,4")])
707 ;; Zero extension instructions.
708 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
710 (define_insn "zero_extendqihi2"
711 [(set (match_operand:HI 0 "register_operand" "=r,r")
712 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
717 [(set_attr "type" "unary,load")])
719 (define_insn "*zero_extendqihi2_set_cc_insn"
720 [(set (reg:CCZN 61) (compare:CCZN
721 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
723 (set (match_operand:HI 0 "register_operand" "=r")
724 (zero_extend:HI (match_dup 1)))]
727 [(set_attr "type" "unary")
728 (set_attr "cond" "set_zn")])
730 (define_insn "zero_extendqisi2"
731 [(set (match_operand:SI 0 "register_operand" "=r,r")
732 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
737 [(set_attr "type" "unary,load")])
739 (define_insn "*zero_extendqisi2_set_cc_insn"
740 [(set (reg:CCZN 61) (compare:CCZN
741 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
743 (set (match_operand:SI 0 "register_operand" "=r")
744 (zero_extend:SI (match_dup 1)))]
747 [(set_attr "type" "unary")
748 (set_attr "cond" "set_zn")])
750 (define_insn "zero_extendhisi2"
751 [(set (match_operand:SI 0 "register_operand" "=r,r")
752 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
757 [(set_attr "type" "unary,load")])
759 (define_insn "*zero_extendhisi2_set_cc_insn"
760 [(set (reg:CCZN 61) (compare:CCZN
761 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
763 (set (match_operand:SI 0 "register_operand" "=r")
764 (zero_extend:SI (match_dup 1)))]
767 [(set_attr "type" "unary")
768 (set_attr "cond" "set_zn")])
770 ;; Sign extension instructions.
772 (define_insn "extendqihi2"
773 [(set (match_operand:HI 0 "register_operand" "=r,r")
774 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
779 [(set_attr "type" "unary,load")])
781 (define_insn "*extendqihi2_set_cc_insn"
782 [(set (reg:CCZN 61) (compare:CCZN
783 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
785 (set (match_operand:HI 0 "register_operand" "=r")
786 (sign_extend:HI (match_dup 1)))]
789 [(set_attr "type" "unary")
790 (set_attr "cond" "set_zn")])
792 (define_insn "extendqisi2"
793 [(set (match_operand:SI 0 "register_operand" "=r,r")
794 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
799 [(set_attr "type" "unary,load")])
801 (define_insn "*extendqisi2_set_cc_insn"
802 [(set (reg:CCZN 61) (compare:CCZN
803 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
805 (set (match_operand:SI 0 "register_operand" "=r")
806 (sign_extend:SI (match_dup 1)))]
809 [(set_attr "type" "unary")
810 (set_attr "cond" "set_zn")])
812 (define_insn "extendhisi2"
813 [(set (match_operand:SI 0 "register_operand" "=r,r")
814 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
819 [(set_attr "type" "unary,load")])
821 (define_insn "*extendhisi2_set_cc_insn"
822 [(set (reg:CCZN 61) (compare:CCZN
823 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
825 (set (match_operand:SI 0 "register_operand" "=r")
826 (sign_extend:SI (match_dup 1)))]
829 [(set_attr "type" "unary")
830 (set_attr "cond" "set_zn")])
832 ;; Arithmetic instructions.
834 (define_insn "addsi3"
835 [(set (match_operand:SI 0 "register_operand" "=r")
836 (plus:SI (match_operand:SI 1 "register_operand" "%r")
837 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
841 (define_insn "*addsi3_set_cc_insn"
842 [(set (reg:CC 61) (compare:CC
843 (plus:SI (match_operand:SI 1 "register_operand" "%r")
844 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
846 (set (match_operand:SI 0 "register_operand" "=r")
847 (plus:SI (match_dup 1)
851 [(set_attr "cond" "set")])
853 (define_insn "adddi3"
854 [(set (match_operand:DI 0 "register_operand" "=r")
855 (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
856 (match_operand:DI 2 "nonmemory_operand" "ri")))
857 (clobber (reg:CC 61))]
861 rtx op2 = operands[2];
863 if (GET_CODE (op2) == CONST_INT)
865 int sign = INTVAL (op2);
867 return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
869 return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
872 return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
874 [(set_attr "length" "2")])
876 (define_insn "subsi3"
877 [(set (match_operand:SI 0 "register_operand" "=r")
878 (minus:SI (match_operand:SI 1 "register_operand" "r")
879 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
883 (define_insn "*subsi3_set_cc_insn"
884 [(set (reg:CC 61) (compare:CC
885 (minus:SI (match_operand:SI 1 "register_operand" "%r")
886 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
888 (set (match_operand:SI 0 "register_operand" "=r")
889 (minus:SI (match_dup 1)
893 [(set_attr "cond" "set")])
895 (define_insn "subdi3"
896 [(set (match_operand:DI 0 "register_operand" "=r")
897 (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
898 (match_operand:DI 2 "nonmemory_operand" "ri")))
899 (clobber (reg:CC 61))]
903 rtx op2 = operands[2];
905 if (GET_CODE (op2) == CONST_INT)
907 int sign = INTVAL (op2);
909 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
911 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
914 return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
916 [(set_attr "length" "2")])
918 ;; Boolean instructions.
920 ;; We don't define the DImode versions as expand_binop does a good enough job.
922 (define_insn "andsi3"
923 [(set (match_operand:SI 0 "register_operand" "=r")
924 (and:SI (match_operand:SI 1 "register_operand" "%r")
925 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
929 (define_insn "*andsi3_set_cc_insn"
930 [(set (reg:CCZN 61) (compare:CCZN
931 (and:SI (match_operand:SI 1 "register_operand" "%r")
932 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
934 (set (match_operand:SI 0 "register_operand" "=r")
935 (and:SI (match_dup 1)
939 [(set_attr "cond" "set_zn")])
941 (define_insn "*bicsi3_insn"
942 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
943 (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
944 (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
947 [(set_attr "length" "1,2,1,2")])
949 (define_insn "*bicsi3_set_cc_insn"
950 [(set (reg:CCZN 61) (compare:CCZN
951 (and:SI (match_operand:SI 1 "register_operand" "%r")
952 (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
954 (set (match_operand:SI 0 "register_operand" "=r")
955 (and:SI (match_dup 1)
956 (not:SI (match_dup 2))))]
959 [(set_attr "cond" "set_zn")])
961 (define_insn "iorsi3"
962 [(set (match_operand:SI 0 "register_operand" "=r")
963 (ior:SI (match_operand:SI 1 "register_operand" "%r")
964 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
968 (define_insn "*iorsi3_set_cc_insn"
969 [(set (reg:CCZN 61) (compare:CCZN
970 (ior:SI (match_operand:SI 1 "register_operand" "%r")
971 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
973 (set (match_operand:SI 0 "register_operand" "=r")
974 (ior:SI (match_dup 1)
978 [(set_attr "cond" "set_zn")])
980 (define_insn "xorsi3"
981 [(set (match_operand:SI 0 "register_operand" "=r")
982 (xor:SI (match_operand:SI 1 "register_operand" "%r")
983 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
987 (define_insn "*xorsi3_set_cc_insn"
988 [(set (reg:CCZN 61) (compare:CCZN
989 (xor:SI (match_operand:SI 1 "register_operand" "%r")
990 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
992 (set (match_operand:SI 0 "register_operand" "=r")
993 (xor:SI (match_dup 1)
997 [(set_attr "cond" "set_zn")])
999 (define_insn "negsi2"
1000 [(set (match_operand:SI 0 "register_operand" "=r")
1001 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1004 [(set_attr "type" "unary")])
1006 (define_insn "*negsi2_set_cc_insn"
1007 [(set (reg:CC 61) (compare:CC
1008 (neg:SI (match_operand:SI 1 "register_operand" "r"))
1010 (set (match_operand:SI 0 "register_operand" "=r")
1011 (neg:SI (match_dup 1)))]
1014 [(set_attr "type" "unary")
1015 (set_attr "cond" "set")])
1017 (define_insn "negdi2"
1018 [(set (match_operand:DI 0 "register_operand" "=r")
1019 (neg:DI (match_operand:DI 1 "register_operand" "r")))
1020 (clobber (reg:SI 61))]
1022 "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1023 [(set_attr "type" "unary")
1024 (set_attr "length" "2")])
1026 (define_insn "one_cmplsi2"
1027 [(set (match_operand:SI 0 "register_operand" "=r")
1028 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1031 [(set_attr "type" "unary")])
1033 (define_insn "*one_cmplsi2_set_cc_insn"
1034 [(set (reg:CCZN 61) (compare:CCZN
1035 (not:SI (match_operand:SI 1 "register_operand" "r"))
1037 (set (match_operand:SI 0 "register_operand" "=r")
1038 (not:SI (match_dup 1)))]
1041 [(set_attr "type" "unary")
1042 (set_attr "cond" "set_zn")])
1044 ;; Shift instructions.
1046 (define_expand "ashlsi3"
1047 [(set (match_operand:SI 0 "register_operand" "")
1048 (ashift:SI (match_operand:SI 1 "register_operand" "")
1049 (match_operand:SI 2 "nonmemory_operand" "")))]
1053 if (! TARGET_SHIFTER)
1055 emit_insn (gen_rtx_PARALLEL
1058 gen_rtx_SET (VOIDmode, operands[0],
1059 gen_rtx_ASHIFT (SImode, operands[1],
1061 gen_rtx_CLOBBER (VOIDmode,
1062 gen_rtx_SCRATCH (SImode)))));
1067 (define_expand "ashrsi3"
1068 [(set (match_operand:SI 0 "register_operand" "")
1069 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1070 (match_operand:SI 2 "nonmemory_operand" "")))]
1074 if (! TARGET_SHIFTER)
1076 emit_insn (gen_rtx_PARALLEL
1079 gen_rtx_SET (VOIDmode, operands[0],
1080 gen_rtx_ASHIFTRT (SImode,
1083 gen_rtx_CLOBBER (VOIDmode,
1084 gen_rtx_SCRATCH (SImode)))));
1089 (define_expand "lshrsi3"
1090 [(set (match_operand:SI 0 "register_operand" "")
1091 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1092 (match_operand:SI 2 "nonmemory_operand" "")))]
1096 if (! TARGET_SHIFTER)
1098 emit_insn (gen_rtx_PARALLEL
1101 gen_rtx_SET (VOIDmode, operands[0],
1102 gen_rtx_LSHIFTRT (SImode,
1105 gen_rtx_CLOBBER (VOIDmode,
1106 gen_rtx_SCRATCH (SImode)))));
1111 (define_insn "*ashlsi3_insn"
1112 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1113 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1114 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1117 [(set_attr "type" "shift")
1118 (set_attr "length" "1,2,1,2")])
1120 (define_insn "*ashrsi3_insn"
1121 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1122 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1123 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1126 [(set_attr "type" "shift")
1127 (set_attr "length" "1,2,1,2")])
1129 (define_insn "*lshrsi3_insn"
1130 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1131 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1132 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1135 [(set_attr "type" "shift")
1136 (set_attr "length" "1,2,1,2")])
1138 (define_insn "*shift_si3"
1139 [(set (match_operand:SI 0 "register_operand" "=r")
1140 (match_operator:SI 3 "shift_operator"
1141 [(match_operand:SI 1 "register_operand" "0")
1142 (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1143 (clobber (match_scratch:SI 4 "=&r"))]
1145 "* return output_shift (operands);"
1146 [(set_attr "type" "shift")
1147 (set_attr "length" "8")])
1149 ;; Compare instructions.
1150 ;; This controls RTL generation and register allocation.
1152 ;; We generate RTL for comparisons and branches by having the cmpxx
1153 ;; patterns store away the operands. Then, the scc and bcc patterns
1154 ;; emit RTL for both the compare and the branch.
1156 (define_expand "cmpsi"
1158 (compare:CC (match_operand:SI 0 "register_operand" "")
1159 (match_operand:SI 1 "nonmemory_operand" "")))]
1163 arc_compare_op0 = operands[0];
1164 arc_compare_op1 = operands[1];
1168 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1169 ;; This assumes sub.f 0,symbol,0 is a valid insn.
1170 ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
1171 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1172 ;; if it's a small constant.
1174 (define_insn "*cmpsi_cc_insn"
1176 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1177 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1183 [(set_attr "type" "compare,compare,compare")])
1185 (define_insn "*cmpsi_cczn_insn"
1187 (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1188 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1194 [(set_attr "type" "compare,compare,compare")])
1196 (define_insn "*cmpsi_ccznc_insn"
1197 [(set (reg:CCZNC 61)
1198 (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1199 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1205 [(set_attr "type" "compare,compare,compare")])
1207 ;; Next come the scc insns.
1209 (define_expand "seq"
1210 [(set (match_operand:SI 0 "register_operand" "=r")
1211 (eq:SI (match_dup 1) (const_int 0)))]
1215 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1218 (define_expand "sne"
1219 [(set (match_operand:SI 0 "register_operand" "=r")
1220 (ne:SI (match_dup 1) (const_int 0)))]
1224 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1227 (define_expand "sgt"
1228 [(set (match_operand:SI 0 "register_operand" "=r")
1229 (gt:SI (match_dup 1) (const_int 0)))]
1233 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1236 (define_expand "sle"
1237 [(set (match_operand:SI 0 "register_operand" "=r")
1238 (le:SI (match_dup 1) (const_int 0)))]
1242 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1245 (define_expand "sge"
1246 [(set (match_operand:SI 0 "register_operand" "=r")
1247 (ge:SI (match_dup 1) (const_int 0)))]
1251 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1254 (define_expand "slt"
1255 [(set (match_operand:SI 0 "register_operand" "=r")
1256 (lt:SI (match_dup 1) (const_int 0)))]
1260 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1263 (define_expand "sgtu"
1264 [(set (match_operand:SI 0 "register_operand" "=r")
1265 (gtu:SI (match_dup 1) (const_int 0)))]
1269 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1272 (define_expand "sleu"
1273 [(set (match_operand:SI 0 "register_operand" "=r")
1274 (leu:SI (match_dup 1) (const_int 0)))]
1278 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1281 (define_expand "sgeu"
1282 [(set (match_operand:SI 0 "register_operand" "=r")
1283 (geu:SI (match_dup 1) (const_int 0)))]
1287 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1290 (define_expand "sltu"
1291 [(set (match_operand:SI 0 "register_operand" "=r")
1292 (ltu:SI (match_dup 1) (const_int 0)))]
1296 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1299 (define_insn "*scc_insn"
1300 [(set (match_operand:SI 0 "register_operand" "=r")
1301 (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1303 "mov %0,1\;sub.%D1 %0,%0,%0"
1304 [(set_attr "type" "unary")
1305 (set_attr "length" "2")])
1307 ;; ??? Look up negscc insn. See pa.md for example.
1308 (define_insn "*neg_scc_insn"
1309 [(set (match_operand:SI 0 "register_operand" "=r")
1310 (neg:SI (match_operator:SI 1 "comparison_operator"
1311 [(reg 61) (const_int 0)])))]
1313 "mov %0,-1\;sub.%D1 %0,%0,%0"
1314 [(set_attr "type" "unary")
1315 (set_attr "length" "2")])
1317 (define_insn "*not_scc_insn"
1318 [(set (match_operand:SI 0 "register_operand" "=r")
1319 (not:SI (match_operator:SI 1 "comparison_operator"
1320 [(reg 61) (const_int 0)])))]
1322 "mov %0,1\;sub.%d1 %0,%0,%0"
1323 [(set_attr "type" "unary")
1324 (set_attr "length" "2")])
1326 ;; These control RTL generation for conditional jump insns
1328 (define_expand "beq"
1330 (if_then_else (eq (match_dup 1) (const_int 0))
1331 (label_ref (match_operand 0 "" ""))
1336 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1339 (define_expand "bne"
1341 (if_then_else (ne (match_dup 1) (const_int 0))
1342 (label_ref (match_operand 0 "" ""))
1347 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1350 (define_expand "bgt"
1352 (if_then_else (gt (match_dup 1) (const_int 0))
1353 (label_ref (match_operand 0 "" ""))
1358 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1361 (define_expand "ble"
1363 (if_then_else (le (match_dup 1) (const_int 0))
1364 (label_ref (match_operand 0 "" ""))
1369 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1372 (define_expand "bge"
1374 (if_then_else (ge (match_dup 1) (const_int 0))
1375 (label_ref (match_operand 0 "" ""))
1380 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1383 (define_expand "blt"
1385 (if_then_else (lt (match_dup 1) (const_int 0))
1386 (label_ref (match_operand 0 "" ""))
1391 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1394 (define_expand "bgtu"
1396 (if_then_else (gtu (match_dup 1) (const_int 0))
1397 (label_ref (match_operand 0 "" ""))
1402 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1405 (define_expand "bleu"
1407 (if_then_else (leu (match_dup 1) (const_int 0))
1408 (label_ref (match_operand 0 "" ""))
1413 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1416 (define_expand "bgeu"
1418 (if_then_else (geu (match_dup 1) (const_int 0))
1419 (label_ref (match_operand 0 "" ""))
1424 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1427 (define_expand "bltu"
1429 (if_then_else (ltu (match_dup 1) (const_int 0))
1430 (label_ref (match_operand 0 "" ""))
1435 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1438 ;; Now match both normal and inverted jump.
1440 (define_insn "*branch_insn"
1442 (if_then_else (match_operator 1 "proper_comparison_operator"
1443 [(reg 61) (const_int 0)])
1444 (label_ref (match_operand 0 "" ""))
1449 if (arc_ccfsm_branch_deleted_p ())
1451 arc_ccfsm_record_branch_deleted ();
1452 return \"; branch deleted, next insns conditionalized\";
1455 return \"%~b%d1%# %l0\";
1457 [(set_attr "type" "branch")])
1459 (define_insn "*rev_branch_insn"
1461 (if_then_else (match_operator 1 "proper_comparison_operator"
1462 [(reg 61) (const_int 0)])
1464 (label_ref (match_operand 0 "" ""))))]
1465 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1468 if (arc_ccfsm_branch_deleted_p ())
1470 arc_ccfsm_record_branch_deleted ();
1471 return \"; branch deleted, next insns conditionalized\";
1474 return \"%~b%D1%# %l0\";
1476 [(set_attr "type" "branch")])
1478 ;; Unconditional and other jump instructions.
1481 [(set (pc) (label_ref (match_operand 0 "" "")))]
1484 [(set_attr "type" "uncond_branch")])
1486 (define_insn "indirect_jump"
1487 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1490 [(set_attr "type" "uncond_branch")])
1492 ;; Implement a switch statement.
1493 ;; This wouldn't be necessary in the non-pic case if we could distinguish
1494 ;; label refs of the jump table from other label refs. The problem is that
1495 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1496 ;; the real address since it's the address of the table.
1498 (define_expand "casesi"
1500 (minus:SI (match_operand:SI 0 "register_operand" "")
1501 (match_operand:SI 1 "nonmemory_operand" "")))
1503 (compare:CC (match_dup 5)
1504 (match_operand:SI 2 "nonmemory_operand" "")))
1506 (if_then_else (gtu (reg:CC 61)
1508 (label_ref (match_operand 4 "" ""))
1512 (mem:SI (plus:SI (mult:SI (match_dup 5)
1514 (label_ref (match_operand 3 "" "")))))
1515 (clobber (match_scratch:SI 6 ""))
1516 (clobber (match_scratch:SI 7 ""))])]
1520 operands[5] = gen_reg_rtx (SImode);
1523 (define_insn "*casesi_insn"
1525 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1527 (label_ref (match_operand 1 "" "")))))
1528 (clobber (match_scratch:SI 2 "=r"))
1529 (clobber (match_scratch:SI 3 "=r"))]
1533 output_asm_insn (\"mov %2,%1\", operands);
1535 output_asm_insn (\"asl %3,%0,2\", operands);
1537 output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1538 output_asm_insn (\"ld %2,[%2,%3]\", operands);
1539 output_asm_insn (\"j.nd %a2\", operands);
1542 [(set_attr "type" "uncond_branch")
1543 (set_attr "length" "6")])
1545 (define_insn "tablejump"
1546 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1547 (use (label_ref (match_operand 1 "" "")))]
1548 "0 /* disabled -> using casesi now */"
1550 [(set_attr "type" "uncond_branch")])
1552 (define_expand "call"
1553 ;; operands[1] is stack_size_rtx
1554 ;; operands[2] is next_arg_register
1555 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1556 (match_operand 1 "" ""))
1557 (clobber (reg:SI 31))])]
1561 (define_insn "*call_via_reg"
1562 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1563 (match_operand 1 "" ""))
1564 (clobber (reg:SI 31))]
1566 "lr blink,[status]\;j.d %0\;add blink,blink,2"
1567 [(set_attr "type" "call_no_delay_slot")
1568 (set_attr "length" "3")])
1570 (define_insn "*call_via_label"
1571 [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1572 (match_operand 1 "" ""))
1573 (clobber (reg:SI 31))]
1575 ; The %~ is necessary in case this insn gets conditionalized and the previous
1576 ; insn is the cc setter.
1578 [(set_attr "type" "call")
1579 (set_attr "cond" "canuse")])
1581 (define_expand "call_value"
1582 ;; operand 2 is stack_size_rtx
1583 ;; operand 3 is next_arg_register
1584 [(parallel [(set (match_operand 0 "register_operand" "=r")
1585 (call (match_operand:SI 1 "call_operand" "")
1586 (match_operand 2 "" "")))
1587 (clobber (reg:SI 31))])]
1591 (define_insn "*call_value_via_reg"
1592 [(set (match_operand 0 "register_operand" "=r")
1593 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1594 (match_operand 2 "" "")))
1595 (clobber (reg:SI 31))]
1597 "lr blink,[status]\;j.d %1\;add blink,blink,2"
1598 [(set_attr "type" "call_no_delay_slot")
1599 (set_attr "length" "3")])
1601 (define_insn "*call_value_via_label"
1602 [(set (match_operand 0 "register_operand" "=r")
1603 (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1604 (match_operand 2 "" "")))
1605 (clobber (reg:SI 31))]
1607 ; The %~ is necessary in case this insn gets conditionalized and the previous
1608 ; insn is the cc setter.
1610 [(set_attr "type" "call")
1611 (set_attr "cond" "canuse")])
1617 [(set_attr "type" "misc")])
1619 ;; Special pattern to flush the icache.
1620 ;; ??? Not sure what to do here. Some ARC's are known to support this.
1622 (define_insn "flush_icache"
1623 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1626 [(set_attr "type" "misc")])
1628 ;; Split up troublesome insns for better scheduling.
1630 ;; Peepholes go at the end.