1 ;; Machine description of the Argonaut ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005, 2007
3 ;; Free Software Foundation, Inc.
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)
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.
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 (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")
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 ;; Scheduling description for the ARC
119 (define_cpu_unit "branch")
121 (define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
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")
132 (define_insn_reservation "branch" 1 (eq_attr "type" "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")
142 ;; Move instructions.
144 (define_expand "movqi"
145 [(set (match_operand:QI 0 "general_operand" "")
146 (match_operand:QI 1 "general_operand" ""))]
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"))]
160 "register_operand (operands[0], QImode)
161 || register_operand (operands[1], QImode)"
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"))
175 (set (match_operand:QI 0 "move_dest_operand" "=r")
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" ""))]
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)"
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"))
212 (set (match_operand:HI 0 "move_dest_operand" "=r")
215 "register_operand (operands[0], HImode)
216 || register_operand (operands[1], HImode)"
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" ""))]
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)"
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")
249 (set (match_operand:SI 0 "move_dest_operand" "=r")
251 "register_operand (operands[0], SImode)
252 || register_operand (operands[1], SImode)"
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" ""))]
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)"
276 switch (which_alternative)
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\";
285 return \"mov %0,%1\;mov %R0,%R1\";
287 return \"mov %0,%L1\;mov %R0,%H1\";
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
293 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
295 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
297 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
299 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
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" ""))]
314 ; /* Flow doesn't understand that this is effectively a DFmode move.
315 ; It doesn't know that all of `operands[0]' is set. */
316 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
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)));
326 ;; Floating point move insns.
328 (define_expand "movsf"
329 [(set (match_operand:SF 0 "general_operand" "")
330 (match_operand:SF 1 "general_operand" ""))]
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)"
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" ""))]
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)"
369 switch (which_alternative)
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\";
378 return \"mov %0,%1\;mov %R0,%R1\";
380 return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
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
386 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
388 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
390 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
392 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
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" ""))]
407 ; /* Flow doesn't understand that this is effectively a DFmode move.
408 ; It doesn't know that all of `operands[0]' is set. */
409 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
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)));
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
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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)))]
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" "")))]
587 enum rtx_code code = GET_CODE (operands[1]);
589 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
592 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
595 ;(define_expand "movdicc"
596 ; [(set (match_operand:DI 0 "register_operand" "")
597 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
598 ; (match_operand:DI 2 "nonmemory_operand" "")
599 ; (match_operand:DI 3 "register_operand" "")))]
600 ; "0 /* ??? this would work better if we had cmpdi */"
603 ; enum rtx_code code = GET_CODE (operands[1]);
605 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
608 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
611 (define_expand "movsfcc"
612 [(set (match_operand:SF 0 "register_operand" "")
613 (if_then_else:SF (match_operand 1 "comparison_operator" "")
614 (match_operand:SF 2 "nonmemory_operand" "")
615 (match_operand:SF 3 "register_operand" "")))]
619 enum rtx_code code = GET_CODE (operands[1]);
621 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
624 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
627 ;(define_expand "movdfcc"
628 ; [(set (match_operand:DF 0 "register_operand" "")
629 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
630 ; (match_operand:DF 2 "nonmemory_operand" "")
631 ; (match_operand:DF 3 "register_operand" "")))]
632 ; "0 /* ??? can generate less efficient code if constants involved */"
635 ; enum rtx_code code = GET_CODE (operands[1]);
637 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
640 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
643 (define_insn "*movsicc_insn"
644 [(set (match_operand:SI 0 "register_operand" "=r")
645 (if_then_else:SI (match_operand 1 "comparison_operator" "")
646 (match_operand:SI 2 "nonmemory_operand" "rJi")
647 (match_operand:SI 3 "register_operand" "0")))]
650 [(set_attr "type" "cmove")])
652 ; ??? This doesn't properly handle constants.
653 ;(define_insn "*movdicc_insn"
654 ; [(set (match_operand:DI 0 "register_operand" "=r,r")
655 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
656 ; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
657 ; (match_operand:DI 3 "register_operand" "0,0")))]
661 ; switch (which_alternative)
664 ; /* We normally copy the low-numbered register first. However, if
665 ; the first register operand 0 is the same as the second register of
666 ; operand 1, we must copy in the opposite order. */
667 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
668 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
670 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
672 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
675 ; [(set_attr "type" "cmove,cmove")
676 ; (set_attr "length" "2,4")])
678 (define_insn "*movsfcc_insn"
679 [(set (match_operand:SF 0 "register_operand" "=r,r")
680 (if_then_else:SF (match_operand 1 "comparison_operator" "")
681 (match_operand:SF 2 "nonmemory_operand" "r,E")
682 (match_operand:SF 3 "register_operand" "0,0")))]
687 [(set_attr "type" "cmove,cmove")])
689 ;(define_insn "*movdfcc_insn"
690 ; [(set (match_operand:DF 0 "register_operand" "=r,r")
691 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
692 ; (match_operand:DF 2 "nonmemory_operand" "r,E")
693 ; (match_operand:DF 3 "register_operand" "0,0")))]
697 ; switch (which_alternative)
700 ; /* We normally copy the low-numbered register first. However, if
701 ; the first register operand 0 is the same as the second register of
702 ; operand 1, we must copy in the opposite order. */
703 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
704 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
706 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
708 ; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
711 ; [(set_attr "type" "cmove,cmove")
712 ; (set_attr "length" "2,4")])
714 ;; Zero extension instructions.
715 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
717 (define_insn "zero_extendqihi2"
718 [(set (match_operand:HI 0 "register_operand" "=r,r")
719 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
724 [(set_attr "type" "unary,load")])
726 (define_insn "*zero_extendqihi2_set_cc_insn"
727 [(set (reg:CCZN 61) (compare:CCZN
728 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
730 (set (match_operand:HI 0 "register_operand" "=r")
731 (zero_extend:HI (match_dup 1)))]
734 [(set_attr "type" "unary")
735 (set_attr "cond" "set_zn")])
737 (define_insn "zero_extendqisi2"
738 [(set (match_operand:SI 0 "register_operand" "=r,r")
739 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
744 [(set_attr "type" "unary,load")])
746 (define_insn "*zero_extendqisi2_set_cc_insn"
747 [(set (reg:CCZN 61) (compare:CCZN
748 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
750 (set (match_operand:SI 0 "register_operand" "=r")
751 (zero_extend:SI (match_dup 1)))]
754 [(set_attr "type" "unary")
755 (set_attr "cond" "set_zn")])
757 (define_insn "zero_extendhisi2"
758 [(set (match_operand:SI 0 "register_operand" "=r,r")
759 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
764 [(set_attr "type" "unary,load")])
766 (define_insn "*zero_extendhisi2_set_cc_insn"
767 [(set (reg:CCZN 61) (compare:CCZN
768 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
770 (set (match_operand:SI 0 "register_operand" "=r")
771 (zero_extend:SI (match_dup 1)))]
774 [(set_attr "type" "unary")
775 (set_attr "cond" "set_zn")])
777 ;; Sign extension instructions.
779 (define_insn "extendqihi2"
780 [(set (match_operand:HI 0 "register_operand" "=r,r")
781 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
786 [(set_attr "type" "unary,load")])
788 (define_insn "*extendqihi2_set_cc_insn"
789 [(set (reg:CCZN 61) (compare:CCZN
790 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
792 (set (match_operand:HI 0 "register_operand" "=r")
793 (sign_extend:HI (match_dup 1)))]
796 [(set_attr "type" "unary")
797 (set_attr "cond" "set_zn")])
799 (define_insn "extendqisi2"
800 [(set (match_operand:SI 0 "register_operand" "=r,r")
801 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
806 [(set_attr "type" "unary,load")])
808 (define_insn "*extendqisi2_set_cc_insn"
809 [(set (reg:CCZN 61) (compare:CCZN
810 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
812 (set (match_operand:SI 0 "register_operand" "=r")
813 (sign_extend:SI (match_dup 1)))]
816 [(set_attr "type" "unary")
817 (set_attr "cond" "set_zn")])
819 (define_insn "extendhisi2"
820 [(set (match_operand:SI 0 "register_operand" "=r,r")
821 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
826 [(set_attr "type" "unary,load")])
828 (define_insn "*extendhisi2_set_cc_insn"
829 [(set (reg:CCZN 61) (compare:CCZN
830 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
832 (set (match_operand:SI 0 "register_operand" "=r")
833 (sign_extend:SI (match_dup 1)))]
836 [(set_attr "type" "unary")
837 (set_attr "cond" "set_zn")])
839 ;; Arithmetic instructions.
841 (define_insn "addsi3"
842 [(set (match_operand:SI 0 "register_operand" "=r")
843 (plus:SI (match_operand:SI 1 "register_operand" "%r")
844 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
848 (define_insn "*addsi3_set_cc_insn"
849 [(set (reg:CC 61) (compare:CC
850 (plus:SI (match_operand:SI 1 "register_operand" "%r")
851 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
853 (set (match_operand:SI 0 "register_operand" "=r")
854 (plus:SI (match_dup 1)
858 [(set_attr "cond" "set")])
860 (define_insn "adddi3"
861 [(set (match_operand:DI 0 "register_operand" "=r")
862 (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
863 (match_operand:DI 2 "nonmemory_operand" "ri")))
864 (clobber (reg:CC 61))]
868 rtx op2 = operands[2];
870 if (GET_CODE (op2) == CONST_INT)
872 int sign = INTVAL (op2);
874 return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
876 return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
879 return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
881 [(set_attr "length" "2")])
883 (define_insn "subsi3"
884 [(set (match_operand:SI 0 "register_operand" "=r")
885 (minus:SI (match_operand:SI 1 "register_operand" "r")
886 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
890 (define_insn "*subsi3_set_cc_insn"
891 [(set (reg:CC 61) (compare:CC
892 (minus:SI (match_operand:SI 1 "register_operand" "%r")
893 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
895 (set (match_operand:SI 0 "register_operand" "=r")
896 (minus:SI (match_dup 1)
900 [(set_attr "cond" "set")])
902 (define_insn "subdi3"
903 [(set (match_operand:DI 0 "register_operand" "=r")
904 (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
905 (match_operand:DI 2 "nonmemory_operand" "ri")))
906 (clobber (reg:CC 61))]
910 rtx op2 = operands[2];
912 if (GET_CODE (op2) == CONST_INT)
914 int sign = INTVAL (op2);
916 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
918 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
921 return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
923 [(set_attr "length" "2")])
925 ;; Boolean instructions.
927 ;; We don't define the DImode versions as expand_binop does a good enough job.
929 (define_insn "andsi3"
930 [(set (match_operand:SI 0 "register_operand" "=r")
931 (and:SI (match_operand:SI 1 "register_operand" "%r")
932 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
936 (define_insn "*andsi3_set_cc_insn"
937 [(set (reg:CCZN 61) (compare:CCZN
938 (and:SI (match_operand:SI 1 "register_operand" "%r")
939 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
941 (set (match_operand:SI 0 "register_operand" "=r")
942 (and:SI (match_dup 1)
946 [(set_attr "cond" "set_zn")])
948 (define_insn "*bicsi3_insn"
949 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
950 (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
951 (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
954 [(set_attr "length" "1,2,1,2")])
956 (define_insn "*bicsi3_set_cc_insn"
957 [(set (reg:CCZN 61) (compare:CCZN
958 (and:SI (match_operand:SI 1 "register_operand" "%r")
959 (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
961 (set (match_operand:SI 0 "register_operand" "=r")
962 (and:SI (match_dup 1)
963 (not:SI (match_dup 2))))]
966 [(set_attr "cond" "set_zn")])
968 (define_insn "iorsi3"
969 [(set (match_operand:SI 0 "register_operand" "=r")
970 (ior:SI (match_operand:SI 1 "register_operand" "%r")
971 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
975 (define_insn "*iorsi3_set_cc_insn"
976 [(set (reg:CCZN 61) (compare:CCZN
977 (ior:SI (match_operand:SI 1 "register_operand" "%r")
978 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
980 (set (match_operand:SI 0 "register_operand" "=r")
981 (ior:SI (match_dup 1)
985 [(set_attr "cond" "set_zn")])
987 (define_insn "xorsi3"
988 [(set (match_operand:SI 0 "register_operand" "=r")
989 (xor:SI (match_operand:SI 1 "register_operand" "%r")
990 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
994 (define_insn "*xorsi3_set_cc_insn"
995 [(set (reg:CCZN 61) (compare:CCZN
996 (xor:SI (match_operand:SI 1 "register_operand" "%r")
997 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
999 (set (match_operand:SI 0 "register_operand" "=r")
1000 (xor:SI (match_dup 1)
1004 [(set_attr "cond" "set_zn")])
1006 (define_insn "negsi2"
1007 [(set (match_operand:SI 0 "register_operand" "=r")
1008 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1011 [(set_attr "type" "unary")])
1013 (define_insn "*negsi2_set_cc_insn"
1014 [(set (reg:CC 61) (compare:CC
1015 (neg:SI (match_operand:SI 1 "register_operand" "r"))
1017 (set (match_operand:SI 0 "register_operand" "=r")
1018 (neg:SI (match_dup 1)))]
1021 [(set_attr "type" "unary")
1022 (set_attr "cond" "set")])
1024 (define_insn "negdi2"
1025 [(set (match_operand:DI 0 "register_operand" "=r")
1026 (neg:DI (match_operand:DI 1 "register_operand" "r")))
1027 (clobber (reg:SI 61))]
1029 "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1030 [(set_attr "type" "unary")
1031 (set_attr "length" "2")])
1033 (define_insn "one_cmplsi2"
1034 [(set (match_operand:SI 0 "register_operand" "=r")
1035 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1038 [(set_attr "type" "unary")])
1040 (define_insn "*one_cmplsi2_set_cc_insn"
1041 [(set (reg:CCZN 61) (compare:CCZN
1042 (not:SI (match_operand:SI 1 "register_operand" "r"))
1044 (set (match_operand:SI 0 "register_operand" "=r")
1045 (not:SI (match_dup 1)))]
1048 [(set_attr "type" "unary")
1049 (set_attr "cond" "set_zn")])
1051 ;; Shift instructions.
1053 (define_expand "ashlsi3"
1054 [(set (match_operand:SI 0 "register_operand" "")
1055 (ashift:SI (match_operand:SI 1 "register_operand" "")
1056 (match_operand:SI 2 "nonmemory_operand" "")))]
1060 if (! TARGET_SHIFTER)
1062 emit_insn (gen_rtx_PARALLEL
1065 gen_rtx_SET (VOIDmode, operands[0],
1066 gen_rtx_ASHIFT (SImode, operands[1],
1068 gen_rtx_CLOBBER (VOIDmode,
1069 gen_rtx_SCRATCH (SImode)))));
1074 (define_expand "ashrsi3"
1075 [(set (match_operand:SI 0 "register_operand" "")
1076 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1077 (match_operand:SI 2 "nonmemory_operand" "")))]
1081 if (! TARGET_SHIFTER)
1083 emit_insn (gen_rtx_PARALLEL
1086 gen_rtx_SET (VOIDmode, operands[0],
1087 gen_rtx_ASHIFTRT (SImode,
1090 gen_rtx_CLOBBER (VOIDmode,
1091 gen_rtx_SCRATCH (SImode)))));
1096 (define_expand "lshrsi3"
1097 [(set (match_operand:SI 0 "register_operand" "")
1098 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1099 (match_operand:SI 2 "nonmemory_operand" "")))]
1103 if (! TARGET_SHIFTER)
1105 emit_insn (gen_rtx_PARALLEL
1108 gen_rtx_SET (VOIDmode, operands[0],
1109 gen_rtx_LSHIFTRT (SImode,
1112 gen_rtx_CLOBBER (VOIDmode,
1113 gen_rtx_SCRATCH (SImode)))));
1118 (define_insn "*ashlsi3_insn"
1119 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1120 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1121 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1124 [(set_attr "type" "shift")
1125 (set_attr "length" "1,2,1,2")])
1127 (define_insn "*ashrsi3_insn"
1128 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1129 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1130 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1133 [(set_attr "type" "shift")
1134 (set_attr "length" "1,2,1,2")])
1136 (define_insn "*lshrsi3_insn"
1137 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1138 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1139 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1142 [(set_attr "type" "shift")
1143 (set_attr "length" "1,2,1,2")])
1145 (define_insn "*shift_si3"
1146 [(set (match_operand:SI 0 "register_operand" "=r")
1147 (match_operator:SI 3 "shift_operator"
1148 [(match_operand:SI 1 "register_operand" "0")
1149 (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1150 (clobber (match_scratch:SI 4 "=&r"))]
1152 "* return output_shift (operands);"
1153 [(set_attr "type" "shift")
1154 (set_attr "length" "8")])
1156 ;; Compare instructions.
1157 ;; This controls RTL generation and register allocation.
1159 ;; We generate RTL for comparisons and branches by having the cmpxx
1160 ;; patterns store away the operands. Then, the scc and bcc patterns
1161 ;; emit RTL for both the compare and the branch.
1163 (define_expand "cmpsi"
1165 (compare:CC (match_operand:SI 0 "register_operand" "")
1166 (match_operand:SI 1 "nonmemory_operand" "")))]
1170 arc_compare_op0 = operands[0];
1171 arc_compare_op1 = operands[1];
1175 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1176 ;; This assumes sub.f 0,symbol,0 is a valid insn.
1177 ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
1178 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1179 ;; if it's a small constant.
1181 (define_insn "*cmpsi_cc_insn"
1183 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1184 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1190 [(set_attr "type" "compare,compare,compare")])
1192 (define_insn "*cmpsi_cczn_insn"
1194 (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1195 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1201 [(set_attr "type" "compare,compare,compare")])
1203 (define_insn "*cmpsi_ccznc_insn"
1204 [(set (reg:CCZNC 61)
1205 (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1206 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1212 [(set_attr "type" "compare,compare,compare")])
1214 ;; Next come the scc insns.
1216 (define_expand "seq"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (eq:SI (match_dup 1) (const_int 0)))]
1222 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1225 (define_expand "sne"
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (ne:SI (match_dup 1) (const_int 0)))]
1231 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1234 (define_expand "sgt"
1235 [(set (match_operand:SI 0 "register_operand" "=r")
1236 (gt:SI (match_dup 1) (const_int 0)))]
1240 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1243 (define_expand "sle"
1244 [(set (match_operand:SI 0 "register_operand" "=r")
1245 (le:SI (match_dup 1) (const_int 0)))]
1249 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1252 (define_expand "sge"
1253 [(set (match_operand:SI 0 "register_operand" "=r")
1254 (ge:SI (match_dup 1) (const_int 0)))]
1258 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1261 (define_expand "slt"
1262 [(set (match_operand:SI 0 "register_operand" "=r")
1263 (lt:SI (match_dup 1) (const_int 0)))]
1267 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1270 (define_expand "sgtu"
1271 [(set (match_operand:SI 0 "register_operand" "=r")
1272 (gtu:SI (match_dup 1) (const_int 0)))]
1276 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1279 (define_expand "sleu"
1280 [(set (match_operand:SI 0 "register_operand" "=r")
1281 (leu:SI (match_dup 1) (const_int 0)))]
1285 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1288 (define_expand "sgeu"
1289 [(set (match_operand:SI 0 "register_operand" "=r")
1290 (geu:SI (match_dup 1) (const_int 0)))]
1294 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1297 (define_expand "sltu"
1298 [(set (match_operand:SI 0 "register_operand" "=r")
1299 (ltu:SI (match_dup 1) (const_int 0)))]
1303 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1306 (define_insn "*scc_insn"
1307 [(set (match_operand:SI 0 "register_operand" "=r")
1308 (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1310 "mov %0,1\;sub.%D1 %0,%0,%0"
1311 [(set_attr "type" "unary")
1312 (set_attr "length" "2")])
1314 ;; ??? Look up negscc insn. See pa.md for example.
1315 (define_insn "*neg_scc_insn"
1316 [(set (match_operand:SI 0 "register_operand" "=r")
1317 (neg:SI (match_operator:SI 1 "comparison_operator"
1318 [(reg 61) (const_int 0)])))]
1320 "mov %0,-1\;sub.%D1 %0,%0,%0"
1321 [(set_attr "type" "unary")
1322 (set_attr "length" "2")])
1324 (define_insn "*not_scc_insn"
1325 [(set (match_operand:SI 0 "register_operand" "=r")
1326 (not:SI (match_operator:SI 1 "comparison_operator"
1327 [(reg 61) (const_int 0)])))]
1329 "mov %0,1\;sub.%d1 %0,%0,%0"
1330 [(set_attr "type" "unary")
1331 (set_attr "length" "2")])
1333 ;; These control RTL generation for conditional jump insns
1335 (define_expand "beq"
1337 (if_then_else (eq (match_dup 1) (const_int 0))
1338 (label_ref (match_operand 0 "" ""))
1343 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1346 (define_expand "bne"
1348 (if_then_else (ne (match_dup 1) (const_int 0))
1349 (label_ref (match_operand 0 "" ""))
1354 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1357 (define_expand "bgt"
1359 (if_then_else (gt (match_dup 1) (const_int 0))
1360 (label_ref (match_operand 0 "" ""))
1365 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1368 (define_expand "ble"
1370 (if_then_else (le (match_dup 1) (const_int 0))
1371 (label_ref (match_operand 0 "" ""))
1376 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1379 (define_expand "bge"
1381 (if_then_else (ge (match_dup 1) (const_int 0))
1382 (label_ref (match_operand 0 "" ""))
1387 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1390 (define_expand "blt"
1392 (if_then_else (lt (match_dup 1) (const_int 0))
1393 (label_ref (match_operand 0 "" ""))
1398 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1401 (define_expand "bgtu"
1403 (if_then_else (gtu (match_dup 1) (const_int 0))
1404 (label_ref (match_operand 0 "" ""))
1409 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1412 (define_expand "bleu"
1414 (if_then_else (leu (match_dup 1) (const_int 0))
1415 (label_ref (match_operand 0 "" ""))
1420 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1423 (define_expand "bgeu"
1425 (if_then_else (geu (match_dup 1) (const_int 0))
1426 (label_ref (match_operand 0 "" ""))
1431 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1434 (define_expand "bltu"
1436 (if_then_else (ltu (match_dup 1) (const_int 0))
1437 (label_ref (match_operand 0 "" ""))
1442 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1445 ;; Now match both normal and inverted jump.
1447 (define_insn "*branch_insn"
1449 (if_then_else (match_operator 1 "proper_comparison_operator"
1450 [(reg 61) (const_int 0)])
1451 (label_ref (match_operand 0 "" ""))
1456 if (arc_ccfsm_branch_deleted_p ())
1458 arc_ccfsm_record_branch_deleted ();
1459 return \"; branch deleted, next insns conditionalized\";
1462 return \"%~b%d1%# %l0\";
1464 [(set_attr "type" "branch")])
1466 (define_insn "*rev_branch_insn"
1468 (if_then_else (match_operator 1 "proper_comparison_operator"
1469 [(reg 61) (const_int 0)])
1471 (label_ref (match_operand 0 "" ""))))]
1472 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1475 if (arc_ccfsm_branch_deleted_p ())
1477 arc_ccfsm_record_branch_deleted ();
1478 return \"; branch deleted, next insns conditionalized\";
1481 return \"%~b%D1%# %l0\";
1483 [(set_attr "type" "branch")])
1485 ;; Unconditional and other jump instructions.
1488 [(set (pc) (label_ref (match_operand 0 "" "")))]
1491 [(set_attr "type" "uncond_branch")])
1493 (define_insn "indirect_jump"
1494 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1497 [(set_attr "type" "uncond_branch")])
1499 ;; Implement a switch statement.
1500 ;; This wouldn't be necessary in the non-pic case if we could distinguish
1501 ;; label refs of the jump table from other label refs. The problem is that
1502 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1503 ;; the real address since it's the address of the table.
1505 (define_expand "casesi"
1507 (minus:SI (match_operand:SI 0 "register_operand" "")
1508 (match_operand:SI 1 "nonmemory_operand" "")))
1510 (compare:CC (match_dup 5)
1511 (match_operand:SI 2 "nonmemory_operand" "")))
1513 (if_then_else (gtu (reg:CC 61)
1515 (label_ref (match_operand 4 "" ""))
1519 (mem:SI (plus:SI (mult:SI (match_dup 5)
1521 (label_ref (match_operand 3 "" "")))))
1522 (clobber (match_scratch:SI 6 ""))
1523 (clobber (match_scratch:SI 7 ""))])]
1527 operands[5] = gen_reg_rtx (SImode);
1530 (define_insn "*casesi_insn"
1532 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1534 (label_ref (match_operand 1 "" "")))))
1535 (clobber (match_scratch:SI 2 "=r"))
1536 (clobber (match_scratch:SI 3 "=r"))]
1540 output_asm_insn (\"mov %2,%1\", operands);
1542 output_asm_insn (\"asl %3,%0,2\", operands);
1544 output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1545 output_asm_insn (\"ld %2,[%2,%3]\", operands);
1546 output_asm_insn (\"j.nd %a2\", operands);
1549 [(set_attr "type" "uncond_branch")
1550 (set_attr "length" "6")])
1552 (define_insn "tablejump"
1553 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1554 (use (label_ref (match_operand 1 "" "")))]
1555 "0 /* disabled -> using casesi now */"
1557 [(set_attr "type" "uncond_branch")])
1559 (define_expand "call"
1560 ;; operands[1] is stack_size_rtx
1561 ;; operands[2] is next_arg_register
1562 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1563 (match_operand 1 "" ""))
1564 (clobber (reg:SI 31))])]
1568 (define_insn "*call_via_reg"
1569 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1570 (match_operand 1 "" ""))
1571 (clobber (reg:SI 31))]
1573 "lr blink,[status]\;j.d %0\;add blink,blink,2"
1574 [(set_attr "type" "call_no_delay_slot")
1575 (set_attr "length" "3")])
1577 (define_insn "*call_via_label"
1578 [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1579 (match_operand 1 "" ""))
1580 (clobber (reg:SI 31))]
1582 ; The %~ is necessary in case this insn gets conditionalized and the previous
1583 ; insn is the cc setter.
1585 [(set_attr "type" "call")
1586 (set_attr "cond" "canuse")])
1588 (define_expand "call_value"
1589 ;; operand 2 is stack_size_rtx
1590 ;; operand 3 is next_arg_register
1591 [(parallel [(set (match_operand 0 "register_operand" "=r")
1592 (call (match_operand:SI 1 "call_operand" "")
1593 (match_operand 2 "" "")))
1594 (clobber (reg:SI 31))])]
1598 (define_insn "*call_value_via_reg"
1599 [(set (match_operand 0 "register_operand" "=r")
1600 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1601 (match_operand 2 "" "")))
1602 (clobber (reg:SI 31))]
1604 "lr blink,[status]\;j.d %1\;add blink,blink,2"
1605 [(set_attr "type" "call_no_delay_slot")
1606 (set_attr "length" "3")])
1608 (define_insn "*call_value_via_label"
1609 [(set (match_operand 0 "register_operand" "=r")
1610 (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1611 (match_operand 2 "" "")))
1612 (clobber (reg:SI 31))]
1614 ; The %~ is necessary in case this insn gets conditionalized and the previous
1615 ; insn is the cc setter.
1617 [(set_attr "type" "call")
1618 (set_attr "cond" "canuse")])
1624 [(set_attr "type" "misc")])
1626 ;; Special pattern to flush the icache.
1627 ;; ??? Not sure what to do here. Some ARC's are known to support this.
1629 (define_insn "flush_icache"
1630 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1633 [(set_attr "type" "misc")])
1635 ;; Split up troublesome insns for better scheduling.
1637 ;; Peepholes go at the end.