1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2025 Free Software Foundation, Inc.
4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 ;; behalf of Synopsys Inc.
7 ;; Position Independent Code support added,Code cleaned up,
8 ;; Comments and Support For ARC700 instructions added by
9 ;; Saurabh Verma (saurabh.verma@codito.com)
10 ;; Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 ;; Performance improvements by
13 ;; Joern Rennecke (joern.rennecke@embecosm.com)
16 ;; This file is part of GCC.
18 ;; GCC is free software; you can redistribute it and/or modify
19 ;; it under the terms of the GNU General Public License as published by
20 ;; the Free Software Foundation; either version 3, or (at your option)
23 ;; GCC is distributed in the hope that it will be useful,
24 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 ;; GNU General Public License for more details.
28 ;; You should have received a copy of the GNU General Public License
29 ;; along with GCC; see the file COPYING3. If not see
30 ;; <http://www.gnu.org/licenses/>.
32 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
34 ;; <op> dest, src Two operand instruction's syntax
35 ;; <op> dest, src1, src2 Three operand instruction's syntax
37 ;; ARC and ARCompact PREDICATES:
39 ;; comparison_operator LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
40 ;; memory_operand memory [m]
41 ;; immediate_operand immediate constant [IKLMNOP]
42 ;; register_operand register [rq]
43 ;; general_operand register, memory, constant [rqmIKLMNOP]
45 ;; Note that the predicates are only used when selecting a pattern
46 ;; to determine if an operand is valid.
48 ;; The constraints then select which of the possible valid operands
49 ;; is present (and guide register selection). The actual assembly
50 ;; instruction is then selected on the basis of the constraints.
52 ;; ARC and ARCompact CONSTRAINTS:
54 ;; b stack pointer r28
55 ;; f frame pointer r27
56 ;; Rgp global pointer r26
57 ;; g general reg, memory, constant
60 ;; q registers commonly used in
61 ;; 16-bit insns r0-r3, r12-r15
62 ;; c core registers r0-r60, ap, pcl
63 ;; r general registers r0-r28, blink, ap, pcl
65 ;; H fp 16-bit constant
66 ;; I signed 12-bit immediate (for ARCompact)
67 ;; K unsigned 3-bit immediate (for ARCompact)
68 ;; L unsigned 6-bit immediate (for ARCompact)
69 ;; M unsinged 5-bit immediate (for ARCompact)
70 ;; O unsinged 7-bit immediate (for ARCompact)
71 ;; P unsinged 8-bit immediate (for ARCompact)
72 ;; N constant '1' (for ARCompact)
76 ;; -> prefetch instruction
78 ;; -----------------------------------------------------------------------------
80 ;; Include DFA scheduluers
81 (include ("arc600.md"))
82 (include ("arc700.md"))
83 (include ("arcEM.md"))
84 (include ("arcHS.md"))
85 (include ("arcHS4x.md"))
89 (include ("predicates.md"))
90 (include ("constraints.md"))
91 ;; -----------------------------------------------------------------------------
95 ;; -----------------------------------------------------------------------------
96 ;; Symbolic name Value Desc.
97 ;; -----------------------------------------------------------------------------
98 ;; UNSPEC_PLT 3 symbol to be referenced through the PLT
99 ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT
100 ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the
101 ;; GOTBASE.(Referenced as @GOTOFF)
102 ;; UNSPEC_GOTOFFPC 6 Local symbol. To be referenced pc-relative.
103 ;; ----------------------------------------------------------------------------
105 (define_c_enum "unspec" [
147 VUNSPEC_ARC_CORE_READ
148 VUNSPEC_ARC_CORE_WRITE
157 VUNSPEC_ARC_STACK_IRQ
159 VUNSPEC_ARC_DEXCL_NORES
166 VUNSPEC_ARC_EH_RETURN
167 VUNSPEC_ARC_ARC600_RTIE
168 VUNSPEC_ARC_ARC600_STALL
193 (RETURN_ADDR_REGNUM 31)
232 ;; What is the insn_cost for this insn? The target hook can still override
233 ;; this. For optimizing for size the "length" attribute is used instead.
234 (define_attr "cost" "" (const_int 0))
236 (define_attr "is_sfunc" "no,yes" (const_string "no"))
238 ;; Insn type. Used to default other attribute values.
239 ; While the attribute is_sfunc is set for any call of a special function,
240 ; the instruction type sfunc is used only for the special call sequence
241 ; that loads the (pc-relative) function address into r12 and then calls
245 "add,sub,bxor,move,load,store,cmove,unary,binary,compare,shift,uncond_branch,
246 jump,branch,brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
248 two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
249 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, simd_vload,
250 simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
251 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
252 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
253 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
254 simd_valign, simd_valign_with_acc, simd_vcontrol,
255 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
256 fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block"
257 (cond [(eq_attr "is_sfunc" "yes")
258 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
259 (match_test "flag_pic") (const_string "sfunc")]
260 (const_string "call_no_delay_slot"))]
261 (const_string "binary")))
263 ;; The following three attributes are mixed case so that they can be
264 ;; used conveniently with the CALL_ATTR macro.
265 (define_attr "is_CALL" "no,yes"
266 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
267 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
268 (const_string "no")))
270 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
272 (define_attr "is_NON_SIBCALL" "no,yes"
273 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
274 (eq_attr "is_CALL" "yes") (const_string "yes")]
275 (const_string "no")))
277 ;; true for compact instructions (those with _s suffix)
278 ;; "maybe" means compact unless we conditionalize the insn.
279 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
280 (cond [(eq_attr "type" "sfunc")
281 (const_string "maybe")]
282 (const_string "false")))
285 ; Is there an instruction that we are actually putting into the delay slot?
286 (define_attr "delay_slot_filled" "no,yes"
287 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
289 (match_test "!TARGET_AT_DBR_CONDEXEC
291 && INSN_ANNULLED_BRANCH_P (insn)
292 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
294 (const_string "yes")))
296 ; Is a delay slot present for purposes of shorten_branches?
297 ; We have to take the length of this insn into account for forward branches
298 ; even if we don't put the insn actually into a delay slot.
299 (define_attr "delay_slot_present" "no,yes"
300 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
302 (const_string "yes")))
304 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
305 ; length of a different insn with the same uid.
306 (define_attr "delay_slot_length" ""
307 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
309 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
310 - get_attr_length (insn)")))
312 ; for ARCv2 we need to disable/enable different instruction alternatives
313 (define_attr "cpu_facility" "std,av1,av2,fpx,cd"
314 (const_string "std"))
316 ; We should consider all the instructions enabled until otherwise
317 (define_attr "enabled" "no,yes"
318 (cond [(and (eq_attr "cpu_facility" "av1")
319 (match_test "TARGET_V2"))
322 (and (eq_attr "cpu_facility" "av2")
323 (not (match_test "TARGET_V2")))
326 (and (eq_attr "cpu_facility" "fpx")
327 (match_test "TARGET_FP_DP_AX"))
330 (and (eq_attr "cpu_facility" "cd")
331 (not (and (match_test "TARGET_V2")
332 (match_test "TARGET_CODE_DENSITY"))))
335 (const_string "yes")))
337 (define_attr "predicable" "no,yes" (const_string "no"))
338 ;; if 'predicable' were not so brain-dead, we would specify:
339 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
340 ;; (eq_attr "iscompact" "maybe") (const_string "no")]
341 ;; (const_string "yes"))
342 ;; and then for everything but calls, we could just set the cond attribute.
344 ;; Condition codes: this one is used by final_prescan_insn to speed up
345 ;; conditionalizing instructions. It saves having to scan the rtl to see if
346 ;; it uses or alters the condition codes.
348 ;; USE: This insn uses the condition codes (eg: a conditional branch).
349 ;; CANUSE: This insn can use the condition codes (for conditional execution).
350 ;; SET: All condition codes are set by this insn.
351 ;; SET_ZN: the Z and N flags are set by this insn.
352 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
353 ;; CLOB: The condition codes are set to unknown values by this insn.
354 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
356 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
358 [(and (eq_attr "predicable" "yes")
359 (eq_attr "is_sfunc" "no")
360 (eq_attr "delay_slot_filled" "no"))
361 (const_string "canuse")
363 (eq_attr "type" "call")
364 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
365 (match_test "!flag_pic") (const_string "canuse_limm")]
366 (const_string "nocond"))
368 (eq_attr "iscompact" "maybe,false")
369 (cond [ (and (eq_attr "type" "move")
370 (match_operand 1 "immediate_operand" ""))
372 (ior (match_operand 1 "u6_immediate_operand" "")
373 (match_operand 1 "long_immediate_operand" ""))
374 (const_string "canuse")
375 (const_string "canuse_limm"))
377 (eq_attr "type" "binary")
378 (cond [(ne (symbol_ref "REGNO (operands[0])")
379 (symbol_ref "REGNO (operands[1])"))
380 (const_string "nocond")
381 (match_operand 2 "register_operand" "")
382 (const_string "canuse")
383 (match_operand 2 "u6_immediate_operand" "")
384 (const_string "canuse")
385 (match_operand 2 "long_immediate_operand" "")
386 (const_string "canuse")
387 (match_operand 2 "const_int_operand" "")
388 (const_string "canuse_limm")]
389 (const_string "nocond"))
391 (eq_attr "type" "compare")
394 (eq_attr "type" "cmove,branch")
397 (eq_attr "is_sfunc" "yes")
398 (cond [(match_test "(TARGET_MEDIUM_CALLS
399 && !TARGET_LONG_CALLS_SET
401 (const_string "canuse_limm_add")
402 (match_test "(TARGET_MEDIUM_CALLS
403 && !TARGET_LONG_CALLS_SET)")
404 (const_string "canuse_limm")]
405 (const_string "canuse"))
409 (const_string "nocond"))]
411 (cond [(eq_attr "type" "compare")
414 (eq_attr "type" "cmove,branch")
419 (const_string "nocond"))))
421 /* ??? Having all these patterns gives ifcvt more freedom to generate
422 inefficient code. It seem to operate on the premise that
423 register-register copies and registers are free. I see better code
424 with -fno-if-convert now than without. */
426 [(match_operator 0 "proper_comparison_operator"
427 [(reg CC_REG) (const_int 0)])]
431 ;; Length (in # of bytes, long immediate constants counted too).
432 ;; ??? There's a nasty interaction between the conditional execution fsm
433 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
434 (define_attr "length" ""
436 [(eq_attr "iscompact" "true")
439 (eq_attr "iscompact" "maybe")
441 [(eq_attr "type" "sfunc")
442 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
445 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)
446 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (1))")
450 (eq_attr "iscompact" "true_limm")
453 (eq_attr "iscompact" "maybe_limm")
454 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
457 (eq_attr "type" "load")
459 (match_operand 1 "long_immediate_loadstore_operand" "")
460 (const_int 8) (const_int 4))
462 (eq_attr "type" "store")
464 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
465 (match_operand 1 "immediate_operand" ""))
466 (const_int 8) (const_int 4))
468 (eq_attr "type" "move,unary")
470 [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
471 (match_operand 1 "register_operand" "") (const_int 4)
472 (match_operand 1 "long_immediate_operand" "") (const_int 8)
473 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
476 (and (eq_attr "type" "shift")
477 (match_operand 1 "immediate_operand"))
479 (eq_attr "type" "binary,shift")
481 (ior (match_operand 2 "long_immediate_operand" "")
482 (and (ne (symbol_ref "REGNO (operands[0])")
483 (symbol_ref "REGNO (operands[1])"))
484 (eq (match_operand 2 "u6_immediate_operand" "")
487 (const_int 8) (const_int 4))
489 (eq_attr "type" "cmove")
490 (if_then_else (match_operand 1 "register_operand" "")
491 (const_int 4) (const_int 8))
493 (eq_attr "type" "call_no_delay_slot") (const_int 8)
499 ;; The length here is the length of a single asm. Unfortunately it might be
500 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
501 ;; lament asm's not being put in delay slots?
503 (define_asm_attributes
504 [(set_attr "length" "8")
505 (set_attr "type" "multi")
506 (set_attr "cond" "clob") ])
509 ;; The first two cond clauses and the default are necessary for correctness;
510 ;; the remaining cond clause is mainly an optimization, as otherwise nops
511 ;; would be inserted; however, if we didn't do this optimization, we would
512 ;; have to be more conservative in our length calculations.
514 (define_attr "in_delay_slot" "false,true"
515 (cond [(eq_attr "type" "uncond_branch,jump,branch,
516 call,sfunc,call_no_delay_slot,
517 brcc, brcc_no_delay_slot,loop_setup,loop_end")
518 (const_string "false")
519 (match_test "arc_write_ext_corereg (insn)")
520 (const_string "false")
521 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
522 next_active_insn (insn))")
523 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
524 + arc_hazard (insn, next_active_insn (insn)))"))
525 (const_string "false")
526 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
527 (const_string "false")
528 (eq_attr "iscompact" "maybe") (const_string "true")
531 (if_then_else (eq_attr "length" "2,4")
532 (const_string "true")
533 (const_string "false"))))
535 ; must not put an insn inside that refers to blink.
536 (define_attr "in_call_delay_slot" "false,true"
537 (cond [(eq_attr "in_delay_slot" "false")
538 (const_string "false")
539 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
540 (const_string "false")]
541 (const_string "true")))
543 (define_attr "in_sfunc_delay_slot" "false,true"
544 (cond [(eq_attr "in_call_delay_slot" "false")
545 (const_string "false")
546 (match_test "arc_regno_use_in (12, PATTERN (insn))")
547 (const_string "false")]
548 (const_string "true")))
550 (define_attr "in_ret_delay_slot" "no,yes"
551 (cond [(eq_attr "in_delay_slot" "false")
553 (match_test "regno_clobbered_p
554 (RETURN_ADDR_REGNUM, insn, SImode, 1)")
556 (const_string "yes")))
558 ;; Delay slot definition for ARCompact ISA
560 ;; When outputting an annul-true insn elegible for cond-exec
561 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
562 ;; for ARC600; we could also use this for ARC700 if the branch can't be
563 ;; unaligned and is at least somewhat likely (add parameter for this).
565 (define_delay (eq_attr "type" "call")
566 [(eq_attr "in_call_delay_slot" "true")
567 (eq_attr "in_call_delay_slot" "true")
570 (define_delay (eq_attr "type" "brcc")
571 [(eq_attr "in_delay_slot" "true")
576 (eq_attr "type" "return")
577 [(eq_attr "in_ret_delay_slot" "yes")
581 (define_delay (eq_attr "type" "loop_end")
582 [(eq_attr "in_delay_slot" "true")
586 ;; The only meaningful way to have an annull-true
587 ;; filled delay slot is to conditionalize the delay slot insn.
588 (define_delay (and (eq_attr "type" "branch,uncond_branch,jump")
589 (match_test "!optimize_size"))
590 [(eq_attr "in_delay_slot" "true")
594 ;; -mlongcall -fpic sfuncs use r12 to load the function address
595 (define_delay (eq_attr "type" "sfunc")
596 [(eq_attr "in_sfunc_delay_slot" "true")
599 ;; ??? need to use a working strategy for canuse_limm:
600 ;; - either canuse_limm is not eligible for delay slots, and has no
601 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
602 ;; somehow modify them to become inelegible for delay slots if a decision
603 ;; is made that makes conditional execution required.
605 (define_attr "tune" "none,arc600,arc7xx,arc700_4_2_std,arc700_4_2_xmac, \
608 (cond [(symbol_ref "arc_tune == ARC_TUNE_ARC600")
609 (const_string "arc600")
610 (symbol_ref "arc_tune == ARC_TUNE_ARC7XX")
611 (const_string "arc7xx")
612 (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_STD")
613 (const_string "arc700_4_2_std")
614 (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_XMAC")
615 (const_string "arc700_4_2_xmac")
616 (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
617 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A"))
618 (const_string "archs4x")
619 (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD")
620 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW"))
621 (const_string "archs4xd")]
622 (const_string "none"))))
624 (define_attr "tune_arc700" "false,true"
625 (if_then_else (eq_attr "tune" "arc7xx, arc700_4_2_std, arc700_4_2_xmac")
626 (const_string "true")
627 (const_string "false")))
629 (define_attr "tune_dspmpy" "none, slow, fast"
631 (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
632 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
633 (const_string "fast")
634 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW")
635 (const_string "slow")]
636 (const_string "none"))))
638 (define_attr "tune_store" "none, normal, rel31a"
640 (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
641 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
642 (const_string "normal")
643 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A")
644 (const_string "rel31a")]
645 (const_string "none"))))
647 ;; Move instructions.
648 (define_expand "movqi"
649 [(set (match_operand:QI 0 "move_dest_operand" "")
650 (match_operand:QI 1 "general_operand" ""))]
652 "if (prepare_move_operands (operands, QImode)) DONE;")
654 ; In order to allow the ccfsm machinery to do its work, the leading compact
655 ; alternatives say 'canuse' - there is another alternative that will match
656 ; when the condition codes are used.
657 ; Likewise, the length of an alternative that might be shifted to conditional
658 ; execution must reflect this, lest out-of-range branches are created.
659 ; The iscompact attribute allows the epilogue expander to know for which
660 ; insns it should lengthen the return insn.
661 (define_insn "*movqi_insn"
662 [(set (match_operand:QI 0 "move_dest_operand" "=q, q,r,q, h, w, w,???w,h, w,q,S,!*x, r,r, Ucm,m,???m, m,Usc")
663 (match_operand:QI 1 "move_src_operand" "rL,rP,q,P,hCm1,cL, I,?Rac,i,?i,T,q,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
664 "register_operand (operands[0], QImode)
665 || register_operand (operands[1], QImode)
666 || (CONSTANT_P (operands[1])
667 && (!satisfies_constraint_I (operands[1]) || !optimize_size)
668 && satisfies_constraint_Usc (operands[0]))
669 || (satisfies_constraint_Cm3 (operands[1])
670 && memory_operand (operands[0], QImode))"
692 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
693 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
694 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
695 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
697 (define_expand "movhi"
698 [(set (match_operand:HI 0 "move_dest_operand" "")
699 (match_operand:HI 1 "general_operand" ""))]
701 "if (prepare_move_operands (operands, HImode)) DONE;")
703 (define_insn "*movhi_insn"
704 [(set (match_operand:HI 0 "move_dest_operand" "=q, q,r,q, h, w, w,???w,q,h, w,q,S, r,r, Ucm,m,???m, m,VUsc")
705 (match_operand:HI 1 "move_src_operand" " rL,rP,q,P,hCm1,cL, I,?Rac,i,i,?i,T,q,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
706 "register_operand (operands[0], HImode)
707 || register_operand (operands[1], HImode)
708 || (CONSTANT_P (operands[1])
709 /* Don't use a LIMM that we could load with a single insn - we loose
710 delay-slot filling opportunities. */
711 && !satisfies_constraint_I (operands[1])
712 && satisfies_constraint_Usc (operands[0]))
713 || (satisfies_constraint_Cm3 (operands[1])
714 && memory_operand (operands[0], HImode))"
736 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
737 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false")
738 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
739 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
741 (define_expand "movsi"
742 [(set (match_operand:SI 0 "move_dest_operand" "")
743 (match_operand:SI 1 "general_operand" ""))]
745 "if (prepare_move_operands (operands, SImode)) DONE;")
747 ; In order to allow the ccfsm machinery to do its work, the leading compact
748 ; alternatives say 'canuse' - there is another alternative that will match
749 ; when the condition codes are used.
750 ; The length of an alternative that might be shifted to conditional
751 ; execution must reflect this, lest out-of-range branches are created.
752 ; the iscompact attribute allows the epilogue expander to know for which
753 ; insns it should lengthen the return insn.
754 (define_insn_and_split "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
755 [(set (match_operand:SI 0 "move_dest_operand" "=q, q,r,q, h, rl,r, r, r, r, ?r, r, q, h, rl, q, S, Us<,qRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m, m,VUsc")
756 (match_operand:SI 1 "move_src_operand" "rL,rP,q,P,hCm1,rLl,I,Clo,Chi,Cbi,Cpc,Clb,Cax,Cal,Cal,Uts,q,qRck, Us>,Usd,Ucm, Usd, Ucd,m, r,!*Rzd,r,Cm3, C32"))]
757 "register_operand (operands[0], SImode)
758 || register_operand (operands[1], SImode)
759 || (CONSTANT_P (operands[1])
760 && (!satisfies_constraint_I (operands[1]) || !optimize_size)
761 && satisfies_constraint_Usc (operands[0]))
762 || (satisfies_constraint_Cm3 (operands[1])
763 && memory_operand (operands[0], SImode))"
773 movh.cl\\t%0,%L1>>16 ;8
774 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl\\t%0,%1 >> %p1,%p1,8;9\" : \"movbi.cl\\t%0,%L1 >> 24,24,8;9\";
776 add\\t%0,pcl,%1@pcl ;11
782 * return arc_short_long (insn, \"push%?\\t%1\", \"st%U0\\t%1,%0\");
783 * return arc_short_long (insn, \"pop%?\\t%0\", \"ld%U1\\t%0,%1\");
793 st%U0%V0\\t%1,%0 ;28"
795 && GET_CODE (PATTERN (insn)) != COND_EXEC
796 && register_operand (operands[0], SImode)
797 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
798 && satisfies_constraint_Cax (operands[1])"
801 arc_split_mov_const (operands);
804 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
805 [(set_attr "type" "move, move, move,move,move, move, move,shift,shift,shift,binary,binary,multi,move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store")
806 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,false,false, false, false,false,true,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false")
807 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,8,8,*,6,*,*,*,*,*,*,4,*,4,*,*,*,*,*,8")
808 (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,yes,no,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
809 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,av2,*")])
811 ;; Sometimes generated by the epilogue code. We don't want to
812 ;; recognize these addresses in general, because the limm is costly,
813 ;; and we can't use them for stores. */
814 (define_insn "*movsi_pre_mod"
815 [(set (match_operand:SI 0 "register_operand" "=w")
818 (plus:SI (reg:SI SP_REG)
819 (match_operand 1 "immediate_operand" "Cal")))))]
822 [(set_attr "type" "load")
823 (set_attr "length" "8")])
825 ;; Store a value to directly to memory. The location might also be cached.
826 ;; Since the cached copy can cause a write-back at unpredictable times,
827 ;; we first write cached, then we write uncached.
828 (define_insn "store_direct"
829 [(set (match_operand:SI 0 "move_dest_operand" "=m")
830 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
833 "st%U0\\t%1,%0\;st%U0.di\\t%1,%0"
834 [(set_attr "type" "store")])
836 ;; Combiner patterns for compare with zero
837 (define_mode_iterator SQH [QI HI])
838 (define_mode_attr SQH_postfix [(QI "b") (HI "%_")])
840 (define_code_iterator SEZ [sign_extend zero_extend])
841 (define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")])
842 ; Optab prefix for sign/zero-extending operations
843 (define_code_attr su_optab [(sign_extend "") (zero_extend "u")])
845 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout"
846 [(set (match_operand 0 "cc_set_register" "")
847 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
850 "<SEZ_prefix><SQH_postfix>.f\\t0,%1"
851 [(set_attr "type" "compare")
852 (set_attr "cond" "set_zn")])
854 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0"
855 [(set (match_operand 0 "cc_set_register" "")
856 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
858 (set (match_operand:SI 2 "register_operand" "=r")
859 (SEZ:SI (match_dup 1)))]
861 "<SEZ_prefix><SQH_postfix>.f\\t%2,%1"
862 [(set_attr "type" "compare")
863 (set_attr "cond" "set_zn")])
865 (define_insn "*xbfu_cmp0_noout"
866 [(set (match_operand 0 "cc_set_register" "")
869 (match_operand:SI 1 "register_operand" " r,r")
870 (match_operand:SI 2 "const_int_operand" "C3p,n")
871 (match_operand:SI 3 "const_int_operand" " n,n"))
873 "TARGET_HS && TARGET_BARREL_SHIFTER"
875 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
876 operands[2] = GEN_INT (assemble_op2);
877 return "xbfu%?.f\\t0,%1,%2";
879 [(set_attr "type" "shift")
880 (set_attr "iscompact" "false")
881 (set_attr "length" "4,8")
882 (set_attr "predicable" "no")
883 (set_attr "cond" "set_zn")])
885 (define_insn "*xbfu_cmp0"
886 [(set (match_operand 4 "cc_set_register" "")
889 (match_operand:SI 1 "register_operand" "0 ,r,0")
890 (match_operand:SI 2 "const_int_operand" "C3p,n,n")
891 (match_operand:SI 3 "const_int_operand" "n ,n,n"))
893 (set (match_operand:SI 0 "register_operand" "=r,r,r")
894 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
895 "TARGET_HS && TARGET_BARREL_SHIFTER"
897 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
898 operands[2] = GEN_INT (assemble_op2);
899 return "xbfu%?.f\\t%0,%1,%2";
901 [(set_attr "type" "shift")
902 (set_attr "iscompact" "false")
903 (set_attr "length" "4,8,8")
904 (set_attr "predicable" "yes,no,yes")
905 (set_attr "cond" "set_zn")])
907 ; splitting to 'tst' allows short insns and combination into brcc.
908 (define_insn_and_split "*movsi_set_cc_insn"
909 [(set (match_operand 2 "cc_set_register" "")
910 (match_operator 3 "zn_compare_operator"
911 [(match_operand:SI 1 "nonmemory_operand" "rL,rI,Cal")
913 (set (match_operand:SI 0 "register_operand" "=r,r,r")
917 "reload_completed && operands_match_p (operands[0], operands[1])"
918 [(set (match_dup 2) (match_dup 3))]
920 [(set_attr "type" "compare")
921 (set_attr "predicable" "yes,no,yes")
922 (set_attr "cond" "set_zn")
923 (set_attr "length" "4,4,8")])
925 (define_insn "unary_comparison"
926 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
927 (match_operator:CC_ZN 3 "zn_compare_operator"
928 [(match_operator:SI 2 "unary_operator"
929 [(match_operand:SI 1 "register_operand" "c")])
933 [(set_attr "type" "compare")
934 (set_attr "cond" "set_zn")])
937 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
938 (define_insn "*unary_comparison_result_used"
939 [(set (match_operand 2 "cc_register" "")
940 (match_operator 4 "zn_compare_operator"
941 [(match_operator:SI 3 "unary_operator"
942 [(match_operand:SI 1 "register_operand" "c")])
944 (set (match_operand:SI 0 "register_operand" "=w")
948 [(set_attr "type" "compare")
949 (set_attr "cond" "set_zn")
950 (set_attr "length" "4")])
952 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
953 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
954 ; even if we don't need the clobber.
955 (define_insn_and_split "*tst_movb"
957 (match_operand 0 "cc_register" "")
958 (match_operator 4 "zn_compare_operator"
960 (match_operand:SI 1 "register_operand" "%q, q, c, c, c, c, q, q, c")
961 (match_operand:SI 2 "nonmemory_operand" "q,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
963 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))]
965 "movb.f.cl %3,%1,%p2,%p2,%x2"
966 "TARGET_NPS_BITOPS && reload_completed
967 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
968 [(set (match_dup 0) (match_dup 4))])
972 (match_operand 0 "cc_register" "")
973 (match_operator 3 "zn_compare_operator"
975 (match_operand:SI 1 "register_operand"
976 "%q, q, c, c, c, c, c, c")
977 (match_operand:SI 2 "nonmemory_operand"
978 " q,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
981 || !satisfies_constraint_Cbf (operands[2])
982 || satisfies_constraint_C0p (operands[2])
983 || satisfies_constraint_I (operands[2])
984 || satisfies_constraint_C1p (operands[2])
985 || satisfies_constraint_Chs (operands[2])"
987 switch (which_alternative)
989 case 0: case 2: case 3: case 7:
990 return \"tst%?\\t%1,%2\";
992 return \"btst%?\\t%1,%z2\";
994 return \"bmsk%?.f\\t0,%1,%Z2\";
996 return \"bclr%?.f\\t0,%1,%M2\";
998 return \"asr.f\\t0,%1,%p2\";
1003 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
1004 (set_attr "type" "compare,compare,compare,compare,compare,compare,binary,compare")
1005 (set_attr "length" "*,*,4,4,4,4,4,8")
1006 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
1007 (set_attr "cond" "set_zn")])
1009 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
1010 ; combine will do that and not try the AND.
1012 ; It would take 66 constraint combinations to describe the zero_extract
1013 ; constants that are covered by the 12-bit signed constant for tst
1014 ; (excluding the ones that are better done by mov or btst).
1015 ; so we rather use an extra pattern for tst;
1016 ; since this is about constants, reload shouldn't care.
1017 (define_insn "*tst_bitfield_tst"
1018 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1019 (match_operator 4 "zn_compare_operator"
1021 (match_operand:SI 1 "register_operand" "c")
1022 (match_operand:SI 2 "const_int_operand" "n")
1023 (match_operand:SI 3 "const_int_operand" "n"))
1025 "INTVAL (operands[2]) > 1
1026 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
1027 || (INTVAL (operands[3]) <= 11
1028 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
1029 "tst\\t%1,((1<<%2)-1)<<%3"
1030 [(set_attr "type" "compare")
1031 (set_attr "cond" "set_zn")
1032 (set_attr "length" "4")])
1034 ; Likewise for asr.f.
1035 (define_insn "*tst_bitfield_asr"
1036 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1037 (match_operator 4 "zn_compare_operator"
1039 (match_operand:SI 1 "register_operand" "c")
1040 (match_operand:SI 2 "const_int_operand" "n")
1041 (match_operand:SI 3 "const_int_operand" "n"))
1043 "INTVAL (operands[2]) > 1
1044 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
1046 [(set_attr "type" "shift")
1047 (set_attr "cond" "set_zn")
1048 (set_attr "length" "4")])
1050 (define_insn "*tst_bitfield"
1051 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1052 (match_operator 5 "zn_compare_operator"
1054 (match_operand:SI 1 "register_operand" "%q,c, c,Rrq,c")
1055 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
1056 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
1058 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
1064 movb.f.cl\\t%4,%1,%3,%3,%2
1065 and.f\\t0,%1,((1<<%2)-1)<<%3"
1066 [(set_attr "iscompact" "maybe,false,false,false,false")
1067 (set_attr "type" "compare,compare,compare,shift,compare")
1068 (set_attr "cond" "set_zn")
1069 (set_attr "length" "*,4,4,4,8")])
1071 ;; The next two patterns are for plos, ior, xor, and, and mult.
1072 (define_insn "*commutative_binary_cmp0_noout"
1073 [(set (match_operand 0 "cc_set_register" "")
1074 (match_operator 4 "zn_compare_operator"
1075 [(match_operator:SI 3 "commutative_operator"
1076 [(match_operand:SI 1 "register_operand" "%r,r")
1077 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1081 [(set_attr "type" "compare")
1082 (set_attr "cond" "set_zn")
1083 (set_attr "length" "4,8")])
1085 (define_insn "*commutative_binary_cmp0"
1086 [(set (match_operand 3 "cc_set_register" "")
1087 (match_operator 5 "zn_compare_operator"
1088 [(match_operator:SI 4 "commutative_operator"
1089 [(match_operand:SI 1 "register_operand" "%0, 0,r,r")
1090 (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")])
1092 (set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1096 [(set_attr "type" "compare")
1097 (set_attr "cond" "set_zn")
1098 (set_attr "predicable" "yes,yes,no,no")
1099 (set_attr "length" "4,4,4,8")])
1101 ; for flag setting 'add' instructions like if (a+b) { ...}
1102 ; the combiner needs this pattern
1103 (define_insn "*addsi_compare"
1104 [(set (reg:CC_ZN CC_REG)
1105 (compare:CC_ZN (neg:SI
1106 (match_operand:SI 0 "register_operand" "r"))
1107 (match_operand:SI 1 "register_operand" "r")))]
1110 [(set_attr "cond" "set")
1111 (set_attr "type" "compare")
1112 (set_attr "length" "4")])
1114 (define_insn "addsi_compare_2"
1115 [(set (reg:CC_C CC_REG)
1116 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "r,r")
1117 (match_operand:SI 1 "nonmemory_operand" "rL,Cal"))
1121 [(set_attr "cond" "set")
1122 (set_attr "type" "compare")
1123 (set_attr "length" "4,8")])
1125 (define_insn "*addsi_compare_3"
1126 [(set (reg:CC_C CC_REG)
1127 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "r")
1128 (match_operand:SI 1 "register_operand" "r"))
1132 [(set_attr "cond" "set")
1133 (set_attr "type" "compare")
1134 (set_attr "length" "4")])
1136 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1137 (define_insn "*commutative_binary_comparison_result_used"
1138 [(set (match_operand 3 "cc_register" "")
1139 (match_operator 5 "zn_compare_operator"
1140 ; We can accept any commutative operator except mult because
1141 ; our 'w' class below could try to use LP_COUNT.
1142 [(match_operator:SI 4 "commutative_operator_sans_mult"
1143 [(match_operand:SI 1 "register_operand" "c,0,c")
1144 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1146 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1149 "%O4.f\\t%0,%1,%2 ; non-mult commutative"
1150 [(set_attr "type" "compare,compare,compare")
1151 (set_attr "cond" "set_zn,set_zn,set_zn")
1152 (set_attr "length" "4,4,8")])
1154 ; a MULT-specific version of this pattern to avoid touching the
1156 (define_insn "*commutative_binary_mult_comparison_result_used"
1157 [(set (match_operand 3 "cc_register" "")
1158 (match_operator 5 "zn_compare_operator"
1159 [(match_operator:SI 4 "mult_operator"
1160 [(match_operand:SI 1 "register_operand" "c,0,c")
1161 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1163 ; Make sure to use the W class to not touch LP_COUNT.
1164 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1166 "!TARGET_ARC600_FAMILY"
1167 "%O4.f\\t%0,%1,%2 ; mult commutative"
1168 [(set_attr "type" "compare,compare,compare")
1169 (set_attr "cond" "set_zn,set_zn,set_zn")
1170 (set_attr "length" "4,4,8")])
1172 (define_insn "*noncommutative_binary_cmp0"
1173 [(set (match_operand 3 "cc_set_register" "")
1174 (match_operator 5 "zn_compare_operator"
1175 [(match_operator:SI 4 "noncommutative_operator"
1176 [(match_operand:SI 1 "register_operand" "0,r,0, 0,r")
1177 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,Cal,Cal")])
1179 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1182 "%O4%?.f\\t%0,%1,%2"
1183 [(set_attr "type" "compare")
1184 (set_attr "cond" "set_zn")
1185 (set_attr "predicable" "yes,no,no,yes,no")
1186 (set_attr "length" "4,4,4,8,8")])
1188 (define_insn "*noncommutative_binary_cmp0_noout"
1189 [(set (match_operand 0 "cc_set_register" "")
1190 (match_operator 3 "zn_compare_operator"
1191 [(match_operator:SI 4 "noncommutative_operator"
1192 [(match_operand:SI 1 "register_operand" "r,r")
1193 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1197 [(set_attr "type" "compare")
1198 (set_attr "cond" "set_zn")
1199 (set_attr "length" "4,8")])
1202 (define_insn "*rsub_cmp0"
1203 [(set (match_operand 4 "cc_set_register" "")
1204 (match_operator 3 "zn_compare_operator"
1206 (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1207 (match_operand:SI 2 "register_operand" "r,r"))
1209 (set (match_operand:SI 0 "register_operand" "=r,r")
1210 (minus:SI (match_dup 1) (match_dup 2)))]
1213 [(set_attr "type" "compare")
1214 (set_attr "cond" "set_zn")
1215 (set_attr "length" "4,8")])
1217 (define_insn "*rsub_cmp0_noout"
1218 [(set (match_operand 0 "cc_set_register" "")
1219 (match_operator 3 "zn_compare_operator"
1221 (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1222 (match_operand:SI 2 "register_operand" "r,r"))
1226 [(set_attr "type" "compare")
1227 (set_attr "cond" "set_zn")
1228 (set_attr "length" "4,8")])
1230 (define_expand "bic_f_zn"
1232 [(set (reg:CC_ZN CC_REG)
1234 (and:SI (match_operand:SI 1 "register_operand" "")
1235 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1237 (set (match_operand:SI 0 "register_operand" "")
1238 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1241 (define_insn "*bic_f"
1242 [(set (match_operand 3 "cc_set_register" "")
1243 (match_operator 4 "zn_compare_operator"
1244 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1246 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1248 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1249 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1252 [(set_attr "type" "compare,compare,compare")
1253 (set_attr "cond" "set_zn,set_zn,set_zn")
1254 (set_attr "length" "4,4,8")])
1256 (define_insn "*bic_cmp0_noout"
1257 [(set (match_operand 0 "cc_set_register" "")
1259 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1260 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1262 "register_operand (operands[1], SImode)
1263 || register_operand (operands[2], SImode)"
1265 [(set_attr "type" "unary")
1266 (set_attr "cond" "set_zn")
1267 (set_attr "length" "4,8,8")])
1269 (define_insn "*bic_cmp0"
1270 [(set (match_operand 0 "cc_set_register" "")
1272 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1273 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1275 (set (match_operand:SI 3 "register_operand" "=r,r,r")
1276 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1277 "register_operand (operands[1], SImode)
1278 || register_operand (operands[2], SImode)"
1280 [(set_attr "type" "unary")
1281 (set_attr "cond" "set_zn")
1282 (set_attr "length" "4,8,8")])
1284 (define_expand "movdi"
1285 [(set (match_operand:DI 0 "move_dest_operand" "")
1286 (match_operand:DI 1 "general_operand" ""))]
1289 if (prepare_move_operands (operands, DImode))
1293 (define_insn_and_split "*movdi_insn"
1294 [(set (match_operand:DI 0 "move_dest_operand" "=r, r,r, m")
1295 (match_operand:DI 1 "move_double_src_operand" "r,Hi,m,rCm3"))]
1296 "register_operand (operands[0], DImode)
1297 || register_operand (operands[1], DImode)
1298 || (satisfies_constraint_Cm3 (operands[1])
1299 && memory_operand (operands[0], DImode))"
1305 "&& reload_completed && arc_split_move_p (operands)"
1308 arc_split_move (operands);
1311 [(set_attr "type" "move,move,load,store")
1312 (set_attr "length" "8,16,16,16")])
1314 ;; Floating point move insns.
1316 (define_expand "movsf"
1317 [(set (match_operand:SF 0 "move_dest_operand" "")
1318 (match_operand:SF 1 "general_operand" ""))]
1320 "if (prepare_move_operands (operands, SFmode)) DONE;")
1322 (define_insn "*movsf_insn"
1323 [(set (match_operand:SF 0 "move_dest_operand" "=h,h, r,r, q,S,Usc,r,m")
1324 (match_operand:SF 1 "move_src_operand" "hCfZ,E,rCfZ,E,Uts,q, E,m,r"))]
1325 "register_operand (operands[0], SFmode)
1326 || register_operand (operands[1], SFmode)
1327 || (CONSTANT_P (operands[1])
1328 && (!satisfies_constraint_I (operands[1]) || !optimize_size)
1329 && satisfies_constraint_Usc (operands[0]))"
1340 [(set_attr "type" "move,move,move,move,load,store,store,load,store")
1341 (set_attr "predicable" "no,no,yes,yes,no,no,no,no,no")
1342 (set_attr "length" "*,*,4,*,*,*,*,*,*")
1343 (set_attr "iscompact" "true,true_limm,false,false,true,true,false,false,false")])
1345 (define_expand "movdf"
1346 [(set (match_operand:DF 0 "move_dest_operand" "")
1347 (match_operand:DF 1 "general_operand" ""))]
1349 "if (prepare_move_operands (operands, DFmode)) DONE;")
1351 (define_insn_and_split "*movdf_insn"
1352 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,r,r,r,m")
1353 (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))]
1354 "(register_operand (operands[0], DFmode)
1355 || register_operand (operands[1], DFmode))"
1363 "&& reload_completed && arc_split_move_p (operands)"
1366 arc_split_move (operands);
1369 [(set_attr "type" "move,move,move,move,load,store")
1370 (set_attr "length" "4,16,8,16,16,16")])
1372 (define_insn_and_split "*movdf_insn_nolrsr"
1373 [(set (match_operand:DF 0 "register_operand" "=r")
1374 (match_operand:DF 1 "arc_double_register_operand" "D"))
1375 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1377 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1382 (set (match_dup 0) (match_dup 3))
1384 ; daddh?? r1, r0, r0
1386 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1389 (use (match_dup 0)) ; used to block can_combine_p
1390 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1393 ; We have to do this twice, once to read the value into R0 and
1394 ; second time to put back the contents which the first DEXCLx
1395 ; will have overwritten
1398 (set (match_dup 4) ; aka r0result
1400 (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1402 (clobber (match_dup 1))
1404 ; Generate the second, which makes sure operand5 and operand4 values
1405 ; are put back in the Dx register properly.
1406 (set (match_dup 1) (unspec_volatile:DF
1407 [(match_dup 5) (match_dup 4)]
1408 VUNSPEC_ARC_DEXCL_NORES))
1410 ; Note: we cannot use a (clobber (match_scratch)) here because
1411 ; the combine pass will end up replacing uses of it with 0
1413 "operands[3] = CONST0_RTX (DFmode);
1414 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1415 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1416 [(set_attr "type" "move")])
1418 ;; Load/Store with update instructions.
1420 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1421 ;; hardware can also do cases where the increment is not the size of the
1424 ;; In all these cases, we use operands 0 and 1 for the register being
1425 ;; incremented because those are the operands that local-alloc will
1426 ;; tie and these are the pair most likely to be tieable (and the ones
1427 ;; that will benefit the most).
1429 ;; We use match_operator here because we need to know whether the memory
1430 ;; object is volatile or not.
1433 ;; Note: loadqi_update has no 16-bit variant
1434 (define_insn "*loadqi_update"
1435 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1436 (match_operator:QI 4 "any_mem_operand"
1437 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1438 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1439 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1440 (plus:SI (match_dup 1) (match_dup 2)))]
1442 "ldb.a%V4 %3,[%0,%2]"
1443 [(set_attr "type" "load,load")
1444 (set_attr "length" "4,8")])
1446 (define_insn "*load_zeroextendqisi_update"
1447 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1448 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1449 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1450 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1451 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1452 (plus:SI (match_dup 1) (match_dup 2)))]
1454 "ldb.a%V4 %3,[%0,%2]"
1455 [(set_attr "type" "load,load")
1456 (set_attr "length" "4,8")])
1458 (define_insn "*load_signextendqisi_update"
1459 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1460 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1461 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1462 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1463 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1464 (plus:SI (match_dup 1) (match_dup 2)))]
1466 "ldb.x.a%V4 %3,[%0,%2]"
1467 [(set_attr "type" "load,load")
1468 (set_attr "length" "4,8")])
1470 (define_insn "*storeqi_update"
1471 [(set (match_operator:QI 4 "any_mem_operand"
1472 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1473 (match_operand:SI 2 "short_immediate_operand" "I"))])
1474 (match_operand:QI 3 "register_operand" "c"))
1475 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1476 (plus:SI (match_dup 1) (match_dup 2)))]
1478 "stb.a%V4 %3,[%0,%2]"
1479 [(set_attr "type" "store")
1480 (set_attr "length" "4")])
1482 ;; ??? pattern may have to be re-written
1483 ;; Note: no 16-bit variant for this pattern
1484 (define_insn "*loadhi_update"
1485 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1486 (match_operator:HI 4 "any_mem_operand"
1487 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1488 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1489 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1490 (plus:SI (match_dup 1) (match_dup 2)))]
1492 "ld%_.a%V4 %3,[%0,%2]"
1493 [(set_attr "type" "load,load")
1494 (set_attr "length" "4,8")])
1496 (define_insn "*load_zeroextendhisi_update"
1497 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1498 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1499 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1500 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1501 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1502 (plus:SI (match_dup 1) (match_dup 2)))]
1504 "ld%_.a%V4 %3,[%0,%2]"
1505 [(set_attr "type" "load,load")
1506 (set_attr "length" "4,8")])
1508 ;; Note: no 16-bit variant for this instruction
1509 (define_insn "*load_signextendhisi_update"
1510 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1511 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1512 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1513 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1514 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1515 (plus:SI (match_dup 1) (match_dup 2)))]
1517 "ld%_.x.a%V4 %3,[%0,%2]"
1518 [(set_attr "type" "load,load")
1519 (set_attr "length" "4,8")])
1521 (define_insn "*storehi_update"
1522 [(set (match_operator:HI 4 "any_mem_operand"
1523 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1524 (match_operand:SI 2 "short_immediate_operand" "I"))])
1525 (match_operand:HI 3 "register_operand" "c"))
1526 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1527 (plus:SI (match_dup 1) (match_dup 2)))]
1529 "st%_.a%V4 %3,[%0,%2]"
1530 [(set_attr "type" "store")
1531 (set_attr "length" "4")])
1533 ;; No 16-bit variant for this instruction pattern
1534 (define_insn "*loadsi_update"
1535 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1536 (match_operator:SI 4 "any_mem_operand"
1537 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1538 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1539 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1540 (plus:SI (match_dup 1) (match_dup 2)))]
1542 "ld.a%V4 %3,[%0,%2]"
1543 [(set_attr "type" "load,load")
1544 (set_attr "length" "4,8")])
1546 (define_insn "*storesi_update"
1547 [(set (match_operator:SI 4 "any_mem_operand"
1548 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1549 (match_operand:SI 2 "short_immediate_operand" "I"))])
1550 (match_operand:SI 3 "register_operand" "c"))
1551 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1552 (plus:SI (match_dup 1) (match_dup 2)))]
1554 "st.a%V4 %3,[%0,%2]"
1555 [(set_attr "type" "store")
1556 (set_attr "length" "4")])
1558 (define_insn "*loadsf_update"
1559 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1560 (match_operator:SF 4 "any_mem_operand"
1561 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1562 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1563 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1564 (plus:SI (match_dup 1) (match_dup 2)))]
1566 "ld.a%V4 %3,[%0,%2]"
1567 [(set_attr "type" "load,load")
1568 (set_attr "length" "4,8")])
1570 (define_insn "*storesf_update"
1571 [(set (match_operator:SF 4 "any_mem_operand"
1572 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1573 (match_operand:SI 2 "short_immediate_operand" "I"))])
1574 (match_operand:SF 3 "register_operand" "c"))
1575 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1576 (plus:SI (match_dup 1) (match_dup 2)))]
1578 "st.a%V4 %3,[%0,%2]"
1579 [(set_attr "type" "store")
1580 (set_attr "length" "4")])
1582 ;; Conditional move instructions.
1584 (define_expand "movsicc"
1585 [(set (match_operand:SI 0 "dest_reg_operand" "")
1586 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1587 (match_operand:SI 2 "nonmemory_operand" "")
1588 (match_operand:SI 3 "register_operand" "")))]
1591 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1592 if (operands[1] == NULL_RTX)
1596 (define_expand "movdicc"
1597 [(set (match_operand:DI 0 "dest_reg_operand" "")
1598 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1599 (match_operand:DI 2 "nonmemory_operand" "")
1600 (match_operand:DI 3 "register_operand" "")))]
1603 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1604 if (operands[1] == NULL_RTX)
1609 (define_expand "movsfcc"
1610 [(set (match_operand:SF 0 "dest_reg_operand" "")
1611 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1612 (match_operand:SF 2 "nonmemory_operand" "")
1613 (match_operand:SF 3 "register_operand" "")))]
1616 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1617 if (operands[1] == NULL_RTX)
1621 (define_expand "movdfcc"
1622 [(set (match_operand:DF 0 "dest_reg_operand" "")
1623 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1624 (match_operand:DF 2 "nonmemory_operand" "")
1625 (match_operand:DF 3 "register_operand" "")))]
1628 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1629 if (operands[1] == NULL_RTX)
1633 (define_insn "*movsicc_insn"
1634 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1635 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1636 [(match_operand 4 "cc_register" "") (const_int 0)])
1637 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1638 (match_operand:SI 2 "register_operand" "0,0")))]
1641 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1642 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11))
1643 return "sub%?.ne\\t%0,%0,%0";
1644 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1645 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1646 && rtx_equal_p (operands[1], constm1_rtx)
1647 && GET_CODE (operands[3]) == LTU)
1648 return "sbc.cs\\t%0,%0,%0";
1649 return "mov.%d3\\t%0,%1";
1651 [(set_attr "type" "cmove,cmove")
1652 (set_attr "length" "4,8")])
1654 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1655 ;; if the single bit is the sign bit, then GCC likes to convert this
1656 ;; into a sign extend and a compare less than, or greater to zero.
1657 ;; This is usually fine, except for the NXP400 where we have access to
1658 ;; a bit test instruction, along with a special short load instruction
1659 ;; (from CMEM), that doesn't support sign-extension on load.
1661 ;; This peephole optimisation attempts to restore the use of bit-test
1662 ;; in those cases where it is useful to do so.
1664 [(set (match_operand:SI 0 "register_operand" "")
1666 (match_operand:QI 1 "any_mem_operand" "")))
1667 (set (reg:CC_ZN CC_REG)
1668 (compare:CC_ZN (match_dup 0)
1671 (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1672 [(reg:CC_ZN CC_REG) (const_int 0)])
1673 (match_operand 3 "" "")
1674 (match_operand 4 "" "")))]
1676 && cmem_address (XEXP (operands[1], 0), SImode)
1677 && peep2_reg_dead_p (2, operands[0])
1678 && peep2_regno_dead_p (3, CC_REG)"
1682 (set (reg:CC_ZN CC_REG)
1683 (compare:CC_ZN (zero_extract:SI
1689 (if_then_else (match_dup 2)
1692 "if (GET_CODE (operands[2]) == GE)
1693 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1695 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1697 ; Try to generate more short moves, and/or less limms, by substituting a
1698 ; conditional move with a conditional sub.
1700 [(set (match_operand:SI 0 "compact_register_operand")
1701 (match_operand:SI 1 "const_int_operand"))
1703 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1704 [(match_operand 4 "cc_register" "") (const_int 0)])
1705 (match_operand:SI 2 "const_int_operand" "")
1707 "!satisfies_constraint_P (operands[1])
1708 && satisfies_constraint_P (operands[2])
1709 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1710 [(set (match_dup 0) (match_dup 2))
1714 (plus:SI (match_dup 0) (match_dup 1))))]
1715 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1716 GET_MODE (operands[4])),
1717 VOIDmode, operands[4], const0_rtx);
1718 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1720 (define_insn "*movdicc_insn"
1721 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1722 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1723 [(match_operand 4 "cc_register" "") (const_int 0)])
1724 (match_operand:DI 1 "nonmemory_operand" "c,i")
1725 (match_operand:DI 2 "register_operand" "0,0")))]
1729 switch (which_alternative)
1733 /* We normally copy the low-numbered register first. However, if
1734 the first register operand 0 is the same as the second register of
1735 operand 1, we must copy in the opposite order. */
1736 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1737 return \"mov.%d3\\t%R0,%R1\;mov.%d3\\t%0,%1\";
1739 return \"mov.%d3\\t%0,%1\;mov.%d3\\t%R0,%R1\";
1741 return \"mov.%d3\\t%L0,%L1\;mov.%d3\\t%H0,%H1\";
1746 [(set_attr "type" "cmove,cmove")
1747 (set_attr "length" "8,16")])
1750 (define_insn "*movsfcc_insn"
1751 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1752 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1753 [(match_operand 4 "cc_register" "") (const_int 0)])
1754 (match_operand:SF 1 "nonmemory_operand" "c,E")
1755 (match_operand:SF 2 "register_operand" "0,0")))]
1759 mov.%d3\\t%0,%1 ; %A1"
1760 [(set_attr "type" "cmove,cmove")])
1762 (define_insn "*movdfcc_insn"
1763 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1764 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1765 [(match_operand 4 "cc_register" "") (const_int 0)])
1766 (match_operand:DF 2 "nonmemory_operand" "c,E")
1767 (match_operand:DF 3 "register_operand" "0,0")))]
1771 switch (which_alternative)
1775 /* We normally copy the low-numbered register first. However, if
1776 the first register operand 0 is the same as the second register of
1777 operand 1, we must copy in the opposite order. */
1778 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1779 return \"mov.%d1\\t%R0,%R2\;mov.%d1\\t%0,%2\";
1781 return \"mov.%d1\\t%0,%2\;mov.%d1\\t%R0,%R2\";
1783 return \"mov.%d1\\t%L0,%L2\;mov.%d1\\t%H0,%H2; %A2\";
1786 [(set_attr "type" "cmove,cmove")
1787 (set_attr "length" "8,16")])
1789 ;; -------------------------------------------------------------------
1790 ;; Sign/Zero extension
1791 ;; -------------------------------------------------------------------
1793 (define_insn "*zero_extendqihi2_i"
1794 [(set (match_operand:HI 0 "dest_reg_operand" "=q,q,r,r,r,r")
1796 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,Ucm,m")))]
1805 [(set_attr "type" "unary,unary,unary,unary,load,load")
1806 (set_attr "iscompact" "maybe,true,false,false,false,false")
1807 (set_attr "predicable" "no,no,yes,no,no,no")])
1809 (define_expand "zero_extendqihi2"
1810 [(set (match_operand:HI 0 "dest_reg_operand" "")
1811 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1816 (define_insn "*zero_extendqisi2_ac"
1817 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,q,!*x,r,r")
1819 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,T,Usd,Ucm,m")))]
1830 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1831 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1832 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1834 (define_expand "zero_extendqisi2"
1835 [(set (match_operand:SI 0 "dest_reg_operand" "")
1836 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1841 (define_insn "*zero_extendhisi2_i"
1842 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,!x,q,r,r")
1844 (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,r,Usd,T,Ucm,m")))]
1855 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1856 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1857 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1859 (define_expand "zero_extendhisi2"
1860 [(set (match_operand:SI 0 "dest_reg_operand" "")
1861 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1866 ;; Sign extension instructions.
1868 (define_insn "*extendqihi2_i"
1869 [(set (match_operand:HI 0 "dest_reg_operand" "=q,r,r,r")
1871 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1878 [(set_attr "type" "unary,unary,load,load")
1879 (set_attr "iscompact" "true,false,false,false")
1880 (set_attr "length" "*,*,*,8")])
1882 (define_expand "extendqihi2"
1883 [(set (match_operand:HI 0 "dest_reg_operand" "")
1884 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1889 (define_insn "*extendqisi2_ac"
1890 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r")
1892 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1899 [(set_attr "type" "unary,unary,load,load")
1900 (set_attr "iscompact" "true,false,false,false")
1901 (set_attr "length" "*,*,*,8")])
1903 (define_expand "extendqisi2"
1904 [(set (match_operand:SI 0 "dest_reg_operand" "")
1905 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1910 (define_insn "*extendhisi2_i"
1911 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,q,r,r")
1913 (match_operand:HI 1 "nonvol_nonimm_operand" "q,r,Ucd,Uex,m")))]
1919 ld%_.x%U1%V1\\t%0,%1
1920 ld%_.x%U1%V1\\t%0,%1"
1921 [(set_attr "type" "unary,unary,load,load,load")
1922 (set_attr "iscompact" "true,false,true,false,false")
1923 (set_attr "length" "*,*,*,4,8")])
1925 (define_expand "extendhisi2"
1926 [(set (match_operand:SI 0 "dest_reg_operand" "")
1927 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1932 ;; Unary arithmetic insns
1934 ;; We allow constant operands to enable late constant propagation, but it is
1935 ;; not worth while to have more than one dedicated alternative to output them -
1936 ;; if we are really worried about getting these the maximum benefit of all
1937 ;; the available alternatives, we should add an extra pass to fold such
1938 ;; operations to movsi.
1940 ;; Absolute instructions
1942 (define_insn "abssi2"
1943 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w,w")
1944 (abs:SI (match_operand:SI 1 "nonmemory_operand" "q,cL,Cal")))]
1947 [(set_attr "type" "two_cycle_core")
1948 (set_attr "length" "*,4,8")
1949 (set_attr "iscompact" "true,false,false")])
1951 ;; Maximum and minimum insns
1953 (define_insn "smaxsi3"
1954 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
1955 (smax:SI (match_operand:SI 1 "register_operand" "%0, r, r")
1956 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1959 [(set_attr "type" "two_cycle_core")
1960 (set_attr "length" "4,4,8")
1961 (set_attr "predicable" "yes,no,no")]
1964 (define_insn "sminsi3"
1965 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
1966 (smin:SI (match_operand:SI 1 "register_operand" "%0, r, r")
1967 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1970 [(set_attr "type" "two_cycle_core")
1971 (set_attr "length" "4,4,8")
1972 (set_attr "predicable" "yes,no,no")]
1975 ;; Arithmetic instructions.
1977 ; The alternatives in the constraints still serve three purposes:
1978 ; - estimate insn size assuming conditional execution
1979 ; - guide reload to re-order the second and third operand to get a better fit.
1980 ; - give tentative insn type to guide scheduling
1981 ; N.B. "%" for commutativity doesn't help when there is another matching
1982 ; (but longer) alternative.
1983 (define_insn "*addsi3_mixed"
1984 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
1985 [(set (match_operand:SI 0 "register_operand" "=q, h,!*Rsd,Rcb,Rcb, q, q, q, r,r, r, r, r, r, q, r, r")
1986 (plus:SI (match_operand:SI 1 "register_operand" "%0, 0, q, 0, 0,Rcb, q, 0, 0,r, r, r, 0, r, 0, 0, r")
1987 (match_operand:SI 2 "nonmemory_operand" "hL,Cm1, L,CP4,CM4,CM4,qK, O,rL,0,rC6u,C6n,CIs,C4p,Cal,Cal,Cal")))]
1990 add_s\\t%0,%1,%2 ;b,b,h
1991 add_s\\t%0,%1,%2 ;h,h,s3
1992 add_s\\t%0,%1,%2 ;R0/R1,b,u6
1993 sub_s\\t%0,%1,%n2 ;sp,sp,u7
1994 add_s\\t%0,%1,%2 ;sp,sp,u7
1995 add_s\\t%0,%1,%2 ;b,sp,u7
1996 add_s\\t%0,%1,%2 ;a,b,c/u3
1997 add_s\\t%0,%1,%2 ;b,b,u7
1998 add%?\\t%0,%1,%2 ;(p)b,b,c/u6
1999 add%?\\t%0,%2,%1 ;(p)b,b,c
2000 add%s2\\t%0,%1,%S2 ;a,b,c/u6
2001 sub%s2\\t%0,%1,%N2 ;a,b,u6
2002 add%s2\\t%0,%1,%S2 ;b,b,s12
2004 add_s\\t%0,%1,%2 ;b,b,limm
2005 add%?\\t%0,%1,%2 ;(p)b,b,limm
2006 add\\t%0,%1,%2 ;a,b,limm"
2007 [(set_attr "type" "add,add,add,sub,add,add,add,add,add,add,add,sub,add,bxor,add,add,add")
2008 (set_attr "iscompact" "true,true,true,true,true,true,true,true,false,false,false,false,false,false,true_limm,false,false")
2009 (set_attr "length" "2,2,2,2,2,2,2,2,4,4,4,4,4,4,6,8,8")
2010 (set_attr "predicable" "no,no,no,no,no,no,no,no,yes,yes,no,no,no,no,no,yes,no")
2013 ;; ARCv2 MPYW and MPYUW
2014 (define_expand "mulhisi3"
2015 [(set (match_operand:SI 0 "register_operand" "")
2016 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
2017 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
2020 if (CONSTANT_P (operands[2]))
2022 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
2028 (define_insn "mulhisi3_imm"
2029 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
2030 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
2031 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
2034 [(set_attr "length" "4,4,4,8,8")
2035 (set_attr "iscompact" "false")
2036 (set_attr "type" "mul16_em")
2037 (set_attr "predicable" "yes,no,no,yes,no")
2038 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2041 (define_insn "mulhisi3_reg"
2042 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
2043 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,0,r"))
2044 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "q,r,r"))))]
2047 [(set_attr "length" "*,4,4")
2048 (set_attr "iscompact" "maybe,false,false")
2049 (set_attr "type" "mul16_em")
2050 (set_attr "predicable" "yes,yes,no")
2051 (set_attr "cond" "canuse,canuse,nocond")
2054 (define_expand "umulhisi3"
2055 [(set (match_operand:SI 0 "register_operand" "")
2056 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2057 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
2060 if (CONSTANT_P (operands[2]))
2062 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
2068 (define_insn "umulhisi3_imm"
2069 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
2070 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
2071 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
2073 "mpyuw%?\\t%0,%1,%2"
2074 [(set_attr "length" "4,4,4,8,8")
2075 (set_attr "iscompact" "false")
2076 (set_attr "type" "mul16_em")
2077 (set_attr "predicable" "yes,no,no,yes,no")
2078 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2081 (define_insn "umulhisi3_reg"
2082 [(set (match_operand:SI 0 "register_operand" "=q, r, r")
2083 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, 0, r"))
2084 (zero_extend:SI (match_operand:HI 2 "register_operand" "q, r, r"))))]
2086 "mpyuw%?\\t%0,%1,%2"
2087 [(set_attr "length" "*,4,4")
2088 (set_attr "iscompact" "maybe,false,false")
2089 (set_attr "type" "mul16_em")
2090 (set_attr "predicable" "yes,yes,no")
2091 (set_attr "cond" "canuse,canuse,nocond")
2094 ;; ARC700/ARC600/V2 multiply
2097 (define_expand "mulsi3"
2098 [(set (match_operand:SI 0 "register_operand" "")
2099 (mult:SI (match_operand:SI 1 "register_operand" "")
2100 (match_operand:SI 2 "nonmemory_operand" "")))]
2103 if (TARGET_MUL64_SET)
2105 emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2]));
2108 else if (TARGET_MULMAC_32BY16_SET)
2110 emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2]));
2115 (define_insn_and_split "mulsi32x16"
2116 [(set (match_operand:SI 0 "register_operand" "=w")
2117 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2118 (match_operand:SI 2 "nonmemory_operand" "ci")))
2119 (clobber (reg:DI MUL32x16_REG))]
2120 "TARGET_MULMAC_32BY16_SET"
2122 "TARGET_MULMAC_32BY16_SET && reload_completed"
2125 if (immediate_operand (operands[2], SImode)
2126 && INTVAL (operands[2]) >= 0
2127 && INTVAL (operands[2]) <= 65535)
2129 emit_insn (gen_umul_600 (operands[1], operands[2],
2130 gen_acc2 (), gen_acc1 ()));
2131 emit_move_insn (operands[0], gen_acc2 ());
2134 emit_insn (gen_umul_600 (operands[1], operands[2],
2135 gen_acc2 (), gen_acc1 ()));
2136 emit_insn (gen_mac_600 (operands[1], operands[2],
2137 gen_acc2 (), gen_acc1 ()));
2138 emit_move_insn (operands[0], gen_acc2 ());
2141 [(set_attr "type" "multi")
2142 (set_attr "length" "8")])
2144 ; mululw conditional execution without a LIMM clobbers an input register;
2145 ; we'd need a different pattern to describe this.
2146 ; To make the conditional execution valid for the LIMM alternative, we
2147 ; have to emit the LIMM before the register operand.
2148 (define_insn "umul_600"
2149 [(set (match_operand:SI 2 "acc2_operand" "")
2150 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2151 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2155 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2156 "TARGET_MULMAC_32BY16_SET"
2158 [(set_attr "length" "4,4,8")
2159 (set_attr "type" "mulmac_600")
2160 (set_attr "predicable" "no")
2161 (set_attr "cond" "nocond")])
2163 (define_insn "mac_600"
2164 [(set (match_operand:SI 2 "acc2_operand" "")
2166 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2168 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2173 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2174 "TARGET_MULMAC_32BY16_SET"
2175 "machlw%?\\t0,%0,%1"
2176 [(set_attr "length" "4,4,8")
2177 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2178 (set_attr "predicable" "no, no, yes")
2179 (set_attr "cond" "nocond, canuse_limm, canuse")])
2181 ; The gcc-internal representation may differ from the hardware
2182 ; register number in order to allow the generic code to correctly
2183 ; split the concatenation of mhi and mlo.
2184 (define_insn_and_split "mulsi64"
2185 [(set (match_operand:SI 0 "register_operand" "=w")
2186 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2187 (match_operand:SI 2 "nonmemory_operand" "ci")))
2188 (clobber (reg:DI MUL64_OUT_REG))]
2191 "TARGET_MUL64_SET && reload_completed"
2194 rtx mhi = gen_rtx_REG (SImode, R59_REG);
2195 rtx mlo = gen_rtx_REG (SImode, R58_REG);
2196 emit_insn (gen_mulsi_600 (operands[1], operands[2], mlo, mhi));
2197 emit_move_insn (operands[0], mlo);
2200 [(set_attr "type" "multi")
2201 (set_attr "length" "8")])
2203 (define_insn "mulsi_600"
2204 [(set (match_operand:SI 2 "mlo_operand" "")
2205 (mult:SI (match_operand:SI 0 "register_operand" "%q,c,c,c")
2206 (match_operand:SI 1 "nonmemory_operand" "q,cL,I,Cal")))
2207 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2210 [(set_attr "length" "*,4,4,8")
2211 (set_attr "iscompact" "maybe,false,false,false")
2212 (set_attr "type" "multi,multi,multi,multi")
2213 (set_attr "predicable" "yes,yes,no,yes")
2214 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2216 (define_insn_and_split "mulsidi_600"
2217 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2218 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2219 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2220 (clobber (reg:DI R58_REG))]
2223 "TARGET_MUL64_SET && reload_completed"
2226 int hi = !TARGET_BIG_ENDIAN;
2228 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2229 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2230 emit_insn (gen_mul64 (operands[1], operands[2]));
2231 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2232 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2235 [(set_attr "type" "multi")
2236 (set_attr "length" "4,4,8")])
2238 (define_insn "mul64"
2239 [(set (reg:DI MUL64_OUT_REG)
2241 (sign_extend:DI (match_operand:SI 0 "register_operand" "%q, c,c, c"))
2242 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "q,cL,L,C32"))))]
2245 [(set_attr "length" "*,4,4,8")
2246 (set_attr "iscompact" "maybe,false,false,false")
2247 (set_attr "type" "multi,multi,multi,multi")
2248 (set_attr "predicable" "yes,yes,no,yes")
2249 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2251 (define_insn_and_split "umulsidi_600"
2252 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2253 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2254 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2255 (clobber (reg:DI R58_REG))]
2258 "TARGET_MUL64_SET && reload_completed"
2261 int hi = !TARGET_BIG_ENDIAN;
2263 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2264 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2265 emit_insn (gen_mulu64 (operands[1], operands[2]));
2266 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2267 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2270 [(set_attr "type" "umulti")
2271 (set_attr "length" "4,4,8")])
2273 (define_insn "mulu64"
2274 [(set (reg:DI MUL64_OUT_REG)
2276 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2277 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2279 "mulu64%?\\t0,%0,%1"
2280 [(set_attr "length" "4,4,8")
2281 (set_attr "iscompact" "false")
2282 (set_attr "type" "umulti")
2283 (set_attr "predicable" "yes,no,yes")
2284 (set_attr "cond" "canuse,canuse_limm,canuse")])
2286 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2287 ; may not be used as destination constraint.
2289 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2290 ; but mpyu is faster for the standard multiplier.
2291 ; Note: we must make sure LP_COUNT is not one of the destination
2292 ; registers, since it cannot be the destination of a multi-cycle insn
2294 (define_insn "mulsi3_700"
2295 [(set (match_operand:SI 0 "register_operand" "=r, r,r, r,r")
2296 (mult:SI (match_operand:SI 1 "register_operand" "%0, r,0, 0,r")
2297 (match_operand:SI 2 "nonmemory_operand" "rL,rL,I,Cal,Cal")))]
2300 [(set_attr "length" "4,4,4,8,8")
2301 (set_attr "type" "umulti")
2302 (set_attr "predicable" "yes,no,no,yes,no")
2303 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2305 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2306 ; short variant. LP_COUNT constraints are still valid.
2307 (define_insn "mulsi3_v2"
2308 [(set (match_operand:SI 0 "register_operand" "=q,q, r, r,r, r, r")
2309 (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, r")
2310 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,rL,I,Cal,Cal")))]
2320 [(set_attr "length" "*,*,4,4,4,8,8")
2321 (set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
2322 (set_attr "type" "umulti")
2323 (set_attr "predicable" "no,no,yes,no,no,yes,no")
2324 (set_attr "cond" "nocond,nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2326 (define_expand "mulsidi3"
2327 [(set (match_operand:DI 0 "register_operand" "")
2328 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2329 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2332 if (TARGET_PLUS_MACD)
2334 if (CONST_INT_P (operands[2]))
2336 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2340 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2346 operands[2] = force_reg (SImode, operands[2]);
2347 if (!register_operand (operands[0], DImode))
2349 rtx result = gen_reg_rtx (DImode);
2351 operands[2] = force_reg (SImode, operands[2]);
2352 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2353 emit_move_insn (operands[0], result);
2357 else if (TARGET_MUL64_SET)
2359 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2362 else if (TARGET_MULMAC_32BY16_SET)
2364 operands[2] = force_reg (SImode, operands[2]);
2365 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2368 operands[2] = force_reg (SImode, operands[2]);
2371 (define_insn_and_split "mulsidi64"
2372 [(set (match_operand:DI 0 "register_operand" "=w")
2373 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2374 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2375 (clobber (reg:DI MUL32x16_REG))]
2376 "TARGET_MULMAC_32BY16_SET"
2378 "TARGET_MULMAC_32BY16_SET && reload_completed"
2381 rtx result_hi = gen_highpart (SImode, operands[0]);
2382 rtx result_low = gen_lowpart (SImode, operands[0]);
2384 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2385 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2386 emit_move_insn (result_low, gen_acc2 ());
2389 [(set_attr "type" "multi")
2390 (set_attr "length" "8")])
2393 (define_insn "mul64_600"
2394 [(set (reg:DI MUL32x16_REG)
2395 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2397 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2402 "TARGET_MULMAC_32BY16_SET"
2404 [(set_attr "length" "4,4,8")
2405 (set_attr "type" "mulmac_600")
2406 (set_attr "predicable" "no,no,yes")
2407 (set_attr "cond" "nocond, canuse_limm, canuse")])
2410 ;; ??? check if this is canonical rtl
2411 (define_insn "mac64_600"
2412 [(set (reg:DI MUL32x16_REG)
2414 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2416 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2417 (const_int 16) (const_int 16))
2419 (reg:DI MUL32x16_REG)))
2420 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2423 (mult:DI (sign_extend:DI (match_dup 1))
2425 (sign_extract:DI (match_dup 2)
2426 (const_int 16) (const_int 16))
2428 (reg:DI MUL32x16_REG))
2429 (const_int 32) (const_int 32)))]
2430 "TARGET_MULMAC_32BY16_SET"
2431 "machlw%?\\t%0,%1,%2"
2432 [(set_attr "length" "4,4,8")
2433 (set_attr "type" "mulmac_600")
2434 (set_attr "predicable" "no,no,yes")
2435 (set_attr "cond" "nocond, canuse_limm, canuse")])
2438 ;; DI <- DI(signed SI) * DI(signed SI)
2439 (define_insn_and_split "mulsidi3_700"
2440 [(set (match_operand:DI 0 "register_operand" "=&r")
2441 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2442 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2443 "TARGET_MPY && !TARGET_PLUS_MACD"
2445 "&& reload_completed"
2448 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2449 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2450 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2451 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2452 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2453 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2456 [(set_attr "type" "multi")
2457 (set_attr "length" "8")])
2459 (define_insn "mulsi3_highpart"
2460 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2464 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2465 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2468 "mpy%+%?\\t%0,%1,%2"
2469 [(set_attr "length" "4,4,8,8")
2470 (set_attr "type" "multi")
2471 (set_attr "predicable" "yes,no,yes,no")
2472 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2474 ; Note that mpyhu has the same latency as mpy / mpyh,
2475 ; thus we use the type multi.
2476 (define_insn "*umulsi3_highpart_i"
2477 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2481 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2482 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2485 "mpy%+u%?\\t%0,%1,%2"
2486 [(set_attr "length" "4,4,8,8")
2487 (set_attr "type" "multi")
2488 (set_attr "predicable" "yes,no,yes,no")
2489 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2491 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2492 ;; need a separate pattern for immediates
2493 ;; ??? This is fine for combine, but not for reload.
2494 (define_insn "umulsi3_highpart_int"
2495 [(set (match_operand:SI 0 "register_operand" "=r, r, r,r, r")
2499 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, r, 0, 0, r"))
2500 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I,Cal,Cal"))
2503 "mpy%+u%?\\t%0,%1,%2"
2504 [(set_attr "length" "4,4,4,8,8")
2505 (set_attr "type" "multi")
2506 (set_attr "predicable" "yes,no,no,yes,no")
2507 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2509 (define_expand "umulsi3_highpart"
2510 [(set (match_operand:SI 0 "general_operand" "")
2514 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2515 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2520 rtx target = operands[0];
2522 if (!register_operand (target, SImode))
2523 target = gen_reg_rtx (SImode);
2525 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2526 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2527 operands[2], SImode);
2528 else if (!immediate_operand (operands[2], SImode))
2529 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2530 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2531 if (target != operands[0])
2532 emit_move_insn (operands[0], target);
2536 (define_expand "umulsidi3"
2537 [(set (match_operand:DI 0 "register_operand" "")
2538 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2539 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2542 if (TARGET_PLUS_MACD)
2544 if (CONST_INT_P (operands[2]))
2546 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2550 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2556 operands[2] = force_reg (SImode, operands[2]);
2557 if (!register_operand (operands[0], DImode))
2559 rtx result = gen_reg_rtx (DImode);
2561 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2562 emit_move_insn (operands[0], result);
2566 else if (TARGET_MUL64_SET)
2568 operands[2] = force_reg (SImode, operands[2]);
2569 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2572 else if (TARGET_MULMAC_32BY16_SET)
2574 operands[2] = force_reg (SImode, operands[2]);
2575 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2584 (define_insn_and_split "umulsidi64"
2585 [(set (match_operand:DI 0 "register_operand" "=w")
2586 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2587 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2588 (clobber (reg:DI MUL32x16_REG))]
2589 "TARGET_MULMAC_32BY16_SET"
2591 "TARGET_MULMAC_32BY16_SET && reload_completed"
2597 result_hi = gen_highpart (SImode, operands[0]);
2598 result_low = gen_lowpart (SImode, operands[0]);
2600 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2601 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2602 emit_move_insn (result_low, gen_acc2 ());
2605 [(set_attr "type" "multi")
2606 (set_attr "length" "8")])
2608 (define_insn "umul64_600"
2609 [(set (reg:DI MUL32x16_REG)
2610 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2612 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2617 "TARGET_MULMAC_32BY16_SET"
2619 [(set_attr "length" "4,4,8")
2620 (set_attr "type" "mulmac_600")
2621 (set_attr "predicable" "no")
2622 (set_attr "cond" "nocond")])
2625 (define_insn "umac64_600"
2626 [(set (reg:DI MUL32x16_REG)
2628 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2630 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2631 (const_int 16) (const_int 16))
2633 (reg:DI MUL32x16_REG)))
2634 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2637 (mult:DI (zero_extend:DI (match_dup 1))
2639 (zero_extract:DI (match_dup 2)
2640 (const_int 16) (const_int 16))
2642 (reg:DI MUL32x16_REG))
2643 (const_int 32) (const_int 32)))]
2644 "TARGET_MULMAC_32BY16_SET"
2645 "machulw%?\\t%0,%1,%2"
2646 [(set_attr "length" "4,4,8")
2647 (set_attr "type" "mulmac_600")
2648 (set_attr "predicable" "no,no,yes")
2649 (set_attr "cond" "nocond, canuse_limm, canuse")])
2651 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2652 (define_insn_and_split "umulsidi3_700"
2653 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2654 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2655 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2656 "TARGET_MPY && !TARGET_PLUS_MACD"
2658 "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed"
2661 int hi = !TARGET_BIG_ENDIAN;
2663 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2664 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2665 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2666 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2669 [(set_attr "type" "umulti")
2670 (set_attr "length" "8")])
2672 (define_expand "addsi3"
2673 [(set (match_operand:SI 0 "dest_reg_operand" "")
2674 (plus:SI (match_operand:SI 1 "register_operand" "")
2675 (match_operand:SI 2 "nonmemory_operand" "")))]
2678 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2679 operands[2] = force_reg (SImode, operands[2]);
2682 (define_expand "adddi3"
2684 [(set (match_operand:DI 0 "register_operand" "")
2685 (plus:DI (match_operand:DI 1 "register_operand" "")
2686 (match_operand:DI 2 "nonmemory_operand" "")))
2687 (clobber (reg:CC CC_REG))])])
2689 (define_insn_and_split "*adddi3"
2690 [(set (match_operand:DI 0 "register_operand" "")
2691 (plus:DI (match_operand:DI 1 "register_operand" "")
2692 (match_operand:DI 2 "nonmemory_operand" "")))
2693 (clobber (reg:CC CC_REG))]
2694 "arc_pre_reload_split ()"
2699 rtx l0 = gen_lowpart (SImode, operands[0]);
2700 rtx h0 = gen_highpart (SImode, operands[0]);
2701 rtx l1 = gen_lowpart (SImode, operands[1]);
2702 rtx h1 = gen_highpart (SImode, operands[1]);
2703 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2704 subreg_lowpart_offset (SImode, DImode));
2705 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2706 subreg_highpart_offset (SImode, DImode));
2708 if (l2 == const0_rtx)
2710 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2711 emit_move_insn (l0, l1);
2712 emit_insn (gen_addsi3 (h0, h1, h2));
2713 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2714 emit_move_insn (l0, l1);
2717 if (rtx_equal_p (l0, h1))
2719 if (h2 != const0_rtx)
2720 emit_insn (gen_addsi3 (h0, h1, h2));
2721 else if (!rtx_equal_p (h0, h1))
2722 emit_move_insn (h0, h1);
2723 emit_insn (gen_add_f (l0, l1, l2));
2727 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2728 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2731 emit_insn (gen_add_f (l0, l1, l2));
2732 emit_insn (gen_adc (h0, h1, h2));
2735 [(set_attr "length" "8")])
2737 (define_insn "add_f"
2738 [(set (reg:CC_C CC_REG)
2740 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,L,0,I,Cal,r")
2741 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0, r,rCal"))
2743 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2744 (plus:SI (match_dup 1) (match_dup 2)))]
2745 "register_operand (operands[1], SImode)
2746 || register_operand (operands[2], SImode)"
2754 [(set_attr "cond" "set")
2755 (set_attr "type" "compare")
2756 (set_attr "length" "4,4,4,4,8,8")])
2758 (define_insn "*add_f_2"
2759 [(set (reg:CC_C CC_REG)
2761 (plus:SI (match_operand:SI 1 "register_operand" "r ,0,r")
2762 (match_operand:SI 2 "nonmemory_operand" "rL,I,rCal"))
2764 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
2765 (plus:SI (match_dup 1) (match_dup 2)))]
2768 [(set_attr "cond" "set")
2769 (set_attr "type" "compare")
2770 (set_attr "length" "4,4,8")])
2773 [(set (match_operand:SI 0 "register_operand" "=r, r,r,r, r,r")
2776 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2777 (match_operand:SI 1 "nonmemory_operand" "%r, 0,r,0,Cal,r"))
2778 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I, r,Cal")))]
2779 "register_operand (operands[1], SImode)
2780 || register_operand (operands[2], SImode)"
2788 [(set_attr "cond" "use")
2789 (set_attr "type" "cc_arith")
2790 (set_attr "length" "4,4,4,4,8,8")])
2792 (define_insn "adc_f"
2793 [(set (reg:CC_C CC_REG)
2798 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2799 (match_operand:SI 1 "register_operand" "%r"))
2800 (match_operand:SI 2 "register_operand" "r")))
2802 (ltu:DI (reg:CC_C CC_REG) (const_int 0))
2803 (zero_extend:DI (match_dup 1)))))
2804 (set (match_operand:SI 0 "register_operand" "=r")
2807 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2812 [(set_attr "cond" "set")
2813 (set_attr "predicable" "no")
2814 (set_attr "type" "cc_arith")
2815 (set_attr "length" "4")])
2817 ; combiner-splitter cmp / scc -> cmp / adc
2819 [(set (match_operand:SI 0 "dest_reg_operand" "")
2820 (gtu:SI (match_operand:SI 1 "register_operand" "")
2821 (match_operand:SI 2 "register_operand" "")))
2822 (clobber (reg CC_REG))]
2824 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2825 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2827 ; combine won't work when an intermediate result is used later...
2828 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2830 [(set (match_operand:SI 0 "dest_reg_operand" "")
2831 (plus:SI (match_operand:SI 1 "register_operand" "")
2832 (match_operand:SI 2 "nonmemory_operand" "")))
2833 (set (reg:CC_C CC_REG)
2834 (compare:CC_C (match_dup 0)
2835 (match_operand:SI 3 "nonmemory_operand" "")))]
2836 "rtx_equal_p (operands[1], operands[3])
2837 || rtx_equal_p (operands[2], operands[3])"
2839 [(set (reg:CC_C CC_REG)
2840 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2842 (plus:SI (match_dup 1) (match_dup 2)))])])
2844 ; ??? need to delve into combine to find out why this is not useful.
2845 ; We'd like to be able to grok various C idioms for carry bit usage.
2846 ;(define_insn "*adc_0"
2847 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2848 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2849 ; (match_operand:SI 1 "register_operand" "c")))]
2852 ; [(set_attr "cond" "use")
2853 ; (set_attr "type" "cc_arith")
2854 ; (set_attr "length" "4")])
2857 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2858 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2859 ; (match_operand:SI 2 "register_operand" "c"))
2860 ; (match_operand:SI 3 "register_operand" "c")))
2861 ; (clobber (reg CC_REG))]
2863 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2864 ; (set (match_dup 0)
2865 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2868 (define_expand "subsi3"
2869 [(set (match_operand:SI 0 "dest_reg_operand" "")
2870 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2871 (match_operand:SI 2 "nonmemory_operand" "")))]
2877 if (!register_operand (operands[2], SImode))
2879 operands[1] = force_reg (SImode, operands[1]);
2882 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2883 operands[c] = force_reg (SImode, operands[c]);
2886 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2887 ; combine should make such an insn go away.
2888 (define_insn_and_split "subsi3_insn"
2889 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r, r,r,r,r, r, r, r")
2890 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,q,0,rL,r,L,I,Cal,Cal, r")
2891 (match_operand:SI 2 "nonmemory_operand" "q,q,r, 0,r,r,0, 0, r,Cal")))]
2892 "register_operand (operands[1], SImode)
2893 || register_operand (operands[2], SImode)"
2905 "reload_completed && get_attr_length (insn) == 8
2906 && satisfies_constraint_I (operands[1])
2907 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2908 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2909 "split_subsi (operands);"
2910 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2911 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2912 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2913 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2914 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2917 (define_expand "subdi3"
2918 [(set (match_operand:DI 0 "register_operand" "")
2919 (minus:DI (match_operand:DI 1 "register_operand" "")
2920 (match_operand:DI 2 "nonmemory_operand" "")))
2921 (clobber (reg:CC CC_REG))]
2924 rtx l0 = gen_lowpart (SImode, operands[0]);
2925 rtx h0 = gen_highpart (SImode, operands[0]);
2926 rtx l1 = gen_lowpart (SImode, operands[1]);
2927 rtx h1 = gen_highpart (SImode, operands[1]);
2928 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2929 subreg_lowpart_offset (SImode, DImode));
2930 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2931 subreg_highpart_offset (SImode, DImode));
2933 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2935 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2936 if (!rtx_equal_p (h0, h1))
2937 emit_insn (gen_rtx_SET (h0, h1));
2938 emit_insn (gen_sub_f (l0, l1, l2));
2942 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2943 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2946 emit_insn (gen_sub_f (l0, l1, l2));
2947 emit_insn (gen_sbc (h0, h1, h2));
2951 (define_insn "*sbc_0"
2952 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2953 (minus:SI (match_operand:SI 1 "register_operand" "c")
2954 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2958 [(set_attr "cond" "use")
2959 (set_attr "type" "cc_arith")
2960 (set_attr "length" "4")])
2963 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2966 (match_operand:SI 1 "nonmemory_operand" "r, 0,r,0, r,Cal")
2967 (ltu:SI (reg:CC_C CC_REG) (const_int 0)))
2968 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I,Cal,r")))]
2969 "register_operand (operands[1], SImode)
2970 || register_operand (operands[2], SImode)"
2978 [(set_attr "cond" "use")
2979 (set_attr "type" "cc_arith")
2980 (set_attr "length" "4,4,4,4,8,8")])
2982 (define_insn "sub_f"
2983 [(set (reg:CC CC_REG)
2984 (compare:CC (match_operand:SI 1 "nonmemory_operand" " r,L,0,I,r,Cal")
2985 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0,Cal,r")))
2986 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2987 (minus:SI (match_dup 1) (match_dup 2)))]
2988 "register_operand (operands[1], SImode)
2989 || register_operand (operands[2], SImode)"
2997 [(set_attr "type" "compare")
2998 (set_attr "length" "4,4,4,4,8,8")])
3000 ; combine won't work when an intermediate result is used later...
3001 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3003 [(set (reg:CC CC_REG)
3004 (compare:CC (match_operand:SI 1 "register_operand" "")
3005 (match_operand:SI 2 "nonmemory_operand" "")))
3006 (set (match_operand:SI 0 "dest_reg_operand" "")
3007 (minus:SI (match_dup 1) (match_dup 2)))]
3010 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3011 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3014 [(set (reg:CC CC_REG)
3015 (compare:CC (match_operand:SI 1 "register_operand" "")
3016 (match_operand:SI 2 "nonmemory_operand" "")))
3017 (set (match_operand 3 "" "") (match_operand 4 "" ""))
3018 (set (match_operand:SI 0 "dest_reg_operand" "")
3019 (minus:SI (match_dup 1) (match_dup 2)))]
3020 "!reg_overlap_mentioned_p (operands[3], operands[1])
3021 && !reg_overlap_mentioned_p (operands[3], operands[2])
3022 && !reg_overlap_mentioned_p (operands[0], operands[4])
3023 && !reg_overlap_mentioned_p (operands[0], operands[3])"
3025 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3026 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3027 (set (match_dup 3) (match_dup 4))])
3029 (define_insn "*add_n"
3030 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
3031 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
3032 (match_operand:SI 2 "_2_4_8_operand" ""))
3033 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
3035 "add%z2%?\\t%0,%3,%1"
3036 [(set_attr "type" "shift")
3037 (set_attr "length" "*,4,8")
3038 (set_attr "predicable" "yes,no,no")
3039 (set_attr "cond" "canuse,nocond,nocond")
3040 (set_attr "iscompact" "maybe,false,false")])
3042 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3043 ;; what synth_mult likes.
3044 (define_insn "*sub_n"
3045 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3046 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3047 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
3048 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3050 "sub%c3%?\\t%0,%1,%2"
3051 [(set_attr "type" "shift")
3052 (set_attr "length" "4,4,8")
3053 (set_attr "predicable" "yes,no,no")
3054 (set_attr "cond" "canuse,nocond,nocond")
3055 (set_attr "iscompact" "false")])
3057 (define_insn "*sub_n"
3058 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3059 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3060 (mult:SI (match_operand:SI 2 "register_operand" "r,r,r")
3061 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3063 "sub%z3%?\\t%0,%1,%2"
3064 [(set_attr "type" "shift")
3065 (set_attr "length" "4,4,8")
3066 (set_attr "predicable" "yes,no,no")
3067 (set_attr "cond" "canuse,nocond,nocond")
3068 (set_attr "iscompact" "false")])
3070 ; ??? check if combine matches this.
3071 (define_insn "*bset"
3072 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3073 (ior:SI (ashift:SI (const_int 1)
3074 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3075 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3078 [(set_attr "length" "4,4,8")
3079 (set_attr "predicable" "yes,no,no")
3080 (set_attr "cond" "canuse,nocond,nocond")]
3083 ; ??? check if combine matches this.
3084 (define_insn "*bxor"
3085 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3086 (xor:SI (ashift:SI (const_int 1)
3087 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3088 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3091 [(set_attr "length" "4,4,8")
3092 (set_attr "predicable" "yes,no,no")
3093 (set_attr "cond" "canuse,nocond,nocond")]
3096 ; ??? check if combine matches this.
3097 (define_insn "*bclr"
3098 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3099 (and:SI (not:SI (ashift:SI (const_int 1)
3100 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r")))
3101 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3104 [(set_attr "length" "4,4,8")
3105 (set_attr "predicable" "yes,no,no")
3106 (set_attr "cond" "canuse,nocond,nocond")]
3109 ; ??? FIXME: find combine patterns for bmsk.
3111 ;;Following are the define_insns added for the purpose of peephole2's
3113 ; see also iorsi3 for use with constant bit number.
3114 (define_insn "*bset_insn"
3115 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3116 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3117 (ashift:SI (const_int 1)
3118 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3121 bset%?\\t%0,%1,%2 ;;peep2, constr 1
3122 bset\\t%0,%1,%2 ;;peep2, constr 2
3123 bset\\t%0,%1,%2 ;;peep2, constr 3"
3124 [(set_attr "length" "4,4,8")
3125 (set_attr "predicable" "yes,no,no")
3126 (set_attr "cond" "canuse,nocond,nocond")]
3129 ; see also xorsi3 for use with constant bit number.
3130 (define_insn "*bxor_insn"
3131 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3132 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3133 (ashift:SI (const_int 1)
3134 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3140 [(set_attr "length" "4,4,8")
3141 (set_attr "predicable" "yes,no,no")
3142 (set_attr "cond" "canuse,nocond,nocond")]
3145 ; see also andsi3 for use with constant bit number.
3146 (define_insn "*bclr_insn"
3147 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3148 (and:SI (not:SI (ashift:SI (const_int 1)
3149 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")))
3150 (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")))]
3156 [(set_attr "length" "4,4,8")
3157 (set_attr "predicable" "yes,no,no")
3158 (set_attr "cond" "canuse,nocond,nocond")]
3161 ; see also andsi3 for use with constant bit number.
3162 (define_insn "*bmsk_insn"
3163 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3164 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3165 (plus:SI (ashift:SI (const_int 1)
3166 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3174 [(set_attr "length" "4,4,8")
3175 (set_attr "predicable" "yes,no,no")
3176 (set_attr "cond" "canuse,nocond,nocond")]
3179 ;;Instructions added for peephole2s end
3181 ;; Boolean instructions.
3183 (define_expand "andsi3"
3184 [(set (match_operand:SI 0 "dest_reg_operand" "")
3185 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3186 (match_operand:SI 2 "nonmemory_operand" "")))]
3188 "if (!satisfies_constraint_Cux (operands[2]))
3189 operands[1] = force_reg (SImode, operands[1]);
3192 (define_insn "andsi3_i" ;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
3193 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, q, q, r,r, r, r, r,r, r, r, r, r, q,r, r, r, W")
3194 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,q, 0, 0, q, 0,r, 0, 0, 0,0, r, r, r, r, q,0, 0, r, o")
3195 (match_operand:SI 2 "nonmemory_operand" "q,0,C1p,Ccp,Cux,rL,0,C2pC1p,Ccp,CnL,I,rL,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
3196 "(register_operand (operands[1], SImode)
3197 && nonmemory_operand (operands[2], SImode))
3198 || (memory_operand (operands[1], SImode)
3199 && satisfies_constraint_Cux (operands[2]))"
3201 switch (which_alternative)
3203 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3204 return "and%?\\t%0,%1,%2";
3206 return "and%?\\t%0,%2,%1";
3208 return "bmsk%?\\t%0,%1,%Z2";
3210 if (satisfies_constraint_C2p (operands[2]))
3212 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3213 return "bmskn%?\\t%0,%1,%Z2";
3217 return "bmsk%?\\t%0,%1,%Z2";
3219 case 3: case 8: case 13:
3220 return "bclr%?\\t%0,%1,%M2";
3222 return (INTVAL (operands[2]) == 0xff
3223 ? "extb%?\\t%0,%1" : "ext%_%?\\t%0,%1");
3224 case 9: case 14: return \"bic%?\\t%0,%1,%n2-1\";
3226 return "movb.cl\\t%0,%1,%p2,%p2,%x2";
3231 if (satisfies_constraint_Ucm (operands[1]))
3232 tmpl = (INTVAL (operands[2]) == 0xff
3233 ? "xldb%U1\\t%0,%1" : "xld%_%U1\\t%0,%1");
3235 tmpl = INTVAL (operands[2]) == 0xff ? "ldb\\t%0,%1" : "ld%_\\t%0,%1";
3237 if (TARGET_BIG_ENDIAN)
3241 xop[0] = operands[0];
3242 xop[1] = adjust_address (operands[1], QImode,
3243 INTVAL (operands[2]) == 0xff ? 3 : 2);
3244 output_asm_insn (tmpl, xop);
3252 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3253 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3254 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3255 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3256 (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3258 ; combiner splitter, pattern found in ldtoa.c .
3259 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3261 [(set (reg:CC_Z CC_REG)
3262 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3263 (match_operand 1 "const_int_operand" ""))
3264 (match_operand 2 "const_int_operand" "")))
3265 (clobber (match_operand:SI 3 "register_operand" ""))]
3266 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3268 (plus:SI (match_dup 0) (match_dup 4)))
3269 (set (reg:CC_Z CC_REG)
3270 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3272 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3274 ;;bic define_insn that allows limm to be the first operand
3275 (define_insn "*bicsi3_insn"
3276 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r,r,r,r")
3277 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "q,Lr,I,Cal,Lr,Cal,r"))
3278 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,r,r,Cal")))]
3281 bic%?\\t%0,%2,%1 ;;constraint 0
3282 bic%?\\t%0,%2,%1 ;;constraint 1
3283 bic\\t%0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3284 bic%?\\t%0,%2,%1 ;;constraint 3, FIXME: will it ever get generated ???
3285 bic\\t%0,%2,%1 ;;constraint 4
3286 bic\\t%0,%2,%1 ;;constraint 5, FIXME: will it ever get generated ???
3287 bic\\t%0,%2,%1 ;;constraint 6"
3288 [(set_attr "length" "*,4,4,8,4,8,8")
3289 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3290 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3291 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3293 (define_insn_and_split "iorsi3"
3294 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r,r, r,r, r, r,r, q, r, r")
3295 (ior:SI (match_operand:SI 1 "register_operand" "%0,q, 0, 0,r, 0,0, r, r,0, r, 0, r")
3296 (match_operand:SI 2 "nonmemory_operand" "q,0,C0p,rL,0,C0p,I,rL,C0p,I,C0x,Cal,Cal")))]
3313 && GET_CODE (PATTERN (insn)) != COND_EXEC
3314 && register_operand (operands[0], SImode)
3315 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
3316 && satisfies_constraint_C0x (operands[2])"
3319 arc_split_ior (operands);
3322 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,false")
3323 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,*,8,8")
3324 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
3325 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,nocond,canuse,nocond")])
3327 (define_insn "xorsi3"
3328 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, r,r, r,r, r, r,r, r, r")
3329 (xor:SI (match_operand:SI 1 "register_operand" "%0,q, 0,r, 0,0, r, r,0, 0, r")
3330 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,0,C0p,I,rL,C0p,I,Cal,Cal")))]
3333 switch (which_alternative)
3335 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3336 return \"xor%?\\t%0,%1,%2\";
3338 return \"xor%?\\t%0,%2,%1\";
3340 return \"bxor%?\\t%0,%1,%z2\";
3345 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3346 (set_attr "type" "binary")
3347 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3348 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3349 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3351 (define_insn "negsi2"
3352 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r")
3353 (neg:SI (match_operand:SI 1 "register_operand" "0,q,0,r")))]
3356 [(set_attr "type" "unary")
3357 (set_attr "iscompact" "maybe,true,false,false")
3358 (set_attr "predicable" "no,no,yes,no")])
3360 (define_insn "one_cmplsi2"
3361 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
3362 (not:SI (match_operand:SI 1 "register_operand" "q,c")))]
3365 [(set_attr "type" "unary,unary")
3366 (set_attr "iscompact" "true,false")])
3368 (define_insn_and_split "one_cmpldi2"
3369 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3370 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3373 "&& reload_completed"
3374 [(set (match_dup 2) (not:SI (match_dup 3)))
3375 (set (match_dup 4) (not:SI (match_dup 5)))]
3377 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3379 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3380 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3381 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3382 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3384 [(set_attr "type" "unary,unary")
3385 (set_attr "cond" "nocond,nocond")
3386 (set_attr "length" "4,8")])
3388 ;; Shift instructions.
3390 (define_code_iterator ANY_ROTATE [rotate rotatert])
3391 (define_code_iterator ANY_SHIFT_ROTATE [ashift ashiftrt lshiftrt
3394 (define_code_attr insn [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")
3395 (rotate "rotl") (rotatert "rotr")])
3397 (define_expand "<insn>si3"
3398 [(set (match_operand:SI 0 "dest_reg_operand" "")
3399 (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand" "")
3400 (match_operand:SI 2 "nonmemory_operand" "")))]
3403 ; asl, asr, lsr patterns:
3404 ; There is no point in including an 'I' alternative since only the lowest 5
3405 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3406 ; is defined in an external symbol, as we don't have special relocations
3407 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3408 ; provide one alternatice for this, without condexec support.
3409 (define_insn "*ashlsi3_insn"
3410 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3411 (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3412 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3413 "TARGET_BARREL_SHIFTER
3414 && (register_operand (operands[1], SImode)
3415 || register_operand (operands[2], SImode))"
3417 [(set_attr "type" "shift")
3418 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3419 (set_attr "predicable" "no,no,no,yes,no,no")
3420 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3422 (define_insn "*ashrsi3_insn"
3423 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3424 (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3425 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3426 "TARGET_BARREL_SHIFTER
3427 && (register_operand (operands[1], SImode)
3428 || register_operand (operands[2], SImode))"
3430 [(set_attr "type" "shift")
3431 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3432 (set_attr "predicable" "no,no,no,yes,no,no")
3433 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3435 (define_insn "*lshrsi3_insn"
3436 [(set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, r, r")
3437 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "q, 0, 0, r,rCal")
3438 (match_operand:SI 2 "nonmemory_operand" "N,qM,rL,rL,rCal")))]
3439 "TARGET_BARREL_SHIFTER
3440 && (register_operand (operands[1], SImode)
3441 || register_operand (operands[2], SImode))"
3448 [(set_attr "type" "shift")
3449 (set_attr "iscompact" "maybe,maybe,false,false,false")
3450 (set_attr "predicable" "no,no,yes,no,no")
3451 (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")])
3453 (define_insn "<insn>si2_cnt16"
3454 [(set (match_operand:SI 0 "register_operand" "=r")
3455 (ANY_ROTATE:SI (match_operand:SI 1 "register_operand" "r")
3459 [(set_attr "length" "4")
3460 (set_attr "type" "two_cycle_core")])
3462 (define_insn "ashlsi2_cnt16"
3463 [(set (match_operand:SI 0 "register_operand" "=r")
3464 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
3466 "TARGET_SWAP && TARGET_V2"
3468 [(set_attr "type" "shift")
3469 (set_attr "iscompact" "false")
3470 (set_attr "length" "4")
3471 (set_attr "predicable" "no")])
3473 (define_insn "lshrsi2_cnt16"
3474 [(set (match_operand:SI 0 "register_operand" "=r")
3475 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "rL")
3477 "TARGET_SWAP && TARGET_V2"
3479 [(set_attr "type" "shift")
3480 (set_attr "iscompact" "false")
3481 (set_attr "length" "4")
3482 (set_attr "predicable" "no")])
3484 ;; Split asl dst,1,src into bset dst,0,src.
3485 (define_insn_and_split "*ashlsi3_1"
3486 [(set (match_operand:SI 0 "dest_reg_operand")
3487 (ashift:SI (const_int 1)
3488 (match_operand:SI 1 "nonmemory_operand")))]
3489 "!TARGET_BARREL_SHIFTER
3490 && arc_pre_reload_split ()"
3494 (ior:SI (ashift:SI (const_int 1) (match_dup 1))
3497 [(set_attr "type" "shift")
3498 (set_attr "length" "8")])
3500 (define_insn_and_split "*<insn>si3_nobs"
3501 [(set (match_operand:SI 0 "dest_reg_operand")
3502 (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand")
3503 (match_operand:SI 2 "nonmemory_operand")))]
3504 "!TARGET_BARREL_SHIFTER
3505 && operands[2] != const1_rtx
3506 && arc_pre_reload_split ()"
3511 arc_split_<insn> (operands);
3515 ;; <ANY_SHIFT_ROTATE>si3_loop appears after <ANY_SHIFT_ROTATE>si3_nobs
3516 (define_insn "<insn>si3_loop"
3517 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3518 (ANY_SHIFT_ROTATE:SI
3519 (match_operand:SI 1 "register_operand" "0,0")
3520 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")))
3521 (clobber (reg:SI LP_COUNT))
3522 (clobber (reg:CC CC_REG))
3524 "!TARGET_BARREL_SHIFTER
3525 && operands[2] != const1_rtx"
3526 "* return output_shift_loop (<CODE>, operands);"
3527 [(set_attr "type" "shift")
3528 (set_attr "length" "16,20")])
3532 (define_expand "ashldi3"
3534 [(set (match_operand:DI 0 "register_operand")
3535 (ashift:DI (match_operand:DI 1 "register_operand")
3536 (match_operand:QI 2 "const_int_operand")))
3537 (clobber (reg:CC CC_REG))])]
3540 if (operands[2] != const1_rtx)
3544 (define_insn_and_split "*ashldi3_cnt1"
3545 [(set (match_operand:DI 0 "register_operand")
3546 (ashift:DI (match_operand:DI 1 "register_operand")
3548 (clobber (reg:CC CC_REG))]
3549 "arc_pre_reload_split ()"
3552 [(parallel [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 1)))
3553 (clobber (reg:CC CC_REG))])]
3555 [(set_attr "length" "8")])
3557 (define_expand "ashrdi3"
3559 [(set (match_operand:DI 0 "register_operand")
3560 (ashiftrt:DI (match_operand:DI 1 "register_operand")
3561 (match_operand:QI 2 "const_int_operand")))
3562 (clobber (reg:CC CC_REG))])]
3565 if (operands[2] != const1_rtx)
3569 ;; Split into asr.f hi; rrc lo
3570 (define_insn_and_split "*ashrdi3_cnt1"
3571 [(set (match_operand:DI 0 "register_operand")
3572 (ashiftrt:DI (match_operand:DI 1 "register_operand")
3574 (clobber (reg:CC CC_REG))]
3575 "arc_pre_reload_split ()"
3580 emit_insn (gen_ashrsi3_cnt1_carry (gen_highpart (SImode, operands[0]),
3581 gen_highpart (SImode, operands[1])));
3582 emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]),
3583 gen_lowpart (SImode, operands[1])));
3586 [(set_attr "length" "8")])
3588 (define_expand "lshrdi3"
3590 [(set (match_operand:DI 0 "register_operand")
3591 (lshiftrt:DI (match_operand:DI 1 "register_operand")
3592 (match_operand:QI 2 "const_int_operand")))
3593 (clobber (reg:CC CC_REG))])]
3596 if (operands[2] != const1_rtx)
3600 ;; Split into lsr.f hi; rrc lo
3601 (define_insn_and_split "*lshrdi3_cnt1"
3602 [(set (match_operand:DI 0 "register_operand")
3603 (lshiftrt:DI (match_operand:DI 1 "register_operand")
3605 (clobber (reg:CC CC_REG))]
3606 "arc_pre_reload_split ()"
3611 emit_insn (gen_lshrsi3_cnt1_carry (gen_highpart (SImode, operands[0]),
3612 gen_highpart (SImode, operands[1])));
3613 emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]),
3614 gen_lowpart (SImode, operands[1])));
3617 [(set_attr "length" "8")])
3619 ;; Rotate instructions.
3621 (define_insn "rotrsi3_insn"
3622 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
3623 (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz")
3624 (match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))]
3625 "TARGET_BARREL_SHIFTER"
3627 [(set_attr "type" "shift,shift,shift")
3628 (set_attr "predicable" "yes,no,no")
3629 (set_attr "length" "4,4,8")])
3631 (define_insn_and_split "*rotlsi3"
3632 [(set (match_operand:SI 0 "dest_reg_operand")
3633 (rotate:SI (match_operand:SI 1 "register_operand")
3634 (match_operand:SI 2 "nonmemory_operand")))]
3635 "TARGET_BARREL_SHIFTER
3636 && arc_pre_reload_split ()"
3639 [(set (match_dup 0) (rotatert:SI (match_dup 1) (match_dup 3)))]
3641 if (CONST_INT_P (operands[2]))
3643 int n = INTVAL (operands[2]) & 31;
3646 emit_move_insn (operands[0], operands[1]);
3649 else operands[3] = GEN_INT (32 - n);
3653 if (!register_operand (operands[2], SImode))
3654 operands[2] = force_reg (SImode, operands[2]);
3655 operands[3] = gen_reg_rtx (SImode);
3656 emit_insn (gen_negsi2 (operands[3], operands[2]));
3660 ;; Rotate through carry flag
3662 (define_insn "rrcsi2"
3663 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3665 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3667 (ashift:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
3671 [(set_attr "type" "shift")
3672 (set_attr "predicable" "no")
3673 (set_attr "length" "4")])
3675 (define_insn "rrcsi2_carry"
3676 [(set (reg:CC_C CC_REG)
3677 (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
3678 (const_int 1))] UNSPEC_ARC_CC_NEZ))
3679 (set (match_operand:SI 0 "dest_reg_operand" "=r")
3681 (lshiftrt:SI (match_dup 1) (const_int 1))
3682 (ashift:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
3686 [(set_attr "type" "shift")
3687 (set_attr "predicable" "no")
3688 (set_attr "length" "4")])
3690 ;; DImode Rotate instructions
3692 (define_expand "rotldi3"
3694 [(set (match_operand:DI 0 "register_operand")
3695 (rotate:DI (match_operand:DI 1 "register_operand")
3696 (match_operand:QI 2 "const_int_operand")))
3697 (clobber (reg:CC CC_REG))])]
3700 if (operands[2] != const1_rtx)
3704 ;; split into add.f lo; adc.f hi; adc lo
3705 (define_insn_and_split "*rotldi3_cnt1"
3706 [(set (match_operand:DI 0 "register_operand")
3707 (rotate:DI (match_operand:DI 1 "register_operand")
3709 (clobber (reg:CC CC_REG))]
3710 "arc_pre_reload_split ()"
3715 rtx lo0 = gen_lowpart (SImode, operands[0]);
3716 rtx lo1 = gen_lowpart (SImode, operands[1]);
3717 rtx hi1 = gen_highpart (SImode, operands[1]);
3718 emit_insn (gen_add_f (lo0, lo1, lo1));
3719 emit_insn (gen_adc_f (gen_highpart (SImode, operands[0]), hi1, hi1));
3720 emit_insn (gen_adc (lo0, lo0, const0_rtx));
3723 [(set_attr "length" "12")])
3725 (define_expand "rotrdi3"
3727 [(set (match_operand:DI 0 "register_operand")
3728 (rotatert:DI (match_operand:DI 1 "register_operand")
3729 (match_operand:QI 2 "const_int_operand")))
3730 (clobber (reg:CC CC_REG))])]
3733 if (operands[2] != const1_rtx)
3737 ;; split into asr.f lo; rrc.f hi; rrc lo
3738 (define_insn_and_split "*rotrdi3_cnt1"
3739 [(set (match_operand:DI 0 "register_operand")
3740 (rotatert:DI (match_operand:DI 1 "register_operand")
3742 (clobber (reg:CC CC_REG))]
3743 "arc_pre_reload_split ()"
3748 rtx lo = gen_lowpart (SImode, operands[1]);
3749 emit_insn (gen_btst_0_carry (lo));
3750 emit_insn (gen_rrcsi2_carry (gen_highpart (SImode, operands[0]),
3751 gen_highpart (SImode, operands[1])));
3752 emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]), lo));
3755 [(set_attr "length" "12")])
3757 ;; Compare / branch instructions.
3759 (define_expand "cbranchsi4"
3760 [(set (reg:CC CC_REG)
3761 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3762 (match_operand:SI 2 "nonmemory_operand" "")))
3765 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3767 (label_ref (match_operand 3 "" ""))
3771 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3772 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3773 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3774 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3778 ;; ??? Could add a peephole to generate compare with swapped operands and
3779 ;; modifed cc user if second, but not first operand is a compact register.
3780 (define_insn "cmpsi_cc_insn_mixed"
3781 [(set (reg:CC CC_REG)
3782 (compare:CC (match_operand:SI 0 "register_operand" "q, q, h, c, c, q,c")
3783 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,cL,Cal,Cal")))]
3786 [(set_attr "type" "compare")
3787 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3788 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3789 (set_attr "cond" "set")
3790 (set_attr "length" "*,*,*,4,4,*,8")
3791 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3793 (define_insn "*cmpsi_cc_zn_insn"
3794 [(set (reg:CC_ZN CC_REG)
3795 (compare:CC_ZN (match_operand:SI 0 "register_operand" "q,c")
3799 [(set_attr "type" "compare,compare")
3800 (set_attr "iscompact" "true,false")
3801 (set_attr "predicable" "no,yes")
3802 (set_attr "cond" "set_zn")
3803 (set_attr "length" "*,4")])
3805 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3806 (define_insn "*btst"
3807 [(set (reg:CC_ZN CC_REG)
3809 (zero_extract:SI (match_operand:SI 0 "register_operand" "q,c")
3811 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3815 [(set_attr "iscompact" "true,false")
3816 (set_attr "predicable" "no,yes")
3817 (set_attr "cond" "set")
3818 (set_attr "type" "compare")
3819 (set_attr "length" "*,4")])
3821 (define_insn "*cmpsi_cc_z_insn"
3822 [(set (reg:CC_Z CC_REG)
3823 (compare:CC_Z (match_operand:SI 0 "register_operand" "q,c")
3824 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3829 [(set_attr "type" "compare,compare")
3830 (set_attr "iscompact" "true,false")
3831 (set_attr "cond" "set,set_zn")
3832 (set_attr "length" "*,4")])
3834 (define_insn "*cmpsi_cc_c_insn"
3835 [(set (reg:CC_C CC_REG)
3836 (compare:CC_C (match_operand:SI 0 "register_operand" "q, q, h, c, q, c")
3837 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,Cal,Cal")))]
3840 [(set_attr "type" "compare")
3841 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3842 (set_attr "cond" "set")
3843 (set_attr "length" "*,*,*,4,*,8")
3844 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3846 ;; Next come the scc insns.
3848 (define_expand "cstoresi4"
3849 [(set (match_operand:SI 0 "dest_reg_operand" "")
3850 (match_operator:SI 1 "ordered_comparison_operator"
3851 [(match_operand:SI 2 "nonmemory_operand" "")
3852 (match_operand:SI 3 "nonmemory_operand" "")]))]
3855 if (!TARGET_CODE_DENSITY)
3857 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3858 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3859 operands[1] = gen_compare_reg (operands[1], SImode);
3860 emit_insn (gen_scc_insn (operands[0], operands[1]));
3863 if (!register_operand (operands[2], SImode))
3864 operands[2] = force_reg (SImode, operands[2]);
3868 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3869 (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")])
3871 (define_expand "cstore<mode>4"
3872 [(set (reg:CC CC_REG)
3873 (compare:CC (match_operand:SDF 2 "register_operand" "")
3874 (match_operand:SDF 3 "register_operand" "")))
3875 (set (match_operand:SI 0 "dest_reg_operand" "")
3876 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3879 "TARGET_HARD_FLOAT || TARGET_OPTFPE"
3881 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3882 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3883 operands[1] = gen_compare_reg (operands[1], SImode);
3884 emit_insn (gen_scc_insn (operands[0], operands[1]));
3888 ; We need a separate expander for this lest we loose the mode of CC_REG
3889 ; when match_operator substitutes the literal operand into the comparison.
3890 (define_expand "scc_insn"
3891 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3893 (define_mode_iterator CC_ltu [CC_C CC])
3895 (define_insn "scc_ltu_<mode>"
3896 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3897 (ltu:SI (reg:CC_ltu CC_REG) (const_int 0)))]
3900 [(set_attr "type" "shift")
3901 (set_attr "predicable" "no")
3902 (set_attr "length" "4")])
3904 (define_insn_and_split "*scc_insn"
3905 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3906 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3910 && GET_CODE (operands[1]) != LTU"
3911 [(set (match_dup 0) (const_int 1))
3914 (set (match_dup 0) (const_int 0)))]
3917 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3918 GET_MODE (XEXP (operands[1], 0))),
3920 XEXP (operands[1], 0), XEXP (operands[1], 1));
3922 [(set_attr "type" "unary")])
3924 ; cond_exec patterns
3925 (define_insn "*movsi_ne"
3927 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0))
3928 (set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, q, r")
3929 (match_operand:SI 1 "nonmemory_operand" "C_0, h, Lr,Cal,Cal")))]
3932 * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\";
3933 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3935 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3937 [(set_attr "type" "cmove")
3938 (set_attr "iscompact" "true,true,false,true_limm,false")
3939 (set_attr "length" "2,2,4,6,8")
3940 (set_attr "cpu_facility" "*,av2,*,av2,*")])
3942 (define_insn "*movsi_cond_exec"
3944 (match_operator 3 "proper_comparison_operator"
3945 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3946 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3947 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3950 [(set_attr "type" "cmove")
3951 (set_attr "length" "4,8")])
3953 (define_insn "*commutative_cond_exec"
3955 (match_operator 5 "proper_comparison_operator"
3956 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3957 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3958 (match_operator:SI 3 "commutative_operator"
3959 [(match_operand:SI 1 "register_operand" "%0,0")
3960 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3963 arc_output_commutative_cond_exec (operands, true);
3966 [(set_attr "cond" "use")
3967 (set_attr "type" "cmove")
3968 (set_attr_alternative "length"
3971 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3976 (define_insn "*sub_cond_exec"
3978 (match_operator 4 "proper_comparison_operator"
3979 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3980 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3981 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3982 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3987 rsub.%d4\\t%0,%2,%1"
3988 [(set_attr "cond" "use")
3989 (set_attr "type" "cmove")
3990 (set_attr "length" "4,4,8")])
3992 (define_insn "*noncommutative_cond_exec"
3994 (match_operator 5 "proper_comparison_operator"
3995 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3996 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3997 (match_operator:SI 3 "noncommutative_operator"
3998 [(match_operand:SI 1 "register_operand" "0,0")
3999 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
4001 "%O3.%d5\\t%0,%1,%2"
4002 [(set_attr "cond" "use")
4003 (set_attr "type" "cmove")
4004 (set_attr "length" "4,8")])
4006 ;; These control RTL generation for conditional jump insns
4007 ;; Match both normal and inverted jump.
4009 ; We need a separate expander for this lest we loose the mode of CC_REG
4010 ; when match_operator substitutes the literal operand into the comparison.
4011 (define_expand "branch_insn"
4013 (if_then_else (match_operand 1 "" "")
4014 (label_ref (match_operand 0 "" ""))
4017 ; When estimating sizes during arc_reorg, when optimizing for speed, there
4018 ; are three reasons why we need to consider branches to be length 6:
4019 ; - annull-false delay slot insns are implemented using conditional execution,
4020 ; thus preventing short insn formation where used.
4021 ; - for ARC600: annull-true delay slot isnns are implemented where possile
4022 ; using conditional execution, preventing short insn formation where used.
4023 ; - for ARC700: likely or somewhat likely taken branches are made long and
4024 ; unaligned if possible to avoid branch penalty.
4025 (define_insn "*branch_insn"
4027 (if_then_else (match_operator 1 "proper_comparison_operator"
4028 [(reg CC_REG) (const_int 0)])
4029 (label_ref (match_operand 0 "" ""))
4034 if (get_attr_length (insn) == 2)
4035 return \"b%d1%?\\t%l0\";
4037 return \"b%d1%*\\t%l0\";
4039 [(set_attr "type" "branch")
4043 (eq_attr "delay_slot_filled" "yes")
4048 (match_operand 1 "equality_comparison_operator" "")
4049 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4050 (gt (minus (match_dup 0) (pc))
4051 (minus (const_int 506)
4052 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4053 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
4054 (lt (minus (match_dup 0) (pc)) (const_int -64))
4055 (gt (minus (match_dup 0) (pc))
4056 (minus (const_int 58)
4057 (symbol_ref "get_attr_delay_slot_length (insn)")))))
4062 (set (attr "iscompact")
4063 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
4064 (const_string "false")))])
4066 (define_insn "*rev_branch_insn"
4068 (if_then_else (match_operator 1 "proper_comparison_operator"
4069 [(reg CC_REG) (const_int 0)])
4071 (label_ref (match_operand 0 "" ""))))]
4072 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
4074 [(set_attr "type" "branch")
4078 (eq_attr "delay_slot_filled" "yes")
4083 (match_operand 1 "equality_comparison_operator" "")
4084 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4085 (gt (minus (match_dup 0) (pc))
4086 (minus (const_int 506)
4087 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4088 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
4089 (lt (minus (match_dup 0) (pc)) (const_int -64))
4090 (gt (minus (match_dup 0) (pc))
4091 (minus (const_int 58)
4092 (symbol_ref "get_attr_delay_slot_length (insn)")))))
4097 (set (attr "iscompact")
4098 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
4099 (const_string "false")))])
4101 ;; Unconditional and other jump instructions.
4103 (define_expand "jump"
4104 [(set (pc) (label_ref (match_operand 0 "" "")))]
4108 (define_insn "jump_i"
4109 [(set (pc) (label_ref (match_operand 0 "" "")))]
4110 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
4112 [(set_attr "type" "uncond_branch")
4113 (set (attr "iscompact")
4114 (if_then_else (match_test "get_attr_length (insn) == 2")
4115 (const_string "true") (const_string "false")))
4116 (set_attr "cond" "canuse")
4117 (set (attr "length")
4119 ; In arc_reorg we just guesstimate; might be more or less than 4.
4120 (match_test "arc_branch_size_unknown_p ()")
4123 (eq_attr "delay_slot_filled" "yes")
4126 (match_test "CROSSING_JUMP_P (insn)")
4129 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4130 (gt (minus (match_dup 0) (pc))
4131 (minus (const_int 506)
4132 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4136 (define_insn "indirect_jump"
4137 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,q,r"))]
4145 [(set_attr "type" "jump")
4146 (set_attr "iscompact" "false,false,false,maybe,false")
4147 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
4149 ;; Implement a switch statement.
4150 (define_expand "casesi"
4151 [(match_operand:SI 0 "register_operand" "") ; Index
4152 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
4153 (match_operand:SI 2 "const_int_operand" "") ; Total range
4154 (match_operand:SI 3 "" "") ; Table label
4155 (match_operand:SI 4 "" "")] ; Out of range label
4158 if (operands[1] != const0_rtx)
4160 rtx reg = gen_reg_rtx (SImode);
4161 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
4164 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0],
4166 operands[0], operands[2], operands[4]));
4168 emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3]));
4171 rtx reg = gen_reg_rtx (SImode);
4172 rtx lbl = operands[3];
4173 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4175 operands[3] = force_reg (Pmode, operands[3]);
4176 emit_insn (gen_casesi_load (reg,
4177 operands[3], operands[0], lbl));
4178 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4179 emit_insn (gen_addsi3 (reg, reg, operands[3]));
4180 emit_jump_insn (gen_casesi_jump (reg, lbl));
4185 (define_insn "casesi_dispatch"
4187 (unspec:SI [(match_operand:SI 0 "register_operand" "r")
4188 (label_ref (match_operand 1 "" ""))]
4189 UNSPEC_ARC_CASESI))]
4192 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4193 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4194 switch (GET_MODE (diff_vec))
4197 return \"bi\\t[%0]\";
4200 return \"bih\\t[%0]\";
4201 default: gcc_unreachable ();
4204 [(set_attr "type" "brcc_no_delay_slot")
4205 (set_attr "iscompact" "false")
4206 (set_attr "length" "4")])
4208 (define_insn "casesi_load"
4209 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
4210 (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal")
4211 (match_operand:SI 2 "register_operand" "q,r,r")]
4212 UNSPEC_ARC_CASESI)))
4213 (use (label_ref (match_operand 3 "" "")))]
4217 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4219 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4221 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4222 gcc_assert (GET_MODE (diff_vec) == SImode);
4223 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4226 switch (GET_MODE (diff_vec))
4229 return \"ld.as\\t%0,[%1,%2]\";
4231 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4232 return \"ld%_.as\\t%0,[%1,%2]\";
4233 return \"ld%_.x.as\\t%0,[%1,%2]\";
4235 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4236 return \"ldb%?\\t%0,[%1,%2]\";
4237 return \"ldb.x\\t%0,[%1,%2]\";
4242 [(set_attr "type" "load")
4243 (set_attr_alternative "iscompact"
4245 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4246 (as_a<rtx_insn *> (operands[3]))))")
4247 (symbol_ref "QImode"))
4248 (const_string "false")
4249 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4250 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4251 (const_string "false")]
4252 (const_string "true"))
4253 (const_string "false")
4254 (const_string "false")])
4255 (set_attr_alternative "length"
4257 [(eq_attr "iscompact" "false") (const_int 4)
4258 ; We have to mention (match_dup 3) to convince genattrtab.cc that this
4259 ; is a varying length insn.
4260 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4261 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4266 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4267 ; even for CASE_VECTOR_PC_RELATIVE.
4268 (define_insn "casesi_jump"
4269 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,q,c"))
4270 (use (label_ref (match_operand 1 "" "")))]
4273 [(set_attr "type" "jump")
4274 (set_attr "iscompact" "false,maybe,false")
4275 (set_attr "cond" "canuse")])
4277 (define_expand "call"
4278 ;; operands[1] is stack_size_rtx
4279 ;; operands[2] is next_arg_register
4280 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4281 (match_operand 1 "" ""))
4282 (clobber (reg:SI 31))])]
4287 gcc_assert (MEM_P (operands[0]));
4288 callee = XEXP (operands[0], 0);
4289 /* This is to decide if we should generate indirect calls by loading the
4290 32 bit address of the callee into a register before performing the
4291 branch and link - this exposes cse opportunities.
4292 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4293 if (GET_CODE (callee) != REG
4294 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4295 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4299 ; At instruction output time, if it doesn't match and we end up with
4300 ; alternative 1 ("q"), that means that we can't use the short form.
4301 (define_insn "*call_i"
4302 [(call (mem:SI (match_operand:SI 0
4303 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4304 (match_operand 1 "" ""))
4305 (clobber (reg:SI 31))]
4317 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4318 (set_attr "iscompact" "maybe,*,true,*,*,*,*,*,*")
4319 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4320 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4322 (define_expand "call_value"
4323 ;; operand 2 is stack_size_rtx
4324 ;; operand 3 is next_arg_register
4325 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4326 (call (match_operand:SI 1 "call_operand" "")
4327 (match_operand 2 "" "")))
4328 (clobber (reg:SI 31))])]
4334 gcc_assert (MEM_P (operands[1]));
4335 callee = XEXP (operands[1], 0);
4336 /* See the comment in define_expand \"call\". */
4337 if (GET_CODE (callee) != REG
4338 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4339 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4342 ; At instruction output time, if it doesn't match and we end up with
4343 ; alternative 1 ("q"), that means that we can't use the short form.
4344 (define_insn "*call_value_i"
4345 [(set (match_operand 0 "dest_reg_operand" "=q,w, w, w, w, w,w,w, w")
4346 (call (mem:SI (match_operand:SI 1
4347 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4348 (match_operand 2 "" "")))
4349 (clobber (reg:SI 31))]
4361 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4362 (set_attr "iscompact" "maybe,*,true,false,*,*,*,*,*")
4363 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4364 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4366 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4367 ; use it for lack of inter-procedural branch shortening.
4368 ; Link-time relaxation would help...
4371 [(trap_if (const_int 1) (const_int 0))]
4372 "!TARGET_ARC600_FAMILY"
4374 [(set_attr "type" "misc")
4375 (set_attr "length" "2")])
4381 [(set_attr "type" "misc")
4382 (set_attr "iscompact" "true")
4383 (set_attr "cond" "canuse")
4384 (set_attr "length" "2")])
4387 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4390 [(set_attr "type" "misc")
4391 (set_attr "iscompact" "maybe")
4392 (set_attr "length" "*")])
4394 (define_insn "blockage"
4395 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)]
4398 [(set_attr "length" "0")
4399 (set_attr "type" "block")]
4402 (define_insn "arc600_stall"
4403 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_ARC600_STALL)]
4405 "mov\\t0,mlo\t;wait until multiply complete."
4406 [(set_attr "length" "4")
4407 (set_attr "type" "move")]
4410 ;; Split up troublesome insns for better scheduling.
4412 ;; Peepholes go at the end.
4413 ;;asl followed by add can be replaced by an add{1,2,3}
4414 ;; Three define_peepholes have been added for this optimization
4415 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4416 ;; can be generated by combine. Check if these peepholes still provide
4419 ;; -------------------------------------------------------------
4420 ;; Pattern 1 : r0 = r1 << {i}
4421 ;; r3 = r4/INT + r0 ;;and commutative
4424 ;; add{i} r3,r4/INT,r1
4425 ;; -------------------------------------------------------------
4426 ;; ??? This should be covered by combine, alas, at times combine gets
4427 ;; too clever for it's own good: when the shifted input is known to be
4428 ;; either 0 or 1, the operation will be made into an if-then-else, and
4429 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4430 ;; newlib/libc/time/mktm_r.c .
4433 [(set (match_operand:SI 0 "dest_reg_operand" "")
4434 (ashift:SI (match_operand:SI 1 "register_operand" "")
4435 (match_operand:SI 2 "_1_2_3_operand" "")))
4436 (set (match_operand:SI 3 "dest_reg_operand" "")
4437 (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
4438 (match_operand:SI 5 "arc_nonmemory_operand" "")))]
4439 "(true_regnum (operands[4]) == true_regnum (operands[0])
4440 || true_regnum (operands[5]) == true_regnum (operands[0]))
4441 && (peep2_reg_dead_p (2, operands[0])
4442 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4443 ;; the preparation statements take care to put proper operand in
4444 ;; operands[4] operands[4] will always contain the correct
4445 ;; operand. This is added to satisfy commutativity
4447 (plus:SI (mult:SI (match_dup 1)
4450 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4451 operands[4] = operands[5];
4452 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4455 ;; -------------------------------------------------------------
4456 ;; Pattern 1 : r0 = r1 << {i}
4461 ;; -------------------------------------------------------------
4462 ;; ??? This should be covered by combine, alas, at times combine gets
4463 ;; too clever for it's own good: when the shifted input is known to be
4464 ;; either 0 or 1, the operation will be made into an if-then-else, and
4465 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4466 ;; newlib/libm/math/e_jn.c .
4469 [(set (match_operand:SI 0 "dest_reg_operand" "")
4470 (ashift:SI (match_operand:SI 1 "register_operand" "")
4471 (match_operand:SI 2 "const_int_operand" "")))
4472 (set (match_operand:SI 3 "dest_reg_operand" "")
4473 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4475 "(INTVAL (operands[2]) == 1
4476 || INTVAL (operands[2]) == 2
4477 || INTVAL (operands[2]) == 3)
4478 && (peep2_reg_dead_p (2, operands[0])
4479 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4481 (minus:SI (match_dup 4)
4482 (mult:SI (match_dup 1)
4484 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4489 ; When using the high single bit, the result of a multiply is either
4490 ; the original number or zero. But MPY costs 4 cycles, which we
4491 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4493 [(set (match_operand:SI 0 "dest_reg_operand" "")
4494 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4496 (set (match_operand:SI 4 "register_operand" "")
4497 (mult:SI (match_operand:SI 2 "register_operand")
4498 (match_operand:SI 3 "nonmemory_operand" "")))]
4500 && (rtx_equal_p (operands[0], operands[2])
4501 || rtx_equal_p (operands[0], operands[3]))
4502 && peep2_regno_dead_p (0, CC_REG)
4503 && (rtx_equal_p (operands[0], operands[4])
4504 || (peep2_reg_dead_p (2, operands[0])
4505 && peep2_reg_dead_p (1, operands[4])))"
4506 [(parallel [(set (reg:CC_Z CC_REG)
4507 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4509 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4511 (ne (reg:CC_Z CC_REG) (const_int 0))
4512 (set (match_dup 4) (match_dup 5)))]
4514 if (!rtx_equal_p (operands[0], operands[2]))
4515 operands[5] = operands[2];
4516 else if (!rtx_equal_p (operands[0], operands[3]))
4517 operands[5] = operands[3];
4519 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4523 [(set (match_operand:SI 0 "dest_reg_operand" "")
4524 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4526 (set (match_operand:SI 4 "register_operand" "")
4527 (mult:SI (match_operand:SI 2 "register_operand")
4528 (match_operand:SI 3 "nonmemory_operand" "")))]
4530 && (rtx_equal_p (operands[0], operands[2])
4531 || rtx_equal_p (operands[0], operands[3]))
4532 && peep2_regno_dead_p (2, CC_REG)"
4533 [(parallel [(set (reg:CC_Z CC_REG)
4534 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4536 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4537 (set (match_dup 4) (match_dup 5))
4539 (eq (reg:CC_Z CC_REG) (const_int 0))
4540 (set (match_dup 4) (const_int 0)))]
4541 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4543 ;; Instructions generated through builtins
4545 (define_insn "clrsbsi2"
4546 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4547 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))]
4550 [(set_attr "length" "4,8")
4551 (set_attr "type" "two_cycle_core,two_cycle_core")])
4553 (define_insn "norm_f"
4554 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4555 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))
4556 (set (reg:CC_ZN CC_REG)
4557 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4560 [(set_attr "length" "4,8")
4561 (set_attr "type" "two_cycle_core,two_cycle_core")])
4563 (define_insn_and_split "clrsbhi2"
4564 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4565 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4569 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4570 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4572 (define_insn "normw"
4573 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4575 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4580 [(set_attr "length" "4,8")
4581 (set_attr "type" "two_cycle_core,two_cycle_core")])
4583 (define_expand "clzsi2"
4585 [(set (match_operand:SI 0 "register_operand" "")
4586 (clz:SI (match_operand:SI 1 "register_operand" "")))
4587 (clobber (match_dup 2))])]
4592 /* ARCv2's FLS is a bit more optimal than using norm. */
4593 rtx tmp = gen_reg_rtx (SImode);
4594 emit_insn (gen_fls (tmp, operands[1]));
4595 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), tmp));
4598 operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);
4601 (define_insn_and_split "*arc_clzsi2"
4602 [(set (match_operand:SI 0 "register_operand" "=r")
4603 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4604 (clobber (reg:CC_ZN CC_REG))]
4610 emit_insn (gen_norm_f (operands[0], operands[1]));
4614 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4615 gen_rtx_SET (operands[0], const0_rtx)));
4619 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4620 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4623 [(set_attr "type" "unary")
4624 (set_attr "length" "12")])
4626 (define_expand "ctzsi2"
4627 [(match_operand:SI 0 "register_operand" "")
4628 (match_operand:SI 1 "register_operand" "")]
4633 emit_insn (gen_ffs (operands[0], operands[1]));
4636 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4640 (define_insn_and_split "arc_ctzsi2"
4641 [(set (match_operand:SI 0 "register_operand" "=r")
4642 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4643 (clobber (reg:CC_ZN CC_REG))
4644 (clobber (match_scratch:SI 2 "=&r"))]
4650 rtx temp = operands[0];
4652 if (reg_overlap_mentioned_p (temp, operands[1])
4653 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4654 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4657 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4658 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4659 emit_insn (gen_clrsbsi2 (operands[0], temp));
4663 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4664 gen_rtx_SET (operands[0], GEN_INT (32))));
4668 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4669 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4673 [(set_attr "type" "unary")
4674 (set_attr "length" "20")])
4676 (define_insn "divaw"
4677 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4678 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4679 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4681 "TARGET_ARC700 || TARGET_EA_SET"
4686 [(set_attr "length" "4,8,8")
4687 (set_attr "type" "divaw,divaw,divaw")])
4690 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4697 [(set_attr "length" "4,4,8")
4698 (set_attr "type" "misc,misc,misc")
4699 (set_attr "predicable" "yes,no,yes")
4700 (set_attr "cond" "clob,clob,clob")])
4703 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4707 [(set_attr "length" "4")
4708 (set_attr "type" "misc")])
4712 (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)]
4713 "!TARGET_ARC600_FAMILY"
4715 [(set_attr "length" "4")
4716 (set_attr "type" "rtie")
4717 (set_attr "cond" "clob")])
4720 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4724 [(set_attr "length" "4")
4725 (set_attr "type" "misc")])
4728 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4738 [(set_attr "length" "4")
4739 (set_attr "type" "misc")])
4742 (define_insn "sleep"
4743 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "Lr")]
4747 [(set_attr "length" "4")
4748 (set_attr "type" "misc")])
4750 (define_insn "core_read"
4751 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4752 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4753 VUNSPEC_ARC_CORE_READ))]
4756 if (check_if_valid_regno_const (operands, 1))
4757 return \"mov \t%0, r%1\";
4758 return \"mov \t%0, r%1\";
4760 [(set_attr "length" "4")
4761 (set_attr "type" "unary")])
4763 (define_insn "core_write"
4764 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4765 (match_operand:SI 1 "general_operand" "Hn,!r")]
4766 VUNSPEC_ARC_CORE_WRITE)]
4769 if (check_if_valid_regno_const (operands, 1))
4770 return \"mov\\tr%1,%0\";
4771 return \"mov\\tr%1,%0\";
4773 [(set_attr "length" "4")
4774 (set_attr "type" "unary")])
4777 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4778 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4782 [(set_attr "length" "4,8,4,8")
4783 (set_attr "type" "lr,lr,lr,lr")])
4786 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4787 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4791 [(set_attr "length" "8,4,8,4")
4792 (set_attr "type" "sr,sr,sr,sr")])
4794 (define_mode_iterator ALLI [QI HI SI (DI "TARGET_LL64")])
4795 (define_mode_attr mALLI [(QI "b") (HI "%_") (SI "") (DI "d")])
4797 (define_insn "lddi<mode>"
4798 [(set (match_operand:ALLI 0 "register_operand" "=r")
4799 (unspec_volatile:ALLI [(match_operand:ALLI 1 "memory_operand" "m")]
4802 "ld<mALLI>%U1.di\\t%0,%1"
4803 [(set_attr "type" "load")])
4805 (define_insn "stdi<mode>"
4806 [(unspec_volatile [(match_operand:ALLI 0 "memory_operand" "m,m,Usc")
4807 (match_operand:ALLI 1 "nonmemory_operand" "r,Cm3,i")]
4810 "st<mALLI>%U0.di\\t%1,%0"
4811 [(set_attr "length" "*,*,8")
4812 (set_attr "type" "store")])
4814 (define_insn_and_split "*stdidi_split"
4815 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")
4816 (match_operand:DI 1 "register_operand" "r")]
4820 "&& reload_completed"
4821 [(unspec_volatile:SI [(match_dup 2) (match_dup 3)] VUNSPEC_ARC_STDI)
4822 (unspec_volatile:SI [(match_dup 4) (match_dup 5)] VUNSPEC_ARC_STDI)]
4825 operands[3] = gen_lowpart (SImode, operands[1]);
4826 operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
4827 operands[2] = gen_lowpart (SImode, operands[0]);
4828 operands[4] = gen_highpart (SImode, operands[0]);
4833 (define_insn_and_split "*lddidi_split"
4834 [(set (match_operand:DI 0 "register_operand" "=r")
4835 (unspec_volatile:DI [(match_operand:DI 1 "memory_operand" "m")]
4839 "&& reload_completed"
4840 [(set (match_dup 2) (unspec_volatile:SI [(match_dup 3)] VUNSPEC_ARC_LDDI))
4841 (set (match_dup 4) (unspec_volatile:SI [(match_dup 5)] VUNSPEC_ARC_LDDI))]
4844 operands[3] = gen_lowpart (SImode, operands[1]);
4845 operands[5] = gen_highpart (SImode, operands[1]);
4846 operands[2] = gen_lowpart (SImode, operands[0]);
4847 operands[4] = gen_highpart (SImode, operands[0]);
4852 (define_insn "trap_s"
4853 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4854 VUNSPEC_ARC_TRAP_S)]
4855 "!TARGET_ARC600_FAMILY"
4857 if (which_alternative == 0)
4859 return \"trap_s\\t%0\";
4862 /* Keep this message in sync with the one in arc.cc:arc_expand_builtin,
4863 because *.md files do not get scanned by exgettext. */
4864 fatal_error (input_location,
4865 \"operand to %<trap_s%> should be an unsigned 6-bit value\");
4867 [(set_attr "length" "2")
4868 (set_attr "type" "misc")])
4870 (define_insn "unimp_s"
4871 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4872 VUNSPEC_ARC_UNIMP_S)]
4873 "!TARGET_ARC600_FAMILY"
4875 [(set_attr "length" "4")
4876 (set_attr "type" "misc")])
4878 ;; End of instructions generated through builtins
4880 ; Since the demise of REG_N_SETS as reliable data readily available to the
4881 ; target, it is no longer possible to find out
4882 ; in the prologue / epilogue expanders how many times blink is set.
4883 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4884 ; any explicit use of blink will cause it to be saved; hence we cannot
4885 ; represent the blink use in return / sibcall instructions themselves, and
4886 ; instead have to show it in EPILOGUE_USES and must explicitly
4887 ; forbid instructions that change blink in the return / sibcall delay slot.
4888 (define_expand "sibcall"
4889 [(parallel [(call (match_operand 0 "memory_operand" "")
4890 (match_operand 1 "general_operand" ""))
4892 (use (match_operand 2 "" ""))])]
4896 rtx callee = XEXP (operands[0], 0);
4898 if (operands[2] == NULL_RTX)
4899 operands[2] = const0_rtx;
4900 if (GET_CODE (callee) != REG
4901 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4902 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4906 (define_expand "sibcall_value"
4907 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4908 (call (match_operand 1 "memory_operand" "")
4909 (match_operand 2 "general_operand" "")))
4911 (use (match_operand 3 "" ""))])]
4915 rtx callee = XEXP (operands[1], 0);
4917 if (operands[3] == NULL_RTX)
4918 operands[3] = const0_rtx;
4919 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4920 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4924 (define_insn "*sibcall_insn"
4925 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4926 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4927 (match_operand 1 "" ""))
4929 (use (match_operand 2 "" ""))]
4937 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4938 (set_attr "predicable" "yes,no,no,yes,yes")
4939 (set_attr "iscompact" "false,false,maybe,false,false")
4940 (set_attr "is_SIBCALL" "yes")]
4943 (define_insn "*sibcall_value_insn"
4944 [(set (match_operand 0 "dest_reg_operand" "")
4945 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4946 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4947 (match_operand 2 "" "")))
4949 (use (match_operand 3 "" ""))]
4957 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4958 (set_attr "predicable" "yes,no,no,yes,yes")
4959 (set_attr "iscompact" "false,false,maybe,false,false")
4960 (set_attr "is_SIBCALL" "yes")]
4963 (define_expand "prologue"
4967 arc_expand_prologue ();
4971 (define_expand "epilogue"
4975 arc_expand_epilogue (0);
4979 (define_expand "sibcall_epilogue"
4983 arc_expand_epilogue (1);
4987 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4988 ; in the prologue / epilogue expanders how many times blink is set.
4989 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4990 ; any explicit use of blink will cause it to be saved; hence we cannot
4991 ; represent the blink use in return / sibcall instructions themselves, and
4992 ; instead have to show it in EPILOGUE_USES and must explicitly
4993 ; forbid instructions that change blink in the return / sibcall delay slot.
4994 (define_insn "simple_return"
4998 [(set_attr "type" "return")
4999 (set_attr "cond" "canuse")
5000 (set_attr "iscompact" "maybe")
5001 (set_attr "length" "*")])
5003 (define_insn "arc600_rtie"
5005 (unspec_volatile [(match_operand 0 "pmode_register_operand" "")]
5006 VUNSPEC_ARC_ARC600_RTIE)]
5007 "TARGET_ARC600_FAMILY"
5009 [(set_attr "length" "4")
5010 (set_attr "type" "rtie")
5011 (set_attr "cond" "clob")])
5013 (define_insn "p_return_i"
5015 (if_then_else (match_operator 0 "proper_comparison_operator"
5016 [(reg CC_REG) (const_int 0)])
5017 (simple_return) (pc)))]
5019 "j%d0%!%*\\t[blink]"
5020 [(set_attr "type" "return")
5021 (set_attr "cond" "use")
5022 (set_attr "iscompact" "maybe" )
5023 (set (attr "length")
5024 (cond [(not (match_operand 0 "equality_comparison_operator" ""))
5026 (eq_attr "delay_slot_filled" "yes")
5030 ;; Return nonzero if this function is known to have a null epilogue.
5031 ;; This allows the optimizer to omit jumps to jumps if no stack
5033 (define_expand "return"
5035 "arc_can_use_return_insn ()"
5038 ;; Comment in final.cc (insn_current_reference_address) says
5039 ;; forward branch addresses are calculated from the next insn after branch
5040 ;; and for backward branches, it is calculated from the branch insn start.
5041 ;; The shortening logic here is tuned to accomodate this behavior
5042 ;; ??? This should be grokked by the ccfsm machinery.
5043 (define_insn "cbranchsi4_scratch"
5045 (if_then_else (match_operator 0 "proper_comparison_operator"
5046 [(match_operand:SI 1 "register_operand" "c,c, c")
5047 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
5048 (label_ref (match_operand 3 "" ""))
5050 (clobber (match_operand 4 "cc_register" ""))]
5052 || (TARGET_EARLY_CBRANCHSI
5053 && brcc_nolimm_operator (operands[0], VOIDmode)))
5054 && !CROSSING_JUMP_P (insn)"
5056 switch (get_attr_length (insn))
5058 case 2: return \"br%d0%?\\t%1,%2,%l3\";
5059 case 4: return \"br%d0%*\\t%1,%B2,%l3\";
5060 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5061 return \"br%d0%*\\t%1,%B2,%l3\";
5064 case 12:return \"cmp%?\\t%1,%B2\\n\\tb%d0%*\\t%l3 ;br%d0 out of range\";
5065 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5068 [(set_attr "cond" "clob, clob, clob")
5071 (match_test "valid_brcc_with_delay_p (operands)")
5072 (const_string "brcc")
5073 (const_string "brcc_no_delay_slot")))
5074 ; For forward branches, we need to account not only for the distance to
5075 ; the target, but also the difference between pcl and pc, the instruction
5076 ; length, and any delay insn, if present.
5079 (cond ; the outer cond does a test independent of branch shortening.
5080 [(match_operand 0 "brcc_nolimm_operator" "")
5082 [(and (match_operand:CC_Z 4 "cc_register")
5083 (eq_attr "delay_slot_filled" "no")
5084 (ge (minus (match_dup 3) (pc)) (const_int -128))
5085 (le (minus (match_dup 3) (pc))
5086 (minus (const_int 122)
5087 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5089 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5090 (le (minus (match_dup 3) (pc))
5091 (minus (const_int 244)
5092 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5094 (and (match_operand:SI 1 "compact_register_operand" "")
5095 (match_operand:SI 2 "compact_hreg_operand" ""))
5098 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5099 (le (minus (match_dup 3) (pc)) (const_int 244)))
5101 (and (match_operand:SI 1 "compact_register_operand" "")
5102 (match_operand:SI 2 "compact_hreg_operand" ""))
5105 (set (attr "iscompact")
5106 (if_then_else (match_test "get_attr_length (insn) & 2")
5107 (const_string "true") (const_string "false")))])
5109 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5110 (define_insn "*bbit"
5113 (match_operator 3 "equality_comparison_operator"
5114 [(zero_extract:SI (match_operand:SI 1 "register_operand" "q,c")
5116 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5118 (label_ref (match_operand 0 "" ""))
5120 (clobber (reg:CC_ZN CC_REG))]
5121 "!CROSSING_JUMP_P (insn)"
5123 switch (get_attr_length (insn))
5125 case 4: return (GET_CODE (operands[3]) == EQ
5126 ? \"bbit0%*\\t%1,%2,%0\" : \"bbit1%*\\t%1,%2,%0\");
5128 case 8: return \"btst%?\\t%1,%2\n\tb%d3%*\\t%0; bbit out of range\";
5129 default: gcc_unreachable ();
5132 [(set_attr "type" "brcc")
5133 (set_attr "cond" "clob")
5134 (set (attr "length")
5135 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5136 (le (minus (match_dup 0) (pc))
5137 (minus (const_int 248)
5138 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5140 (eq (symbol_ref "which_alternative") (const_int 0))
5143 (set (attr "iscompact")
5144 (if_then_else (match_test "get_attr_length (insn) == 6")
5145 (const_string "true") (const_string "false")))])
5147 ;; -------------------------------------------------------------------
5149 ;; -------------------------------------------------------------------
5151 ; operand 0 is the loop count pseudo register
5152 ; operand 1 is the label to jump to at the top of the loop
5153 (define_expand "doloop_end"
5154 [(parallel [(set (pc)
5156 (ne (match_operand 0 "nonimmediate_operand")
5158 (label_ref (match_operand 1 "" ""))
5160 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5161 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5162 (clobber (match_dup 2))])]
5165 if (GET_MODE (operands[0]) != SImode)
5167 operands[2] = gen_rtx_SCRATCH (SImode);
5170 (define_insn "arc_lp"
5171 [(unspec:SI [(reg:SI LP_COUNT)]
5173 (use (label_ref (match_operand 0 "" "")))
5174 (use (label_ref (match_operand 1 "" "")))]
5176 "lp\\t@%l1\\t; lp_count:@%l0->@%l1"
5177 [(set_attr "type" "loop_setup")
5178 (set_attr "length" "4")])
5180 ;; if by any chance the lp_count is not used, then use an 'r'
5181 ;; register, instead of going to memory.
5182 ;; split pattern for the very slim chance when the loop register is
5184 (define_insn_and_split "loop_end"
5186 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m")
5188 (label_ref (match_operand 1 "" ""))
5190 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5191 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5192 (clobber (match_scratch:SI 2 "=X,&r"))]
5195 ; ZOL_END, begins @%l1
5197 "reload_completed && memory_operand (operands[0], Pmode)"
5198 [(set (match_dup 2) (match_dup 0))
5200 [(set (reg:CC_ZN CC_REG)
5201 (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1))
5203 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
5204 (set (match_dup 0) (match_dup 2))
5206 (if_then_else (ne (reg:CC_ZN CC_REG)
5208 (label_ref (match_dup 1))
5211 [(set_attr "length" "0,24")
5212 (set_attr "predicable" "no")
5213 (set_attr "type" "loop_end")])
5215 (define_insn "loop_fail"
5216 [(set (reg:SI LP_COUNT)
5217 (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5218 (set (reg:CC_ZN CC_REG)
5219 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5222 "sub.f%?\\tlp_count,lp_count,1"
5223 [(set_attr "iscompact" "false")
5224 (set_attr "type" "compare")
5225 (set_attr "cond" "set_zn")
5226 (set_attr "length" "4")
5227 (set_attr "predicable" "yes")])
5229 (define_insn_and_split "dbnz"
5232 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m")
5235 (label_ref (match_operand 1 "" ""))
5238 (plus:SI (match_dup 0)
5240 (clobber (match_scratch:SI 2 "=X,r"))]
5245 "TARGET_DBNZ && reload_completed && memory_operand (operands[0], SImode)"
5246 [(set (match_dup 2) (match_dup 0))
5247 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5248 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5249 (set (match_dup 0) (match_dup 2))
5250 (set (pc) (if_then_else (ge (reg:CC CC_REG)
5252 (label_ref (match_dup 1))
5255 [(set_attr "iscompact" "false")
5256 (set_attr "type" "loop_end")
5257 (set_attr "length" "4,20")])
5259 (define_expand "cpymemsi"
5260 [(match_operand:BLK 0 "" "")
5261 (match_operand:BLK 1 "" "")
5262 (match_operand:SI 2 "nonmemory_operand" "")
5263 (match_operand 3 "immediate_operand" "")]
5265 "if (arc_expand_cpymem (operands)) DONE; else FAIL;")
5267 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5268 ;; to the point that we can generate cmove instructions.
5269 (define_expand "cbranch<mode>4"
5270 [(set (reg:CC CC_REG)
5271 (compare:CC (match_operand:SDF 1 "register_operand" "")
5272 (match_operand:SDF 2 "register_operand" "")))
5275 (match_operator 0 "comparison_operator" [(reg CC_REG)
5277 (label_ref (match_operand 3 "" ""))
5280 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5282 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5283 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5284 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5285 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5289 (define_expand "cmp_float"
5290 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5291 (clobber (reg:SI RETURN_ADDR_REGNUM))
5292 (clobber (reg:SI R12_REG))])]
5296 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5297 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5298 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5300 (define_insn "*cmpsf_<cmp>"
5301 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5302 (clobber (reg:SI RETURN_ADDR_REGNUM))
5303 (clobber (reg:SI R12_REG))]
5304 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5305 && SFUNC_CHECK_PREDICABLE"
5306 "*return arc_output_libcall (\"__<cmp>sf2\");"
5307 [(set_attr "is_sfunc" "yes")
5308 (set_attr "predicable" "yes")])
5310 ;; N.B. for "*cmpdf_ord":
5311 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5312 ;; for the floating point emulation to recognize the NaN.
5313 (define_insn "*cmpdf_<cmp>"
5314 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5315 (clobber (reg:SI RETURN_ADDR_REGNUM))
5316 (clobber (reg:SI R12_REG))]
5317 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5318 && SFUNC_CHECK_PREDICABLE"
5319 "*return arc_output_libcall (\"__<cmp>df2\");"
5320 [(set_attr "is_sfunc" "yes")
5321 (set_attr "predicable" "yes")])
5323 (define_insn "abssf2"
5324 [(set (match_operand:SF 0 "dest_reg_operand" "=q,r,r")
5325 (abs:SF (match_operand:SF 1 "register_operand" "0,0,r")))]
5328 [(set_attr "type" "unary")
5329 (set_attr "iscompact" "maybe,false,false")
5330 (set_attr "length" "2,4,4")
5331 (set_attr "predicable" "no,yes,no")])
5333 (define_insn "negsf2"
5334 [(set (match_operand:SF 0 "dest_reg_operand" "=r,r")
5335 (neg:SF (match_operand:SF 1 "register_operand" "0,r")))]
5338 [(set_attr "type" "unary")
5339 (set_attr "predicable" "yes,no")])
5341 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5342 (define_insn "*millicode_thunk_st"
5343 [(match_parallel 0 "millicode_store_operation"
5344 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5347 output_asm_insn ("bl%* __st_r13_to_%0",
5348 &SET_SRC (XVECEXP (operands[0], 0,
5349 XVECLEN (operands[0], 0) - 2)));
5352 [(set_attr "type" "call")])
5354 (define_insn "*millicode_thunk_ld"
5355 [(match_parallel 0 "millicode_load_clob_operation"
5356 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5359 output_asm_insn ("bl%* __ld_r13_to_%0",
5360 &SET_DEST (XVECEXP (operands[0], 0,
5361 XVECLEN (operands[0], 0) - 2)));
5364 [(set_attr "type" "call")])
5366 ; the sibthunk restores blink, so we use the return rtx.
5367 (define_insn "*millicode_sibthunk_ld"
5368 [(match_parallel 0 "millicode_load_operation"
5370 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5371 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5374 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5375 &SET_DEST (XVECEXP (operands[0], 0,
5376 XVECLEN (operands[0], 0) - 1)));
5379 [(set_attr "type" "call")
5380 (set_attr "is_SIBCALL" "yes")])
5382 ;; For thread pointer builtins
5383 (define_expand "get_thread_pointersi"
5384 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5386 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5388 (define_expand "set_thread_pointersi"
5389 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5391 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5393 ;; If hardware floating point is available, don't define a negdf pattern;
5394 ;; it would be something like:
5395 ;;(define_insn "negdf2"
5396 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5397 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5398 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5401 ;; bxor%? %H0,%H1,31
5402 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5403 ;; drsubh%F0%F1 0,0,0
5404 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5405 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5406 ;; (set_attr "iscompact" "false,false,false,false")
5407 ;; (set_attr "length" "4,4,8,12")
5408 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5409 ;; and this suffers from always requiring a long immediate when using
5410 ;; the floating point hardware.
5411 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5412 ;; constant zero efficiently into a register when we want to do the
5413 ;; computation using the floating point hardware. There should be a special
5414 ;; subdf alternative that matches a zero operand 1, which then can allow
5415 ;; to use bxor to flip the high bit of an integer register.
5416 ;; ??? we actually can't use the floating point hardware for neg, because
5417 ;; this would not work right for -0. OTOH optabs.cc has already code
5418 ;; to synthesyze negate by flipping the sign bit.
5421 (define_insn "bswapsi2"
5422 [(set (match_operand:SI 0 "register_operand" "= r,r")
5423 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5424 "TARGET_V2 && TARGET_SWAP"
5426 [(set_attr "length" "4,8")
5427 (set_attr "type" "two_cycle_core")])
5429 (define_expand "prefetch"
5430 [(prefetch (match_operand:SI 0 "address_operand" "")
5431 (match_operand:SI 1 "const_int_operand" "")
5432 (match_operand:SI 2 "const_int_operand" ""))]
5436 (define_insn "prefetch_1"
5437 [(prefetch (match_operand:SI 0 "register_operand" "r")
5438 (match_operand:SI 1 "const_int_operand" "n")
5439 (match_operand:SI 2 "const_int_operand" "n"))]
5442 if ((INTVAL (operands[1]) & 1) != 0)
5443 return "prefetchw [%0]";
5445 return "prefetch [%0]";
5447 [(set_attr "type" "load")
5448 (set_attr "length" "4")])
5450 (define_insn "prefetch_2"
5451 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5452 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5453 (match_operand:SI 2 "const_int_operand" "n,n,n")
5454 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5457 if ((INTVAL (operands[2]) & 1) != 0)
5458 return "prefetchw\\t[%0, %1]";
5460 return "prefetch\\t[%0, %1]";
5462 [(set_attr "type" "load")
5463 (set_attr "length" "4,4,8")])
5465 (define_insn "prefetch_3"
5466 [(prefetch (match_operand:SI 0 "address_operand" "p")
5467 (match_operand:SI 1 "const_int_operand" "n")
5468 (match_operand:SI 2 "const_int_operand" "n"))]
5471 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5472 if ((INTVAL (operands[1]) & 1) != 0)
5473 return "prefetchw%U0\\t%0";
5475 return "prefetch%U0\\t%0";
5477 [(set_attr "type" "load")
5478 (set_attr "length" "8")])
5480 (define_insn "divsi3"
5481 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5482 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5483 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5486 [(set_attr "length" "4,4,8,4,4,4,8,8")
5487 (set_attr "iscompact" "false")
5488 (set_attr "type" "div_rem")
5489 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5490 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5493 (define_insn "udivsi3"
5494 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5495 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5496 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5499 [(set_attr "length" "4,4,8,4,4,4,8,8")
5500 (set_attr "iscompact" "false")
5501 (set_attr "type" "div_rem")
5502 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5503 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5506 (define_insn "modsi3"
5507 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5508 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5509 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5512 [(set_attr "length" "4,4,8,4,4,4,8,8")
5513 (set_attr "iscompact" "false")
5514 (set_attr "type" "div_rem")
5515 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5516 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5519 (define_insn "umodsi3"
5520 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5521 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5522 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5525 [(set_attr "length" "4,4,8,4,4,4,8,8")
5526 (set_attr "iscompact" "false")
5527 (set_attr "type" "div_rem")
5528 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5529 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5532 ;; SETcc instructions
5533 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5535 (define_insn "arcset<code>"
5536 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5537 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5538 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5539 "TARGET_V2 && TARGET_CODE_DENSITY"
5540 "set<code>%?\\t%0,%1,%2"
5541 [(set_attr "length" "4,4,4,4,4,8,8")
5542 (set_attr "iscompact" "false")
5543 (set_attr "type" "compare")
5544 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5545 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5548 (define_insn "arcsetltu"
5549 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5550 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5551 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5552 "TARGET_V2 && TARGET_CODE_DENSITY"
5553 "setlo%?\\t%0,%1,%2"
5554 [(set_attr "length" "4,4,4,4,4,8,8")
5555 (set_attr "iscompact" "false")
5556 (set_attr "type" "compare")
5557 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5558 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5561 (define_insn "arcsetgeu"
5562 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5563 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5564 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5565 "TARGET_V2 && TARGET_CODE_DENSITY"
5566 "seths%?\\t%0,%1,%2"
5567 [(set_attr "length" "4,4,4,4,4,8,8")
5568 (set_attr "iscompact" "false")
5569 (set_attr "type" "compare")
5570 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5571 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5574 ;; Special cases of SETCC
5575 (define_insn_and_split "arcsethi"
5576 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5577 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5578 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5579 "TARGET_V2 && TARGET_CODE_DENSITY"
5580 "setlo%?\\t%0,%2,%1"
5582 && CONST_INT_P (operands[2])
5583 && satisfies_constraint_C62 (operands[2])"
5586 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5587 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5588 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5591 [(set_attr "length" "4,4,4,8")
5592 (set_attr "iscompact" "false")
5593 (set_attr "type" "compare")
5594 (set_attr "predicable" "yes,no,no,no")
5595 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5598 (define_insn_and_split "arcsetls"
5599 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5600 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5601 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5602 "TARGET_V2 && TARGET_CODE_DENSITY"
5603 "seths%?\\t%0,%2,%1"
5605 && CONST_INT_P (operands[2])
5606 && satisfies_constraint_C62 (operands[2])"
5609 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5610 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5611 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5614 [(set_attr "length" "4,4,4,8")
5615 (set_attr "iscompact" "false")
5616 (set_attr "type" "compare")
5617 (set_attr "predicable" "yes,no,no,no")
5618 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5621 ; Any mode that needs to be solved by secondary reload
5622 (define_mode_iterator SRI [QI HI])
5624 (define_expand "reload_<mode>_load"
5625 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5626 (match_operand:SRI 1 "memory_operand" "m")
5627 (match_operand:SI 2 "register_operand" "=&r")])]
5630 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5634 (define_expand "reload_<mode>_store"
5635 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5636 (match_operand:SRI 1 "register_operand" "r")
5637 (match_operand:SI 2 "register_operand" "=&r")])]
5640 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5644 (define_insn "extzvsi"
5645 [(set (match_operand:SI 0 "register_operand" "=r , r,r,r")
5646 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r,r,0")
5647 (match_operand:SI 2 "const_int_operand" "C3p,C3p,n,n")
5648 (match_operand:SI 3 "const_int_operand" "n , n,n,n")))]
5649 "TARGET_HS && TARGET_BARREL_SHIFTER"
5651 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5652 operands[2] = GEN_INT (assemble_op2);
5653 return "xbfu%?\\t%0,%1,%2";
5655 [(set_attr "type" "shift")
5656 (set_attr "iscompact" "false")
5657 (set_attr "length" "4,4,8,8")
5658 (set_attr "predicable" "yes,no,no,yes")
5659 (set_attr "cond" "canuse,nocond,nocond,canuse_limm")])
5661 (define_insn "kflag"
5662 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5669 [(set_attr "length" "4,4,8")
5670 (set_attr "type" "misc,misc,misc")
5671 (set_attr "predicable" "yes,no,yes")
5672 (set_attr "cond" "clob,clob,clob")])
5675 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5676 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5680 [(set_attr "length" "4")
5681 (set_attr "type" "misc")])
5684 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5685 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5687 "TARGET_NORM && TARGET_V2"
5689 [(set_attr "length" "4,8")
5690 (set_attr "type" "two_cycle_core,two_cycle_core")])
5692 (define_insn "ffs_f"
5693 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5694 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5696 (set (reg:CC_ZN CC_REG)
5697 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5698 "TARGET_NORM && TARGET_V2"
5700 [(set_attr "length" "4,8")
5701 (set_attr "type" "two_cycle_core,two_cycle_core")])
5703 (define_expand "ffssi2"
5704 [(parallel [(set (match_dup 2)
5705 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5707 (set (reg:CC_ZN CC_REG)
5708 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5709 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5710 (set (match_operand:SI 0 "dest_reg_operand" "")
5711 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5714 "TARGET_NORM && TARGET_V2"
5716 operands[2] = gen_reg_rtx (SImode);
5720 [(set (match_operand:SI 0 "register_operand" "=r,r")
5721 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "rL,Cal")]
5723 "TARGET_NORM && TARGET_V2"
5725 [(set_attr "length" "4,8")
5726 (set_attr "type" "two_cycle_core,two_cycle_core")])
5729 [(unspec_volatile:SI [(match_operand:SI 0 "nonmemory_operand" "rL")]
5733 [(set_attr "length" "4")
5734 (set_attr "type" "misc")])
5739 (define_expand "addsf3"
5740 [(set (match_operand:SF 0 "register_operand" "")
5741 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5742 (match_operand:SF 2 "nonmemory_operand" "")))]
5743 "TARGET_FP_SP_BASE || TARGET_SPFP"
5745 if (!register_operand (operands[1], SFmode)
5746 && !register_operand (operands[2], SFmode))
5747 operands[1] = force_reg (SFmode, operands[1]);
5751 (define_expand "subsf3"
5752 [(set (match_operand:SF 0 "register_operand" "")
5753 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5754 (match_operand:SF 2 "nonmemory_operand" "")))]
5755 "TARGET_FP_SP_BASE || TARGET_SPFP"
5757 if (!register_operand (operands[1], SFmode)
5758 && !register_operand (operands[2], SFmode))
5759 operands[1] = force_reg (SFmode, operands[1]);
5763 (define_expand "mulsf3"
5764 [(set (match_operand:SF 0 "register_operand" "")
5765 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5766 (match_operand:SF 2 "nonmemory_operand" "")))]
5767 "TARGET_FP_SP_BASE || TARGET_SPFP"
5769 if (!register_operand (operands[1], SFmode)
5770 && !register_operand (operands[2], SFmode))
5771 operands[1] = force_reg (SFmode, operands[1]);
5775 (define_expand "adddf3"
5776 [(set (match_operand:DF 0 "double_register_operand" "")
5777 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5778 (match_operand:DF 2 "nonmemory_operand" "")))]
5779 "TARGET_FP_DP_BASE || TARGET_DPFP"
5783 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5785 rtx first, second, tmp;
5786 split_double (operands[2], &first, &second);
5787 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5788 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5789 operands[2], tmp, const0_rtx));
5792 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5793 operands[2], const1_rtx, const1_rtx));
5796 else if (TARGET_FP_DP_BASE)
5798 if (!even_register_operand (operands[2], DFmode))
5799 operands[2] = force_reg (DFmode, operands[2]);
5801 if (!even_register_operand (operands[1], DFmode))
5802 operands[1] = force_reg (DFmode, operands[1]);
5809 (define_expand "subdf3"
5810 [(set (match_operand:DF 0 "double_register_operand" "")
5811 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5812 (match_operand:DF 2 "nonmemory_operand" "")))]
5813 "TARGET_FP_DP_BASE || TARGET_DPFP"
5817 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5818 operands[1] = force_reg (DFmode, operands[1]);
5819 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5820 || GET_CODE (operands[2]) == CONST_DOUBLE)
5822 rtx first, second, tmp;
5823 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5824 split_double (operands[const_index], &first, &second);
5825 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5826 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5827 operands[2], tmp, const0_rtx));
5830 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5831 operands[2], const1_rtx, const1_rtx));
5834 else if (TARGET_FP_DP_BASE)
5836 if (!even_register_operand (operands[2], DFmode))
5837 operands[2] = force_reg (DFmode, operands[2]);
5839 if (!even_register_operand (operands[1], DFmode))
5840 operands[1] = force_reg (DFmode, operands[1]);
5847 (define_expand "muldf3"
5848 [(set (match_operand:DF 0 "double_register_operand" "")
5849 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5850 (match_operand:DF 2 "nonmemory_operand" "")))]
5851 "TARGET_FP_DP_BASE || TARGET_DPFP"
5855 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5857 rtx first, second, tmp;
5858 split_double (operands[2], &first, &second);
5859 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5860 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5861 operands[2], tmp, const0_rtx));
5864 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5865 operands[2], const1_rtx, const1_rtx));
5868 else if (TARGET_FP_DP_BASE)
5870 if (!even_register_operand (operands[2], DFmode))
5871 operands[2] = force_reg (DFmode, operands[2]);
5873 if (!even_register_operand (operands[1], DFmode))
5874 operands[1] = force_reg (DFmode, operands[1]);
5881 (define_expand "divsf3"
5882 [(set (match_operand:SF 0 "register_operand" "")
5883 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5884 (match_operand:SF 2 "nonmemory_operand" "")))]
5885 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5887 if (TARGET_FPX_QUARK)
5889 operands[1] = force_reg (SFmode, operands[1]);
5890 operands[2] = force_reg (SFmode, operands[2]);
5894 if (!register_operand (operands[1], SFmode)
5895 && !register_operand (operands[2], SFmode))
5896 operands[1] = force_reg (SFmode, operands[1]);
5901 (define_expand "sqrtsf2"
5902 [(set (match_operand:SF 0 "register_operand" "")
5903 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5904 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5906 if (TARGET_FPX_QUARK)
5908 operands[1] = force_reg (SFmode, operands[1]);
5912 ;; SF->SI (using rounding towards zero)
5913 (define_expand "fix_truncsfsi2"
5914 [(set (match_operand:SI 0 "register_operand" "")
5915 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5916 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5920 (define_expand "floatsisf2"
5921 [(set (match_operand:SF 0 "register_operand" "")
5922 (float:SF (match_operand:SI 1 "register_operand" "")))]
5923 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5926 (define_expand "extzv"
5927 [(set (match_operand:SI 0 "register_operand" "")
5928 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5929 (match_operand:SI 2 "const_int_operand" "")
5930 (match_operand:SI 3 "const_int_operand" "")))]
5931 "TARGET_NPS_BITOPS")
5933 ; We need a sanity check in the instuction predicate because combine
5934 ; will throw any old rubbish at us and see what sticks.
5935 (define_insn "*extzv_i"
5936 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5937 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5938 (match_operand:SI 2 "const_int_operand" "n")
5939 (match_operand:SI 3 "const_int_operand" "n")))]
5940 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5941 "movb.cl\\t%0,%1,0,%3,%2"
5942 [(set_attr "type" "shift")
5943 (set_attr "length" "4")])
5945 (define_expand "insv"
5946 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5947 (match_operand:SI 1 "const_int_operand" "")
5948 (match_operand:SI 2 "const_int_operand" ""))
5949 (match_operand:SI 3 "nonmemory_operand" ""))]
5952 int size = INTVAL (operands[1]);
5954 if (size != 1 && size != 2 && size != 4 && size != 8)
5955 operands[3] = force_reg (SImode, operands[3]);
5958 (define_insn "*insv_i"
5959 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5960 (match_operand:SI 1 "const_int_operand" "C18,n")
5961 (match_operand:SI 2 "const_int_operand" "n,n"))
5962 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5964 && (register_operand (operands[3], SImode)
5965 || satisfies_constraint_C18 (operands[1]))"
5967 movbi\\t%0,%0,%3,%2,%1
5968 movb\\t%0,%0,%3,%2,0,%1"
5969 [(set_attr "type" "shift")
5970 (set_attr "length" "4")])
5972 (define_insn "*movb"
5973 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5974 (match_operand:SI 1 "const_int_operand" "n")
5975 (match_operand:SI 2 "const_int_operand" "n"))
5976 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5978 (match_operand:SI 4 "const_int_operand" "n")))]
5980 "movb\\t%0,%0,%3,%2,%4,%1"
5981 [(set_attr "type" "shift")
5982 (set_attr "length" "4")])
5984 (define_insn "*movb_signed"
5985 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5986 (match_operand:SI 1 "const_int_operand" "n")
5987 (match_operand:SI 2 "const_int_operand" "n"))
5988 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5990 (match_operand:SI 4 "const_int_operand" "n")))]
5992 "movb\\t%0,%0,%3,%2,%4,%1"
5993 [(set_attr "type" "shift")
5994 (set_attr "length" "4")])
5996 (define_insn "*movb_high"
5997 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5998 (match_operand:SI 1 "const_int_operand" "n")
5999 (match_operand:SI 2 "const_int_operand" "n"))
6000 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6001 (match_operand:SI 4 "const_int_operand" "n")))]
6003 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6004 "movb\\t%0,%0,%3,%2,%4,%1"
6005 [(set_attr "type" "shift")
6006 (set_attr "length" "4")])
6008 ; N.B.: when processing signed bitfields that fit in the top half of
6009 ; a word, gcc will use a narrow sign extending load, and in this case
6010 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6011 (define_insn "*movb_high_signed"
6012 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6013 (match_operand:SI 1 "const_int_operand" "n")
6014 (match_operand:SI 2 "const_int_operand" "n"))
6015 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6016 (match_operand:SI 4 "const_int_operand" "n")))]
6018 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6019 "movb\\t%0,%0,%3,%2,%4,%1"
6020 [(set_attr "type" "shift")
6021 (set_attr "length" "4")])
6024 [(set (match_operand:SI 0 "register_operand" "")
6025 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6026 (match_operand:SI 2 "const_int_operand" ""))
6027 (subreg:SI (match_operand 3 "") 0)))]
6029 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6030 && !reg_overlap_mentioned_p (operands[0], operands[1])"
6031 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6032 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6034 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6036 (define_insn "*mrgb"
6037 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6038 (match_operand:SI 1 "const_int_operand" "n")
6039 (match_operand:SI 2 "const_int_operand" "n"))
6040 (zero_extract:SI (match_dup 0) (match_dup 1)
6041 (match_operand:SI 3 "const_int_operand" "n")))
6042 (set (zero_extract:SI (match_dup 0)
6043 (match_operand:SI 4 "const_int_operand" "n")
6044 (match_operand:SI 5 "const_int_operand" "n"))
6045 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6047 (match_operand:SI 7 "const_int_operand" "n")))]
6050 output_asm_insn ("mrgb\\t%0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6051 /* The ;%? updates the known unalignment. */
6052 return arc_short_long (insn, ";%?", "nop_s");
6054 [(set_attr "type" "shift")
6055 (set_attr "length" "6")
6056 (set_attr "iscompact" "true")])
6058 ;; combine fumbles combination of two movb patterns, and then the
6059 ;; combination is rejected by combinable_i3pat.
6060 ;; Thus, we can only use a peephole2 to combine two such insns.
6063 [(set (match_operand:SI 0 "register_operand" "")
6064 (match_operand:SI 1 "register_operand" ""))
6065 (set (zero_extract:SI (match_dup 0)
6066 (match_operand:SI 2 "const_int_operand" "")
6067 (match_operand:SI 3 "const_int_operand" ""))
6068 (zero_extract:SI (match_dup 1)
6070 (match_operand:SI 4 "const_int_operand" "")))
6071 (match_operand 9) ; unrelated insn scheduled here
6072 (set (zero_extract:SI (match_dup 0)
6073 (match_operand:SI 5 "const_int_operand" "")
6074 (match_operand:SI 6 "const_int_operand" ""))
6075 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6077 (match_operand:SI 8 "const_int_operand" "")))]
6079 // Check that the second movb doesn't clobber an input of the extra insn.
6080 && !reg_overlap_mentioned_p (operands[0], operands[9])
6082 && !reg_set_p (operands[0], operands[9])
6083 && !reg_set_p (operands[7], operands[9])"
6084 [(set (match_dup 0) (match_dup 1))
6085 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6086 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6087 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6088 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6092 [(set (match_operand:SI 0 "register_operand" "")
6093 (match_operand:SI 1 "register_operand" ""))
6094 (set (zero_extract:SI (match_dup 0)
6095 (match_operand:SI 2 "const_int_operand" "")
6096 (match_operand:SI 3 "const_int_operand" ""))
6097 (zero_extract:SI (match_dup 1)
6099 (match_operand:SI 4 "const_int_operand" "")))
6100 (set (match_dup 1) (match_operand 8))
6101 (set (zero_extract:SI (match_dup 0)
6102 (match_operand:SI 5 "const_int_operand" "")
6103 (match_operand:SI 6 "const_int_operand" ""))
6104 (zero_extract:SI (match_dup 1) (match_dup 5)
6105 (match_operand:SI 7 "const_int_operand" "")))]
6107 && !reg_overlap_mentioned_p (operands[0], operands[8])"
6108 [(set (match_dup 0) (match_dup 1))
6109 (set (match_dup 1) (match_dup 8))
6110 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6111 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6112 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6113 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6116 ;; Split sign-extension of single least significant bit as and x,$1;neg x
6117 (define_insn_and_split "*extvsi_1_0"
6118 [(set (match_operand:SI 0 "register_operand" "=r")
6119 (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
6122 "!TARGET_BARREL_SHIFTER"
6125 [(set (match_dup 0) (and:SI (match_dup 1) (const_int 1)))
6126 (set (match_dup 0) (neg:SI (match_dup 0)))]
6128 [(set_attr "length" "8")])
6130 (define_insn_and_split "*extvsi_n_0"
6131 [(set (match_operand:SI 0 "register_operand" "=r")
6132 (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
6133 (match_operand:QI 2 "const_int_operand")
6135 "!TARGET_BARREL_SHIFTER
6136 && IN_RANGE (INTVAL (operands[2]), 2,
6137 (optimize_insn_for_size_p () ? 28 : 30))"
6140 [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 3)))
6141 (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))
6142 (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 4)))]
6144 int tmp = INTVAL (operands[2]);
6145 operands[3] = GEN_INT (~(HOST_WIDE_INT_M1U << tmp));
6146 operands[4] = GEN_INT (HOST_WIDE_INT_1U << (tmp - 1));
6148 [(set_attr "length" "14")])
6150 (define_insn_and_split "rotlsi3_cnt1"
6151 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
6152 (rotate:SI (match_operand:SI 1 "register_operand" "r")
6154 "!TARGET_BARREL_SHIFTER"
6159 emit_insn (gen_add_f (operands[0], operands[1], operands[1]));
6160 emit_insn (gen_adc (operands[0], operands[0], const0_rtx));
6164 (define_insn "rotrsi3_cnt1"
6165 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
6166 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6170 [(set_attr "type" "shift")
6171 (set_attr "predicable" "no")
6172 (set_attr "length" "4")])
6174 (define_insn "*rotrsi3_cnt8"
6175 [(set (match_operand:SI 0 "register_operand" "=r")
6176 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6178 "TARGET_BARREL_SHIFTER && TARGET_V2"
6180 [(set_attr "type" "shift")
6181 (set_attr "predicable" "no")
6182 (set_attr "length" "4")])
6184 (define_insn "ashlsi3_cnt1"
6185 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6186 (ashift:SI (match_operand:SI 1 "register_operand" "q,c")
6190 [(set_attr "type" "unary")
6191 (set_attr "iscompact" "maybe,false")
6192 (set_attr "length" "*,4")
6193 (set_attr "predicable" "no,no")])
6195 (define_insn "*ashlsi2_cnt8"
6196 [(set (match_operand:SI 0 "register_operand" "=r")
6197 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6199 "TARGET_BARREL_SHIFTER && TARGET_V2"
6201 [(set_attr "type" "shift")
6202 (set_attr "iscompact" "false")
6203 (set_attr "length" "4")
6204 (set_attr "predicable" "no")])
6206 (define_insn "lshrsi3_cnt1"
6207 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6208 (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6212 [(set_attr "type" "unary")
6213 (set_attr "iscompact" "maybe,false")
6214 (set_attr "predicable" "no,no")])
6216 (define_insn "lshrsi3_cnt1_carry"
6217 [(set (reg:CC_C CC_REG)
6218 (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
6219 (const_int 1))] UNSPEC_ARC_CC_NEZ))
6220 (set (match_operand:SI 0 "dest_reg_operand" "=r")
6221 (lshiftrt:SI (match_dup 1) (const_int 1)))]
6224 [(set_attr "type" "unary")
6225 (set_attr "length" "4")
6226 (set_attr "predicable" "no")])
6228 (define_insn "ashrsi3_cnt1"
6229 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6230 (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6234 [(set_attr "type" "unary")
6235 (set_attr "iscompact" "maybe,false")
6236 (set_attr "predicable" "no,no")])
6238 (define_insn "ashrsi3_cnt1_carry"
6239 [(set (reg:CC_C CC_REG)
6240 (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
6241 (const_int 1))] UNSPEC_ARC_CC_NEZ))
6242 (set (match_operand:SI 0 "dest_reg_operand" "=r")
6243 (ashiftrt:SI (match_dup 1) (const_int 1)))]
6246 [(set_attr "type" "unary")
6247 (set_attr "length" "4")
6248 (set_attr "predicable" "no")])
6250 (define_insn "btst_0_carry"
6251 [(set (reg:CC_C CC_REG)
6252 (unspec:CC_C [(and:SI (match_operand:SI 0 "register_operand" "r")
6253 (const_int 1))] UNSPEC_ARC_CC_NEZ))]
6256 [(set_attr "type" "unary")
6257 (set_attr "length" "4")
6258 (set_attr "predicable" "no")])
6261 [(set (match_operand:SI 0 "register_operand" "")
6262 (zero_extract:SI (match_dup 0)
6263 (match_operand:SI 1 "const_int_operand" "")
6264 (match_operand:SI 2 "const_int_operand" "")))
6265 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6270 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6271 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6272 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6274 ;; Dummy pattern used as a place holder for automatically saved
6276 (define_insn "stack_irq_dwarf"
6277 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6280 [(set_attr "length" "0")])
6282 ;; MAC and DMPY instructions
6284 ; Use VMAC2H(U) instruction to emulate scalar 16bit mac.
6285 (define_expand "maddhisi4"
6286 [(match_operand:SI 0 "register_operand" "")
6287 (match_operand:HI 1 "register_operand" "")
6288 (match_operand:HI 2 "register_operand" "")
6289 (match_operand:SI 3 "register_operand" "")]
6292 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6294 emit_move_insn (acc_reg, operands[3]);
6295 emit_insn (gen_machi (operands[0], operands[1], operands[2], acc_reg));
6299 (define_insn "machi"
6300 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6302 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6303 (sign_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6304 (match_operand:SI 3 "accl_operand" "")))
6305 (clobber (reg:DI ARCV2_ACC))]
6308 [(set_attr "length" "4")
6309 (set_attr "type" "multi")
6310 (set_attr "predicable" "no")
6311 (set_attr "cond" "nocond")])
6313 ; The same for the unsigned variant, but using VMAC2HU instruction.
6314 (define_expand "umaddhisi4"
6315 [(match_operand:SI 0 "register_operand" "")
6316 (match_operand:HI 1 "register_operand" "")
6317 (match_operand:HI 2 "register_operand" "")
6318 (match_operand:SI 3 "register_operand" "")]
6321 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6323 emit_move_insn (acc_reg, operands[3]);
6324 emit_insn (gen_umachi (operands[0], operands[1], operands[2], acc_reg));
6328 (define_insn "umachi"
6329 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6331 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6332 (zero_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6333 (match_operand:SI 3 "accl_operand" "")))
6334 (clobber (reg:DI ARCV2_ACC))]
6337 [(set_attr "length" "4")
6338 (set_attr "type" "multi")
6339 (set_attr "predicable" "no")
6340 (set_attr "cond" "nocond")])
6342 (define_expand "maddsidi4"
6343 [(match_operand:DI 0 "register_operand" "")
6344 (match_operand:SI 1 "register_operand" "")
6345 (match_operand:SI 2 "extend_operand" "")
6346 (match_operand:DI 3 "register_operand" "")]
6349 emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6353 (define_insn_and_split "maddsidi4_split"
6354 [(set (match_operand:DI 0 "register_operand" "=r")
6357 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6358 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6359 (match_operand:DI 3 "register_operand" "r")))
6360 (clobber (reg:DI ARCV2_ACC))]
6363 "TARGET_PLUS_DMPY && reload_completed"
6366 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6367 emit_move_insn (acc_reg, operands[3]);
6368 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6369 && REGNO (operands[0]) != ACC_REG_FIRST)
6370 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6373 emit_insn (gen_mac (operands[1], operands[2]));
6374 if (REGNO (operands[0]) != ACC_REG_FIRST)
6375 emit_move_insn (operands[0], acc_reg);
6379 [(set_attr "type" "multi")
6380 (set_attr "length" "36")])
6383 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6386 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6387 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,Cal")))
6388 (reg:DI ARCV2_ACC)))
6389 (set (reg:DI ARCV2_ACC)
6391 (mult:DI (sign_extend:DI (match_dup 1))
6392 (sign_extend:DI (match_dup 2)))
6393 (reg:DI ARCV2_ACC)))]
6396 [(set_attr "length" "4,4,8")
6397 (set_attr "type" "multi")
6398 (set_attr "predicable" "yes,no,no")
6399 (set_attr "cond" "canuse,nocond,nocond")])
6402 [(set (reg:DI ARCV2_ACC)
6404 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6405 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6406 (reg:DI ARCV2_ACC)))]
6409 [(set_attr "length" "4,8")
6410 (set_attr "type" "multi")
6411 (set_attr "predicable" "no")
6412 (set_attr "cond" "nocond")])
6415 [(set (reg:DI ARCV2_ACC)
6417 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6418 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6419 (reg:DI ARCV2_ACC)))
6420 (set (match_operand:SI 2 "register_operand" "")
6421 (match_operand:SI 3 "accl_operand" ""))]
6425 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6429 (define_insn "mac_r"
6430 [(set (match_operand:SI 0 "register_operand" "=r,r")
6433 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6434 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6435 (reg:DI ARCV2_ACC))))
6436 (clobber (reg:DI ARCV2_ACC))]
6439 [(set_attr "length" "4,8")
6440 (set_attr "type" "multi")
6441 (set_attr "predicable" "no")
6442 (set_attr "cond" "nocond")])
6444 (define_expand "umaddsidi4"
6445 [(match_operand:DI 0 "register_operand" "")
6446 (match_operand:SI 1 "register_operand" "")
6447 (match_operand:SI 2 "extend_operand" "")
6448 (match_operand:DI 3 "register_operand" "")]
6451 emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6455 (define_insn_and_split "umaddsidi4_split"
6456 [(set (match_operand:DI 0 "register_operand" "=r")
6459 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6460 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6461 (match_operand:DI 3 "register_operand" "r")))
6462 (clobber (reg:DI ARCV2_ACC))]
6465 "TARGET_PLUS_DMPY && reload_completed"
6468 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6469 emit_move_insn (acc_reg, operands[3]);
6470 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6471 && REGNO (operands[0]) != ACC_REG_FIRST)
6472 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6475 emit_insn (gen_macu (operands[1], operands[2]));
6476 if (REGNO (operands[0]) != ACC_REG_FIRST)
6477 emit_move_insn (operands[0], acc_reg);
6481 [(set_attr "type" "multi")
6482 (set_attr "length" "36")])
6484 (define_insn "macdu"
6485 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6488 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6489 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,i")))
6490 (reg:DI ARCV2_ACC)))
6491 (set (reg:DI ARCV2_ACC)
6493 (mult:DI (zero_extend:DI (match_dup 1))
6494 (zero_extend:DI (match_dup 2)))
6495 (reg:DI ARCV2_ACC)))]
6498 [(set_attr "length" "4,4,8")
6499 (set_attr "type" "multi")
6500 (set_attr "predicable" "yes,no,no")
6501 (set_attr "cond" "canuse,nocond,nocond")])
6504 [(set (reg:DI ARCV2_ACC)
6506 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6507 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6508 (reg:DI ARCV2_ACC)))]
6511 [(set_attr "length" "4,8")
6512 (set_attr "type" "multi")
6513 (set_attr "predicable" "no")
6514 (set_attr "cond" "nocond")])
6517 [(set (reg:DI ARCV2_ACC)
6519 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6520 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6521 (reg:DI ARCV2_ACC)))
6522 (set (match_operand:SI 2 "register_operand" "")
6523 (match_operand:SI 3 "accl_operand" ""))]
6527 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6531 (define_insn "macu_r"
6532 [(set (match_operand:SI 0 "register_operand" "=r,r")
6535 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6536 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6537 (reg:DI ARCV2_ACC))))
6538 (clobber (reg:DI ARCV2_ACC))]
6541 [(set_attr "length" "4,8")
6542 (set_attr "type" "multi")
6543 (set_attr "predicable" "no")
6544 (set_attr "cond" "nocond")])
6546 (define_insn "mpyd<su_optab>_arcv2hs"
6547 [(set (match_operand:DI 0 "even_register_operand" "=r")
6548 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r"))
6549 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6550 (set (reg:DI ARCV2_ACC)
6552 (SEZ:DI (match_dup 1))
6553 (SEZ:DI (match_dup 2))))]
6555 "mpyd<su_optab>%?\\t%0,%1,%2"
6556 [(set_attr "length" "4")
6557 (set_attr "iscompact" "false")
6558 (set_attr "type" "multi")
6559 (set_attr "predicable" "no")])
6561 (define_insn "*pmpyd<su_optab>_arcv2hs"
6562 [(set (match_operand:DI 0 "even_register_operand" "=r")
6564 (SEZ:DI (match_operand:SI 1 "even_register_operand" "%0"))
6565 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6566 (set (reg:DI ARCV2_ACC)
6568 (SEZ:DI (match_dup 1))
6569 (SEZ:DI (match_dup 2))))]
6571 "mpyd<su_optab>%?\\t%0,%1,%2"
6572 [(set_attr "length" "4")
6573 (set_attr "iscompact" "false")
6574 (set_attr "type" "multi")
6575 (set_attr "predicable" "yes")])
6577 (define_insn "mpyd<su_optab>_imm_arcv2hs"
6578 [(set (match_operand:DI 0 "even_register_operand" "=r,r, r")
6579 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r,0, r"))
6580 (match_operand 2 "immediate_operand" "L,I,Cal")))
6581 (set (reg:DI ARCV2_ACC)
6582 (mult:DI (SEZ:DI (match_dup 1))
6585 "mpyd<su_optab>%?\\t%0,%1,%2"
6586 [(set_attr "length" "4,4,8")
6587 (set_attr "iscompact" "false")
6588 (set_attr "type" "multi")
6589 (set_attr "predicable" "no")])
6591 (define_insn "*pmpyd<su_optab>_imm_arcv2hs"
6592 [(set (match_operand:DI 0 "even_register_operand" "=r,r")
6594 (SEZ:DI (match_operand:SI 1 "even_register_operand" "0,0"))
6595 (match_operand 2 "immediate_operand" "L,Cal")))
6596 (set (reg:DI ARCV2_ACC)
6597 (mult:DI (SEZ:DI (match_dup 1))
6600 "mpyd<su_optab>%?\\t%0,%1,%2"
6601 [(set_attr "length" "4,8")
6602 (set_attr "iscompact" "false")
6603 (set_attr "type" "multi")
6604 (set_attr "predicable" "yes")])
6606 (define_insn "add_shift"
6607 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6608 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
6609 (match_operand:SI 2 "_1_2_3_operand" ""))
6610 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
6612 "add%2%?\\t%0,%3,%1"
6613 [(set_attr "length" "*,4,8")
6614 (set_attr "predicable" "yes,no,no")
6615 (set_attr "iscompact" "maybe,false,false")
6616 (set_attr "cond" "canuse,nocond,nocond")])
6618 (define_insn "*add_shift2"
6619 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6620 (plus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6621 (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r")
6622 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6624 "add%3%?\\t%0,%1,%2"
6625 [(set_attr "length" "*,4,8")
6626 (set_attr "predicable" "yes,no,no")
6627 (set_attr "iscompact" "maybe,false,false")
6628 (set_attr "cond" "canuse,nocond,nocond")])
6630 (define_insn "*sub_shift"
6631 [(set (match_operand:SI 0"register_operand" "=r,r,r")
6632 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6633 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
6634 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6637 [(set_attr "length" "4,4,8")
6638 (set_attr "cond" "canuse,nocond,nocond")
6639 (set_attr "predicable" "yes,no,no")])
6641 (define_insn "*sub_shift_cmp0_noout"
6642 [(set (match_operand 0 "cc_set_register" "")
6644 (minus:SI (match_operand:SI 1 "register_operand" "r")
6645 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6646 (match_operand:SI 3 "_1_2_3_operand" "")))
6650 [(set_attr "length" "4")])
6652 (define_insn "*compare_si_ashiftsi"
6653 [(set (match_operand 0 "cc_set_register" "")
6654 (compare:CC (match_operand:SI 1 "register_operand" "r")
6655 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6656 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6659 [(set_attr "length" "4")])
6661 ;; Convert the sequence
6665 ;; sub{123}.f 0,ra,rn
6667 [(set (match_operand:SI 0 "register_operand" "")
6668 (ashift:SI (match_operand:SI 1 "register_operand" "")
6669 (match_operand:SI 2 "_1_2_3_operand" "")))
6670 (set (reg:CC CC_REG)
6671 (compare:CC (match_operand:SI 3 "register_operand" "")
6673 "peep2_reg_dead_p (2, operands[0])"
6674 [(set (reg:CC CC_REG) (compare:CC (match_dup 3)
6675 (ashift:SI (match_dup 1) (match_dup 2))))])
6677 (define_peephole2 ; std
6678 [(set (match_operand:SI 2 "memory_operand" "")
6679 (match_operand:SI 0 "register_operand" ""))
6680 (set (match_operand:SI 3 "memory_operand" "")
6681 (match_operand:SI 1 "register_operand" ""))]
6685 if (!gen_operands_ldd_std (operands, false, false))
6687 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6688 operands[2] = adjust_address (operands[2], DImode, 0);
6689 emit_insn (gen_rtx_SET (operands[2], operands[0]));
6693 (define_peephole2 ; ldd
6694 [(set (match_operand:SI 0 "register_operand" "")
6695 (match_operand:SI 2 "memory_operand" ""))
6696 (set (match_operand:SI 1 "register_operand" "")
6697 (match_operand:SI 3 "memory_operand" ""))]
6701 if (!gen_operands_ldd_std (operands, true, false))
6703 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6704 operands[2] = adjust_address (operands[2], DImode, 0);
6705 emit_insn (gen_rtx_SET (operands[0], operands[2]));
6709 ;; We require consecutive registers for LDD instruction. Check if we
6710 ;; can reorder them and use an LDD.
6712 (define_peephole2 ; swap the destination registers of two loads
6713 ; before a commutative operation.
6714 [(set (match_operand:SI 0 "register_operand" "")
6715 (match_operand:SI 2 "memory_operand" ""))
6716 (set (match_operand:SI 1 "register_operand" "")
6717 (match_operand:SI 3 "memory_operand" ""))
6718 (set (match_operand:SI 4 "register_operand" "")
6719 (match_operator:SI 5 "commutative_operator"
6720 [(match_operand 6 "register_operand" "")
6721 (match_operand 7 "register_operand" "") ]))]
6723 && (((rtx_equal_p (operands[0], operands[6]))
6724 && (rtx_equal_p (operands[1], operands[7])))
6725 || ((rtx_equal_p (operands[0], operands[7]))
6726 && (rtx_equal_p (operands[1], operands[6]))))
6727 && (peep2_reg_dead_p (3, operands[0])
6728 || rtx_equal_p (operands[0], operands[4]))
6729 && (peep2_reg_dead_p (3, operands[1])
6730 || rtx_equal_p (operands[1], operands[4]))"
6731 [(set (match_dup 0) (match_dup 2))
6732 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]
6734 if (!gen_operands_ldd_std (operands, true, true))
6740 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6741 operands[2] = adjust_address (operands[2], DImode, 0);
6746 (define_insn "*push_multi_fp"
6747 [(match_parallel 0 "push_multi_operand"
6748 [(set (reg:SI SP_REG)
6749 (plus:SI (reg:SI SP_REG)
6750 (match_operand 1 "immediate_operand" "")))
6751 (set (mem:SI (plus:SI (reg:SI SP_REG)
6752 (match_operand 2 "immediate_operand"
6755 "TARGET_CODE_DENSITY"
6757 int len = XVECLEN (operands[0], 0);
6758 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6759 if (MEM_P (XEXP (tmp, 0)))
6761 operands[3] = XEXP (tmp, 1);
6762 return "enter_s\\t{r13-%3} ; sp=sp+(%1)";
6766 tmp = XVECEXP (operands[0], 0, len - 3);
6767 operands[3] = XEXP (tmp, 1);
6768 return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)";
6771 [(set_attr "type" "call_no_delay_slot")
6772 (set_attr "length" "2")])
6774 (define_insn "*push_multi_fp_blink"
6775 [(match_parallel 0 "push_multi_operand"
6776 [(set (reg:SI SP_REG)
6777 (plus:SI (reg:SI SP_REG)
6778 (match_operand 1 "immediate_operand" "")))
6779 (set (mem:SI (plus:SI (reg:SI SP_REG)
6780 (match_operand 2 "immediate_operand"
6782 (reg:SI RETURN_ADDR_REGNUM))])]
6783 "TARGET_CODE_DENSITY"
6785 int len = XVECLEN (operands[0], 0);
6786 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6787 if (MEM_P (XEXP (tmp, 0)))
6789 operands[3] = XEXP (tmp, 1);
6790 return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)";
6794 tmp = XVECEXP (operands[0], 0, len - 3);
6795 operands[3] = XEXP (tmp, 1);
6796 return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)";
6799 [(set_attr "type" "call_no_delay_slot")
6800 (set_attr "length" "2")])
6802 (define_insn "*pop_multi_fp"
6803 [(match_parallel 0 "pop_multi_operand"
6804 [(set (reg:SI SP_REG)
6805 (plus:SI (reg:SI SP_REG)
6806 (match_operand 1 "immediate_operand" "")))
6811 (match_operand 2 "immediate_operand" ""))))])]
6812 "TARGET_CODE_DENSITY"
6814 int len = XVECLEN (operands[0], 0);
6815 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6816 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6818 operands[3] = XEXP (tmp, 0);
6819 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6820 return "leave_s\\t{r13-%3} ; sp=sp+%1";
6824 tmp = XVECEXP (operands[0], 0, len - 2);
6825 operands[3] = XEXP (tmp, 0);
6826 return "leave_s\\t{r13-%3, fp} ; sp=sp+%1";
6829 [(set_attr "type" "call_no_delay_slot")
6830 (set_attr "length" "2")])
6832 (define_insn "*pop_multi_fp_blink"
6833 [(match_parallel 0 "pop_multi_operand"
6834 [(set (reg:SI SP_REG)
6835 (plus:SI (reg:SI SP_REG)
6836 (match_operand 1 "immediate_operand" "")))
6837 (set (reg:SI RETURN_ADDR_REGNUM)
6841 (match_operand 2 "immediate_operand" ""))))])]
6842 "TARGET_CODE_DENSITY"
6844 int len = XVECLEN (operands[0], 0);
6845 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6846 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6848 operands[3] = XEXP (tmp, 0);
6849 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6850 return "leave_s\\t{r13-%3, blink} ; sp=sp+%1";
6854 tmp = XVECEXP (operands[0], 0, len - 2);
6855 operands[3] = XEXP (tmp, 0);
6856 return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1";
6859 [(set_attr "type" "call_no_delay_slot")
6860 (set_attr "length" "2")])
6862 (define_insn "*pop_multi_fp_ret"
6863 [(match_parallel 0 "pop_multi_operand"
6865 (set (reg:SI SP_REG)
6866 (plus:SI (reg:SI SP_REG)
6867 (match_operand 1 "immediate_operand" "")))
6872 (match_operand 2 "immediate_operand" ""))))])]
6873 "TARGET_CODE_DENSITY"
6875 int len = XVECLEN (operands[0], 0);
6876 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6877 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6879 operands[3] = XEXP (tmp, 0);
6880 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6881 return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1";
6885 tmp = XVECEXP (operands[0], 0, len - 2);
6886 operands[3] = XEXP (tmp, 0);
6887 return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1";
6890 [(set_attr "type" "call_no_delay_slot")
6891 (set_attr "length" "2")])
6893 (define_insn "*pop_multi_fp_blink_ret"
6894 [(match_parallel 0 "pop_multi_operand"
6896 (set (reg:SI SP_REG)
6897 (plus:SI (reg:SI SP_REG)
6898 (match_operand 1 "immediate_operand" "")))
6899 (set (reg:SI RETURN_ADDR_REGNUM)
6903 (match_operand 2 "immediate_operand" ""))))])]
6904 "TARGET_CODE_DENSITY"
6906 int len = XVECLEN (operands[0], 0);
6907 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6908 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6910 operands[3] = XEXP (tmp, 0);
6911 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6912 return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1";
6916 tmp = XVECEXP (operands[0], 0, len - 2);
6917 operands[3] = XEXP (tmp, 0);
6918 return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1";
6921 [(set_attr "type" "call_no_delay_slot")
6922 (set_attr "length" "2")])
6924 ;; Patterns for exception handling
6925 (define_insn_and_split "eh_return"
6926 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6927 VUNSPEC_ARC_EH_RETURN)]
6934 arc_eh_return_address_location (operands[0]);
6937 [(set_attr "length" "8")]
6940 ;; include the arc-FPX instructions
6943 ;; include the arc-FPU instructions
6946 (include "simdext.md")
6948 ;; include atomic extensions
6949 (include "atomic.md")