1 ;; Machine description of the Argonaut ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004, 2005
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 2, 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 COPYING. If not, write to
19 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; ??? This is an old port, and is undoubtedly suffering from bit rot.
26 ;; Insn type. Used to default other attribute values.
29 "move,load,store,cmove,unary,binary,compare,shift,mul,uncond_branch,branch,call,call_no_delay_slot,multi,misc"
30 (const_string "binary"))
32 ;; Length (in # of insns, long immediate constants counted too).
33 ;; ??? There's a nasty interaction between the conditional execution fsm
34 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
35 (define_attr "length" ""
36 (cond [(eq_attr "type" "load")
37 (if_then_else (match_operand 1 "long_immediate_loadstore_operand" "")
38 (const_int 2) (const_int 1))
40 (eq_attr "type" "store")
41 (if_then_else (match_operand 0 "long_immediate_loadstore_operand" "")
42 (const_int 2) (const_int 1))
44 (eq_attr "type" "move,unary,compare")
45 (if_then_else (match_operand 1 "long_immediate_operand" "")
46 (const_int 2) (const_int 1))
48 (eq_attr "type" "binary,mul")
49 (if_then_else (match_operand 2 "long_immediate_operand" "")
50 (const_int 2) (const_int 1))
52 (eq_attr "type" "cmove")
53 (if_then_else (match_operand 2 "register_operand" "")
54 (const_int 1) (const_int 2))
56 (eq_attr "type" "multi") (const_int 2)
61 ;; The length here is the length of a single asm. Unfortunately it might be
62 ;; 1 or 2 so we must allow for 2. That's ok though. How often will users
63 ;; lament asm's not being put in delay slots?
64 (define_asm_attributes
65 [(set_attr "length" "2")
66 (set_attr "type" "multi")])
68 ;; Condition codes: this one is used by final_prescan_insn to speed up
69 ;; conditionalizing instructions. It saves having to scan the rtl to see if
70 ;; it uses or alters the condition codes.
72 ;; USE: This insn uses the condition codes (e.g.: a conditional branch).
73 ;; CANUSE: This insn can use the condition codes (for conditional execution).
74 ;; SET: All condition codes are set by this insn.
75 ;; SET_ZN: the Z and N flags are set by this insn.
76 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
77 ;; CLOB: The condition codes are set to unknown values by this insn.
78 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
80 (define_attr "cond" "use,canuse,set,set_zn,set_znc,clob,nocond"
81 (cond [(and (eq_attr "type" "unary,binary,move")
82 (eq_attr "length" "1"))
83 (const_string "canuse")
85 (eq_attr "type" "compare")
88 (eq_attr "type" "cmove,branch")
91 (eq_attr "type" "multi,misc")
95 (const_string "nocond")))
99 (define_attr "in_delay_slot" "false,true"
100 (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
101 (const_string "false")
104 (if_then_else (eq_attr "length" "1")
105 (const_string "true")
106 (const_string "false"))))
108 (define_delay (eq_attr "type" "call")
109 [(eq_attr "in_delay_slot" "true")
110 (eq_attr "in_delay_slot" "true")
111 (eq_attr "in_delay_slot" "true")])
113 (define_delay (eq_attr "type" "branch,uncond_branch")
114 [(eq_attr "in_delay_slot" "true")
115 (eq_attr "in_delay_slot" "true")
116 (eq_attr "in_delay_slot" "true")])
118 ;; Scheduling description for the ARC
120 (define_cpu_unit "branch")
122 (define_insn_reservation "any_insn" 1 (eq_attr "type" "!load,compare,branch")
125 ;; 1) A conditional jump cannot immediately follow the insn setting the flags.
126 ;; This isn't a complete solution as it doesn't come with guarantees. That
127 ;; is done in the branch patterns and in arc_print_operand. This exists to
128 ;; avoid inserting a nop when we can.
130 (define_insn_reservation "compare" 1 (eq_attr "type" "compare")
133 (define_insn_reservation "branch" 1 (eq_attr "type" "branch")
136 ;; 2) References to loaded registers should wait a cycle.
138 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
140 (define_insn_reservation "memory" 2 (eq_attr "type" "load")
143 ;; Move instructions.
145 (define_expand "movqi"
146 [(set (match_operand:QI 0 "general_operand" "")
147 (match_operand:QI 1 "general_operand" ""))]
151 /* Everything except mem = const or mem = mem can be done easily. */
153 if (GET_CODE (operands[0]) == MEM)
154 operands[1] = force_reg (QImode, operands[1]);
157 (define_insn "*movqi_insn"
158 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
159 (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
161 "register_operand (operands[0], QImode)
162 || register_operand (operands[1], QImode)"
168 [(set_attr "type" "move,move,load,store")])
170 ;; ??? This may never match since there's no cmpqi insn.
172 (define_insn "*movqi_set_cc_insn"
173 [(set (reg:CCZN 61) (compare:CCZN
174 (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
176 (set (match_operand:QI 0 "move_dest_operand" "=r")
180 [(set_attr "type" "move")
181 (set_attr "cond" "set_zn")])
183 (define_expand "movhi"
184 [(set (match_operand:HI 0 "general_operand" "")
185 (match_operand:HI 1 "general_operand" ""))]
189 /* Everything except mem = const or mem = mem can be done easily. */
191 if (GET_CODE (operands[0]) == MEM)
192 operands[1] = force_reg (HImode, operands[1]);
195 (define_insn "*movhi_insn"
196 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
197 (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
198 "register_operand (operands[0], HImode)
199 || register_operand (operands[1], HImode)"
205 [(set_attr "type" "move,move,load,store")])
207 ;; ??? Will this ever match?
209 (define_insn "*movhi_set_cc_insn"
210 [(set (reg:CCZN 61) (compare:CCZN
211 (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
213 (set (match_operand:HI 0 "move_dest_operand" "=r")
216 "register_operand (operands[0], HImode)
217 || register_operand (operands[1], HImode)"
219 [(set_attr "type" "move")
220 (set_attr "cond" "set_zn")])
222 (define_expand "movsi"
223 [(set (match_operand:SI 0 "general_operand" "")
224 (match_operand:SI 1 "general_operand" ""))]
228 /* Everything except mem = const or mem = mem can be done easily. */
230 if (GET_CODE (operands[0]) == MEM)
231 operands[1] = force_reg (SImode, operands[1]);
234 (define_insn "*movsi_insn"
235 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
236 (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
237 "register_operand (operands[0], SImode)
238 || register_operand (operands[1], SImode)"
244 [(set_attr "type" "move,move,load,store")])
246 (define_insn "*movsi_set_cc_insn"
247 [(set (reg:CCZN 61) (compare:CCZN
248 (match_operand:SI 1 "move_src_operand" "rIJi")
250 (set (match_operand:SI 0 "move_dest_operand" "=r")
252 "register_operand (operands[0], SImode)
253 || register_operand (operands[1], SImode)"
255 [(set_attr "type" "move")
256 (set_attr "cond" "set_zn")])
258 (define_expand "movdi"
259 [(set (match_operand:DI 0 "general_operand" "")
260 (match_operand:DI 1 "general_operand" ""))]
264 /* Everything except mem = const or mem = mem can be done easily. */
266 if (GET_CODE (operands[0]) == MEM)
267 operands[1] = force_reg (DImode, operands[1]);
270 (define_insn "*movdi_insn"
271 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
272 (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
273 "register_operand (operands[0], DImode)
274 || register_operand (operands[1], DImode)"
277 switch (which_alternative)
280 /* We normally copy the low-numbered register first. However, if
281 the first register operand 0 is the same as the second register of
282 operand 1, we must copy in the opposite order. */
283 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
284 return \"mov %R0,%R1\;mov %0,%1\";
286 return \"mov %0,%1\;mov %R0,%R1\";
288 return \"mov %0,%L1\;mov %R0,%H1\";
290 /* If the low-address word is used in the address, we must load it
291 last. Otherwise, load it first. Note that we cannot have
292 auto-increment in that case since the address register is known to be
294 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
296 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
298 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
300 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
305 [(set_attr "type" "move,move,load,store")
306 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
307 (set_attr "length" "2,4,2,2")])
309 ;(define_expand "movdi"
310 ; [(set (match_operand:DI 0 "general_operand" "")
311 ; (match_operand:DI 1 "general_operand" ""))]
315 ; /* Flow doesn't understand that this is effectively a DFmode move.
316 ; It doesn't know that all of `operands[0]' is set. */
317 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
319 ; /* Emit insns that movsi_insn can handle. */
320 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
321 ; operand_subword (operands[1], 0, 0, DImode)));
322 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
323 ; operand_subword (operands[1], 1, 0, DImode)));
327 ;; Floating point move insns.
329 (define_expand "movsf"
330 [(set (match_operand:SF 0 "general_operand" "")
331 (match_operand:SF 1 "general_operand" ""))]
335 /* Everything except mem = const or mem = mem can be done easily. */
336 if (GET_CODE (operands[0]) == MEM)
337 operands[1] = force_reg (SFmode, operands[1]);
340 (define_insn "*movsf_insn"
341 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
342 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
343 "register_operand (operands[0], SFmode)
344 || register_operand (operands[1], SFmode)"
350 [(set_attr "type" "move,move,load,store")])
352 (define_expand "movdf"
353 [(set (match_operand:DF 0 "general_operand" "")
354 (match_operand:DF 1 "general_operand" ""))]
358 /* Everything except mem = const or mem = mem can be done easily. */
359 if (GET_CODE (operands[0]) == MEM)
360 operands[1] = force_reg (DFmode, operands[1]);
363 (define_insn "*movdf_insn"
364 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
365 (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
366 "register_operand (operands[0], DFmode)
367 || register_operand (operands[1], DFmode)"
370 switch (which_alternative)
373 /* We normally copy the low-numbered register first. However, if
374 the first register operand 0 is the same as the second register of
375 operand 1, we must copy in the opposite order. */
376 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
377 return \"mov %R0,%R1\;mov %0,%1\";
379 return \"mov %0,%1\;mov %R0,%R1\";
381 return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
383 /* If the low-address word is used in the address, we must load it
384 last. Otherwise, load it first. Note that we cannot have
385 auto-increment in that case since the address register is known to be
387 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
389 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
391 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
393 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
398 [(set_attr "type" "move,move,load,store")
399 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
400 (set_attr "length" "2,4,2,2")])
402 ;(define_expand "movdf"
403 ; [(set (match_operand:DF 0 "general_operand" "")
404 ; (match_operand:DF 1 "general_operand" ""))]
408 ; /* Flow doesn't understand that this is effectively a DFmode move.
409 ; It doesn't know that all of `operands[0]' is set. */
410 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
412 ; /* Emit insns that movsi_insn can handle. */
413 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
414 ; operand_subword (operands[1], 0, 0, DFmode)));
415 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
416 ; operand_subword (operands[1], 1, 0, DFmode)));
420 ;; Load/Store with update instructions.
422 ;; Some of these we can get by using pre-decrement or pre-increment, but the
423 ;; hardware can also do cases where the increment is not the size of the
426 ;; In all these cases, we use operands 0 and 1 for the register being
427 ;; incremented because those are the operands that local-alloc will
428 ;; tie and these are the pair most likely to be tieable (and the ones
429 ;; that will benefit the most).
431 ;; We use match_operator here because we need to know whether the memory
432 ;; object is volatile or not.
434 (define_insn "*loadqi_update"
435 [(set (match_operand:QI 3 "register_operand" "=r,r")
436 (match_operator:QI 4 "load_update_operand"
437 [(match_operand:SI 1 "register_operand" "0,0")
438 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
439 (set (match_operand:SI 0 "register_operand" "=r,r")
440 (plus:SI (match_dup 1) (match_dup 2)))]
442 "ldb.a%V4 %3,[%0,%2]"
443 [(set_attr "type" "load,load")
444 (set_attr "length" "1,2")])
446 (define_insn "*load_zeroextendqisi_update"
447 [(set (match_operand:SI 3 "register_operand" "=r,r")
448 (zero_extend:SI (match_operator:QI 4 "load_update_operand"
449 [(match_operand:SI 1 "register_operand" "0,0")
450 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
451 (set (match_operand:SI 0 "register_operand" "=r,r")
452 (plus:SI (match_dup 1) (match_dup 2)))]
454 "ldb.a%V4 %3,[%0,%2]"
455 [(set_attr "type" "load,load")
456 (set_attr "length" "1,2")])
458 (define_insn "*load_signextendqisi_update"
459 [(set (match_operand:SI 3 "register_operand" "=r,r")
460 (sign_extend:SI (match_operator:QI 4 "load_update_operand"
461 [(match_operand:SI 1 "register_operand" "0,0")
462 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
463 (set (match_operand:SI 0 "register_operand" "=r,r")
464 (plus:SI (match_dup 1) (match_dup 2)))]
466 "ldb.x.a%V4 %3,[%0,%2]"
467 [(set_attr "type" "load,load")
468 (set_attr "length" "1,2")])
470 (define_insn "*storeqi_update"
471 [(set (match_operator:QI 4 "store_update_operand"
472 [(match_operand:SI 1 "register_operand" "0")
473 (match_operand:SI 2 "short_immediate_operand" "I")])
474 (match_operand:QI 3 "register_operand" "r"))
475 (set (match_operand:SI 0 "register_operand" "=r")
476 (plus:SI (match_dup 1) (match_dup 2)))]
478 "stb.a%V4 %3,[%0,%2]"
479 [(set_attr "type" "store")
480 (set_attr "length" "1")])
482 (define_insn "*loadhi_update"
483 [(set (match_operand:HI 3 "register_operand" "=r,r")
484 (match_operator:HI 4 "load_update_operand"
485 [(match_operand:SI 1 "register_operand" "0,0")
486 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
487 (set (match_operand:SI 0 "register_operand" "=r,r")
488 (plus:SI (match_dup 1) (match_dup 2)))]
490 "ldw.a%V4 %3,[%0,%2]"
491 [(set_attr "type" "load,load")
492 (set_attr "length" "1,2")])
494 (define_insn "*load_zeroextendhisi_update"
495 [(set (match_operand:SI 3 "register_operand" "=r,r")
496 (zero_extend:SI (match_operator:HI 4 "load_update_operand"
497 [(match_operand:SI 1 "register_operand" "0,0")
498 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
499 (set (match_operand:SI 0 "register_operand" "=r,r")
500 (plus:SI (match_dup 1) (match_dup 2)))]
502 "ldw.a%V4 %3,[%0,%2]"
503 [(set_attr "type" "load,load")
504 (set_attr "length" "1,2")])
506 (define_insn "*load_signextendhisi_update"
507 [(set (match_operand:SI 3 "register_operand" "=r,r")
508 (sign_extend:SI (match_operator:HI 4 "load_update_operand"
509 [(match_operand:SI 1 "register_operand" "0,0")
510 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
511 (set (match_operand:SI 0 "register_operand" "=r,r")
512 (plus:SI (match_dup 1) (match_dup 2)))]
514 "ldw.x.a%V4 %3,[%0,%2]"
515 [(set_attr "type" "load,load")
516 (set_attr "length" "1,2")])
518 (define_insn "*storehi_update"
519 [(set (match_operator:HI 4 "store_update_operand"
520 [(match_operand:SI 1 "register_operand" "0")
521 (match_operand:SI 2 "short_immediate_operand" "I")])
522 (match_operand:HI 3 "register_operand" "r"))
523 (set (match_operand:SI 0 "register_operand" "=r")
524 (plus:SI (match_dup 1) (match_dup 2)))]
526 "stw.a%V4 %3,[%0,%2]"
527 [(set_attr "type" "store")
528 (set_attr "length" "1")])
530 (define_insn "*loadsi_update"
531 [(set (match_operand:SI 3 "register_operand" "=r,r")
532 (match_operator:SI 4 "load_update_operand"
533 [(match_operand:SI 1 "register_operand" "0,0")
534 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
535 (set (match_operand:SI 0 "register_operand" "=r,r")
536 (plus:SI (match_dup 1) (match_dup 2)))]
539 [(set_attr "type" "load,load")
540 (set_attr "length" "1,2")])
542 (define_insn "*storesi_update"
543 [(set (match_operator:SI 4 "store_update_operand"
544 [(match_operand:SI 1 "register_operand" "0")
545 (match_operand:SI 2 "short_immediate_operand" "I")])
546 (match_operand:SI 3 "register_operand" "r"))
547 (set (match_operand:SI 0 "register_operand" "=r")
548 (plus:SI (match_dup 1) (match_dup 2)))]
551 [(set_attr "type" "store")
552 (set_attr "length" "1")])
554 (define_insn "*loadsf_update"
555 [(set (match_operand:SF 3 "register_operand" "=r,r")
556 (match_operator:SF 4 "load_update_operand"
557 [(match_operand:SI 1 "register_operand" "0,0")
558 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
559 (set (match_operand:SI 0 "register_operand" "=r,r")
560 (plus:SI (match_dup 1) (match_dup 2)))]
563 [(set_attr "type" "load,load")
564 (set_attr "length" "1,2")])
566 (define_insn "*storesf_update"
567 [(set (match_operator:SF 4 "store_update_operand"
568 [(match_operand:SI 1 "register_operand" "0")
569 (match_operand:SI 2 "short_immediate_operand" "I")])
570 (match_operand:SF 3 "register_operand" "r"))
571 (set (match_operand:SI 0 "register_operand" "=r")
572 (plus:SI (match_dup 1) (match_dup 2)))]
575 [(set_attr "type" "store")
576 (set_attr "length" "1")])
578 ;; Conditional move instructions.
580 (define_expand "movsicc"
581 [(set (match_operand:SI 0 "register_operand" "")
582 (if_then_else:SI (match_operand 1 "comparison_operator" "")
583 (match_operand:SI 2 "nonmemory_operand" "")
584 (match_operand:SI 3 "register_operand" "")))]
588 enum rtx_code code = GET_CODE (operands[1]);
590 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
593 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
596 ;(define_expand "movdicc"
597 ; [(set (match_operand:DI 0 "register_operand" "")
598 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
599 ; (match_operand:DI 2 "nonmemory_operand" "")
600 ; (match_operand:DI 3 "register_operand" "")))]
601 ; "0 /* ??? this would work better if we had cmpdi */"
604 ; enum rtx_code code = GET_CODE (operands[1]);
606 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
609 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
612 (define_expand "movsfcc"
613 [(set (match_operand:SF 0 "register_operand" "")
614 (if_then_else:SF (match_operand 1 "comparison_operator" "")
615 (match_operand:SF 2 "nonmemory_operand" "")
616 (match_operand:SF 3 "register_operand" "")))]
620 enum rtx_code code = GET_CODE (operands[1]);
622 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
625 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
628 ;(define_expand "movdfcc"
629 ; [(set (match_operand:DF 0 "register_operand" "")
630 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
631 ; (match_operand:DF 2 "nonmemory_operand" "")
632 ; (match_operand:DF 3 "register_operand" "")))]
633 ; "0 /* ??? can generate less efficient code if constants involved */"
636 ; enum rtx_code code = GET_CODE (operands[1]);
638 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
641 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
644 (define_insn "*movsicc_insn"
645 [(set (match_operand:SI 0 "register_operand" "=r")
646 (if_then_else:SI (match_operand 1 "comparison_operator" "")
647 (match_operand:SI 2 "nonmemory_operand" "rJi")
648 (match_operand:SI 3 "register_operand" "0")))]
651 [(set_attr "type" "cmove")])
653 ; ??? This doesn't properly handle constants.
654 ;(define_insn "*movdicc_insn"
655 ; [(set (match_operand:DI 0 "register_operand" "=r,r")
656 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
657 ; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
658 ; (match_operand:DI 3 "register_operand" "0,0")))]
662 ; switch (which_alternative)
665 ; /* We normally copy the low-numbered register first. However, if
666 ; the first register operand 0 is the same as the second register of
667 ; operand 1, we must copy in the opposite order. */
668 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
669 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
671 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
673 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
676 ; [(set_attr "type" "cmove,cmove")
677 ; (set_attr "length" "2,4")])
679 (define_insn "*movsfcc_insn"
680 [(set (match_operand:SF 0 "register_operand" "=r,r")
681 (if_then_else:SF (match_operand 1 "comparison_operator" "")
682 (match_operand:SF 2 "nonmemory_operand" "r,E")
683 (match_operand:SF 3 "register_operand" "0,0")))]
688 [(set_attr "type" "cmove,cmove")])
690 ;(define_insn "*movdfcc_insn"
691 ; [(set (match_operand:DF 0 "register_operand" "=r,r")
692 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
693 ; (match_operand:DF 2 "nonmemory_operand" "r,E")
694 ; (match_operand:DF 3 "register_operand" "0,0")))]
698 ; switch (which_alternative)
701 ; /* We normally copy the low-numbered register first. However, if
702 ; the first register operand 0 is the same as the second register of
703 ; operand 1, we must copy in the opposite order. */
704 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
705 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
707 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
709 ; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
712 ; [(set_attr "type" "cmove,cmove")
713 ; (set_attr "length" "2,4")])
715 ;; Zero extension instructions.
716 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
718 (define_insn "zero_extendqihi2"
719 [(set (match_operand:HI 0 "register_operand" "=r,r")
720 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
725 [(set_attr "type" "unary,load")])
727 (define_insn "*zero_extendqihi2_set_cc_insn"
728 [(set (reg:CCZN 61) (compare:CCZN
729 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
731 (set (match_operand:HI 0 "register_operand" "=r")
732 (zero_extend:HI (match_dup 1)))]
735 [(set_attr "type" "unary")
736 (set_attr "cond" "set_zn")])
738 (define_insn "zero_extendqisi2"
739 [(set (match_operand:SI 0 "register_operand" "=r,r")
740 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
745 [(set_attr "type" "unary,load")])
747 (define_insn "*zero_extendqisi2_set_cc_insn"
748 [(set (reg:CCZN 61) (compare:CCZN
749 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
751 (set (match_operand:SI 0 "register_operand" "=r")
752 (zero_extend:SI (match_dup 1)))]
755 [(set_attr "type" "unary")
756 (set_attr "cond" "set_zn")])
758 (define_insn "zero_extendhisi2"
759 [(set (match_operand:SI 0 "register_operand" "=r,r")
760 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
765 [(set_attr "type" "unary,load")])
767 (define_insn "*zero_extendhisi2_set_cc_insn"
768 [(set (reg:CCZN 61) (compare:CCZN
769 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
771 (set (match_operand:SI 0 "register_operand" "=r")
772 (zero_extend:SI (match_dup 1)))]
775 [(set_attr "type" "unary")
776 (set_attr "cond" "set_zn")])
778 ;; Sign extension instructions.
780 (define_insn "extendqihi2"
781 [(set (match_operand:HI 0 "register_operand" "=r,r")
782 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
787 [(set_attr "type" "unary,load")])
789 (define_insn "*extendqihi2_set_cc_insn"
790 [(set (reg:CCZN 61) (compare:CCZN
791 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
793 (set (match_operand:HI 0 "register_operand" "=r")
794 (sign_extend:HI (match_dup 1)))]
797 [(set_attr "type" "unary")
798 (set_attr "cond" "set_zn")])
800 (define_insn "extendqisi2"
801 [(set (match_operand:SI 0 "register_operand" "=r,r")
802 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
807 [(set_attr "type" "unary,load")])
809 (define_insn "*extendqisi2_set_cc_insn"
810 [(set (reg:CCZN 61) (compare:CCZN
811 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
813 (set (match_operand:SI 0 "register_operand" "=r")
814 (sign_extend:SI (match_dup 1)))]
817 [(set_attr "type" "unary")
818 (set_attr "cond" "set_zn")])
820 (define_insn "extendhisi2"
821 [(set (match_operand:SI 0 "register_operand" "=r,r")
822 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
827 [(set_attr "type" "unary,load")])
829 (define_insn "*extendhisi2_set_cc_insn"
830 [(set (reg:CCZN 61) (compare:CCZN
831 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
833 (set (match_operand:SI 0 "register_operand" "=r")
834 (sign_extend:SI (match_dup 1)))]
837 [(set_attr "type" "unary")
838 (set_attr "cond" "set_zn")])
840 ;; Arithmetic instructions.
842 (define_insn "addsi3"
843 [(set (match_operand:SI 0 "register_operand" "=r")
844 (plus:SI (match_operand:SI 1 "register_operand" "%r")
845 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
849 (define_insn "*addsi3_set_cc_insn"
850 [(set (reg:CC 61) (compare:CC
851 (plus:SI (match_operand:SI 1 "register_operand" "%r")
852 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
854 (set (match_operand:SI 0 "register_operand" "=r")
855 (plus:SI (match_dup 1)
859 [(set_attr "cond" "set")])
861 (define_insn "adddi3"
862 [(set (match_operand:DI 0 "register_operand" "=r")
863 (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
864 (match_operand:DI 2 "nonmemory_operand" "ri")))
865 (clobber (reg:CC 61))]
869 rtx op2 = operands[2];
871 if (GET_CODE (op2) == CONST_INT)
873 int sign = INTVAL (op2);
875 return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
877 return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
880 return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
882 [(set_attr "length" "2")])
884 (define_insn "subsi3"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (minus:SI (match_operand:SI 1 "register_operand" "r")
887 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
891 (define_insn "*subsi3_set_cc_insn"
892 [(set (reg:CC 61) (compare:CC
893 (minus:SI (match_operand:SI 1 "register_operand" "%r")
894 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
896 (set (match_operand:SI 0 "register_operand" "=r")
897 (minus:SI (match_dup 1)
901 [(set_attr "cond" "set")])
903 (define_insn "subdi3"
904 [(set (match_operand:DI 0 "register_operand" "=r")
905 (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
906 (match_operand:DI 2 "nonmemory_operand" "ri")))
907 (clobber (reg:CC 61))]
911 rtx op2 = operands[2];
913 if (GET_CODE (op2) == CONST_INT)
915 int sign = INTVAL (op2);
917 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
919 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
922 return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
924 [(set_attr "length" "2")])
926 ;; Boolean instructions.
928 ;; We don't define the DImode versions as expand_binop does a good enough job.
930 (define_insn "andsi3"
931 [(set (match_operand:SI 0 "register_operand" "=r")
932 (and:SI (match_operand:SI 1 "register_operand" "%r")
933 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
937 (define_insn "*andsi3_set_cc_insn"
938 [(set (reg:CCZN 61) (compare:CCZN
939 (and:SI (match_operand:SI 1 "register_operand" "%r")
940 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
942 (set (match_operand:SI 0 "register_operand" "=r")
943 (and:SI (match_dup 1)
947 [(set_attr "cond" "set_zn")])
949 (define_insn "*bicsi3_insn"
950 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
951 (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
952 (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
955 [(set_attr "length" "1,2,1,2")])
957 (define_insn "*bicsi3_set_cc_insn"
958 [(set (reg:CCZN 61) (compare:CCZN
959 (and:SI (match_operand:SI 1 "register_operand" "%r")
960 (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
962 (set (match_operand:SI 0 "register_operand" "=r")
963 (and:SI (match_dup 1)
964 (not:SI (match_dup 2))))]
967 [(set_attr "cond" "set_zn")])
969 (define_insn "iorsi3"
970 [(set (match_operand:SI 0 "register_operand" "=r")
971 (ior:SI (match_operand:SI 1 "register_operand" "%r")
972 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
976 (define_insn "*iorsi3_set_cc_insn"
977 [(set (reg:CCZN 61) (compare:CCZN
978 (ior:SI (match_operand:SI 1 "register_operand" "%r")
979 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
981 (set (match_operand:SI 0 "register_operand" "=r")
982 (ior:SI (match_dup 1)
986 [(set_attr "cond" "set_zn")])
988 (define_insn "xorsi3"
989 [(set (match_operand:SI 0 "register_operand" "=r")
990 (xor:SI (match_operand:SI 1 "register_operand" "%r")
991 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
995 (define_insn "*xorsi3_set_cc_insn"
996 [(set (reg:CCZN 61) (compare:CCZN
997 (xor:SI (match_operand:SI 1 "register_operand" "%r")
998 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
1000 (set (match_operand:SI 0 "register_operand" "=r")
1001 (xor:SI (match_dup 1)
1005 [(set_attr "cond" "set_zn")])
1007 (define_insn "negsi2"
1008 [(set (match_operand:SI 0 "register_operand" "=r")
1009 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1012 [(set_attr "type" "unary")])
1014 (define_insn "*negsi2_set_cc_insn"
1015 [(set (reg:CC 61) (compare:CC
1016 (neg:SI (match_operand:SI 1 "register_operand" "r"))
1018 (set (match_operand:SI 0 "register_operand" "=r")
1019 (neg:SI (match_dup 1)))]
1022 [(set_attr "type" "unary")
1023 (set_attr "cond" "set")])
1025 (define_insn "negdi2"
1026 [(set (match_operand:DI 0 "register_operand" "=r")
1027 (neg:DI (match_operand:DI 1 "register_operand" "r")))
1028 (clobber (reg:SI 61))]
1030 "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1031 [(set_attr "type" "unary")
1032 (set_attr "length" "2")])
1034 (define_insn "one_cmplsi2"
1035 [(set (match_operand:SI 0 "register_operand" "=r")
1036 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1039 [(set_attr "type" "unary")])
1041 (define_insn "*one_cmplsi2_set_cc_insn"
1042 [(set (reg:CCZN 61) (compare:CCZN
1043 (not:SI (match_operand:SI 1 "register_operand" "r"))
1045 (set (match_operand:SI 0 "register_operand" "=r")
1046 (not:SI (match_dup 1)))]
1049 [(set_attr "type" "unary")
1050 (set_attr "cond" "set_zn")])
1052 ;; Shift instructions.
1054 (define_expand "ashlsi3"
1055 [(set (match_operand:SI 0 "register_operand" "")
1056 (ashift:SI (match_operand:SI 1 "register_operand" "")
1057 (match_operand:SI 2 "nonmemory_operand" "")))]
1061 if (! TARGET_SHIFTER)
1063 emit_insn (gen_rtx_PARALLEL
1066 gen_rtx_SET (VOIDmode, operands[0],
1067 gen_rtx_ASHIFT (SImode, operands[1],
1069 gen_rtx_CLOBBER (VOIDmode,
1070 gen_rtx_SCRATCH (SImode)))));
1075 (define_expand "ashrsi3"
1076 [(set (match_operand:SI 0 "register_operand" "")
1077 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1078 (match_operand:SI 2 "nonmemory_operand" "")))]
1082 if (! TARGET_SHIFTER)
1084 emit_insn (gen_rtx_PARALLEL
1087 gen_rtx_SET (VOIDmode, operands[0],
1088 gen_rtx_ASHIFTRT (SImode,
1091 gen_rtx_CLOBBER (VOIDmode,
1092 gen_rtx_SCRATCH (SImode)))));
1097 (define_expand "lshrsi3"
1098 [(set (match_operand:SI 0 "register_operand" "")
1099 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1100 (match_operand:SI 2 "nonmemory_operand" "")))]
1104 if (! TARGET_SHIFTER)
1106 emit_insn (gen_rtx_PARALLEL
1109 gen_rtx_SET (VOIDmode, operands[0],
1110 gen_rtx_LSHIFTRT (SImode,
1113 gen_rtx_CLOBBER (VOIDmode,
1114 gen_rtx_SCRATCH (SImode)))));
1119 (define_insn "*ashlsi3_insn"
1120 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1121 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1122 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1125 [(set_attr "type" "shift")
1126 (set_attr "length" "1,2,1,2")])
1128 (define_insn "*ashrsi3_insn"
1129 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1130 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1131 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1134 [(set_attr "type" "shift")
1135 (set_attr "length" "1,2,1,2")])
1137 (define_insn "*lshrsi3_insn"
1138 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1139 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1140 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1143 [(set_attr "type" "shift")
1144 (set_attr "length" "1,2,1,2")])
1146 (define_insn "*shift_si3"
1147 [(set (match_operand:SI 0 "register_operand" "=r")
1148 (match_operator:SI 3 "shift_operator"
1149 [(match_operand:SI 1 "register_operand" "0")
1150 (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1151 (clobber (match_scratch:SI 4 "=&r"))]
1153 "* return output_shift (operands);"
1154 [(set_attr "type" "shift")
1155 (set_attr "length" "8")])
1157 ;; Compare instructions.
1158 ;; This controls RTL generation and register allocation.
1160 ;; We generate RTL for comparisons and branches by having the cmpxx
1161 ;; patterns store away the operands. Then, the scc and bcc patterns
1162 ;; emit RTL for both the compare and the branch.
1164 (define_expand "cmpsi"
1166 (compare:CC (match_operand:SI 0 "register_operand" "")
1167 (match_operand:SI 1 "nonmemory_operand" "")))]
1171 arc_compare_op0 = operands[0];
1172 arc_compare_op1 = operands[1];
1176 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1177 ;; This assumes sub.f 0,symbol,0 is a valid insn.
1178 ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
1179 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1180 ;; if it's a small constant.
1182 (define_insn "*cmpsi_cc_insn"
1184 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1185 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1191 [(set_attr "type" "compare,compare,compare")])
1193 (define_insn "*cmpsi_cczn_insn"
1195 (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1196 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1202 [(set_attr "type" "compare,compare,compare")])
1204 (define_insn "*cmpsi_ccznc_insn"
1205 [(set (reg:CCZNC 61)
1206 (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1207 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1213 [(set_attr "type" "compare,compare,compare")])
1215 ;; Next come the scc insns.
1217 (define_expand "seq"
1218 [(set (match_operand:SI 0 "register_operand" "=r")
1219 (eq:SI (match_dup 1) (const_int 0)))]
1223 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1226 (define_expand "sne"
1227 [(set (match_operand:SI 0 "register_operand" "=r")
1228 (ne:SI (match_dup 1) (const_int 0)))]
1232 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1235 (define_expand "sgt"
1236 [(set (match_operand:SI 0 "register_operand" "=r")
1237 (gt:SI (match_dup 1) (const_int 0)))]
1241 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1244 (define_expand "sle"
1245 [(set (match_operand:SI 0 "register_operand" "=r")
1246 (le:SI (match_dup 1) (const_int 0)))]
1250 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1253 (define_expand "sge"
1254 [(set (match_operand:SI 0 "register_operand" "=r")
1255 (ge:SI (match_dup 1) (const_int 0)))]
1259 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1262 (define_expand "slt"
1263 [(set (match_operand:SI 0 "register_operand" "=r")
1264 (lt:SI (match_dup 1) (const_int 0)))]
1268 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1271 (define_expand "sgtu"
1272 [(set (match_operand:SI 0 "register_operand" "=r")
1273 (gtu:SI (match_dup 1) (const_int 0)))]
1277 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1280 (define_expand "sleu"
1281 [(set (match_operand:SI 0 "register_operand" "=r")
1282 (leu:SI (match_dup 1) (const_int 0)))]
1286 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1289 (define_expand "sgeu"
1290 [(set (match_operand:SI 0 "register_operand" "=r")
1291 (geu:SI (match_dup 1) (const_int 0)))]
1295 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1298 (define_expand "sltu"
1299 [(set (match_operand:SI 0 "register_operand" "=r")
1300 (ltu:SI (match_dup 1) (const_int 0)))]
1304 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1307 (define_insn "*scc_insn"
1308 [(set (match_operand:SI 0 "register_operand" "=r")
1309 (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1311 "mov %0,1\;sub.%D1 %0,%0,%0"
1312 [(set_attr "type" "unary")
1313 (set_attr "length" "2")])
1315 ;; ??? Look up negscc insn. See pa.md for example.
1316 (define_insn "*neg_scc_insn"
1317 [(set (match_operand:SI 0 "register_operand" "=r")
1318 (neg:SI (match_operator:SI 1 "comparison_operator"
1319 [(reg 61) (const_int 0)])))]
1321 "mov %0,-1\;sub.%D1 %0,%0,%0"
1322 [(set_attr "type" "unary")
1323 (set_attr "length" "2")])
1325 (define_insn "*not_scc_insn"
1326 [(set (match_operand:SI 0 "register_operand" "=r")
1327 (not:SI (match_operator:SI 1 "comparison_operator"
1328 [(reg 61) (const_int 0)])))]
1330 "mov %0,1\;sub.%d1 %0,%0,%0"
1331 [(set_attr "type" "unary")
1332 (set_attr "length" "2")])
1334 ;; These control RTL generation for conditional jump insns
1336 (define_expand "beq"
1338 (if_then_else (eq (match_dup 1) (const_int 0))
1339 (label_ref (match_operand 0 "" ""))
1344 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1347 (define_expand "bne"
1349 (if_then_else (ne (match_dup 1) (const_int 0))
1350 (label_ref (match_operand 0 "" ""))
1355 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1358 (define_expand "bgt"
1360 (if_then_else (gt (match_dup 1) (const_int 0))
1361 (label_ref (match_operand 0 "" ""))
1366 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1369 (define_expand "ble"
1371 (if_then_else (le (match_dup 1) (const_int 0))
1372 (label_ref (match_operand 0 "" ""))
1377 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1380 (define_expand "bge"
1382 (if_then_else (ge (match_dup 1) (const_int 0))
1383 (label_ref (match_operand 0 "" ""))
1388 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1391 (define_expand "blt"
1393 (if_then_else (lt (match_dup 1) (const_int 0))
1394 (label_ref (match_operand 0 "" ""))
1399 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1402 (define_expand "bgtu"
1404 (if_then_else (gtu (match_dup 1) (const_int 0))
1405 (label_ref (match_operand 0 "" ""))
1410 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1413 (define_expand "bleu"
1415 (if_then_else (leu (match_dup 1) (const_int 0))
1416 (label_ref (match_operand 0 "" ""))
1421 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1424 (define_expand "bgeu"
1426 (if_then_else (geu (match_dup 1) (const_int 0))
1427 (label_ref (match_operand 0 "" ""))
1432 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1435 (define_expand "bltu"
1437 (if_then_else (ltu (match_dup 1) (const_int 0))
1438 (label_ref (match_operand 0 "" ""))
1443 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1446 ;; Now match both normal and inverted jump.
1448 (define_insn "*branch_insn"
1450 (if_then_else (match_operator 1 "proper_comparison_operator"
1451 [(reg 61) (const_int 0)])
1452 (label_ref (match_operand 0 "" ""))
1457 if (arc_ccfsm_branch_deleted_p ())
1459 arc_ccfsm_record_branch_deleted ();
1460 return \"; branch deleted, next insns conditionalized\";
1463 return \"%~b%d1%# %l0\";
1465 [(set_attr "type" "branch")])
1467 (define_insn "*rev_branch_insn"
1469 (if_then_else (match_operator 1 "proper_comparison_operator"
1470 [(reg 61) (const_int 0)])
1472 (label_ref (match_operand 0 "" ""))))]
1473 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1476 if (arc_ccfsm_branch_deleted_p ())
1478 arc_ccfsm_record_branch_deleted ();
1479 return \"; branch deleted, next insns conditionalized\";
1482 return \"%~b%D1%# %l0\";
1484 [(set_attr "type" "branch")])
1486 ;; Unconditional and other jump instructions.
1489 [(set (pc) (label_ref (match_operand 0 "" "")))]
1492 [(set_attr "type" "uncond_branch")])
1494 (define_insn "indirect_jump"
1495 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1498 [(set_attr "type" "uncond_branch")])
1500 ;; Implement a switch statement.
1501 ;; This wouldn't be necessary in the non-pic case if we could distinguish
1502 ;; label refs of the jump table from other label refs. The problem is that
1503 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1504 ;; the real address since it's the address of the table.
1506 (define_expand "casesi"
1508 (minus:SI (match_operand:SI 0 "register_operand" "")
1509 (match_operand:SI 1 "nonmemory_operand" "")))
1511 (compare:CC (match_dup 5)
1512 (match_operand:SI 2 "nonmemory_operand" "")))
1514 (if_then_else (gtu (reg:CC 61)
1516 (label_ref (match_operand 4 "" ""))
1520 (mem:SI (plus:SI (mult:SI (match_dup 5)
1522 (label_ref (match_operand 3 "" "")))))
1523 (clobber (match_scratch:SI 6 ""))
1524 (clobber (match_scratch:SI 7 ""))])]
1528 operands[5] = gen_reg_rtx (SImode);
1531 (define_insn "*casesi_insn"
1533 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1535 (label_ref (match_operand 1 "" "")))))
1536 (clobber (match_scratch:SI 2 "=r"))
1537 (clobber (match_scratch:SI 3 "=r"))]
1541 output_asm_insn (\"mov %2,%1\", operands);
1543 output_asm_insn (\"asl %3,%0,2\", operands);
1545 output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1546 output_asm_insn (\"ld %2,[%2,%3]\", operands);
1547 output_asm_insn (\"j.nd %a2\", operands);
1550 [(set_attr "type" "uncond_branch")
1551 (set_attr "length" "6")])
1553 (define_insn "tablejump"
1554 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1555 (use (label_ref (match_operand 1 "" "")))]
1556 "0 /* disabled -> using casesi now */"
1558 [(set_attr "type" "uncond_branch")])
1560 (define_expand "call"
1561 ;; operands[1] is stack_size_rtx
1562 ;; operands[2] is next_arg_register
1563 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1564 (match_operand 1 "" ""))
1565 (clobber (reg:SI 31))])]
1569 (define_insn "*call_via_reg"
1570 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1571 (match_operand 1 "" ""))
1572 (clobber (reg:SI 31))]
1574 "lr blink,[status]\;j.d %0\;add blink,blink,2"
1575 [(set_attr "type" "call_no_delay_slot")
1576 (set_attr "length" "3")])
1578 (define_insn "*call_via_label"
1579 [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1580 (match_operand 1 "" ""))
1581 (clobber (reg:SI 31))]
1583 ; The %~ is necessary in case this insn gets conditionalized and the previous
1584 ; insn is the cc setter.
1586 [(set_attr "type" "call")
1587 (set_attr "cond" "canuse")])
1589 (define_expand "call_value"
1590 ;; operand 2 is stack_size_rtx
1591 ;; operand 3 is next_arg_register
1592 [(parallel [(set (match_operand 0 "register_operand" "=r")
1593 (call (match_operand:SI 1 "call_operand" "")
1594 (match_operand 2 "" "")))
1595 (clobber (reg:SI 31))])]
1599 (define_insn "*call_value_via_reg"
1600 [(set (match_operand 0 "register_operand" "=r")
1601 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1602 (match_operand 2 "" "")))
1603 (clobber (reg:SI 31))]
1605 "lr blink,[status]\;j.d %1\;add blink,blink,2"
1606 [(set_attr "type" "call_no_delay_slot")
1607 (set_attr "length" "3")])
1609 (define_insn "*call_value_via_label"
1610 [(set (match_operand 0 "register_operand" "=r")
1611 (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1612 (match_operand 2 "" "")))
1613 (clobber (reg:SI 31))]
1615 ; The %~ is necessary in case this insn gets conditionalized and the previous
1616 ; insn is the cc setter.
1618 [(set_attr "type" "call")
1619 (set_attr "cond" "canuse")])
1625 [(set_attr "type" "misc")])
1627 ;; Special pattern to flush the icache.
1628 ;; ??? Not sure what to do here. Some ARC's are known to support this.
1630 (define_insn "flush_icache"
1631 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1634 [(set_attr "type" "misc")])
1636 ;; Split up troublesome insns for better scheduling.
1638 ;; Peepholes go at the end.