1 ;; Machine description of the Argonaut ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1998, 1999, 2000, 2004
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, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, 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 (eg: 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 ;; Function units of the ARC
120 ;; (define_function_unit {name} {num-units} {n-users} {test}
121 ;; {ready-delay} {issue-delay} [{conflict-list}])
123 ;; 1) A conditional jump cannot immediately follow the insn setting the flags.
124 ;; This isn't a complete solution as it doesn't come with guarantees. That
125 ;; is done in the branch patterns and in arc_print_operand. This exists to
126 ;; avoid inserting a nop when we can.
127 (define_function_unit "compare" 1 0 (eq_attr "type" "compare") 2 2 [(eq_attr "type" "branch")])
129 ;; 2) References to loaded registers should wait a cycle.
131 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
132 (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
134 ;; Units that take one cycle do not need to be specified.
136 ;; Move instructions.
138 (define_expand "movqi"
139 [(set (match_operand:QI 0 "general_operand" "")
140 (match_operand:QI 1 "general_operand" ""))]
144 /* Everything except mem = const or mem = mem can be done easily. */
146 if (GET_CODE (operands[0]) == MEM)
147 operands[1] = force_reg (QImode, operands[1]);
150 (define_insn "*movqi_insn"
151 [(set (match_operand:QI 0 "move_dest_operand" "=r,r,r,m")
152 (match_operand:QI 1 "move_src_operand" "rI,Ji,m,r"))]
154 "register_operand (operands[0], QImode)
155 || register_operand (operands[1], QImode)"
161 [(set_attr "type" "move,move,load,store")])
163 ;; ??? This may never match since there's no cmpqi insn.
165 (define_insn "*movqi_set_cc_insn"
166 [(set (reg:CCZN 61) (compare:CCZN
167 (sign_extend:SI (match_operand:QI 1 "move_src_operand" "rIJi"))
169 (set (match_operand:QI 0 "move_dest_operand" "=r")
173 [(set_attr "type" "move")
174 (set_attr "cond" "set_zn")])
176 (define_expand "movhi"
177 [(set (match_operand:HI 0 "general_operand" "")
178 (match_operand:HI 1 "general_operand" ""))]
182 /* Everything except mem = const or mem = mem can be done easily. */
184 if (GET_CODE (operands[0]) == MEM)
185 operands[1] = force_reg (HImode, operands[1]);
188 (define_insn "*movhi_insn"
189 [(set (match_operand:HI 0 "move_dest_operand" "=r,r,r,m")
190 (match_operand:HI 1 "move_src_operand" "rI,Ji,m,r"))]
191 "register_operand (operands[0], HImode)
192 || register_operand (operands[1], HImode)"
198 [(set_attr "type" "move,move,load,store")])
200 ;; ??? Will this ever match?
202 (define_insn "*movhi_set_cc_insn"
203 [(set (reg:CCZN 61) (compare:CCZN
204 (sign_extend:SI (match_operand:HI 1 "move_src_operand" "rIJi"))
206 (set (match_operand:HI 0 "move_dest_operand" "=r")
209 "register_operand (operands[0], HImode)
210 || register_operand (operands[1], HImode)"
212 [(set_attr "type" "move")
213 (set_attr "cond" "set_zn")])
215 (define_expand "movsi"
216 [(set (match_operand:SI 0 "general_operand" "")
217 (match_operand:SI 1 "general_operand" ""))]
221 /* Everything except mem = const or mem = mem can be done easily. */
223 if (GET_CODE (operands[0]) == MEM)
224 operands[1] = force_reg (SImode, operands[1]);
227 (define_insn "*movsi_insn"
228 [(set (match_operand:SI 0 "move_dest_operand" "=r,r,r,m")
229 (match_operand:SI 1 "move_src_operand" "rI,GJi,m,r"))]
230 "register_operand (operands[0], SImode)
231 || register_operand (operands[1], SImode)"
237 [(set_attr "type" "move,move,load,store")])
239 (define_insn "*movsi_set_cc_insn"
240 [(set (reg:CCZN 61) (compare:CCZN
241 (match_operand:SI 1 "move_src_operand" "rIJi")
243 (set (match_operand:SI 0 "move_dest_operand" "=r")
245 "register_operand (operands[0], SImode)
246 || register_operand (operands[1], SImode)"
248 [(set_attr "type" "move")
249 (set_attr "cond" "set_zn")])
251 (define_expand "movdi"
252 [(set (match_operand:DI 0 "general_operand" "")
253 (match_operand:DI 1 "general_operand" ""))]
257 /* Everything except mem = const or mem = mem can be done easily. */
259 if (GET_CODE (operands[0]) == MEM)
260 operands[1] = force_reg (DImode, operands[1]);
263 (define_insn "*movdi_insn"
264 [(set (match_operand:DI 0 "move_dest_operand" "=r,r,r,m")
265 (match_operand:DI 1 "move_double_src_operand" "r,HK,m,r"))]
266 "register_operand (operands[0], DImode)
267 || register_operand (operands[1], DImode)"
270 switch (which_alternative)
273 /* We normally copy the low-numbered register first. However, if
274 the first register operand 0 is the same as the second register of
275 operand 1, we must copy in the opposite order. */
276 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
277 return \"mov %R0,%R1\;mov %0,%1\";
279 return \"mov %0,%1\;mov %R0,%R1\";
281 return \"mov %0,%L1\;mov %R0,%H1\";
283 /* If the low-address word is used in the address, we must load it
284 last. Otherwise, load it first. Note that we cannot have
285 auto-increment in that case since the address register is known to be
287 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
289 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
291 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
293 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
298 [(set_attr "type" "move,move,load,store")
299 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
300 (set_attr "length" "2,4,2,2")])
302 ;(define_expand "movdi"
303 ; [(set (match_operand:DI 0 "general_operand" "")
304 ; (match_operand:DI 1 "general_operand" ""))]
308 ; /* Flow doesn't understand that this is effectively a DFmode move.
309 ; It doesn't know that all of `operands[0]' is set. */
310 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
312 ; /* Emit insns that movsi_insn can handle. */
313 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DImode),
314 ; operand_subword (operands[1], 0, 0, DImode)));
315 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DImode),
316 ; operand_subword (operands[1], 1, 0, DImode)));
320 ;; Floating point move insns.
322 (define_expand "movsf"
323 [(set (match_operand:SF 0 "general_operand" "")
324 (match_operand:SF 1 "general_operand" ""))]
328 /* Everything except mem = const or mem = mem can be done easily. */
329 if (GET_CODE (operands[0]) == MEM)
330 operands[1] = force_reg (SFmode, operands[1]);
333 (define_insn "*movsf_insn"
334 [(set (match_operand:SF 0 "move_dest_operand" "=r,r,r,m")
335 (match_operand:SF 1 "move_src_operand" "r,E,m,r"))]
336 "register_operand (operands[0], SFmode)
337 || register_operand (operands[1], SFmode)"
343 [(set_attr "type" "move,move,load,store")])
345 (define_expand "movdf"
346 [(set (match_operand:DF 0 "general_operand" "")
347 (match_operand:DF 1 "general_operand" ""))]
351 /* Everything except mem = const or mem = mem can be done easily. */
352 if (GET_CODE (operands[0]) == MEM)
353 operands[1] = force_reg (DFmode, operands[1]);
356 (define_insn "*movdf_insn"
357 [(set (match_operand:DF 0 "move_dest_operand" "=r,r,r,m")
358 (match_operand:DF 1 "move_double_src_operand" "r,E,m,r"))]
359 "register_operand (operands[0], DFmode)
360 || register_operand (operands[1], DFmode)"
363 switch (which_alternative)
366 /* We normally copy the low-numbered register first. However, if
367 the first register operand 0 is the same as the second register of
368 operand 1, we must copy in the opposite order. */
369 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
370 return \"mov %R0,%R1\;mov %0,%1\";
372 return \"mov %0,%1\;mov %R0,%R1\";
374 return \"mov %0,%L1\;mov %R0,%H1 ; %A1\";
376 /* If the low-address word is used in the address, we must load it
377 last. Otherwise, load it first. Note that we cannot have
378 auto-increment in that case since the address register is known to be
380 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
382 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
384 return \"ld%V1 %0,%1\;ld%V1 %R0,%R1\";
386 return \"st%V0 %1,%0\;st%V0 %R1,%R0\";
391 [(set_attr "type" "move,move,load,store")
392 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
393 (set_attr "length" "2,4,2,2")])
395 ;(define_expand "movdf"
396 ; [(set (match_operand:DF 0 "general_operand" "")
397 ; (match_operand:DF 1 "general_operand" ""))]
401 ; /* Flow doesn't understand that this is effectively a DFmode move.
402 ; It doesn't know that all of `operands[0]' is set. */
403 ; emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
405 ; /* Emit insns that movsi_insn can handle. */
406 ; emit_insn (gen_movsi (operand_subword (operands[0], 0, 0, DFmode),
407 ; operand_subword (operands[1], 0, 0, DFmode)));
408 ; emit_insn (gen_movsi (operand_subword (operands[0], 1, 0, DFmode),
409 ; operand_subword (operands[1], 1, 0, DFmode)));
413 ;; Load/Store with update instructions.
415 ;; Some of these we can get by using pre-decrement or pre-increment, but the
416 ;; hardware can also do cases where the increment is not the size of the
419 ;; In all these cases, we use operands 0 and 1 for the register being
420 ;; incremented because those are the operands that local-alloc will
421 ;; tie and these are the pair most likely to be tieable (and the ones
422 ;; that will benefit the most).
424 ;; We use match_operator here because we need to know whether the memory
425 ;; object is volatile or not.
427 (define_insn "*loadqi_update"
428 [(set (match_operand:QI 3 "register_operand" "=r,r")
429 (match_operator:QI 4 "load_update_operand"
430 [(match_operand:SI 1 "register_operand" "0,0")
431 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
432 (set (match_operand:SI 0 "register_operand" "=r,r")
433 (plus:SI (match_dup 1) (match_dup 2)))]
435 "ldb.a%V4 %3,[%0,%2]"
436 [(set_attr "type" "load,load")
437 (set_attr "length" "1,2")])
439 (define_insn "*load_zeroextendqisi_update"
440 [(set (match_operand:SI 3 "register_operand" "=r,r")
441 (zero_extend:SI (match_operator:QI 4 "load_update_operand"
442 [(match_operand:SI 1 "register_operand" "0,0")
443 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
444 (set (match_operand:SI 0 "register_operand" "=r,r")
445 (plus:SI (match_dup 1) (match_dup 2)))]
447 "ldb.a%V4 %3,[%0,%2]"
448 [(set_attr "type" "load,load")
449 (set_attr "length" "1,2")])
451 (define_insn "*load_signextendqisi_update"
452 [(set (match_operand:SI 3 "register_operand" "=r,r")
453 (sign_extend:SI (match_operator:QI 4 "load_update_operand"
454 [(match_operand:SI 1 "register_operand" "0,0")
455 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
456 (set (match_operand:SI 0 "register_operand" "=r,r")
457 (plus:SI (match_dup 1) (match_dup 2)))]
459 "ldb.x.a%V4 %3,[%0,%2]"
460 [(set_attr "type" "load,load")
461 (set_attr "length" "1,2")])
463 (define_insn "*storeqi_update"
464 [(set (match_operator:QI 4 "store_update_operand"
465 [(match_operand:SI 1 "register_operand" "0")
466 (match_operand:SI 2 "short_immediate_operand" "I")])
467 (match_operand:QI 3 "register_operand" "r"))
468 (set (match_operand:SI 0 "register_operand" "=r")
469 (plus:SI (match_dup 1) (match_dup 2)))]
471 "stb.a%V4 %3,[%0,%2]"
472 [(set_attr "type" "store")
473 (set_attr "length" "1")])
475 (define_insn "*loadhi_update"
476 [(set (match_operand:HI 3 "register_operand" "=r,r")
477 (match_operator:HI 4 "load_update_operand"
478 [(match_operand:SI 1 "register_operand" "0,0")
479 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
480 (set (match_operand:SI 0 "register_operand" "=r,r")
481 (plus:SI (match_dup 1) (match_dup 2)))]
483 "ldw.a%V4 %3,[%0,%2]"
484 [(set_attr "type" "load,load")
485 (set_attr "length" "1,2")])
487 (define_insn "*load_zeroextendhisi_update"
488 [(set (match_operand:SI 3 "register_operand" "=r,r")
489 (zero_extend:SI (match_operator:HI 4 "load_update_operand"
490 [(match_operand:SI 1 "register_operand" "0,0")
491 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
492 (set (match_operand:SI 0 "register_operand" "=r,r")
493 (plus:SI (match_dup 1) (match_dup 2)))]
495 "ldw.a%V4 %3,[%0,%2]"
496 [(set_attr "type" "load,load")
497 (set_attr "length" "1,2")])
499 (define_insn "*load_signextendhisi_update"
500 [(set (match_operand:SI 3 "register_operand" "=r,r")
501 (sign_extend:SI (match_operator:HI 4 "load_update_operand"
502 [(match_operand:SI 1 "register_operand" "0,0")
503 (match_operand:SI 2 "nonmemory_operand" "rI,J")])))
504 (set (match_operand:SI 0 "register_operand" "=r,r")
505 (plus:SI (match_dup 1) (match_dup 2)))]
507 "ldw.x.a%V4 %3,[%0,%2]"
508 [(set_attr "type" "load,load")
509 (set_attr "length" "1,2")])
511 (define_insn "*storehi_update"
512 [(set (match_operator:HI 4 "store_update_operand"
513 [(match_operand:SI 1 "register_operand" "0")
514 (match_operand:SI 2 "short_immediate_operand" "I")])
515 (match_operand:HI 3 "register_operand" "r"))
516 (set (match_operand:SI 0 "register_operand" "=r")
517 (plus:SI (match_dup 1) (match_dup 2)))]
519 "stw.a%V4 %3,[%0,%2]"
520 [(set_attr "type" "store")
521 (set_attr "length" "1")])
523 (define_insn "*loadsi_update"
524 [(set (match_operand:SI 3 "register_operand" "=r,r")
525 (match_operator:SI 4 "load_update_operand"
526 [(match_operand:SI 1 "register_operand" "0,0")
527 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
528 (set (match_operand:SI 0 "register_operand" "=r,r")
529 (plus:SI (match_dup 1) (match_dup 2)))]
532 [(set_attr "type" "load,load")
533 (set_attr "length" "1,2")])
535 (define_insn "*storesi_update"
536 [(set (match_operator:SI 4 "store_update_operand"
537 [(match_operand:SI 1 "register_operand" "0")
538 (match_operand:SI 2 "short_immediate_operand" "I")])
539 (match_operand:SI 3 "register_operand" "r"))
540 (set (match_operand:SI 0 "register_operand" "=r")
541 (plus:SI (match_dup 1) (match_dup 2)))]
544 [(set_attr "type" "store")
545 (set_attr "length" "1")])
547 (define_insn "*loadsf_update"
548 [(set (match_operand:SF 3 "register_operand" "=r,r")
549 (match_operator:SF 4 "load_update_operand"
550 [(match_operand:SI 1 "register_operand" "0,0")
551 (match_operand:SI 2 "nonmemory_operand" "rI,J")]))
552 (set (match_operand:SI 0 "register_operand" "=r,r")
553 (plus:SI (match_dup 1) (match_dup 2)))]
556 [(set_attr "type" "load,load")
557 (set_attr "length" "1,2")])
559 (define_insn "*storesf_update"
560 [(set (match_operator:SF 4 "store_update_operand"
561 [(match_operand:SI 1 "register_operand" "0")
562 (match_operand:SI 2 "short_immediate_operand" "I")])
563 (match_operand:SF 3 "register_operand" "r"))
564 (set (match_operand:SI 0 "register_operand" "=r")
565 (plus:SI (match_dup 1) (match_dup 2)))]
568 [(set_attr "type" "store")
569 (set_attr "length" "1")])
571 ;; Conditional move instructions.
573 (define_expand "movsicc"
574 [(set (match_operand:SI 0 "register_operand" "")
575 (if_then_else:SI (match_operand 1 "comparison_operator" "")
576 (match_operand:SI 2 "nonmemory_operand" "")
577 (match_operand:SI 3 "register_operand" "")))]
581 enum rtx_code code = GET_CODE (operands[1]);
583 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
586 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
589 ;(define_expand "movdicc"
590 ; [(set (match_operand:DI 0 "register_operand" "")
591 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
592 ; (match_operand:DI 2 "nonmemory_operand" "")
593 ; (match_operand:DI 3 "register_operand" "")))]
594 ; "0 /* ??? this would work better if we had cmpdi */"
597 ; enum rtx_code code = GET_CODE (operands[1]);
599 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
602 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
605 (define_expand "movsfcc"
606 [(set (match_operand:SF 0 "register_operand" "")
607 (if_then_else:SF (match_operand 1 "comparison_operator" "")
608 (match_operand:SF 2 "nonmemory_operand" "")
609 (match_operand:SF 3 "register_operand" "")))]
613 enum rtx_code code = GET_CODE (operands[1]);
615 = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
618 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
621 ;(define_expand "movdfcc"
622 ; [(set (match_operand:DF 0 "register_operand" "")
623 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
624 ; (match_operand:DF 2 "nonmemory_operand" "")
625 ; (match_operand:DF 3 "register_operand" "")))]
626 ; "0 /* ??? can generate less efficient code if constants involved */"
629 ; enum rtx_code code = GET_CODE (operands[1]);
631 ; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
634 ; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
637 (define_insn "*movsicc_insn"
638 [(set (match_operand:SI 0 "register_operand" "=r")
639 (if_then_else:SI (match_operand 1 "comparison_operator" "")
640 (match_operand:SI 2 "nonmemory_operand" "rJi")
641 (match_operand:SI 3 "register_operand" "0")))]
644 [(set_attr "type" "cmove")])
646 ; ??? This doesn't properly handle constants.
647 ;(define_insn "*movdicc_insn"
648 ; [(set (match_operand:DI 0 "register_operand" "=r,r")
649 ; (if_then_else:DI (match_operand 1 "comparison_operator" "")
650 ; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
651 ; (match_operand:DI 3 "register_operand" "0,0")))]
655 ; switch (which_alternative)
658 ; /* We normally copy the low-numbered register first. However, if
659 ; the first register operand 0 is the same as the second register of
660 ; operand 1, we must copy in the opposite order. */
661 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
662 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
664 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
666 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
669 ; [(set_attr "type" "cmove,cmove")
670 ; (set_attr "length" "2,4")])
672 (define_insn "*movsfcc_insn"
673 [(set (match_operand:SF 0 "register_operand" "=r,r")
674 (if_then_else:SF (match_operand 1 "comparison_operator" "")
675 (match_operand:SF 2 "nonmemory_operand" "r,E")
676 (match_operand:SF 3 "register_operand" "0,0")))]
681 [(set_attr "type" "cmove,cmove")])
683 ;(define_insn "*movdfcc_insn"
684 ; [(set (match_operand:DF 0 "register_operand" "=r,r")
685 ; (if_then_else:DF (match_operand 1 "comparison_operator" "")
686 ; (match_operand:DF 2 "nonmemory_operand" "r,E")
687 ; (match_operand:DF 3 "register_operand" "0,0")))]
691 ; switch (which_alternative)
694 ; /* We normally copy the low-numbered register first. However, if
695 ; the first register operand 0 is the same as the second register of
696 ; operand 1, we must copy in the opposite order. */
697 ; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
698 ; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
700 ; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
702 ; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
705 ; [(set_attr "type" "cmove,cmove")
706 ; (set_attr "length" "2,4")])
708 ;; Zero extension instructions.
709 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
711 (define_insn "zero_extendqihi2"
712 [(set (match_operand:HI 0 "register_operand" "=r,r")
713 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
718 [(set_attr "type" "unary,load")])
720 (define_insn "*zero_extendqihi2_set_cc_insn"
721 [(set (reg:CCZN 61) (compare:CCZN
722 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
724 (set (match_operand:HI 0 "register_operand" "=r")
725 (zero_extend:HI (match_dup 1)))]
728 [(set_attr "type" "unary")
729 (set_attr "cond" "set_zn")])
731 (define_insn "zero_extendqisi2"
732 [(set (match_operand:SI 0 "register_operand" "=r,r")
733 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
738 [(set_attr "type" "unary,load")])
740 (define_insn "*zero_extendqisi2_set_cc_insn"
741 [(set (reg:CCZN 61) (compare:CCZN
742 (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
744 (set (match_operand:SI 0 "register_operand" "=r")
745 (zero_extend:SI (match_dup 1)))]
748 [(set_attr "type" "unary")
749 (set_attr "cond" "set_zn")])
751 (define_insn "zero_extendhisi2"
752 [(set (match_operand:SI 0 "register_operand" "=r,r")
753 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
758 [(set_attr "type" "unary,load")])
760 (define_insn "*zero_extendhisi2_set_cc_insn"
761 [(set (reg:CCZN 61) (compare:CCZN
762 (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
764 (set (match_operand:SI 0 "register_operand" "=r")
765 (zero_extend:SI (match_dup 1)))]
768 [(set_attr "type" "unary")
769 (set_attr "cond" "set_zn")])
771 ;; Sign extension instructions.
773 (define_insn "extendqihi2"
774 [(set (match_operand:HI 0 "register_operand" "=r,r")
775 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
780 [(set_attr "type" "unary,load")])
782 (define_insn "*extendqihi2_set_cc_insn"
783 [(set (reg:CCZN 61) (compare:CCZN
784 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
786 (set (match_operand:HI 0 "register_operand" "=r")
787 (sign_extend:HI (match_dup 1)))]
790 [(set_attr "type" "unary")
791 (set_attr "cond" "set_zn")])
793 (define_insn "extendqisi2"
794 [(set (match_operand:SI 0 "register_operand" "=r,r")
795 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
800 [(set_attr "type" "unary,load")])
802 (define_insn "*extendqisi2_set_cc_insn"
803 [(set (reg:CCZN 61) (compare:CCZN
804 (sign_extend:SI (match_operand:QI 1 "register_operand" "r"))
806 (set (match_operand:SI 0 "register_operand" "=r")
807 (sign_extend:SI (match_dup 1)))]
810 [(set_attr "type" "unary")
811 (set_attr "cond" "set_zn")])
813 (define_insn "extendhisi2"
814 [(set (match_operand:SI 0 "register_operand" "=r,r")
815 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
820 [(set_attr "type" "unary,load")])
822 (define_insn "*extendhisi2_set_cc_insn"
823 [(set (reg:CCZN 61) (compare:CCZN
824 (sign_extend:SI (match_operand:HI 1 "register_operand" "r"))
826 (set (match_operand:SI 0 "register_operand" "=r")
827 (sign_extend:SI (match_dup 1)))]
830 [(set_attr "type" "unary")
831 (set_attr "cond" "set_zn")])
833 ;; Arithmetic instructions.
835 (define_insn "addsi3"
836 [(set (match_operand:SI 0 "register_operand" "=r")
837 (plus:SI (match_operand:SI 1 "register_operand" "%r")
838 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
842 (define_insn "*addsi3_set_cc_insn"
843 [(set (reg:CC 61) (compare:CC
844 (plus:SI (match_operand:SI 1 "register_operand" "%r")
845 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
847 (set (match_operand:SI 0 "register_operand" "=r")
848 (plus:SI (match_dup 1)
852 [(set_attr "cond" "set")])
854 (define_insn "adddi3"
855 [(set (match_operand:DI 0 "register_operand" "=r")
856 (plus:DI (match_operand:DI 1 "nonmemory_operand" "%r")
857 (match_operand:DI 2 "nonmemory_operand" "ri")))
858 (clobber (reg:CC 61))]
862 rtx op2 = operands[2];
864 if (GET_CODE (op2) == CONST_INT)
866 int sign = INTVAL (op2);
868 return \"add.f %L0,%L1,%2\;adc %H0,%H1,-1\";
870 return \"add.f %L0,%L1,%2\;adc %H0,%H1,0\";
873 return \"add.f %L0,%L1,%L2\;adc %H0,%H1,%H2\";
875 [(set_attr "length" "2")])
877 (define_insn "subsi3"
878 [(set (match_operand:SI 0 "register_operand" "=r")
879 (minus:SI (match_operand:SI 1 "register_operand" "r")
880 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
884 (define_insn "*subsi3_set_cc_insn"
885 [(set (reg:CC 61) (compare:CC
886 (minus:SI (match_operand:SI 1 "register_operand" "%r")
887 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
889 (set (match_operand:SI 0 "register_operand" "=r")
890 (minus:SI (match_dup 1)
894 [(set_attr "cond" "set")])
896 (define_insn "subdi3"
897 [(set (match_operand:DI 0 "register_operand" "=r")
898 (minus:DI (match_operand:DI 1 "nonmemory_operand" "r")
899 (match_operand:DI 2 "nonmemory_operand" "ri")))
900 (clobber (reg:CC 61))]
904 rtx op2 = operands[2];
906 if (GET_CODE (op2) == CONST_INT)
908 int sign = INTVAL (op2);
910 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,-1\";
912 return \"sub.f %L0,%L1,%2\;sbc %H0,%H1,0\";
915 return \"sub.f %L0,%L1,%L2\;sbc %H0,%H1,%H2\";
917 [(set_attr "length" "2")])
919 ;; Boolean instructions.
921 ;; We don't define the DImode versions as expand_binop does a good enough job.
923 (define_insn "andsi3"
924 [(set (match_operand:SI 0 "register_operand" "=r")
925 (and:SI (match_operand:SI 1 "register_operand" "%r")
926 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
930 (define_insn "*andsi3_set_cc_insn"
931 [(set (reg:CCZN 61) (compare:CCZN
932 (and:SI (match_operand:SI 1 "register_operand" "%r")
933 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
935 (set (match_operand:SI 0 "register_operand" "=r")
936 (and:SI (match_dup 1)
940 [(set_attr "cond" "set_zn")])
942 (define_insn "*bicsi3_insn"
943 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
944 (and:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
945 (not:SI (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r"))))]
948 [(set_attr "length" "1,2,1,2")])
950 (define_insn "*bicsi3_set_cc_insn"
951 [(set (reg:CCZN 61) (compare:CCZN
952 (and:SI (match_operand:SI 1 "register_operand" "%r")
953 (not:SI (match_operand:SI 2 "nonmemory_operand" "rIJ")))
955 (set (match_operand:SI 0 "register_operand" "=r")
956 (and:SI (match_dup 1)
957 (not:SI (match_dup 2))))]
960 [(set_attr "cond" "set_zn")])
962 (define_insn "iorsi3"
963 [(set (match_operand:SI 0 "register_operand" "=r")
964 (ior:SI (match_operand:SI 1 "register_operand" "%r")
965 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
969 (define_insn "*iorsi3_set_cc_insn"
970 [(set (reg:CCZN 61) (compare:CCZN
971 (ior:SI (match_operand:SI 1 "register_operand" "%r")
972 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
974 (set (match_operand:SI 0 "register_operand" "=r")
975 (ior:SI (match_dup 1)
979 [(set_attr "cond" "set_zn")])
981 (define_insn "xorsi3"
982 [(set (match_operand:SI 0 "register_operand" "=r")
983 (xor:SI (match_operand:SI 1 "register_operand" "%r")
984 (match_operand:SI 2 "nonmemory_operand" "rIJ")))]
988 (define_insn "*xorsi3_set_cc_insn"
989 [(set (reg:CCZN 61) (compare:CCZN
990 (xor:SI (match_operand:SI 1 "register_operand" "%r")
991 (match_operand:SI 2 "nonmemory_operand" "rIJ"))
993 (set (match_operand:SI 0 "register_operand" "=r")
994 (xor:SI (match_dup 1)
998 [(set_attr "cond" "set_zn")])
1000 (define_insn "negsi2"
1001 [(set (match_operand:SI 0 "register_operand" "=r")
1002 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
1005 [(set_attr "type" "unary")])
1007 (define_insn "*negsi2_set_cc_insn"
1008 [(set (reg:CC 61) (compare:CC
1009 (neg:SI (match_operand:SI 1 "register_operand" "r"))
1011 (set (match_operand:SI 0 "register_operand" "=r")
1012 (neg:SI (match_dup 1)))]
1015 [(set_attr "type" "unary")
1016 (set_attr "cond" "set")])
1018 (define_insn "negdi2"
1019 [(set (match_operand:DI 0 "register_operand" "=r")
1020 (neg:DI (match_operand:DI 1 "register_operand" "r")))
1021 (clobber (reg:SI 61))]
1023 "sub.f %L0,0,%L1\;sbc %H0,0,%H1"
1024 [(set_attr "type" "unary")
1025 (set_attr "length" "2")])
1027 (define_insn "one_cmplsi2"
1028 [(set (match_operand:SI 0 "register_operand" "=r")
1029 (not:SI (match_operand:SI 1 "register_operand" "r")))]
1032 [(set_attr "type" "unary")])
1034 (define_insn "*one_cmplsi2_set_cc_insn"
1035 [(set (reg:CCZN 61) (compare:CCZN
1036 (not:SI (match_operand:SI 1 "register_operand" "r"))
1038 (set (match_operand:SI 0 "register_operand" "=r")
1039 (not:SI (match_dup 1)))]
1042 [(set_attr "type" "unary")
1043 (set_attr "cond" "set_zn")])
1045 ;; Shift instructions.
1047 (define_expand "ashlsi3"
1048 [(set (match_operand:SI 0 "register_operand" "")
1049 (ashift:SI (match_operand:SI 1 "register_operand" "")
1050 (match_operand:SI 2 "nonmemory_operand" "")))]
1054 if (! TARGET_SHIFTER)
1056 emit_insn (gen_rtx_PARALLEL
1059 gen_rtx_SET (VOIDmode, operands[0],
1060 gen_rtx_ASHIFT (SImode, operands[1],
1062 gen_rtx_CLOBBER (VOIDmode,
1063 gen_rtx_SCRATCH (SImode)))));
1068 (define_expand "ashrsi3"
1069 [(set (match_operand:SI 0 "register_operand" "")
1070 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1071 (match_operand:SI 2 "nonmemory_operand" "")))]
1075 if (! TARGET_SHIFTER)
1077 emit_insn (gen_rtx_PARALLEL
1080 gen_rtx_SET (VOIDmode, operands[0],
1081 gen_rtx_ASHIFTRT (SImode,
1084 gen_rtx_CLOBBER (VOIDmode,
1085 gen_rtx_SCRATCH (SImode)))));
1090 (define_expand "lshrsi3"
1091 [(set (match_operand:SI 0 "register_operand" "")
1092 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1093 (match_operand:SI 2 "nonmemory_operand" "")))]
1097 if (! TARGET_SHIFTER)
1099 emit_insn (gen_rtx_PARALLEL
1102 gen_rtx_SET (VOIDmode, operands[0],
1103 gen_rtx_LSHIFTRT (SImode,
1106 gen_rtx_CLOBBER (VOIDmode,
1107 gen_rtx_SCRATCH (SImode)))));
1112 (define_insn "*ashlsi3_insn"
1113 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1114 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1115 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1118 [(set_attr "type" "shift")
1119 (set_attr "length" "1,2,1,2")])
1121 (define_insn "*ashrsi3_insn"
1122 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1123 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1124 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1127 [(set_attr "type" "shift")
1128 (set_attr "length" "1,2,1,2")])
1130 (define_insn "*lshrsi3_insn"
1131 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1132 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "r,r,I,J")
1133 (match_operand:SI 2 "nonmemory_operand" "rI,J,r,r")))]
1136 [(set_attr "type" "shift")
1137 (set_attr "length" "1,2,1,2")])
1139 (define_insn "*shift_si3"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (match_operator:SI 3 "shift_operator"
1142 [(match_operand:SI 1 "register_operand" "0")
1143 (match_operand:SI 2 "nonmemory_operand" "rIJ")]))
1144 (clobber (match_scratch:SI 4 "=&r"))]
1146 "* return output_shift (operands);"
1147 [(set_attr "type" "shift")
1148 (set_attr "length" "8")])
1150 ;; Compare instructions.
1151 ;; This controls RTL generation and register allocation.
1153 ;; We generate RTL for comparisons and branches by having the cmpxx
1154 ;; patterns store away the operands. Then, the scc and bcc patterns
1155 ;; emit RTL for both the compare and the branch.
1157 (define_expand "cmpsi"
1159 (compare:CC (match_operand:SI 0 "register_operand" "")
1160 (match_operand:SI 1 "nonmemory_operand" "")))]
1164 arc_compare_op0 = operands[0];
1165 arc_compare_op1 = operands[1];
1169 ;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
1170 ;; This assumes sub.f 0,symbol,0 is a valid insn.
1171 ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
1172 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
1173 ;; if it's a small constant.
1175 (define_insn "*cmpsi_cc_insn"
1177 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
1178 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1184 [(set_attr "type" "compare,compare,compare")])
1186 (define_insn "*cmpsi_cczn_insn"
1188 (compare:CCZN (match_operand:SI 0 "register_operand" "r,r,r")
1189 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1195 [(set_attr "type" "compare,compare,compare")])
1197 (define_insn "*cmpsi_ccznc_insn"
1198 [(set (reg:CCZNC 61)
1199 (compare:CCZNC (match_operand:SI 0 "register_operand" "r,r,r")
1200 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))]
1206 [(set_attr "type" "compare,compare,compare")])
1208 ;; Next come the scc insns.
1210 (define_expand "seq"
1211 [(set (match_operand:SI 0 "register_operand" "=r")
1212 (eq:SI (match_dup 1) (const_int 0)))]
1216 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1219 (define_expand "sne"
1220 [(set (match_operand:SI 0 "register_operand" "=r")
1221 (ne:SI (match_dup 1) (const_int 0)))]
1225 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1228 (define_expand "sgt"
1229 [(set (match_operand:SI 0 "register_operand" "=r")
1230 (gt:SI (match_dup 1) (const_int 0)))]
1234 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1237 (define_expand "sle"
1238 [(set (match_operand:SI 0 "register_operand" "=r")
1239 (le:SI (match_dup 1) (const_int 0)))]
1243 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1246 (define_expand "sge"
1247 [(set (match_operand:SI 0 "register_operand" "=r")
1248 (ge:SI (match_dup 1) (const_int 0)))]
1252 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1255 (define_expand "slt"
1256 [(set (match_operand:SI 0 "register_operand" "=r")
1257 (lt:SI (match_dup 1) (const_int 0)))]
1261 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1264 (define_expand "sgtu"
1265 [(set (match_operand:SI 0 "register_operand" "=r")
1266 (gtu:SI (match_dup 1) (const_int 0)))]
1270 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1273 (define_expand "sleu"
1274 [(set (match_operand:SI 0 "register_operand" "=r")
1275 (leu:SI (match_dup 1) (const_int 0)))]
1279 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1282 (define_expand "sgeu"
1283 [(set (match_operand:SI 0 "register_operand" "=r")
1284 (geu:SI (match_dup 1) (const_int 0)))]
1288 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1291 (define_expand "sltu"
1292 [(set (match_operand:SI 0 "register_operand" "=r")
1293 (ltu:SI (match_dup 1) (const_int 0)))]
1297 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1300 (define_insn "*scc_insn"
1301 [(set (match_operand:SI 0 "register_operand" "=r")
1302 (match_operator:SI 1 "comparison_operator" [(reg 61) (const_int 0)]))]
1304 "mov %0,1\;sub.%D1 %0,%0,%0"
1305 [(set_attr "type" "unary")
1306 (set_attr "length" "2")])
1308 ;; ??? Look up negscc insn. See pa.md for example.
1309 (define_insn "*neg_scc_insn"
1310 [(set (match_operand:SI 0 "register_operand" "=r")
1311 (neg:SI (match_operator:SI 1 "comparison_operator"
1312 [(reg 61) (const_int 0)])))]
1314 "mov %0,-1\;sub.%D1 %0,%0,%0"
1315 [(set_attr "type" "unary")
1316 (set_attr "length" "2")])
1318 (define_insn "*not_scc_insn"
1319 [(set (match_operand:SI 0 "register_operand" "=r")
1320 (not:SI (match_operator:SI 1 "comparison_operator"
1321 [(reg 61) (const_int 0)])))]
1323 "mov %0,1\;sub.%d1 %0,%0,%0"
1324 [(set_attr "type" "unary")
1325 (set_attr "length" "2")])
1327 ;; These control RTL generation for conditional jump insns
1329 (define_expand "beq"
1331 (if_then_else (eq (match_dup 1) (const_int 0))
1332 (label_ref (match_operand 0 "" ""))
1337 operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
1340 (define_expand "bne"
1342 (if_then_else (ne (match_dup 1) (const_int 0))
1343 (label_ref (match_operand 0 "" ""))
1348 operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
1351 (define_expand "bgt"
1353 (if_then_else (gt (match_dup 1) (const_int 0))
1354 (label_ref (match_operand 0 "" ""))
1359 operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
1362 (define_expand "ble"
1364 (if_then_else (le (match_dup 1) (const_int 0))
1365 (label_ref (match_operand 0 "" ""))
1370 operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
1373 (define_expand "bge"
1375 (if_then_else (ge (match_dup 1) (const_int 0))
1376 (label_ref (match_operand 0 "" ""))
1381 operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
1384 (define_expand "blt"
1386 (if_then_else (lt (match_dup 1) (const_int 0))
1387 (label_ref (match_operand 0 "" ""))
1392 operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
1395 (define_expand "bgtu"
1397 (if_then_else (gtu (match_dup 1) (const_int 0))
1398 (label_ref (match_operand 0 "" ""))
1403 operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
1406 (define_expand "bleu"
1408 (if_then_else (leu (match_dup 1) (const_int 0))
1409 (label_ref (match_operand 0 "" ""))
1414 operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
1417 (define_expand "bgeu"
1419 (if_then_else (geu (match_dup 1) (const_int 0))
1420 (label_ref (match_operand 0 "" ""))
1425 operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
1428 (define_expand "bltu"
1430 (if_then_else (ltu (match_dup 1) (const_int 0))
1431 (label_ref (match_operand 0 "" ""))
1436 operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
1439 ;; Now match both normal and inverted jump.
1441 (define_insn "*branch_insn"
1443 (if_then_else (match_operator 1 "proper_comparison_operator"
1444 [(reg 61) (const_int 0)])
1445 (label_ref (match_operand 0 "" ""))
1450 if (arc_ccfsm_branch_deleted_p ())
1452 arc_ccfsm_record_branch_deleted ();
1453 return \"; branch deleted, next insns conditionalized\";
1456 return \"%~b%d1%# %l0\";
1458 [(set_attr "type" "branch")])
1460 (define_insn "*rev_branch_insn"
1462 (if_then_else (match_operator 1 "proper_comparison_operator"
1463 [(reg 61) (const_int 0)])
1465 (label_ref (match_operand 0 "" ""))))]
1466 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
1469 if (arc_ccfsm_branch_deleted_p ())
1471 arc_ccfsm_record_branch_deleted ();
1472 return \"; branch deleted, next insns conditionalized\";
1475 return \"%~b%D1%# %l0\";
1477 [(set_attr "type" "branch")])
1479 ;; Unconditional and other jump instructions.
1482 [(set (pc) (label_ref (match_operand 0 "" "")))]
1485 [(set_attr "type" "uncond_branch")])
1487 (define_insn "indirect_jump"
1488 [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
1491 [(set_attr "type" "uncond_branch")])
1493 ;; Implement a switch statement.
1494 ;; This wouldn't be necessary in the non-pic case if we could distinguish
1495 ;; label refs of the jump table from other label refs. The problem is that
1496 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
1497 ;; the real address since it's the address of the table.
1499 (define_expand "casesi"
1501 (minus:SI (match_operand:SI 0 "register_operand" "")
1502 (match_operand:SI 1 "nonmemory_operand" "")))
1504 (compare:CC (match_dup 5)
1505 (match_operand:SI 2 "nonmemory_operand" "")))
1507 (if_then_else (gtu (reg:CC 61)
1509 (label_ref (match_operand 4 "" ""))
1513 (mem:SI (plus:SI (mult:SI (match_dup 5)
1515 (label_ref (match_operand 3 "" "")))))
1516 (clobber (match_scratch:SI 6 ""))
1517 (clobber (match_scratch:SI 7 ""))])]
1521 operands[5] = gen_reg_rtx (SImode);
1524 (define_insn "*casesi_insn"
1526 (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "r")
1528 (label_ref (match_operand 1 "" "")))))
1529 (clobber (match_scratch:SI 2 "=r"))
1530 (clobber (match_scratch:SI 3 "=r"))]
1534 output_asm_insn (\"mov %2,%1\", operands);
1536 output_asm_insn (\"asl %3,%0,2\", operands);
1538 output_asm_insn (\"asl %3,%0\;asl %3,%3\", operands);
1539 output_asm_insn (\"ld %2,[%2,%3]\", operands);
1540 output_asm_insn (\"j.nd %a2\", operands);
1543 [(set_attr "type" "uncond_branch")
1544 (set_attr "length" "6")])
1546 (define_insn "tablejump"
1547 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
1548 (use (label_ref (match_operand 1 "" "")))]
1549 "0 /* disabled -> using casesi now */"
1551 [(set_attr "type" "uncond_branch")])
1553 (define_expand "call"
1554 ;; operands[1] is stack_size_rtx
1555 ;; operands[2] is next_arg_register
1556 [(parallel [(call (match_operand:SI 0 "call_operand" "")
1557 (match_operand 1 "" ""))
1558 (clobber (reg:SI 31))])]
1562 (define_insn "*call_via_reg"
1563 [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
1564 (match_operand 1 "" ""))
1565 (clobber (reg:SI 31))]
1567 "lr blink,[status]\;j.d %0\;add blink,blink,2"
1568 [(set_attr "type" "call_no_delay_slot")
1569 (set_attr "length" "3")])
1571 (define_insn "*call_via_label"
1572 [(call (mem:SI (match_operand:SI 0 "call_address_operand" ""))
1573 (match_operand 1 "" ""))
1574 (clobber (reg:SI 31))]
1576 ; The %~ is necessary in case this insn gets conditionalized and the previous
1577 ; insn is the cc setter.
1579 [(set_attr "type" "call")
1580 (set_attr "cond" "canuse")])
1582 (define_expand "call_value"
1583 ;; operand 2 is stack_size_rtx
1584 ;; operand 3 is next_arg_register
1585 [(parallel [(set (match_operand 0 "register_operand" "=r")
1586 (call (match_operand:SI 1 "call_operand" "")
1587 (match_operand 2 "" "")))
1588 (clobber (reg:SI 31))])]
1592 (define_insn "*call_value_via_reg"
1593 [(set (match_operand 0 "register_operand" "=r")
1594 (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
1595 (match_operand 2 "" "")))
1596 (clobber (reg:SI 31))]
1598 "lr blink,[status]\;j.d %1\;add blink,blink,2"
1599 [(set_attr "type" "call_no_delay_slot")
1600 (set_attr "length" "3")])
1602 (define_insn "*call_value_via_label"
1603 [(set (match_operand 0 "register_operand" "=r")
1604 (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
1605 (match_operand 2 "" "")))
1606 (clobber (reg:SI 31))]
1608 ; The %~ is necessary in case this insn gets conditionalized and the previous
1609 ; insn is the cc setter.
1611 [(set_attr "type" "call")
1612 (set_attr "cond" "canuse")])
1618 [(set_attr "type" "misc")])
1620 ;; Special pattern to flush the icache.
1621 ;; ??? Not sure what to do here. Some ARC's are known to support this.
1623 (define_insn "flush_icache"
1624 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 0)]
1627 [(set_attr "type" "misc")])
1629 ;; Split up troublesome insns for better scheduling.
1631 ;; Peepholes go at the end.