1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2023 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 %1,%0\;st%U0.di %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%? %1,%2\";
992 return \"btst%? %1,%z2\";
994 return \"bmsk%?.f 0,%1,%Z2\";
996 return \"bclr%?.f 0,%1,%M2\";
998 return \"asr.f 0,%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 %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 %4,%1,%3,%3,%2
1065 and.f 0,%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 %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 %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 %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 %0,%0,%0";
1649 return "mov.%d3 %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 %R0,%R1\;mov.%d3 %0,%1\";
1739 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1741 return \"mov.%d3 %L0,%L1\;mov.%d3 %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 %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 %R0,%R2\;mov.%d1 %0,%2\";
1781 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1783 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1787 [(set_attr "type" "cmove,cmove")
1788 (set_attr "length" "8,16")])
1790 ;; -------------------------------------------------------------------
1791 ;; Sign/Zero extension
1792 ;; -------------------------------------------------------------------
1794 (define_insn "*zero_extendqihi2_i"
1795 [(set (match_operand:HI 0 "dest_reg_operand" "=q,q,r,r,r,r")
1797 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,Ucm,m")))]
1806 [(set_attr "type" "unary,unary,unary,unary,load,load")
1807 (set_attr "iscompact" "maybe,true,false,false,false,false")
1808 (set_attr "predicable" "no,no,yes,no,no,no")])
1810 (define_expand "zero_extendqihi2"
1811 [(set (match_operand:HI 0 "dest_reg_operand" "")
1812 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1817 (define_insn "*zero_extendqisi2_ac"
1818 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,q,!*x,r,r")
1820 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,T,Usd,Ucm,m")))]
1831 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1832 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1833 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1835 (define_expand "zero_extendqisi2"
1836 [(set (match_operand:SI 0 "dest_reg_operand" "")
1837 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1842 (define_insn "*zero_extendhisi2_i"
1843 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,!x,q,r,r")
1845 (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,r,Usd,T,Ucm,m")))]
1856 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1857 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1858 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1860 (define_expand "zero_extendhisi2"
1861 [(set (match_operand:SI 0 "dest_reg_operand" "")
1862 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1867 ;; Sign extension instructions.
1869 (define_insn "*extendqihi2_i"
1870 [(set (match_operand:HI 0 "dest_reg_operand" "=q,r,r,r")
1872 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1879 [(set_attr "type" "unary,unary,load,load")
1880 (set_attr "iscompact" "true,false,false,false")
1881 (set_attr "length" "*,*,*,8")])
1883 (define_expand "extendqihi2"
1884 [(set (match_operand:HI 0 "dest_reg_operand" "")
1885 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1890 (define_insn "*extendqisi2_ac"
1891 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r")
1893 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1900 [(set_attr "type" "unary,unary,load,load")
1901 (set_attr "iscompact" "true,false,false,false")
1902 (set_attr "length" "*,*,*,8")])
1904 (define_expand "extendqisi2"
1905 [(set (match_operand:SI 0 "dest_reg_operand" "")
1906 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1911 (define_insn "*extendhisi2_i"
1912 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,q,r,r")
1914 (match_operand:HI 1 "nonvol_nonimm_operand" "q,r,Ucd,Uex,m")))]
1920 ld%_.x%U1%V1\\t%0,%1
1921 ld%_.x%U1%V1\\t%0,%1"
1922 [(set_attr "type" "unary,unary,load,load,load")
1923 (set_attr "iscompact" "true,false,true,false,false")
1924 (set_attr "length" "*,*,*,4,8")])
1926 (define_expand "extendhisi2"
1927 [(set (match_operand:SI 0 "dest_reg_operand" "")
1928 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1933 ;; Unary arithmetic insns
1935 ;; We allow constant operands to enable late constant propagation, but it is
1936 ;; not worth while to have more than one dedicated alternative to output them -
1937 ;; if we are really worried about getting these the maximum benefit of all
1938 ;; the available alternatives, we should add an extra pass to fold such
1939 ;; operations to movsi.
1941 ;; Absolute instructions
1943 (define_insn "abssi2"
1944 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w,w")
1945 (abs:SI (match_operand:SI 1 "nonmemory_operand" "q,cL,Cal")))]
1948 [(set_attr "type" "two_cycle_core")
1949 (set_attr "length" "*,4,8")
1950 (set_attr "iscompact" "true,false,false")])
1952 ;; Maximum and minimum insns
1954 (define_insn "smaxsi3"
1955 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
1956 (smax:SI (match_operand:SI 1 "register_operand" "%0, r, r")
1957 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1960 [(set_attr "type" "two_cycle_core")
1961 (set_attr "length" "4,4,8")
1962 (set_attr "predicable" "yes,no,no")]
1965 (define_insn "sminsi3"
1966 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
1967 (smin:SI (match_operand:SI 1 "register_operand" "%0, r, r")
1968 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1971 [(set_attr "type" "two_cycle_core")
1972 (set_attr "length" "4,4,8")
1973 (set_attr "predicable" "yes,no,no")]
1976 ;; Arithmetic instructions.
1978 ; The alternatives in the constraints still serve three purposes:
1979 ; - estimate insn size assuming conditional execution
1980 ; - guide reload to re-order the second and third operand to get a better fit.
1981 ; - give tentative insn type to guide scheduling
1982 ; N.B. "%" for commutativity doesn't help when there is another matching
1983 ; (but longer) alternative.
1984 (define_insn "*addsi3_mixed"
1985 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
1986 [(set (match_operand:SI 0 "register_operand" "=q, h,!*Rsd,Rcb,Rcb, q, q, q, r,r, r, r, r, r, q, r, r")
1987 (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")
1988 (match_operand:SI 2 "nonmemory_operand" "hL,Cm1, L,CP4,CM4,CM4,qK, O,rL,0,rC6u,C6n,CIs,C4p,Cal,Cal,Cal")))]
1991 add_s\\t%0,%1,%2 ;b,b,h
1992 add_s\\t%0,%1,%2 ;h,h,s3
1993 add_s\\t%0,%1,%2 ;R0/R1,b,u6
1994 sub_s\\t%0,%1,%n2 ;sp,sp,u7
1995 add_s\\t%0,%1,%2 ;sp,sp,u7
1996 add_s\\t%0,%1,%2 ;b,sp,u7
1997 add_s\\t%0,%1,%2 ;a,b,c/u3
1998 add_s\\t%0,%1,%2 ;b,b,u7
1999 add%?\\t%0,%1,%2 ;(p)b,b,c/u6
2000 add%?\\t%0,%2,%1 ;(p)b,b,c
2001 add%s2\\t%0,%1,%S2 ;a,b,c/u6
2002 sub%s2\\t%0,%1,%N2 ;a,b,u6
2003 add%s2\\t%0,%1,%S2 ;b,b,s12
2005 add_s\\t%0,%1,%2 ;b,b,limm
2006 add%?\\t%0,%1,%2 ;(p)b,b,limm
2007 add\\t%0,%1,%2 ;a,b,limm"
2008 [(set_attr "type" "add,add,add,sub,add,add,add,add,add,add,add,sub,add,bxor,add,add,add")
2009 (set_attr "iscompact" "true,true,true,true,true,true,true,true,false,false,false,false,false,false,true_limm,false,false")
2010 (set_attr "length" "2,2,2,2,2,2,2,2,4,4,4,4,4,4,6,8,8")
2011 (set_attr "predicable" "no,no,no,no,no,no,no,no,yes,yes,no,no,no,no,no,yes,no")
2014 ;; ARCv2 MPYW and MPYUW
2015 (define_expand "mulhisi3"
2016 [(set (match_operand:SI 0 "register_operand" "")
2017 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
2018 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
2021 if (CONSTANT_P (operands[2]))
2023 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
2029 (define_insn "mulhisi3_imm"
2030 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
2031 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
2032 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
2035 [(set_attr "length" "4,4,4,8,8")
2036 (set_attr "iscompact" "false")
2037 (set_attr "type" "mul16_em")
2038 (set_attr "predicable" "yes,no,no,yes,no")
2039 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2042 (define_insn "mulhisi3_reg"
2043 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
2044 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,0,r"))
2045 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "q,r,r"))))]
2048 [(set_attr "length" "*,4,4")
2049 (set_attr "iscompact" "maybe,false,false")
2050 (set_attr "type" "mul16_em")
2051 (set_attr "predicable" "yes,yes,no")
2052 (set_attr "cond" "canuse,canuse,nocond")
2055 (define_expand "umulhisi3"
2056 [(set (match_operand:SI 0 "register_operand" "")
2057 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2058 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
2061 if (CONSTANT_P (operands[2]))
2063 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
2069 (define_insn "umulhisi3_imm"
2070 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
2071 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
2072 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
2075 [(set_attr "length" "4,4,4,8,8")
2076 (set_attr "iscompact" "false")
2077 (set_attr "type" "mul16_em")
2078 (set_attr "predicable" "yes,no,no,yes,no")
2079 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2082 (define_insn "umulhisi3_reg"
2083 [(set (match_operand:SI 0 "register_operand" "=q, r, r")
2084 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, 0, r"))
2085 (zero_extend:SI (match_operand:HI 2 "register_operand" "q, r, r"))))]
2088 [(set_attr "length" "*,4,4")
2089 (set_attr "iscompact" "maybe,false,false")
2090 (set_attr "type" "mul16_em")
2091 (set_attr "predicable" "yes,yes,no")
2092 (set_attr "cond" "canuse,canuse,nocond")
2095 ;; ARC700/ARC600/V2 multiply
2098 (define_expand "mulsi3"
2099 [(set (match_operand:SI 0 "register_operand" "")
2100 (mult:SI (match_operand:SI 1 "register_operand" "")
2101 (match_operand:SI 2 "nonmemory_operand" "")))]
2104 if (TARGET_MUL64_SET)
2106 emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2]));
2109 else if (TARGET_MULMAC_32BY16_SET)
2111 emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2]));
2116 (define_insn_and_split "mulsi32x16"
2117 [(set (match_operand:SI 0 "register_operand" "=w")
2118 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2119 (match_operand:SI 2 "nonmemory_operand" "ci")))
2120 (clobber (reg:DI MUL32x16_REG))]
2121 "TARGET_MULMAC_32BY16_SET"
2123 "TARGET_MULMAC_32BY16_SET && reload_completed"
2126 if (immediate_operand (operands[2], SImode)
2127 && INTVAL (operands[2]) >= 0
2128 && INTVAL (operands[2]) <= 65535)
2130 emit_insn (gen_umul_600 (operands[1], operands[2],
2131 gen_acc2 (), gen_acc1 ()));
2132 emit_move_insn (operands[0], gen_acc2 ());
2135 emit_insn (gen_umul_600 (operands[1], operands[2],
2136 gen_acc2 (), gen_acc1 ()));
2137 emit_insn (gen_mac_600 (operands[1], operands[2],
2138 gen_acc2 (), gen_acc1 ()));
2139 emit_move_insn (operands[0], gen_acc2 ());
2142 [(set_attr "type" "multi")
2143 (set_attr "length" "8")])
2145 ; mululw conditional execution without a LIMM clobbers an input register;
2146 ; we'd need a different pattern to describe this.
2147 ; To make the conditional execution valid for the LIMM alternative, we
2148 ; have to emit the LIMM before the register operand.
2149 (define_insn "umul_600"
2150 [(set (match_operand:SI 2 "acc2_operand" "")
2151 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2152 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2156 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2157 "TARGET_MULMAC_32BY16_SET"
2159 [(set_attr "length" "4,4,8")
2160 (set_attr "type" "mulmac_600")
2161 (set_attr "predicable" "no")
2162 (set_attr "cond" "nocond")])
2164 (define_insn "mac_600"
2165 [(set (match_operand:SI 2 "acc2_operand" "")
2167 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2169 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2174 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2175 "TARGET_MULMAC_32BY16_SET"
2176 "machlw%? 0, %0, %1"
2177 [(set_attr "length" "4,4,8")
2178 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2179 (set_attr "predicable" "no, no, yes")
2180 (set_attr "cond" "nocond, canuse_limm, canuse")])
2182 ; The gcc-internal representation may differ from the hardware
2183 ; register number in order to allow the generic code to correctly
2184 ; split the concatenation of mhi and mlo.
2185 (define_insn_and_split "mulsi64"
2186 [(set (match_operand:SI 0 "register_operand" "=w")
2187 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2188 (match_operand:SI 2 "nonmemory_operand" "ci")))
2189 (clobber (reg:DI MUL64_OUT_REG))]
2192 "TARGET_MUL64_SET && reload_completed"
2195 rtx mhi = gen_rtx_REG (SImode, R59_REG);
2196 rtx mlo = gen_rtx_REG (SImode, R58_REG);
2197 emit_insn (gen_mulsi_600 (operands[1], operands[2], mlo, mhi));
2198 emit_move_insn (operands[0], mlo);
2201 [(set_attr "type" "multi")
2202 (set_attr "length" "8")])
2204 (define_insn "mulsi_600"
2205 [(set (match_operand:SI 2 "mlo_operand" "")
2206 (mult:SI (match_operand:SI 0 "register_operand" "%q,c,c,c")
2207 (match_operand:SI 1 "nonmemory_operand" "q,cL,I,Cal")))
2208 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2211 [(set_attr "length" "*,4,4,8")
2212 (set_attr "iscompact" "maybe,false,false,false")
2213 (set_attr "type" "multi,multi,multi,multi")
2214 (set_attr "predicable" "yes,yes,no,yes")
2215 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2217 (define_insn_and_split "mulsidi_600"
2218 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2219 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2220 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2221 (clobber (reg:DI R58_REG))]
2224 "TARGET_MUL64_SET && reload_completed"
2227 int hi = !TARGET_BIG_ENDIAN;
2229 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2230 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2231 emit_insn (gen_mul64 (operands[1], operands[2]));
2232 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2233 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2236 [(set_attr "type" "multi")
2237 (set_attr "length" "4,4,8")])
2239 (define_insn "mul64"
2240 [(set (reg:DI MUL64_OUT_REG)
2242 (sign_extend:DI (match_operand:SI 0 "register_operand" "%q, c,c, c"))
2243 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "q,cL,L,C32"))))]
2245 "mul64%? \t0, %0, %1"
2246 [(set_attr "length" "*,4,4,8")
2247 (set_attr "iscompact" "maybe,false,false,false")
2248 (set_attr "type" "multi,multi,multi,multi")
2249 (set_attr "predicable" "yes,yes,no,yes")
2250 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2252 (define_insn_and_split "umulsidi_600"
2253 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2254 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2255 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2256 (clobber (reg:DI R58_REG))]
2259 "TARGET_MUL64_SET && reload_completed"
2262 int hi = !TARGET_BIG_ENDIAN;
2264 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2265 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2266 emit_insn (gen_mulu64 (operands[1], operands[2]));
2267 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2268 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2271 [(set_attr "type" "umulti")
2272 (set_attr "length" "4,4,8")])
2274 (define_insn "mulu64"
2275 [(set (reg:DI MUL64_OUT_REG)
2277 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2278 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2280 "mulu64%? \t0, %0, %1"
2281 [(set_attr "length" "4,4,8")
2282 (set_attr "iscompact" "false")
2283 (set_attr "type" "umulti")
2284 (set_attr "predicable" "yes,no,yes")
2285 (set_attr "cond" "canuse,canuse_limm,canuse")])
2287 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2288 ; may not be used as destination constraint.
2290 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2291 ; but mpyu is faster for the standard multiplier.
2292 ; Note: we must make sure LP_COUNT is not one of the destination
2293 ; registers, since it cannot be the destination of a multi-cycle insn
2295 (define_insn "mulsi3_700"
2296 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=r, r,r, r,r")
2297 (mult:SI (match_operand:SI 1 "register_operand" "%0, r,0, 0,r")
2298 (match_operand:SI 2 "nonmemory_operand" "rL,rL,I,Cal,Cal")))]
2301 [(set_attr "length" "4,4,4,8,8")
2302 (set_attr "type" "umulti")
2303 (set_attr "predicable" "yes,no,no,yes,no")
2304 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2306 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2307 ; short variant. LP_COUNT constraints are still valid.
2308 (define_insn "mulsi3_v2"
2309 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=q,q, r, r,r, r, r")
2310 (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, c")
2311 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,rL,I,Cal,Cal")))]
2321 [(set_attr "length" "*,*,4,4,4,8,8")
2322 (set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
2323 (set_attr "type" "umulti")
2324 (set_attr "predicable" "no,no,yes,no,no,yes,no")
2325 (set_attr "cond" "nocond,nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2327 (define_expand "mulsidi3"
2328 [(set (match_operand:DI 0 "register_operand" "")
2329 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2330 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2333 if (TARGET_PLUS_MACD)
2335 if (CONST_INT_P (operands[2]))
2337 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2341 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2347 operands[2] = force_reg (SImode, operands[2]);
2348 if (!register_operand (operands[0], DImode))
2350 rtx result = gen_reg_rtx (DImode);
2352 operands[2] = force_reg (SImode, operands[2]);
2353 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2354 emit_move_insn (operands[0], result);
2358 else if (TARGET_MUL64_SET)
2360 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2363 else if (TARGET_MULMAC_32BY16_SET)
2365 operands[2] = force_reg (SImode, operands[2]);
2366 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2369 operands[2] = force_reg (SImode, operands[2]);
2372 (define_insn_and_split "mulsidi64"
2373 [(set (match_operand:DI 0 "register_operand" "=w")
2374 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2375 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2376 (clobber (reg:DI MUL32x16_REG))]
2377 "TARGET_MULMAC_32BY16_SET"
2379 "TARGET_MULMAC_32BY16_SET && reload_completed"
2382 rtx result_hi = gen_highpart (SImode, operands[0]);
2383 rtx result_low = gen_lowpart (SImode, operands[0]);
2385 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2386 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2387 emit_move_insn (result_low, gen_acc2 ());
2390 [(set_attr "type" "multi")
2391 (set_attr "length" "8")])
2394 (define_insn "mul64_600"
2395 [(set (reg:DI MUL32x16_REG)
2396 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2398 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2403 "TARGET_MULMAC_32BY16_SET"
2405 [(set_attr "length" "4,4,8")
2406 (set_attr "type" "mulmac_600")
2407 (set_attr "predicable" "no,no,yes")
2408 (set_attr "cond" "nocond, canuse_limm, canuse")])
2411 ;; ??? check if this is canonical rtl
2412 (define_insn "mac64_600"
2413 [(set (reg:DI MUL32x16_REG)
2415 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2417 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2418 (const_int 16) (const_int 16))
2420 (reg:DI MUL32x16_REG)))
2421 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2424 (mult:DI (sign_extend:DI (match_dup 1))
2426 (sign_extract:DI (match_dup 2)
2427 (const_int 16) (const_int 16))
2429 (reg:DI MUL32x16_REG))
2430 (const_int 32) (const_int 32)))]
2431 "TARGET_MULMAC_32BY16_SET"
2432 "machlw%? %0, %1, %2"
2433 [(set_attr "length" "4,4,8")
2434 (set_attr "type" "mulmac_600")
2435 (set_attr "predicable" "no,no,yes")
2436 (set_attr "cond" "nocond, canuse_limm, canuse")])
2439 ;; DI <- DI(signed SI) * DI(signed SI)
2440 (define_insn_and_split "mulsidi3_700"
2441 [(set (match_operand:DI 0 "register_operand" "=&r")
2442 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2443 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2444 "TARGET_MPY && !TARGET_PLUS_MACD"
2446 "&& reload_completed"
2449 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2450 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2451 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2452 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2453 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2454 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2457 [(set_attr "type" "multi")
2458 (set_attr "length" "8")])
2460 (define_insn "mulsi3_highpart"
2461 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2465 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2466 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2469 "mpy%+%?\\t%0,%1,%2"
2470 [(set_attr "length" "4,4,8,8")
2471 (set_attr "type" "multi")
2472 (set_attr "predicable" "yes,no,yes,no")
2473 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2475 ; Note that mpyhu has the same latency as mpy / mpyh,
2476 ; thus we use the type multi.
2477 (define_insn "*umulsi3_highpart_i"
2478 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2482 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2483 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2486 "mpy%+u%?\\t%0,%1,%2"
2487 [(set_attr "length" "4,4,8,8")
2488 (set_attr "type" "multi")
2489 (set_attr "predicable" "yes,no,yes,no")
2490 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2492 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2493 ;; need a separate pattern for immediates
2494 ;; ??? This is fine for combine, but not for reload.
2495 (define_insn "umulsi3_highpart_int"
2496 [(set (match_operand:SI 0 "register_operand" "=r, r, r,r, r")
2500 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, r, 0, 0, r"))
2501 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I,Cal,Cal"))
2504 "mpy%+u%?\\t%0,%1,%2"
2505 [(set_attr "length" "4,4,4,8,8")
2506 (set_attr "type" "multi")
2507 (set_attr "predicable" "yes,no,no,yes,no")
2508 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2510 (define_expand "umulsi3_highpart"
2511 [(set (match_operand:SI 0 "general_operand" "")
2515 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2516 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2521 rtx target = operands[0];
2523 if (!register_operand (target, SImode))
2524 target = gen_reg_rtx (SImode);
2526 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2527 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2528 operands[2], SImode);
2529 else if (!immediate_operand (operands[2], SImode))
2530 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2531 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2532 if (target != operands[0])
2533 emit_move_insn (operands[0], target);
2537 (define_expand "umulsidi3"
2538 [(set (match_operand:DI 0 "register_operand" "")
2539 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2540 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2543 if (TARGET_PLUS_MACD)
2545 if (CONST_INT_P (operands[2]))
2547 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2551 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2557 operands[2] = force_reg (SImode, operands[2]);
2558 if (!register_operand (operands[0], DImode))
2560 rtx result = gen_reg_rtx (DImode);
2562 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2563 emit_move_insn (operands[0], result);
2567 else if (TARGET_MUL64_SET)
2569 operands[2] = force_reg (SImode, operands[2]);
2570 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2573 else if (TARGET_MULMAC_32BY16_SET)
2575 operands[2] = force_reg (SImode, operands[2]);
2576 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2585 (define_insn_and_split "umulsidi64"
2586 [(set (match_operand:DI 0 "register_operand" "=w")
2587 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2588 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2589 (clobber (reg:DI MUL32x16_REG))]
2590 "TARGET_MULMAC_32BY16_SET"
2592 "TARGET_MULMAC_32BY16_SET && reload_completed"
2598 result_hi = gen_highpart (SImode, operands[0]);
2599 result_low = gen_lowpart (SImode, operands[0]);
2601 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2602 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2603 emit_move_insn (result_low, gen_acc2 ());
2606 [(set_attr "type" "multi")
2607 (set_attr "length" "8")])
2609 (define_insn "umul64_600"
2610 [(set (reg:DI MUL32x16_REG)
2611 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2613 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2618 "TARGET_MULMAC_32BY16_SET"
2620 [(set_attr "length" "4,4,8")
2621 (set_attr "type" "mulmac_600")
2622 (set_attr "predicable" "no")
2623 (set_attr "cond" "nocond")])
2626 (define_insn "umac64_600"
2627 [(set (reg:DI MUL32x16_REG)
2629 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2631 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2632 (const_int 16) (const_int 16))
2634 (reg:DI MUL32x16_REG)))
2635 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2638 (mult:DI (zero_extend:DI (match_dup 1))
2640 (zero_extract:DI (match_dup 2)
2641 (const_int 16) (const_int 16))
2643 (reg:DI MUL32x16_REG))
2644 (const_int 32) (const_int 32)))]
2645 "TARGET_MULMAC_32BY16_SET"
2646 "machulw%? %0, %1, %2"
2647 [(set_attr "length" "4,4,8")
2648 (set_attr "type" "mulmac_600")
2649 (set_attr "predicable" "no,no,yes")
2650 (set_attr "cond" "nocond, canuse_limm, canuse")])
2652 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2653 (define_insn_and_split "umulsidi3_700"
2654 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2655 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2656 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2657 "TARGET_MPY && !TARGET_PLUS_MACD"
2659 "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed"
2662 int hi = !TARGET_BIG_ENDIAN;
2664 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2665 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2666 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2667 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2670 [(set_attr "type" "umulti")
2671 (set_attr "length" "8")])
2673 (define_expand "addsi3"
2674 [(set (match_operand:SI 0 "dest_reg_operand" "")
2675 (plus:SI (match_operand:SI 1 "register_operand" "")
2676 (match_operand:SI 2 "nonmemory_operand" "")))]
2678 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2680 operands[2]=force_reg(SImode, operands[2]);
2684 (define_expand "adddi3"
2685 [(set (match_operand:DI 0 "register_operand" "")
2686 (plus:DI (match_operand:DI 1 "register_operand" "")
2687 (match_operand:DI 2 "nonmemory_operand" "")))
2688 (clobber (reg:CC CC_REG))]
2691 rtx l0 = gen_lowpart (SImode, operands[0]);
2692 rtx h0 = gen_highpart (SImode, operands[0]);
2693 rtx l1 = gen_lowpart (SImode, operands[1]);
2694 rtx h1 = gen_highpart (SImode, operands[1]);
2695 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2696 subreg_lowpart_offset (SImode, DImode));
2697 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2698 subreg_highpart_offset (SImode, DImode));
2700 if (l2 == const0_rtx)
2702 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2703 emit_move_insn (l0, l1);
2704 emit_insn (gen_addsi3 (h0, h1, h2));
2705 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2706 emit_move_insn (l0, l1);
2709 if (rtx_equal_p (l0, h1))
2711 if (h2 != const0_rtx)
2712 emit_insn (gen_addsi3 (h0, h1, h2));
2713 else if (!rtx_equal_p (h0, h1))
2714 emit_move_insn (h0, h1);
2715 emit_insn (gen_add_f (l0, l1, l2));
2719 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2720 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2723 emit_insn (gen_add_f (l0, l1, l2));
2724 emit_insn (gen_adc (h0, h1, h2));
2728 (define_insn "add_f"
2729 [(set (reg:CC_C CC_REG)
2731 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,L,0,I,Cal,r")
2732 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0, r,rCal"))
2734 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2735 (plus:SI (match_dup 1) (match_dup 2)))]
2736 "register_operand (operands[1], SImode)
2737 || register_operand (operands[2], SImode)"
2745 [(set_attr "cond" "set")
2746 (set_attr "type" "compare")
2747 (set_attr "length" "4,4,4,4,8,8")])
2749 (define_insn "*add_f_2"
2750 [(set (reg:CC_C CC_REG)
2752 (plus:SI (match_operand:SI 1 "register_operand" "r ,0,r")
2753 (match_operand:SI 2 "nonmemory_operand" "rL,I,rCal"))
2755 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
2756 (plus:SI (match_dup 1) (match_dup 2)))]
2759 [(set_attr "cond" "set")
2760 (set_attr "type" "compare")
2761 (set_attr "length" "4,4,8")])
2764 [(set (match_operand:SI 0 "register_operand" "=r, r,r,r, r,r")
2767 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2768 (match_operand:SI 1 "nonmemory_operand" "%r, 0,r,0,Cal,r"))
2769 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I, r,Cal")))]
2770 "register_operand (operands[1], SImode)
2771 || register_operand (operands[2], SImode)"
2779 [(set_attr "cond" "use")
2780 (set_attr "type" "cc_arith")
2781 (set_attr "length" "4,4,4,4,8,8")])
2783 ; combiner-splitter cmp / scc -> cmp / adc
2785 [(set (match_operand:SI 0 "dest_reg_operand" "")
2786 (gtu:SI (match_operand:SI 1 "register_operand" "")
2787 (match_operand:SI 2 "register_operand" "")))
2788 (clobber (reg CC_REG))]
2790 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2791 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2793 ; combine won't work when an intermediate result is used later...
2794 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2796 [(set (match_operand:SI 0 "dest_reg_operand" "")
2797 (plus:SI (match_operand:SI 1 "register_operand" "")
2798 (match_operand:SI 2 "nonmemory_operand" "")))
2799 (set (reg:CC_C CC_REG)
2800 (compare:CC_C (match_dup 0)
2801 (match_operand:SI 3 "nonmemory_operand" "")))]
2802 "rtx_equal_p (operands[1], operands[3])
2803 || rtx_equal_p (operands[2], operands[3])"
2805 [(set (reg:CC_C CC_REG)
2806 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2808 (plus:SI (match_dup 1) (match_dup 2)))])])
2810 ; ??? need to delve into combine to find out why this is not useful.
2811 ; We'd like to be able to grok various C idioms for carry bit usage.
2812 ;(define_insn "*adc_0"
2813 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2814 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2815 ; (match_operand:SI 1 "register_operand" "c")))]
2818 ; [(set_attr "cond" "use")
2819 ; (set_attr "type" "cc_arith")
2820 ; (set_attr "length" "4")])
2823 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2824 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2825 ; (match_operand:SI 2 "register_operand" "c"))
2826 ; (match_operand:SI 3 "register_operand" "c")))
2827 ; (clobber (reg CC_REG))]
2829 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2830 ; (set (match_dup 0)
2831 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2834 (define_expand "subsi3"
2835 [(set (match_operand:SI 0 "dest_reg_operand" "")
2836 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2837 (match_operand:SI 2 "nonmemory_operand" "")))]
2843 if (!register_operand (operands[2], SImode))
2845 operands[1] = force_reg (SImode, operands[1]);
2848 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2849 operands[c] = force_reg (SImode, operands[c]);
2852 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2853 ; combine should make such an insn go away.
2854 (define_insn_and_split "subsi3_insn"
2855 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r, r,r,r,r, r, r, r")
2856 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,q,0,rL,r,L,I,Cal,Cal, r")
2857 (match_operand:SI 2 "nonmemory_operand" "q,q,r, 0,r,r,0, 0, r,Cal")))]
2858 "register_operand (operands[1], SImode)
2859 || register_operand (operands[2], SImode)"
2871 "reload_completed && get_attr_length (insn) == 8
2872 && satisfies_constraint_I (operands[1])
2873 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2874 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2875 "split_subsi (operands);"
2876 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2877 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2878 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2879 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2880 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2883 (define_expand "subdi3"
2884 [(set (match_operand:DI 0 "register_operand" "")
2885 (minus:DI (match_operand:DI 1 "register_operand" "")
2886 (match_operand:DI 2 "nonmemory_operand" "")))
2887 (clobber (reg:CC CC_REG))]
2890 rtx l0 = gen_lowpart (SImode, operands[0]);
2891 rtx h0 = gen_highpart (SImode, operands[0]);
2892 rtx l1 = gen_lowpart (SImode, operands[1]);
2893 rtx h1 = gen_highpart (SImode, operands[1]);
2894 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2895 subreg_lowpart_offset (SImode, DImode));
2896 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2897 subreg_highpart_offset (SImode, DImode));
2899 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2901 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2902 if (!rtx_equal_p (h0, h1))
2903 emit_insn (gen_rtx_SET (h0, h1));
2904 emit_insn (gen_sub_f (l0, l1, l2));
2908 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2909 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2912 emit_insn (gen_sub_f (l0, l1, l2));
2913 emit_insn (gen_sbc (h0, h1, h2));
2917 (define_insn "*sbc_0"
2918 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2919 (minus:SI (match_operand:SI 1 "register_operand" "c")
2920 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2924 [(set_attr "cond" "use")
2925 (set_attr "type" "cc_arith")
2926 (set_attr "length" "4")])
2929 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2932 (match_operand:SI 1 "nonmemory_operand" "r, 0,r,0, r,Cal")
2933 (ltu:SI (reg:CC_C CC_REG) (const_int 0)))
2934 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I,Cal,r")))]
2935 "register_operand (operands[1], SImode)
2936 || register_operand (operands[2], SImode)"
2944 [(set_attr "cond" "use")
2945 (set_attr "type" "cc_arith")
2946 (set_attr "length" "4,4,4,4,8,8")])
2948 (define_insn "sub_f"
2949 [(set (reg:CC CC_REG)
2950 (compare:CC (match_operand:SI 1 "nonmemory_operand" " r,L,0,I,r,Cal")
2951 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0,Cal,r")))
2952 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2953 (minus:SI (match_dup 1) (match_dup 2)))]
2954 "register_operand (operands[1], SImode)
2955 || register_operand (operands[2], SImode)"
2963 [(set_attr "type" "compare")
2964 (set_attr "length" "4,4,4,4,8,8")])
2966 ; combine won't work when an intermediate result is used later...
2967 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2969 [(set (reg:CC CC_REG)
2970 (compare:CC (match_operand:SI 1 "register_operand" "")
2971 (match_operand:SI 2 "nonmemory_operand" "")))
2972 (set (match_operand:SI 0 "dest_reg_operand" "")
2973 (minus:SI (match_dup 1) (match_dup 2)))]
2976 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2977 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2980 [(set (reg:CC CC_REG)
2981 (compare:CC (match_operand:SI 1 "register_operand" "")
2982 (match_operand:SI 2 "nonmemory_operand" "")))
2983 (set (match_operand 3 "" "") (match_operand 4 "" ""))
2984 (set (match_operand:SI 0 "dest_reg_operand" "")
2985 (minus:SI (match_dup 1) (match_dup 2)))]
2986 "!reg_overlap_mentioned_p (operands[3], operands[1])
2987 && !reg_overlap_mentioned_p (operands[3], operands[2])
2988 && !reg_overlap_mentioned_p (operands[0], operands[4])
2989 && !reg_overlap_mentioned_p (operands[0], operands[3])"
2991 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2992 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2993 (set (match_dup 3) (match_dup 4))])
2995 (define_insn "*add_n"
2996 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
2997 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
2998 (match_operand:SI 2 "_2_4_8_operand" ""))
2999 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
3001 "add%z2%?\\t%0,%3,%1"
3002 [(set_attr "type" "shift")
3003 (set_attr "length" "*,4,8")
3004 (set_attr "predicable" "yes,no,no")
3005 (set_attr "cond" "canuse,nocond,nocond")
3006 (set_attr "iscompact" "maybe,false,false")])
3008 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3009 ;; what synth_mult likes.
3010 (define_insn "*sub_n"
3011 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3012 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3013 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
3014 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3016 "sub%c3%?\\t%0,%1,%2"
3017 [(set_attr "type" "shift")
3018 (set_attr "length" "4,4,8")
3019 (set_attr "predicable" "yes,no,no")
3020 (set_attr "cond" "canuse,nocond,nocond")
3021 (set_attr "iscompact" "false")])
3023 (define_insn "*sub_n"
3024 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3025 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3026 (mult:SI (match_operand:SI 2 "register_operand" "r,r,r")
3027 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3029 "sub%z3%?\\t%0,%1,%2"
3030 [(set_attr "type" "shift")
3031 (set_attr "length" "4,4,8")
3032 (set_attr "predicable" "yes,no,no")
3033 (set_attr "cond" "canuse,nocond,nocond")
3034 (set_attr "iscompact" "false")])
3036 ; ??? check if combine matches this.
3037 (define_insn "*bset"
3038 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3039 (ior:SI (ashift:SI (const_int 1)
3040 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3041 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3044 [(set_attr "length" "4,4,8")
3045 (set_attr "predicable" "yes,no,no")
3046 (set_attr "cond" "canuse,nocond,nocond")]
3049 ; ??? check if combine matches this.
3050 (define_insn "*bxor"
3051 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3052 (xor:SI (ashift:SI (const_int 1)
3053 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3054 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3057 [(set_attr "length" "4,4,8")
3058 (set_attr "predicable" "yes,no,no")
3059 (set_attr "cond" "canuse,nocond,nocond")]
3062 ; ??? check if combine matches this.
3063 (define_insn "*bclr"
3064 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3065 (and:SI (not:SI (ashift:SI (const_int 1)
3066 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r")))
3067 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3070 [(set_attr "length" "4,4,8")
3071 (set_attr "predicable" "yes,no,no")
3072 (set_attr "cond" "canuse,nocond,nocond")]
3075 ; ??? FIXME: find combine patterns for bmsk.
3077 ;;Following are the define_insns added for the purpose of peephole2's
3079 ; see also iorsi3 for use with constant bit number.
3080 (define_insn "*bset_insn"
3081 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3082 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3083 (ashift:SI (const_int 1)
3084 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3087 bset%?\\t%0,%1,%2 ;;peep2, constr 1
3088 bset\\t%0,%1,%2 ;;peep2, constr 2
3089 bset\\t%0,%1,%2 ;;peep2, constr 3"
3090 [(set_attr "length" "4,4,8")
3091 (set_attr "predicable" "yes,no,no")
3092 (set_attr "cond" "canuse,nocond,nocond")]
3095 ; see also xorsi3 for use with constant bit number.
3096 (define_insn "*bxor_insn"
3097 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3098 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3099 (ashift:SI (const_int 1)
3100 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3106 [(set_attr "length" "4,4,8")
3107 (set_attr "predicable" "yes,no,no")
3108 (set_attr "cond" "canuse,nocond,nocond")]
3111 ; see also andsi3 for use with constant bit number.
3112 (define_insn "*bclr_insn"
3113 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3114 (and:SI (not:SI (ashift:SI (const_int 1)
3115 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")))
3116 (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")))]
3122 [(set_attr "length" "4,4,8")
3123 (set_attr "predicable" "yes,no,no")
3124 (set_attr "cond" "canuse,nocond,nocond")]
3127 ; see also andsi3 for use with constant bit number.
3128 (define_insn "*bmsk_insn"
3129 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3130 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3131 (plus:SI (ashift:SI (const_int 1)
3132 (plus:SI (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 ;;Instructions added for peephole2s end
3147 ;; Boolean instructions.
3149 (define_expand "andsi3"
3150 [(set (match_operand:SI 0 "dest_reg_operand" "")
3151 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3152 (match_operand:SI 2 "nonmemory_operand" "")))]
3154 "if (!satisfies_constraint_Cux (operands[2]))
3155 operands[1] = force_reg (SImode, operands[1]);
3158 (define_insn "andsi3_i" ;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
3159 [(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")
3160 (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")
3161 (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")))]
3162 "(register_operand (operands[1], SImode)
3163 && nonmemory_operand (operands[2], SImode))
3164 || (memory_operand (operands[1], SImode)
3165 && satisfies_constraint_Cux (operands[2]))"
3167 switch (which_alternative)
3169 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3170 return "and%? %0,%1,%2";
3172 return "and%? %0,%2,%1";
3174 return "bmsk%? %0,%1,%Z2";
3176 if (satisfies_constraint_C2p (operands[2]))
3178 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3179 return "bmskn%? %0,%1,%Z2";
3183 return "bmsk%? %0,%1,%Z2";
3185 case 3: case 8: case 13:
3186 return "bclr%? %0,%1,%M2";
3188 return (INTVAL (operands[2]) == 0xff
3189 ? "extb%? %0,%1" : "ext%_%? %0,%1");
3190 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3192 return "movb.cl %0,%1,%p2,%p2,%x2";
3197 if (satisfies_constraint_Ucm (operands[1]))
3198 tmpl = (INTVAL (operands[2]) == 0xff
3199 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3201 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3203 if (TARGET_BIG_ENDIAN)
3207 xop[0] = operands[0];
3208 xop[1] = adjust_address (operands[1], QImode,
3209 INTVAL (operands[2]) == 0xff ? 3 : 2);
3210 output_asm_insn (tmpl, xop);
3218 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3219 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3220 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3221 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3222 (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")])
3224 ; combiner splitter, pattern found in ldtoa.c .
3225 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3227 [(set (reg:CC_Z CC_REG)
3228 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3229 (match_operand 1 "const_int_operand" ""))
3230 (match_operand 2 "const_int_operand" "")))
3231 (clobber (match_operand:SI 3 "register_operand" ""))]
3232 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3234 (plus:SI (match_dup 0) (match_dup 4)))
3235 (set (reg:CC_Z CC_REG)
3236 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3238 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3240 ;;bic define_insn that allows limm to be the first operand
3241 (define_insn "*bicsi3_insn"
3242 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r,r,r,r")
3243 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "q,Lr,I,Cal,Lr,Cal,r"))
3244 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,r,r,Cal")))]
3247 bic%?\\t%0, %2, %1 ;;constraint 0
3248 bic%?\\t%0,%2,%1 ;;constraint 1
3249 bic\\t%0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3250 bic%?\\t%0,%2,%1 ;;constraint 3, FIXME: will it ever get generated ???
3251 bic\\t%0,%2,%1 ;;constraint 4
3252 bic\\t%0,%2,%1 ;;constraint 5, FIXME: will it ever get generated ???
3253 bic\\t%0,%2,%1 ;;constraint 6"
3254 [(set_attr "length" "*,4,4,8,4,8,8")
3255 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3256 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3257 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3259 (define_insn_and_split "iorsi3"
3260 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r,r, r,r, r, r,r, q, r, r")
3261 (ior:SI (match_operand:SI 1 "register_operand" "%0,q, 0, 0,r, 0,0, r, r,0, r, 0, r")
3262 (match_operand:SI 2 "nonmemory_operand" "q,0,C0p,rL,0,C0p,I,rL,C0p,I,C0x,Cal,Cal")))]
3279 && GET_CODE (PATTERN (insn)) != COND_EXEC
3280 && register_operand (operands[0], SImode)
3281 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
3282 && satisfies_constraint_C0x (operands[2])"
3285 arc_split_ior (operands);
3288 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,false")
3289 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,*,8,8")
3290 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
3291 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,nocond,canuse,nocond")])
3293 (define_insn "xorsi3"
3294 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, r,r, r,r, r, r,r, r, r")
3295 (xor:SI (match_operand:SI 1 "register_operand" "%0,q, 0,r, 0,0, r, r,0, 0, r")
3296 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,0,C0p,I,rL,C0p,I,Cal,Cal")))]
3299 switch (which_alternative)
3301 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3302 return \"xor%?\\t%0,%1,%2\";
3304 return \"xor%?\\t%0,%2,%1\";
3306 return \"bxor%?\\t%0,%1,%z2\";
3311 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3312 (set_attr "type" "binary")
3313 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3314 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3315 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3317 (define_insn "negsi2"
3318 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r")
3319 (neg:SI (match_operand:SI 1 "register_operand" "0,q,0,r")))]
3322 [(set_attr "type" "unary")
3323 (set_attr "iscompact" "maybe,true,false,false")
3324 (set_attr "predicable" "no,no,yes,no")])
3326 (define_insn "one_cmplsi2"
3327 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
3328 (not:SI (match_operand:SI 1 "register_operand" "q,c")))]
3331 [(set_attr "type" "unary,unary")
3332 (set_attr "iscompact" "true,false")])
3334 (define_insn_and_split "one_cmpldi2"
3335 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3336 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3339 "&& reload_completed"
3340 [(set (match_dup 2) (not:SI (match_dup 3)))
3341 (set (match_dup 4) (not:SI (match_dup 5)))]
3343 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3345 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3346 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3347 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3348 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3350 [(set_attr "type" "unary,unary")
3351 (set_attr "cond" "nocond,nocond")
3352 (set_attr "length" "4,8")])
3354 ;; Shift instructions.
3356 (define_expand "ashlsi3"
3357 [(set (match_operand:SI 0 "dest_reg_operand" "")
3358 (ashift:SI (match_operand:SI 1 "register_operand" "")
3359 (match_operand:SI 2 "nonmemory_operand" "")))]
3362 (define_expand "ashrsi3"
3363 [(set (match_operand:SI 0 "dest_reg_operand" "")
3364 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3365 (match_operand:SI 2 "nonmemory_operand" "")))]
3368 (define_expand "lshrsi3"
3369 [(set (match_operand:SI 0 "dest_reg_operand" "")
3370 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3371 (match_operand:SI 2 "nonmemory_operand" "")))]
3374 ; asl, asr, lsr patterns:
3375 ; There is no point in including an 'I' alternative since only the lowest 5
3376 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3377 ; is defined in an external symbol, as we don't have special relocations
3378 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3379 ; provide one alternatice for this, without condexec support.
3380 (define_insn "*ashlsi3_insn"
3381 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3382 (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3383 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3384 "TARGET_BARREL_SHIFTER
3385 && (register_operand (operands[1], SImode)
3386 || register_operand (operands[2], SImode))"
3388 [(set_attr "type" "shift")
3389 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3390 (set_attr "predicable" "no,no,no,yes,no,no")
3391 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3393 (define_insn "*ashrsi3_insn"
3394 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3395 (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3396 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3397 "TARGET_BARREL_SHIFTER
3398 && (register_operand (operands[1], SImode)
3399 || register_operand (operands[2], SImode))"
3401 [(set_attr "type" "shift")
3402 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3403 (set_attr "predicable" "no,no,no,yes,no,no")
3404 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3406 (define_insn "*lshrsi3_insn"
3407 [(set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, r, r")
3408 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "q, 0, 0, r,rCal")
3409 (match_operand:SI 2 "nonmemory_operand" "N,qM,rL,rL,rCal")))]
3410 "TARGET_BARREL_SHIFTER
3411 && (register_operand (operands[1], SImode)
3412 || register_operand (operands[2], SImode))"
3419 [(set_attr "type" "shift")
3420 (set_attr "iscompact" "maybe,maybe,false,false,false")
3421 (set_attr "predicable" "no,no,yes,no,no")
3422 (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")])
3424 (define_insn_and_split "*ashlsi3_nobs"
3425 [(set (match_operand:SI 0 "dest_reg_operand")
3426 (ashift:SI (match_operand:SI 1 "register_operand")
3427 (match_operand:SI 2 "nonmemory_operand")))]
3428 "!TARGET_BARREL_SHIFTER
3429 && operands[2] != const1_rtx
3430 && arc_pre_reload_split ()"
3435 if (CONST_INT_P (operands[2]))
3437 int n = INTVAL (operands[2]) & 0x1f;
3441 emit_move_insn (operands[0], operands[1]);
3444 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
3446 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
3450 rtx zero = gen_reg_rtx (SImode);
3451 emit_move_insn (zero, const0_rtx);
3452 emit_insn (gen_add_shift (operands[0], operands[1],
3453 GEN_INT (3), zero));
3454 for (n -= 3; n >= 3; n -= 3)
3455 emit_insn (gen_add_shift (operands[0], operands[0],
3456 GEN_INT (3), zero));
3458 emit_insn (gen_add_shift (operands[0], operands[0],
3461 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
3471 emit_insn (gen_andsi3_i (operands[0], operands[1],
3473 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
3476 emit_insn (gen_andsi3_i (operands[0], operands[1],
3478 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
3481 emit_insn (gen_andsi3_i (operands[0], operands[1], const1_rtx));
3482 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
3487 rtx shift = gen_rtx_fmt_ee (ASHIFT, SImode, operands[1], operands[2]);
3488 emit_insn (gen_shift_si3_loop (operands[0], operands[1],
3489 operands[2], shift));
3493 (define_insn_and_split "*ashlri3_nobs"
3494 [(set (match_operand:SI 0 "dest_reg_operand")
3495 (ashiftrt:SI (match_operand:SI 1 "register_operand")
3496 (match_operand:SI 2 "nonmemory_operand")))]
3497 "!TARGET_BARREL_SHIFTER
3498 && operands[2] != const1_rtx
3499 && arc_pre_reload_split ()"
3504 if (CONST_INT_P (operands[2]))
3506 int n = INTVAL (operands[2]) & 0x1f;
3511 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
3513 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
3516 emit_move_insn (operands[0], operands[1]);
3522 rtx shift = gen_rtx_fmt_ee (ASHIFTRT, SImode, operands[1], operands[2]);
3523 if (shiftr4_operator (shift, SImode))
3524 pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
3526 pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
3531 (define_insn_and_split "*lshrsi3_nobs"
3532 [(set (match_operand:SI 0 "dest_reg_operand")
3533 (lshiftrt:SI (match_operand:SI 1 "register_operand")
3534 (match_operand:SI 2 "nonmemory_operand")))]
3535 "!TARGET_BARREL_SHIFTER
3536 && operands[2] != const1_rtx
3537 && arc_pre_reload_split ()"
3542 if (CONST_INT_P (operands[2]))
3544 int n = INTVAL (operands[2]) & 0x1f;
3549 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
3551 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
3554 emit_move_insn (operands[0], operands[1]);
3560 rtx shift = gen_rtx_fmt_ee (LSHIFTRT, SImode, operands[1], operands[2]);
3561 if (shiftr4_operator (shift, SImode))
3562 pat = gen_shift_si3 (operands[0], operands[1], operands[2], shift);
3564 pat = gen_shift_si3_loop (operands[0], operands[1], operands[2], shift);
3569 ;; shift_si3 appears after {ashr,lshr}si3_nobs
3570 (define_insn "shift_si3"
3571 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3572 (match_operator:SI 3 "shiftr4_operator"
3573 [(match_operand:SI 1 "register_operand" "0")
3574 (match_operand:SI 2 "const_int_operand" "n")]))
3575 (clobber (match_scratch:SI 4 "=&r"))
3576 (clobber (reg:CC CC_REG))
3578 "!TARGET_BARREL_SHIFTER
3579 && operands[2] != const1_rtx"
3580 "* return output_shift (operands);"
3581 [(set_attr "type" "shift")
3582 (set_attr "length" "16")])
3584 ;; shift_si3_loop appears after {ashl,ashr,lshr}si3_nobs
3585 (define_insn "shift_si3_loop"
3586 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3587 (match_operator:SI 3 "shift_operator"
3588 [(match_operand:SI 1 "register_operand" "0,0")
3589 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3590 (clobber (reg:SI LP_COUNT))
3591 (clobber (reg:CC CC_REG))
3593 "!TARGET_BARREL_SHIFTER
3594 && operands[2] != const1_rtx"
3595 "* return output_shift (operands);"
3596 [(set_attr "type" "shift")
3597 (set_attr "length" "16,20")])
3599 ;; Rotate instructions.
3601 (define_insn "rotrsi3"
3602 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
3603 (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz")
3604 (match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))]
3605 "TARGET_BARREL_SHIFTER"
3607 [(set_attr "type" "shift,shift,shift")
3608 (set_attr "predicable" "yes,no,no")
3609 (set_attr "length" "4,4,8")])
3611 ;; Compare / branch instructions.
3613 (define_expand "cbranchsi4"
3614 [(set (reg:CC CC_REG)
3615 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3616 (match_operand:SI 2 "nonmemory_operand" "")))
3619 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3621 (label_ref (match_operand 3 "" ""))
3625 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3626 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3627 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3628 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3632 ;; ??? Could add a peephole to generate compare with swapped operands and
3633 ;; modifed cc user if second, but not first operand is a compact register.
3634 (define_insn "cmpsi_cc_insn_mixed"
3635 [(set (reg:CC CC_REG)
3636 (compare:CC (match_operand:SI 0 "register_operand" "q, q, h, c, c, q,c")
3637 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,cL,Cal,Cal")))]
3640 [(set_attr "type" "compare")
3641 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3642 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3643 (set_attr "cond" "set")
3644 (set_attr "length" "*,*,*,4,4,*,8")
3645 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3647 (define_insn "*cmpsi_cc_zn_insn"
3648 [(set (reg:CC_ZN CC_REG)
3649 (compare:CC_ZN (match_operand:SI 0 "register_operand" "q,c")
3653 [(set_attr "type" "compare,compare")
3654 (set_attr "iscompact" "true,false")
3655 (set_attr "predicable" "no,yes")
3656 (set_attr "cond" "set_zn")
3657 (set_attr "length" "*,4")])
3659 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3660 (define_insn "*btst"
3661 [(set (reg:CC_ZN CC_REG)
3663 (zero_extract:SI (match_operand:SI 0 "register_operand" "q,c")
3665 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3669 [(set_attr "iscompact" "true,false")
3670 (set_attr "predicable" "no,yes")
3671 (set_attr "cond" "set")
3672 (set_attr "type" "compare")
3673 (set_attr "length" "*,4")])
3675 (define_insn "*cmpsi_cc_z_insn"
3676 [(set (reg:CC_Z CC_REG)
3677 (compare:CC_Z (match_operand:SI 0 "register_operand" "q,c")
3678 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3683 [(set_attr "type" "compare,compare")
3684 (set_attr "iscompact" "true,false")
3685 (set_attr "cond" "set,set_zn")
3686 (set_attr "length" "*,4")])
3688 (define_insn "*cmpsi_cc_c_insn"
3689 [(set (reg:CC_C CC_REG)
3690 (compare:CC_C (match_operand:SI 0 "register_operand" "q, q, h, c, q, c")
3691 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,Cal,Cal")))]
3694 [(set_attr "type" "compare")
3695 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3696 (set_attr "cond" "set")
3697 (set_attr "length" "*,*,*,4,*,8")
3698 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3700 ;; Next come the scc insns.
3702 (define_expand "cstoresi4"
3703 [(set (match_operand:SI 0 "dest_reg_operand" "")
3704 (match_operator:SI 1 "ordered_comparison_operator"
3705 [(match_operand:SI 2 "nonmemory_operand" "")
3706 (match_operand:SI 3 "nonmemory_operand" "")]))]
3709 if (!TARGET_CODE_DENSITY)
3711 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3712 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3713 operands[1] = gen_compare_reg (operands[1], SImode);
3714 emit_insn (gen_scc_insn (operands[0], operands[1]));
3717 if (!register_operand (operands[2], SImode))
3718 operands[2] = force_reg (SImode, operands[2]);
3722 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3723 (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")])
3725 (define_expand "cstore<mode>4"
3726 [(set (reg:CC CC_REG)
3727 (compare:CC (match_operand:SDF 2 "register_operand" "")
3728 (match_operand:SDF 3 "register_operand" "")))
3729 (set (match_operand:SI 0 "dest_reg_operand" "")
3730 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3733 "TARGET_HARD_FLOAT || TARGET_OPTFPE"
3735 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3736 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3737 operands[1] = gen_compare_reg (operands[1], SImode);
3738 emit_insn (gen_scc_insn (operands[0], operands[1]));
3742 ; We need a separate expander for this lest we loose the mode of CC_REG
3743 ; when match_operator substitutes the literal operand into the comparison.
3744 (define_expand "scc_insn"
3745 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3747 (define_mode_iterator CC_ltu [CC_C CC])
3749 (define_insn "scc_ltu_<mode>"
3750 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3751 (ltu:SI (reg:CC_ltu CC_REG) (const_int 0)))]
3754 [(set_attr "type" "shift")
3755 (set_attr "predicable" "no")
3756 (set_attr "length" "4")])
3758 (define_insn_and_split "*scc_insn"
3759 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3760 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3764 && GET_CODE (operands[1]) != LTU"
3765 [(set (match_dup 0) (const_int 1))
3768 (set (match_dup 0) (const_int 0)))]
3771 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3772 GET_MODE (XEXP (operands[1], 0))),
3774 XEXP (operands[1], 0), XEXP (operands[1], 1));
3776 [(set_attr "type" "unary")])
3778 ; cond_exec patterns
3779 (define_insn "*movsi_ne"
3781 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0))
3782 (set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, q, r")
3783 (match_operand:SI 1 "nonmemory_operand" "C_0, h, Lr,Cal,Cal")))]
3786 * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\";
3787 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3789 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3791 [(set_attr "type" "cmove")
3792 (set_attr "iscompact" "true,true,false,true_limm,false")
3793 (set_attr "length" "2,2,4,6,8")
3794 (set_attr "cpu_facility" "*,av2,*,av2,*")])
3796 (define_insn "*movsi_cond_exec"
3798 (match_operator 3 "proper_comparison_operator"
3799 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3800 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3801 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3804 [(set_attr "type" "cmove")
3805 (set_attr "length" "4,8")])
3807 (define_insn "*commutative_cond_exec"
3809 (match_operator 5 "proper_comparison_operator"
3810 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3811 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3812 (match_operator:SI 3 "commutative_operator"
3813 [(match_operand:SI 1 "register_operand" "%0,0")
3814 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3817 arc_output_commutative_cond_exec (operands, true);
3820 [(set_attr "cond" "use")
3821 (set_attr "type" "cmove")
3822 (set_attr_alternative "length"
3825 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3830 (define_insn "*sub_cond_exec"
3832 (match_operator 4 "proper_comparison_operator"
3833 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3834 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3835 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3836 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3842 [(set_attr "cond" "use")
3843 (set_attr "type" "cmove")
3844 (set_attr "length" "4,4,8")])
3846 (define_insn "*noncommutative_cond_exec"
3848 (match_operator 5 "proper_comparison_operator"
3849 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3850 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3851 (match_operator:SI 3 "noncommutative_operator"
3852 [(match_operand:SI 1 "register_operand" "0,0")
3853 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3856 [(set_attr "cond" "use")
3857 (set_attr "type" "cmove")
3858 (set_attr "length" "4,8")])
3860 ;; These control RTL generation for conditional jump insns
3861 ;; Match both normal and inverted jump.
3863 ; We need a separate expander for this lest we loose the mode of CC_REG
3864 ; when match_operator substitutes the literal operand into the comparison.
3865 (define_expand "branch_insn"
3867 (if_then_else (match_operand 1 "" "")
3868 (label_ref (match_operand 0 "" ""))
3871 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3872 ; are three reasons why we need to consider branches to be length 6:
3873 ; - annull-false delay slot insns are implemented using conditional execution,
3874 ; thus preventing short insn formation where used.
3875 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3876 ; using conditional execution, preventing short insn formation where used.
3877 ; - for ARC700: likely or somewhat likely taken branches are made long and
3878 ; unaligned if possible to avoid branch penalty.
3879 (define_insn "*branch_insn"
3881 (if_then_else (match_operator 1 "proper_comparison_operator"
3882 [(reg CC_REG) (const_int 0)])
3883 (label_ref (match_operand 0 "" ""))
3888 if (get_attr_length (insn) == 2)
3889 return \"b%d1%?\\t%l0\";
3891 return \"b%d1%*\\t%l0\";
3893 [(set_attr "type" "branch")
3897 (eq_attr "delay_slot_filled" "yes")
3902 (match_operand 1 "equality_comparison_operator" "")
3903 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3904 (gt (minus (match_dup 0) (pc))
3905 (minus (const_int 506)
3906 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3907 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3908 (lt (minus (match_dup 0) (pc)) (const_int -64))
3909 (gt (minus (match_dup 0) (pc))
3910 (minus (const_int 58)
3911 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3916 (set (attr "iscompact")
3917 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3918 (const_string "false")))])
3920 (define_insn "*rev_branch_insn"
3922 (if_then_else (match_operator 1 "proper_comparison_operator"
3923 [(reg CC_REG) (const_int 0)])
3925 (label_ref (match_operand 0 "" ""))))]
3926 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3928 [(set_attr "type" "branch")
3932 (eq_attr "delay_slot_filled" "yes")
3937 (match_operand 1 "equality_comparison_operator" "")
3938 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3939 (gt (minus (match_dup 0) (pc))
3940 (minus (const_int 506)
3941 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3942 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3943 (lt (minus (match_dup 0) (pc)) (const_int -64))
3944 (gt (minus (match_dup 0) (pc))
3945 (minus (const_int 58)
3946 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3951 (set (attr "iscompact")
3952 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3953 (const_string "false")))])
3955 ;; Unconditional and other jump instructions.
3957 (define_expand "jump"
3958 [(set (pc) (label_ref (match_operand 0 "" "")))]
3962 (define_insn "jump_i"
3963 [(set (pc) (label_ref (match_operand 0 "" "")))]
3964 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3966 [(set_attr "type" "uncond_branch")
3967 (set (attr "iscompact")
3968 (if_then_else (match_test "get_attr_length (insn) == 2")
3969 (const_string "true") (const_string "false")))
3970 (set_attr "cond" "canuse")
3971 (set (attr "length")
3973 ; In arc_reorg we just guesstimate; might be more or less than 4.
3974 (match_test "arc_branch_size_unknown_p ()")
3977 (eq_attr "delay_slot_filled" "yes")
3980 (match_test "CROSSING_JUMP_P (insn)")
3983 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3984 (gt (minus (match_dup 0) (pc))
3985 (minus (const_int 506)
3986 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3990 (define_insn "indirect_jump"
3991 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,q,r"))]
3999 [(set_attr "type" "jump")
4000 (set_attr "iscompact" "false,false,false,maybe,false")
4001 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
4003 ;; Implement a switch statement.
4004 (define_expand "casesi"
4005 [(match_operand:SI 0 "register_operand" "") ; Index
4006 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
4007 (match_operand:SI 2 "const_int_operand" "") ; Total range
4008 (match_operand:SI 3 "" "") ; Table label
4009 (match_operand:SI 4 "" "")] ; Out of range label
4012 if (operands[1] != const0_rtx)
4014 rtx reg = gen_reg_rtx (SImode);
4015 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
4018 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0],
4020 operands[0], operands[2], operands[4]));
4022 emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3]));
4025 rtx reg = gen_reg_rtx (SImode);
4026 rtx lbl = operands[3];
4027 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4029 operands[3] = force_reg (Pmode, operands[3]);
4030 emit_insn (gen_casesi_load (reg,
4031 operands[3], operands[0], lbl));
4032 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4033 emit_insn (gen_addsi3 (reg, reg, operands[3]));
4034 emit_jump_insn (gen_casesi_jump (reg, lbl));
4039 (define_insn "casesi_dispatch"
4041 (unspec:SI [(match_operand:SI 0 "register_operand" "r")
4042 (label_ref (match_operand 1 "" ""))]
4043 UNSPEC_ARC_CASESI))]
4046 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4047 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4048 switch (GET_MODE (diff_vec))
4051 return \"bi\\t[%0]\";
4054 return \"bih\\t[%0]\";
4055 default: gcc_unreachable ();
4058 [(set_attr "type" "brcc_no_delay_slot")
4059 (set_attr "iscompact" "false")
4060 (set_attr "length" "4")])
4062 (define_insn "casesi_load"
4063 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
4064 (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal")
4065 (match_operand:SI 2 "register_operand" "q,r,r")]
4066 UNSPEC_ARC_CASESI)))
4067 (use (label_ref (match_operand 3 "" "")))]
4071 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4073 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4075 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4076 gcc_assert (GET_MODE (diff_vec) == SImode);
4077 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4080 switch (GET_MODE (diff_vec))
4083 return \"ld.as\\t%0,[%1,%2]\";
4085 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4086 return \"ld%_.as\\t%0,[%1,%2]\";
4087 return \"ld%_.x.as\\t%0,[%1,%2]\";
4089 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4090 return \"ldb%?\\t%0,[%1,%2]\";
4091 return \"ldb.x\\t%0,[%1,%2]\";
4096 [(set_attr "type" "load")
4097 (set_attr_alternative "iscompact"
4099 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4100 (as_a<rtx_insn *> (operands[3]))))")
4101 (symbol_ref "QImode"))
4102 (const_string "false")
4103 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4104 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4105 (const_string "false")]
4106 (const_string "true"))
4107 (const_string "false")
4108 (const_string "false")])
4109 (set_attr_alternative "length"
4111 [(eq_attr "iscompact" "false") (const_int 4)
4112 ; We have to mention (match_dup 3) to convince genattrtab.cc that this
4113 ; is a varying length insn.
4114 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4115 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4120 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4121 ; even for CASE_VECTOR_PC_RELATIVE.
4122 (define_insn "casesi_jump"
4123 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,q,c"))
4124 (use (label_ref (match_operand 1 "" "")))]
4127 [(set_attr "type" "jump")
4128 (set_attr "iscompact" "false,maybe,false")
4129 (set_attr "cond" "canuse")])
4131 (define_expand "call"
4132 ;; operands[1] is stack_size_rtx
4133 ;; operands[2] is next_arg_register
4134 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4135 (match_operand 1 "" ""))
4136 (clobber (reg:SI 31))])]
4141 gcc_assert (MEM_P (operands[0]));
4142 callee = XEXP (operands[0], 0);
4143 /* This is to decide if we should generate indirect calls by loading the
4144 32 bit address of the callee into a register before performing the
4145 branch and link - this exposes cse opportunities.
4146 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4147 if (GET_CODE (callee) != REG
4148 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4149 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4153 ; At instruction output time, if it doesn't match and we end up with
4154 ; alternative 1 ("q"), that means that we can't use the short form.
4155 (define_insn "*call_i"
4156 [(call (mem:SI (match_operand:SI 0
4157 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4158 (match_operand 1 "" ""))
4159 (clobber (reg:SI 31))]
4171 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4172 (set_attr "iscompact" "maybe,*,true,*,*,*,*,*,*")
4173 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4174 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4176 (define_expand "call_value"
4177 ;; operand 2 is stack_size_rtx
4178 ;; operand 3 is next_arg_register
4179 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4180 (call (match_operand:SI 1 "call_operand" "")
4181 (match_operand 2 "" "")))
4182 (clobber (reg:SI 31))])]
4188 gcc_assert (MEM_P (operands[1]));
4189 callee = XEXP (operands[1], 0);
4190 /* See the comment in define_expand \"call\". */
4191 if (GET_CODE (callee) != REG
4192 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4193 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4196 ; At instruction output time, if it doesn't match and we end up with
4197 ; alternative 1 ("q"), that means that we can't use the short form.
4198 (define_insn "*call_value_i"
4199 [(set (match_operand 0 "dest_reg_operand" "=q,w, w, w, w, w,w,w, w")
4200 (call (mem:SI (match_operand:SI 1
4201 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4202 (match_operand 2 "" "")))
4203 (clobber (reg:SI 31))]
4215 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4216 (set_attr "iscompact" "maybe,*,true,false,*,*,*,*,*")
4217 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4218 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4220 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4221 ; use it for lack of inter-procedural branch shortening.
4222 ; Link-time relaxation would help...
4225 [(trap_if (const_int 1) (const_int 0))]
4226 "!TARGET_ARC600_FAMILY"
4228 [(set_attr "type" "misc")
4229 (set_attr "length" "2")])
4235 [(set_attr "type" "misc")
4236 (set_attr "iscompact" "true")
4237 (set_attr "cond" "canuse")
4238 (set_attr "length" "2")])
4241 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4244 [(set_attr "type" "misc")
4245 (set_attr "iscompact" "maybe")
4246 (set_attr "length" "*")])
4248 (define_insn "blockage"
4249 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)]
4252 [(set_attr "length" "0")
4253 (set_attr "type" "block")]
4256 (define_insn "arc600_stall"
4257 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_ARC600_STALL)]
4259 "mov\\t0,mlo\t;wait until multiply complete."
4260 [(set_attr "length" "4")
4261 (set_attr "type" "move")]
4264 ;; Split up troublesome insns for better scheduling.
4266 ;; Peepholes go at the end.
4267 ;;asl followed by add can be replaced by an add{1,2,3}
4268 ;; Three define_peepholes have been added for this optimization
4269 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4270 ;; can be generated by combine. Check if these peepholes still provide
4273 ;; -------------------------------------------------------------
4274 ;; Pattern 1 : r0 = r1 << {i}
4275 ;; r3 = r4/INT + r0 ;;and commutative
4278 ;; add{i} r3,r4/INT,r1
4279 ;; -------------------------------------------------------------
4280 ;; ??? This should be covered by combine, alas, at times combine gets
4281 ;; too clever for it's own good: when the shifted input is known to be
4282 ;; either 0 or 1, the operation will be made into an if-then-else, and
4283 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4284 ;; newlib/libc/time/mktm_r.c .
4287 [(set (match_operand:SI 0 "dest_reg_operand" "")
4288 (ashift:SI (match_operand:SI 1 "register_operand" "")
4289 (match_operand:SI 2 "_1_2_3_operand" "")))
4290 (set (match_operand:SI 3 "dest_reg_operand" "")
4291 (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
4292 (match_operand:SI 5 "arc_nonmemory_operand" "")))]
4293 "(true_regnum (operands[4]) == true_regnum (operands[0])
4294 || true_regnum (operands[5]) == true_regnum (operands[0]))
4295 && (peep2_reg_dead_p (2, operands[0])
4296 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4297 ;; the preparation statements take care to put proper operand in
4298 ;; operands[4] operands[4] will always contain the correct
4299 ;; operand. This is added to satisfy commutativity
4301 (plus:SI (mult:SI (match_dup 1)
4304 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4305 operands[4] = operands[5];
4306 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4309 ;; -------------------------------------------------------------
4310 ;; Pattern 1 : r0 = r1 << {i}
4315 ;; -------------------------------------------------------------
4316 ;; ??? This should be covered by combine, alas, at times combine gets
4317 ;; too clever for it's own good: when the shifted input is known to be
4318 ;; either 0 or 1, the operation will be made into an if-then-else, and
4319 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4320 ;; newlib/libm/math/e_jn.c .
4323 [(set (match_operand:SI 0 "dest_reg_operand" "")
4324 (ashift:SI (match_operand:SI 1 "register_operand" "")
4325 (match_operand:SI 2 "const_int_operand" "")))
4326 (set (match_operand:SI 3 "dest_reg_operand" "")
4327 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4329 "(INTVAL (operands[2]) == 1
4330 || INTVAL (operands[2]) == 2
4331 || INTVAL (operands[2]) == 3)
4332 && (peep2_reg_dead_p (2, operands[0])
4333 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4335 (minus:SI (match_dup 4)
4336 (mult:SI (match_dup 1)
4338 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4343 ; When using the high single bit, the result of a multiply is either
4344 ; the original number or zero. But MPY costs 4 cycles, which we
4345 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4347 [(set (match_operand:SI 0 "dest_reg_operand" "")
4348 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4350 (set (match_operand:SI 4 "register_operand" "")
4351 (mult:SI (match_operand:SI 2 "register_operand")
4352 (match_operand:SI 3 "nonmemory_operand" "")))]
4354 && (rtx_equal_p (operands[0], operands[2])
4355 || rtx_equal_p (operands[0], operands[3]))
4356 && peep2_regno_dead_p (0, CC_REG)
4357 && (rtx_equal_p (operands[0], operands[4])
4358 || (peep2_reg_dead_p (2, operands[0])
4359 && peep2_reg_dead_p (1, operands[4])))"
4360 [(parallel [(set (reg:CC_Z CC_REG)
4361 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4363 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4365 (ne (reg:CC_Z CC_REG) (const_int 0))
4366 (set (match_dup 4) (match_dup 5)))]
4368 if (!rtx_equal_p (operands[0], operands[2]))
4369 operands[5] = operands[2];
4370 else if (!rtx_equal_p (operands[0], operands[3]))
4371 operands[5] = operands[3];
4373 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4377 [(set (match_operand:SI 0 "dest_reg_operand" "")
4378 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4380 (set (match_operand:SI 4 "register_operand" "")
4381 (mult:SI (match_operand:SI 2 "register_operand")
4382 (match_operand:SI 3 "nonmemory_operand" "")))]
4384 && (rtx_equal_p (operands[0], operands[2])
4385 || rtx_equal_p (operands[0], operands[3]))
4386 && peep2_regno_dead_p (2, CC_REG)"
4387 [(parallel [(set (reg:CC_Z CC_REG)
4388 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4390 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4391 (set (match_dup 4) (match_dup 5))
4393 (eq (reg:CC_Z CC_REG) (const_int 0))
4394 (set (match_dup 4) (const_int 0)))]
4395 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4397 ;; Instructions generated through builtins
4399 (define_insn "clrsbsi2"
4400 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4401 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))]
4404 [(set_attr "length" "4,8")
4405 (set_attr "type" "two_cycle_core,two_cycle_core")])
4407 (define_insn "norm_f"
4408 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4409 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))
4410 (set (reg:CC_ZN CC_REG)
4411 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4414 [(set_attr "length" "4,8")
4415 (set_attr "type" "two_cycle_core,two_cycle_core")])
4417 (define_insn_and_split "clrsbhi2"
4418 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4419 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4423 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4424 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4426 (define_insn "normw"
4427 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4429 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4434 [(set_attr "length" "4,8")
4435 (set_attr "type" "two_cycle_core,two_cycle_core")])
4437 (define_expand "clzsi2"
4439 [(set (match_operand:SI 0 "register_operand" "")
4440 (clz:SI (match_operand:SI 1 "register_operand" "")))
4441 (clobber (match_dup 2))])]
4446 /* ARCv2's FLS is a bit more optimal than using norm. */
4447 rtx tmp = gen_reg_rtx (SImode);
4448 emit_insn (gen_fls (tmp, operands[1]));
4449 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), tmp));
4452 operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);
4455 (define_insn_and_split "*arc_clzsi2"
4456 [(set (match_operand:SI 0 "register_operand" "=r")
4457 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4458 (clobber (reg:CC_ZN CC_REG))]
4464 emit_insn (gen_norm_f (operands[0], operands[1]));
4468 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4469 gen_rtx_SET (operands[0], const0_rtx)));
4473 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4474 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4477 [(set_attr "type" "unary")
4478 (set_attr "length" "12")])
4480 (define_expand "ctzsi2"
4481 [(match_operand:SI 0 "register_operand" "")
4482 (match_operand:SI 1 "register_operand" "")]
4487 emit_insn (gen_ffs (operands[0], operands[1]));
4490 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4494 (define_insn_and_split "arc_ctzsi2"
4495 [(set (match_operand:SI 0 "register_operand" "=r")
4496 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4497 (clobber (reg:CC_ZN CC_REG))
4498 (clobber (match_scratch:SI 2 "=&r"))]
4504 rtx temp = operands[0];
4506 if (reg_overlap_mentioned_p (temp, operands[1])
4507 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4508 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4511 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4512 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4513 emit_insn (gen_clrsbsi2 (operands[0], temp));
4517 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4518 gen_rtx_SET (operands[0], GEN_INT (32))));
4522 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4523 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4527 [(set_attr "type" "unary")
4528 (set_attr "length" "20")])
4531 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4532 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4539 [(set_attr "length" "4,8,4")
4540 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4542 (define_insn "divaw"
4543 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4544 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4545 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4547 "TARGET_ARC700 || TARGET_EA_SET"
4552 [(set_attr "length" "4,8,8")
4553 (set_attr "type" "divaw,divaw,divaw")])
4556 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4563 [(set_attr "length" "4,4,8")
4564 (set_attr "type" "misc,misc,misc")
4565 (set_attr "predicable" "yes,no,yes")
4566 (set_attr "cond" "clob,clob,clob")])
4569 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4573 [(set_attr "length" "4")
4574 (set_attr "type" "misc")])
4578 (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)]
4579 "!TARGET_ARC600_FAMILY"
4581 [(set_attr "length" "4")
4582 (set_attr "type" "rtie")
4583 (set_attr "cond" "clob")])
4586 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4590 [(set_attr "length" "4")
4591 (set_attr "type" "misc")])
4594 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4604 [(set_attr "length" "4")
4605 (set_attr "type" "misc")])
4608 (define_insn "sleep"
4609 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "Lr")]
4613 [(set_attr "length" "4")
4614 (set_attr "type" "misc")])
4616 (define_insn "core_read"
4617 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4618 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4619 VUNSPEC_ARC_CORE_READ))]
4622 if (check_if_valid_regno_const (operands, 1))
4623 return \"mov \t%0, r%1\";
4624 return \"mov \t%0, r%1\";
4626 [(set_attr "length" "4")
4627 (set_attr "type" "unary")])
4629 (define_insn "core_write"
4630 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4631 (match_operand:SI 1 "general_operand" "Hn,!r")]
4632 VUNSPEC_ARC_CORE_WRITE)]
4635 if (check_if_valid_regno_const (operands, 1))
4636 return \"mov \tr%1, %0\";
4637 return \"mov \tr%1, %0\";
4639 [(set_attr "length" "4")
4640 (set_attr "type" "unary")])
4643 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4644 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4648 [(set_attr "length" "4,8,4,8")
4649 (set_attr "type" "lr,lr,lr,lr")])
4652 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4653 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4657 [(set_attr "length" "8,4,8,4")
4658 (set_attr "type" "sr,sr,sr,sr")])
4660 (define_mode_iterator ALLI [QI HI SI (DI "TARGET_LL64")])
4661 (define_mode_attr mALLI [(QI "b") (HI "%_") (SI "") (DI "d")])
4663 (define_insn "lddi<mode>"
4664 [(set (match_operand:ALLI 0 "register_operand" "=r")
4665 (unspec_volatile:ALLI [(match_operand:ALLI 1 "memory_operand" "m")]
4668 "ld<mALLI>%U1.di\\t%0,%1"
4669 [(set_attr "type" "load")])
4671 (define_insn "stdi<mode>"
4672 [(unspec_volatile [(match_operand:ALLI 0 "memory_operand" "m,m,Usc")
4673 (match_operand:ALLI 1 "nonmemory_operand" "r,Cm3,i")]
4676 "st<mALLI>%U0.di\\t%1,%0"
4677 [(set_attr "length" "*,*,8")
4678 (set_attr "type" "store")])
4680 (define_insn_and_split "*stdidi_split"
4681 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")
4682 (match_operand:DI 1 "register_operand" "r")]
4686 "&& reload_completed"
4687 [(unspec_volatile:SI [(match_dup 2) (match_dup 3)] VUNSPEC_ARC_STDI)
4688 (unspec_volatile:SI [(match_dup 4) (match_dup 5)] VUNSPEC_ARC_STDI)]
4691 operands[3] = gen_lowpart (SImode, operands[1]);
4692 operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
4693 operands[2] = gen_lowpart (SImode, operands[0]);
4694 operands[4] = gen_highpart (SImode, operands[0]);
4699 (define_insn_and_split "*lddidi_split"
4700 [(set (match_operand:DI 0 "register_operand" "=r")
4701 (unspec_volatile:DI [(match_operand:DI 1 "memory_operand" "m")]
4705 "&& reload_completed"
4706 [(set (match_dup 2) (unspec_volatile:SI [(match_dup 3)] VUNSPEC_ARC_LDDI))
4707 (set (match_dup 4) (unspec_volatile:SI [(match_dup 5)] VUNSPEC_ARC_LDDI))]
4710 operands[3] = gen_lowpart (SImode, operands[1]);
4711 operands[5] = gen_highpart (SImode, operands[1]);
4712 operands[2] = gen_lowpart (SImode, operands[0]);
4713 operands[4] = gen_highpart (SImode, operands[0]);
4718 (define_insn "trap_s"
4719 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4720 VUNSPEC_ARC_TRAP_S)]
4721 "!TARGET_ARC600_FAMILY"
4723 if (which_alternative == 0)
4725 return \"trap_s %0\";
4728 /* Keep this message in sync with the one in arc.cc:arc_expand_builtin,
4729 because *.md files do not get scanned by exgettext. */
4730 fatal_error (input_location,
4731 \"operand to %<trap_s%> should be an unsigned 6-bit value\");
4733 [(set_attr "length" "2")
4734 (set_attr "type" "misc")])
4736 (define_insn "unimp_s"
4737 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4738 VUNSPEC_ARC_UNIMP_S)]
4739 "!TARGET_ARC600_FAMILY"
4741 [(set_attr "length" "4")
4742 (set_attr "type" "misc")])
4744 ;; End of instructions generated through builtins
4746 ; Since the demise of REG_N_SETS as reliable data readily available to the
4747 ; target, it is no longer possible to find out
4748 ; in the prologue / epilogue expanders how many times blink is set.
4749 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4750 ; any explicit use of blink will cause it to be saved; hence we cannot
4751 ; represent the blink use in return / sibcall instructions themselves, and
4752 ; instead have to show it in EPILOGUE_USES and must explicitly
4753 ; forbid instructions that change blink in the return / sibcall delay slot.
4754 (define_expand "sibcall"
4755 [(parallel [(call (match_operand 0 "memory_operand" "")
4756 (match_operand 1 "general_operand" ""))
4758 (use (match_operand 2 "" ""))])]
4762 rtx callee = XEXP (operands[0], 0);
4764 if (operands[2] == NULL_RTX)
4765 operands[2] = const0_rtx;
4766 if (GET_CODE (callee) != REG
4767 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4768 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4772 (define_expand "sibcall_value"
4773 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4774 (call (match_operand 1 "memory_operand" "")
4775 (match_operand 2 "general_operand" "")))
4777 (use (match_operand 3 "" ""))])]
4781 rtx callee = XEXP (operands[1], 0);
4783 if (operands[3] == NULL_RTX)
4784 operands[3] = const0_rtx;
4785 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4786 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4790 (define_insn "*sibcall_insn"
4791 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4792 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4793 (match_operand 1 "" ""))
4795 (use (match_operand 2 "" ""))]
4803 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4804 (set_attr "predicable" "yes,no,no,yes,yes")
4805 (set_attr "iscompact" "false,false,maybe,false,false")
4806 (set_attr "is_SIBCALL" "yes")]
4809 (define_insn "*sibcall_value_insn"
4810 [(set (match_operand 0 "dest_reg_operand" "")
4811 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4812 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4813 (match_operand 2 "" "")))
4815 (use (match_operand 3 "" ""))]
4823 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4824 (set_attr "predicable" "yes,no,no,yes,yes")
4825 (set_attr "iscompact" "false,false,maybe,false,false")
4826 (set_attr "is_SIBCALL" "yes")]
4829 (define_expand "prologue"
4833 arc_expand_prologue ();
4837 (define_expand "epilogue"
4841 arc_expand_epilogue (0);
4845 (define_expand "sibcall_epilogue"
4849 arc_expand_epilogue (1);
4853 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4854 ; in the prologue / epilogue expanders how many times blink is set.
4855 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4856 ; any explicit use of blink will cause it to be saved; hence we cannot
4857 ; represent the blink use in return / sibcall instructions themselves, and
4858 ; instead have to show it in EPILOGUE_USES and must explicitly
4859 ; forbid instructions that change blink in the return / sibcall delay slot.
4860 (define_insn "simple_return"
4864 [(set_attr "type" "return")
4865 (set_attr "cond" "canuse")
4866 (set_attr "iscompact" "maybe")
4867 (set_attr "length" "*")])
4869 (define_insn "arc600_rtie"
4871 (unspec_volatile [(match_operand 0 "pmode_register_operand" "")]
4872 VUNSPEC_ARC_ARC600_RTIE)]
4873 "TARGET_ARC600_FAMILY"
4875 [(set_attr "length" "4")
4876 (set_attr "type" "rtie")
4877 (set_attr "cond" "clob")])
4879 (define_insn "p_return_i"
4881 (if_then_else (match_operator 0 "proper_comparison_operator"
4882 [(reg CC_REG) (const_int 0)])
4883 (simple_return) (pc)))]
4885 "j%d0%!%*\\t[blink]"
4886 [(set_attr "type" "return")
4887 (set_attr "cond" "use")
4888 (set_attr "iscompact" "maybe" )
4889 (set (attr "length")
4890 (cond [(not (match_operand 0 "equality_comparison_operator" ""))
4892 (eq_attr "delay_slot_filled" "yes")
4896 ;; Return nonzero if this function is known to have a null epilogue.
4897 ;; This allows the optimizer to omit jumps to jumps if no stack
4899 (define_expand "return"
4901 "arc_can_use_return_insn ()"
4904 ;; Comment in final.cc (insn_current_reference_address) says
4905 ;; forward branch addresses are calculated from the next insn after branch
4906 ;; and for backward branches, it is calculated from the branch insn start.
4907 ;; The shortening logic here is tuned to accomodate this behavior
4908 ;; ??? This should be grokked by the ccfsm machinery.
4909 (define_insn "cbranchsi4_scratch"
4911 (if_then_else (match_operator 0 "proper_comparison_operator"
4912 [(match_operand:SI 1 "register_operand" "c,c, c")
4913 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4914 (label_ref (match_operand 3 "" ""))
4916 (clobber (match_operand 4 "cc_register" ""))]
4918 || (TARGET_EARLY_CBRANCHSI
4919 && brcc_nolimm_operator (operands[0], VOIDmode)))
4920 && !CROSSING_JUMP_P (insn)"
4922 switch (get_attr_length (insn))
4924 case 2: return \"br%d0%?\\t%1,%2,%l3\";
4925 case 4: return \"br%d0%*\\t%1,%B2,%l3\";
4926 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4927 return \"br%d0%*\\t%1,%B2,%l3\";
4930 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%*\\t%l3 ;br%d0 out of range\";
4931 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4934 [(set_attr "cond" "clob, clob, clob")
4937 (match_test "valid_brcc_with_delay_p (operands)")
4938 (const_string "brcc")
4939 (const_string "brcc_no_delay_slot")))
4940 ; For forward branches, we need to account not only for the distance to
4941 ; the target, but also the difference between pcl and pc, the instruction
4942 ; length, and any delay insn, if present.
4945 (cond ; the outer cond does a test independent of branch shortening.
4946 [(match_operand 0 "brcc_nolimm_operator" "")
4948 [(and (match_operand:CC_Z 4 "cc_register")
4949 (eq_attr "delay_slot_filled" "no")
4950 (ge (minus (match_dup 3) (pc)) (const_int -128))
4951 (le (minus (match_dup 3) (pc))
4952 (minus (const_int 122)
4953 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4955 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4956 (le (minus (match_dup 3) (pc))
4957 (minus (const_int 244)
4958 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4960 (and (match_operand:SI 1 "compact_register_operand" "")
4961 (match_operand:SI 2 "compact_hreg_operand" ""))
4964 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4965 (le (minus (match_dup 3) (pc)) (const_int 244)))
4967 (and (match_operand:SI 1 "compact_register_operand" "")
4968 (match_operand:SI 2 "compact_hreg_operand" ""))
4971 (set (attr "iscompact")
4972 (if_then_else (match_test "get_attr_length (insn) & 2")
4973 (const_string "true") (const_string "false")))])
4975 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4976 (define_insn "*bbit"
4979 (match_operator 3 "equality_comparison_operator"
4980 [(zero_extract:SI (match_operand:SI 1 "register_operand" "q,c")
4982 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4984 (label_ref (match_operand 0 "" ""))
4986 (clobber (reg:CC_ZN CC_REG))]
4987 "!CROSSING_JUMP_P (insn)"
4989 switch (get_attr_length (insn))
4991 case 4: return (GET_CODE (operands[3]) == EQ
4992 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4994 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4995 default: gcc_unreachable ();
4998 [(set_attr "type" "brcc")
4999 (set_attr "cond" "clob")
5000 (set (attr "length")
5001 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5002 (le (minus (match_dup 0) (pc))
5003 (minus (const_int 248)
5004 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5006 (eq (symbol_ref "which_alternative") (const_int 0))
5009 (set (attr "iscompact")
5010 (if_then_else (match_test "get_attr_length (insn) == 6")
5011 (const_string "true") (const_string "false")))])
5013 ;; -------------------------------------------------------------------
5015 ;; -------------------------------------------------------------------
5017 ; operand 0 is the loop count pseudo register
5018 ; operand 1 is the label to jump to at the top of the loop
5019 (define_expand "doloop_end"
5020 [(parallel [(set (pc)
5022 (ne (match_operand 0 "nonimmediate_operand")
5024 (label_ref (match_operand 1 "" ""))
5026 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5027 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5028 (clobber (match_dup 2))])]
5031 if (GET_MODE (operands[0]) != SImode)
5033 operands[2] = gen_rtx_SCRATCH (SImode);
5036 (define_insn "arc_lp"
5037 [(unspec:SI [(reg:SI LP_COUNT)]
5039 (use (label_ref (match_operand 0 "" "")))
5040 (use (label_ref (match_operand 1 "" "")))]
5042 "lp\\t@%l1\\t; lp_count:@%l0->@%l1"
5043 [(set_attr "type" "loop_setup")
5044 (set_attr "length" "4")])
5046 ;; if by any chance the lp_count is not used, then use an 'r'
5047 ;; register, instead of going to memory.
5048 ;; split pattern for the very slim chance when the loop register is
5050 (define_insn_and_split "loop_end"
5052 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m")
5054 (label_ref (match_operand 1 "" ""))
5056 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5057 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5058 (clobber (match_scratch:SI 2 "=X,&r"))]
5061 ; ZOL_END, begins @%l1
5063 "reload_completed && memory_operand (operands[0], Pmode)"
5064 [(set (match_dup 2) (match_dup 0))
5066 [(set (reg:CC_ZN CC_REG)
5067 (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1))
5069 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
5070 (set (match_dup 0) (match_dup 2))
5072 (if_then_else (ne (reg:CC_ZN CC_REG)
5074 (label_ref (match_dup 1))
5077 [(set_attr "length" "0,24")
5078 (set_attr "predicable" "no")
5079 (set_attr "type" "loop_end")])
5081 (define_insn "loop_fail"
5082 [(set (reg:SI LP_COUNT)
5083 (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5084 (set (reg:CC_ZN CC_REG)
5085 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5088 "sub.f%?\\tlp_count,lp_count,1"
5089 [(set_attr "iscompact" "false")
5090 (set_attr "type" "compare")
5091 (set_attr "cond" "set_zn")
5092 (set_attr "length" "4")
5093 (set_attr "predicable" "yes")])
5095 (define_insn_and_split "dbnz"
5098 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m")
5101 (label_ref (match_operand 1 "" ""))
5104 (plus:SI (match_dup 0)
5106 (clobber (match_scratch:SI 2 "=X,r"))]
5111 "TARGET_DBNZ && reload_completed && memory_operand (operands[0], SImode)"
5112 [(set (match_dup 2) (match_dup 0))
5113 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5114 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5115 (set (match_dup 0) (match_dup 2))
5116 (set (pc) (if_then_else (ge (reg:CC CC_REG)
5118 (label_ref (match_dup 1))
5121 [(set_attr "iscompact" "false")
5122 (set_attr "type" "loop_end")
5123 (set_attr "length" "4,20")])
5125 (define_expand "cpymemsi"
5126 [(match_operand:BLK 0 "" "")
5127 (match_operand:BLK 1 "" "")
5128 (match_operand:SI 2 "nonmemory_operand" "")
5129 (match_operand 3 "immediate_operand" "")]
5131 "if (arc_expand_cpymem (operands)) DONE; else FAIL;")
5133 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5134 ;; to the point that we can generate cmove instructions.
5135 (define_expand "cbranch<mode>4"
5136 [(set (reg:CC CC_REG)
5137 (compare:CC (match_operand:SDF 1 "register_operand" "")
5138 (match_operand:SDF 2 "register_operand" "")))
5141 (match_operator 0 "comparison_operator" [(reg CC_REG)
5143 (label_ref (match_operand 3 "" ""))
5146 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5148 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5149 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5150 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5151 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5155 (define_expand "cmp_float"
5156 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5157 (clobber (reg:SI RETURN_ADDR_REGNUM))
5158 (clobber (reg:SI R12_REG))])]
5162 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5163 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5164 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5166 (define_insn "*cmpsf_<cmp>"
5167 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5168 (clobber (reg:SI RETURN_ADDR_REGNUM))
5169 (clobber (reg:SI R12_REG))]
5170 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5171 && SFUNC_CHECK_PREDICABLE"
5172 "*return arc_output_libcall (\"__<cmp>sf2\");"
5173 [(set_attr "is_sfunc" "yes")
5174 (set_attr "predicable" "yes")])
5176 ;; N.B. for "*cmpdf_ord":
5177 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5178 ;; for the floating point emulation to recognize the NaN.
5179 (define_insn "*cmpdf_<cmp>"
5180 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5181 (clobber (reg:SI RETURN_ADDR_REGNUM))
5182 (clobber (reg:SI R12_REG))]
5183 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5184 && SFUNC_CHECK_PREDICABLE"
5185 "*return arc_output_libcall (\"__<cmp>df2\");"
5186 [(set_attr "is_sfunc" "yes")
5187 (set_attr "predicable" "yes")])
5189 (define_insn "abssf2"
5190 [(set (match_operand:SF 0 "dest_reg_operand" "=q,r,r")
5191 (abs:SF (match_operand:SF 1 "register_operand" "0,0,r")))]
5194 [(set_attr "type" "unary")
5195 (set_attr "iscompact" "maybe,false,false")
5196 (set_attr "length" "2,4,4")
5197 (set_attr "predicable" "no,yes,no")])
5199 (define_insn "negsf2"
5200 [(set (match_operand:SF 0 "dest_reg_operand" "=r,r")
5201 (neg:SF (match_operand:SF 1 "register_operand" "0,r")))]
5204 [(set_attr "type" "unary")
5205 (set_attr "predicable" "yes,no")])
5207 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5208 (define_insn "*millicode_thunk_st"
5209 [(match_parallel 0 "millicode_store_operation"
5210 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5213 output_asm_insn ("bl%* __st_r13_to_%0",
5214 &SET_SRC (XVECEXP (operands[0], 0,
5215 XVECLEN (operands[0], 0) - 2)));
5218 [(set_attr "type" "call")])
5220 (define_insn "*millicode_thunk_ld"
5221 [(match_parallel 0 "millicode_load_clob_operation"
5222 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5225 output_asm_insn ("bl%* __ld_r13_to_%0",
5226 &SET_DEST (XVECEXP (operands[0], 0,
5227 XVECLEN (operands[0], 0) - 2)));
5230 [(set_attr "type" "call")])
5232 ; the sibthunk restores blink, so we use the return rtx.
5233 (define_insn "*millicode_sibthunk_ld"
5234 [(match_parallel 0 "millicode_load_operation"
5236 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5237 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5240 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5241 &SET_DEST (XVECEXP (operands[0], 0,
5242 XVECLEN (operands[0], 0) - 1)));
5245 [(set_attr "type" "call")
5246 (set_attr "is_SIBCALL" "yes")])
5248 ;; For thread pointer builtins
5249 (define_expand "get_thread_pointersi"
5250 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5252 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5254 (define_expand "set_thread_pointersi"
5255 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5257 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5259 ;; If hardware floating point is available, don't define a negdf pattern;
5260 ;; it would be something like:
5261 ;;(define_insn "negdf2"
5262 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5263 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5264 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5267 ;; bxor%? %H0,%H1,31
5268 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5269 ;; drsubh%F0%F1 0,0,0
5270 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5271 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5272 ;; (set_attr "iscompact" "false,false,false,false")
5273 ;; (set_attr "length" "4,4,8,12")
5274 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5275 ;; and this suffers from always requiring a long immediate when using
5276 ;; the floating point hardware.
5277 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5278 ;; constant zero efficiently into a register when we want to do the
5279 ;; computation using the floating point hardware. There should be a special
5280 ;; subdf alternative that matches a zero operand 1, which then can allow
5281 ;; to use bxor to flip the high bit of an integer register.
5282 ;; ??? we actually can't use the floating point hardware for neg, because
5283 ;; this would not work right for -0. OTOH optabs.cc has already code
5284 ;; to synthesyze negate by flipping the sign bit.
5287 (define_insn "bswapsi2"
5288 [(set (match_operand:SI 0 "register_operand" "= r,r")
5289 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5290 "TARGET_V2 && TARGET_SWAP"
5292 [(set_attr "length" "4,8")
5293 (set_attr "type" "two_cycle_core")])
5295 (define_expand "prefetch"
5296 [(prefetch (match_operand:SI 0 "address_operand" "")
5297 (match_operand:SI 1 "const_int_operand" "")
5298 (match_operand:SI 2 "const_int_operand" ""))]
5302 (define_insn "prefetch_1"
5303 [(prefetch (match_operand:SI 0 "register_operand" "r")
5304 (match_operand:SI 1 "const_int_operand" "n")
5305 (match_operand:SI 2 "const_int_operand" "n"))]
5308 if (INTVAL (operands[1]))
5309 return "prefetchw [%0]";
5311 return "prefetch [%0]";
5313 [(set_attr "type" "load")
5314 (set_attr "length" "4")])
5316 (define_insn "prefetch_2"
5317 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5318 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5319 (match_operand:SI 2 "const_int_operand" "n,n,n")
5320 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5323 if (INTVAL (operands[2]))
5324 return "prefetchw [%0, %1]";
5326 return "prefetch [%0, %1]";
5328 [(set_attr "type" "load")
5329 (set_attr "length" "4,4,8")])
5331 (define_insn "prefetch_3"
5332 [(prefetch (match_operand:SI 0 "address_operand" "p")
5333 (match_operand:SI 1 "const_int_operand" "n")
5334 (match_operand:SI 2 "const_int_operand" "n"))]
5337 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5338 if (INTVAL (operands[1]))
5339 return "prefetchw%U0 %0";
5341 return "prefetch%U0 %0";
5343 [(set_attr "type" "load")
5344 (set_attr "length" "8")])
5346 (define_insn "divsi3"
5347 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5348 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5349 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5352 [(set_attr "length" "4,4,8,4,4,4,8,8")
5353 (set_attr "iscompact" "false")
5354 (set_attr "type" "div_rem")
5355 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5356 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5359 (define_insn "udivsi3"
5360 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5361 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5362 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5365 [(set_attr "length" "4,4,8,4,4,4,8,8")
5366 (set_attr "iscompact" "false")
5367 (set_attr "type" "div_rem")
5368 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5369 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5372 (define_insn "modsi3"
5373 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5374 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5375 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5378 [(set_attr "length" "4,4,8,4,4,4,8,8")
5379 (set_attr "iscompact" "false")
5380 (set_attr "type" "div_rem")
5381 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5382 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5385 (define_insn "umodsi3"
5386 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5387 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5388 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5391 [(set_attr "length" "4,4,8,4,4,4,8,8")
5392 (set_attr "iscompact" "false")
5393 (set_attr "type" "div_rem")
5394 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5395 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5398 ;; SETcc instructions
5399 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5401 (define_insn "arcset<code>"
5402 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5403 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5404 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5405 "TARGET_V2 && TARGET_CODE_DENSITY"
5406 "set<code>%? %0, %1, %2"
5407 [(set_attr "length" "4,4,4,4,4,8,8")
5408 (set_attr "iscompact" "false")
5409 (set_attr "type" "compare")
5410 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5411 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5414 (define_insn "arcsetltu"
5415 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5416 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5417 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5418 "TARGET_V2 && TARGET_CODE_DENSITY"
5419 "setlo%? %0, %1, %2"
5420 [(set_attr "length" "4,4,4,4,4,8,8")
5421 (set_attr "iscompact" "false")
5422 (set_attr "type" "compare")
5423 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5424 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5427 (define_insn "arcsetgeu"
5428 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5429 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5430 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5431 "TARGET_V2 && TARGET_CODE_DENSITY"
5432 "seths%? %0, %1, %2"
5433 [(set_attr "length" "4,4,4,4,4,8,8")
5434 (set_attr "iscompact" "false")
5435 (set_attr "type" "compare")
5436 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5437 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5440 ;; Special cases of SETCC
5441 (define_insn_and_split "arcsethi"
5442 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5443 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5444 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5445 "TARGET_V2 && TARGET_CODE_DENSITY"
5446 "setlo%? %0, %2, %1"
5448 && CONST_INT_P (operands[2])
5449 && satisfies_constraint_C62 (operands[2])"
5452 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5453 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5454 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5457 [(set_attr "length" "4,4,4,8")
5458 (set_attr "iscompact" "false")
5459 (set_attr "type" "compare")
5460 (set_attr "predicable" "yes,no,no,no")
5461 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5464 (define_insn_and_split "arcsetls"
5465 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5466 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5467 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5468 "TARGET_V2 && TARGET_CODE_DENSITY"
5469 "seths%? %0, %2, %1"
5471 && CONST_INT_P (operands[2])
5472 && satisfies_constraint_C62 (operands[2])"
5475 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5476 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5477 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5480 [(set_attr "length" "4,4,4,8")
5481 (set_attr "iscompact" "false")
5482 (set_attr "type" "compare")
5483 (set_attr "predicable" "yes,no,no,no")
5484 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5487 ; Any mode that needs to be solved by secondary reload
5488 (define_mode_iterator SRI [QI HI])
5490 (define_expand "reload_<mode>_load"
5491 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5492 (match_operand:SRI 1 "memory_operand" "m")
5493 (match_operand:SI 2 "register_operand" "=&r")])]
5496 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5500 (define_expand "reload_<mode>_store"
5501 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5502 (match_operand:SRI 1 "register_operand" "r")
5503 (match_operand:SI 2 "register_operand" "=&r")])]
5506 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5510 (define_insn "extzvsi"
5511 [(set (match_operand:SI 0 "register_operand" "=r , r,r,r")
5512 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r,r,0")
5513 (match_operand:SI 2 "const_int_operand" "C3p,C3p,n,n")
5514 (match_operand:SI 3 "const_int_operand" "n , n,n,n")))]
5515 "TARGET_HS && TARGET_BARREL_SHIFTER"
5517 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5518 operands[2] = GEN_INT (assemble_op2);
5519 return "xbfu%?\\t%0,%1,%2";
5521 [(set_attr "type" "shift")
5522 (set_attr "iscompact" "false")
5523 (set_attr "length" "4,4,8,8")
5524 (set_attr "predicable" "yes,no,no,yes")
5525 (set_attr "cond" "canuse,nocond,nocond,canuse_limm")])
5527 (define_insn "kflag"
5528 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5535 [(set_attr "length" "4,4,8")
5536 (set_attr "type" "misc,misc,misc")
5537 (set_attr "predicable" "yes,no,yes")
5538 (set_attr "cond" "clob,clob,clob")])
5541 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5542 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5546 [(set_attr "length" "4")
5547 (set_attr "type" "misc")])
5550 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5551 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5553 "TARGET_NORM && TARGET_V2"
5555 [(set_attr "length" "4,8")
5556 (set_attr "type" "two_cycle_core,two_cycle_core")])
5558 (define_insn "ffs_f"
5559 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5560 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5562 (set (reg:CC_ZN CC_REG)
5563 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5564 "TARGET_NORM && TARGET_V2"
5566 [(set_attr "length" "4,8")
5567 (set_attr "type" "two_cycle_core,two_cycle_core")])
5569 (define_expand "ffssi2"
5570 [(parallel [(set (match_dup 2)
5571 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5573 (set (reg:CC_ZN CC_REG)
5574 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5575 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5576 (set (match_operand:SI 0 "dest_reg_operand" "")
5577 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5580 "TARGET_NORM && TARGET_V2"
5582 operands[2] = gen_reg_rtx (SImode);
5586 [(set (match_operand:SI 0 "register_operand" "=r,r")
5587 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "rL,Cal")]
5589 "TARGET_NORM && TARGET_V2"
5591 [(set_attr "length" "4,8")
5592 (set_attr "type" "two_cycle_core,two_cycle_core")])
5595 [(unspec_volatile:SI [(match_operand:SI 0 "nonmemory_operand" "rL")]
5599 [(set_attr "length" "4")
5600 (set_attr "type" "misc")])
5605 (define_expand "addsf3"
5606 [(set (match_operand:SF 0 "register_operand" "")
5607 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5608 (match_operand:SF 2 "nonmemory_operand" "")))]
5609 "TARGET_FP_SP_BASE || TARGET_SPFP"
5611 if (!register_operand (operands[1], SFmode)
5612 && !register_operand (operands[2], SFmode))
5613 operands[1] = force_reg (SFmode, operands[1]);
5617 (define_expand "subsf3"
5618 [(set (match_operand:SF 0 "register_operand" "")
5619 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5620 (match_operand:SF 2 "nonmemory_operand" "")))]
5621 "TARGET_FP_SP_BASE || TARGET_SPFP"
5623 if (!register_operand (operands[1], SFmode)
5624 && !register_operand (operands[2], SFmode))
5625 operands[1] = force_reg (SFmode, operands[1]);
5629 (define_expand "mulsf3"
5630 [(set (match_operand:SF 0 "register_operand" "")
5631 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5632 (match_operand:SF 2 "nonmemory_operand" "")))]
5633 "TARGET_FP_SP_BASE || TARGET_SPFP"
5635 if (!register_operand (operands[1], SFmode)
5636 && !register_operand (operands[2], SFmode))
5637 operands[1] = force_reg (SFmode, operands[1]);
5641 (define_expand "adddf3"
5642 [(set (match_operand:DF 0 "double_register_operand" "")
5643 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5644 (match_operand:DF 2 "nonmemory_operand" "")))]
5645 "TARGET_FP_DP_BASE || TARGET_DPFP"
5649 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5651 rtx first, second, tmp;
5652 split_double (operands[2], &first, &second);
5653 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5654 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5655 operands[2], tmp, const0_rtx));
5658 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5659 operands[2], const1_rtx, const1_rtx));
5662 else if (TARGET_FP_DP_BASE)
5664 if (!even_register_operand (operands[2], DFmode))
5665 operands[2] = force_reg (DFmode, operands[2]);
5667 if (!even_register_operand (operands[1], DFmode))
5668 operands[1] = force_reg (DFmode, operands[1]);
5675 (define_expand "subdf3"
5676 [(set (match_operand:DF 0 "double_register_operand" "")
5677 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5678 (match_operand:DF 2 "nonmemory_operand" "")))]
5679 "TARGET_FP_DP_BASE || TARGET_DPFP"
5683 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5684 operands[1] = force_reg (DFmode, operands[1]);
5685 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5686 || GET_CODE (operands[2]) == CONST_DOUBLE)
5688 rtx first, second, tmp;
5689 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5690 split_double (operands[const_index], &first, &second);
5691 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5692 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5693 operands[2], tmp, const0_rtx));
5696 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5697 operands[2], const1_rtx, const1_rtx));
5700 else if (TARGET_FP_DP_BASE)
5702 if (!even_register_operand (operands[2], DFmode))
5703 operands[2] = force_reg (DFmode, operands[2]);
5705 if (!even_register_operand (operands[1], DFmode))
5706 operands[1] = force_reg (DFmode, operands[1]);
5713 (define_expand "muldf3"
5714 [(set (match_operand:DF 0 "double_register_operand" "")
5715 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5716 (match_operand:DF 2 "nonmemory_operand" "")))]
5717 "TARGET_FP_DP_BASE || TARGET_DPFP"
5721 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5723 rtx first, second, tmp;
5724 split_double (operands[2], &first, &second);
5725 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5726 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5727 operands[2], tmp, const0_rtx));
5730 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5731 operands[2], const1_rtx, const1_rtx));
5734 else if (TARGET_FP_DP_BASE)
5736 if (!even_register_operand (operands[2], DFmode))
5737 operands[2] = force_reg (DFmode, operands[2]);
5739 if (!even_register_operand (operands[1], DFmode))
5740 operands[1] = force_reg (DFmode, operands[1]);
5747 (define_expand "divsf3"
5748 [(set (match_operand:SF 0 "register_operand" "")
5749 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5750 (match_operand:SF 2 "nonmemory_operand" "")))]
5751 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5753 if (TARGET_FPX_QUARK)
5755 operands[1] = force_reg (SFmode, operands[1]);
5756 operands[2] = force_reg (SFmode, operands[2]);
5760 if (!register_operand (operands[1], SFmode)
5761 && !register_operand (operands[2], SFmode))
5762 operands[1] = force_reg (SFmode, operands[1]);
5767 (define_expand "sqrtsf2"
5768 [(set (match_operand:SF 0 "register_operand" "")
5769 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5770 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5772 if (TARGET_FPX_QUARK)
5774 operands[1] = force_reg (SFmode, operands[1]);
5778 ;; SF->SI (using rounding towards zero)
5779 (define_expand "fix_truncsfsi2"
5780 [(set (match_operand:SI 0 "register_operand" "")
5781 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5782 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5786 (define_expand "floatsisf2"
5787 [(set (match_operand:SF 0 "register_operand" "")
5788 (float:SF (match_operand:SI 1 "register_operand" "")))]
5789 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5792 (define_expand "extzv"
5793 [(set (match_operand:SI 0 "register_operand" "")
5794 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5795 (match_operand:SI 2 "const_int_operand" "")
5796 (match_operand:SI 3 "const_int_operand" "")))]
5797 "TARGET_NPS_BITOPS")
5799 ; We need a sanity check in the instuction predicate because combine
5800 ; will throw any old rubbish at us and see what sticks.
5801 (define_insn "*extzv_i"
5802 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5803 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5804 (match_operand:SI 2 "const_int_operand" "n")
5805 (match_operand:SI 3 "const_int_operand" "n")))]
5806 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5807 "movb.cl %0,%1,0,%3,%2"
5808 [(set_attr "type" "shift")
5809 (set_attr "length" "4")])
5811 (define_expand "insv"
5812 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5813 (match_operand:SI 1 "const_int_operand" "")
5814 (match_operand:SI 2 "const_int_operand" ""))
5815 (match_operand:SI 3 "nonmemory_operand" ""))]
5818 int size = INTVAL (operands[1]);
5820 if (size != 1 && size != 2 && size != 4 && size != 8)
5821 operands[3] = force_reg (SImode, operands[3]);
5824 (define_insn "*insv_i"
5825 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5826 (match_operand:SI 1 "const_int_operand" "C18,n")
5827 (match_operand:SI 2 "const_int_operand" "n,n"))
5828 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5830 && (register_operand (operands[3], SImode)
5831 || satisfies_constraint_C18 (operands[1]))"
5833 movbi %0,%0,%3,%2,%1
5834 movb %0,%0,%3,%2,0,%1"
5835 [(set_attr "type" "shift")
5836 (set_attr "length" "4")])
5838 (define_insn "*movb"
5839 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5840 (match_operand:SI 1 "const_int_operand" "n")
5841 (match_operand:SI 2 "const_int_operand" "n"))
5842 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5844 (match_operand:SI 4 "const_int_operand" "n")))]
5846 "movb %0,%0,%3,%2,%4,%1"
5847 [(set_attr "type" "shift")
5848 (set_attr "length" "4")])
5850 (define_insn "*movb_signed"
5851 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5852 (match_operand:SI 1 "const_int_operand" "n")
5853 (match_operand:SI 2 "const_int_operand" "n"))
5854 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5856 (match_operand:SI 4 "const_int_operand" "n")))]
5858 "movb %0,%0,%3,%2,%4,%1"
5859 [(set_attr "type" "shift")
5860 (set_attr "length" "4")])
5862 (define_insn "*movb_high"
5863 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5864 (match_operand:SI 1 "const_int_operand" "n")
5865 (match_operand:SI 2 "const_int_operand" "n"))
5866 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5867 (match_operand:SI 4 "const_int_operand" "n")))]
5869 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5870 "movb %0,%0,%3,%2,%4,%1"
5871 [(set_attr "type" "shift")
5872 (set_attr "length" "4")])
5874 ; N.B.: when processing signed bitfields that fit in the top half of
5875 ; a word, gcc will use a narrow sign extending load, and in this case
5876 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
5877 (define_insn "*movb_high_signed"
5878 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5879 (match_operand:SI 1 "const_int_operand" "n")
5880 (match_operand:SI 2 "const_int_operand" "n"))
5881 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5882 (match_operand:SI 4 "const_int_operand" "n")))]
5884 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5885 "movb %0,%0,%3,%2,%4,%1"
5886 [(set_attr "type" "shift")
5887 (set_attr "length" "4")])
5890 [(set (match_operand:SI 0 "register_operand" "")
5891 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5892 (match_operand:SI 2 "const_int_operand" ""))
5893 (subreg:SI (match_operand 3 "") 0)))]
5895 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
5896 && !reg_overlap_mentioned_p (operands[0], operands[1])"
5897 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
5898 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
5900 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
5902 (define_insn "*mrgb"
5903 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5904 (match_operand:SI 1 "const_int_operand" "n")
5905 (match_operand:SI 2 "const_int_operand" "n"))
5906 (zero_extract:SI (match_dup 0) (match_dup 1)
5907 (match_operand:SI 3 "const_int_operand" "n")))
5908 (set (zero_extract:SI (match_dup 0)
5909 (match_operand:SI 4 "const_int_operand" "n")
5910 (match_operand:SI 5 "const_int_operand" "n"))
5911 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
5913 (match_operand:SI 7 "const_int_operand" "n")))]
5916 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
5917 /* The ;%? updates the known unalignment. */
5918 return arc_short_long (insn, ";%?", "nop_s");
5920 [(set_attr "type" "shift")
5921 (set_attr "length" "6")
5922 (set_attr "iscompact" "true")])
5924 ;; combine fumbles combination of two movb patterns, and then the
5925 ;; combination is rejected by combinable_i3pat.
5926 ;; Thus, we can only use a peephole2 to combine two such insns.
5929 [(set (match_operand:SI 0 "register_operand" "")
5930 (match_operand:SI 1 "register_operand" ""))
5931 (set (zero_extract:SI (match_dup 0)
5932 (match_operand:SI 2 "const_int_operand" "")
5933 (match_operand:SI 3 "const_int_operand" ""))
5934 (zero_extract:SI (match_dup 1)
5936 (match_operand:SI 4 "const_int_operand" "")))
5937 (match_operand 9) ; unrelated insn scheduled here
5938 (set (zero_extract:SI (match_dup 0)
5939 (match_operand:SI 5 "const_int_operand" "")
5940 (match_operand:SI 6 "const_int_operand" ""))
5941 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
5943 (match_operand:SI 8 "const_int_operand" "")))]
5945 // Check that the second movb doesn't clobber an input of the extra insn.
5946 && !reg_overlap_mentioned_p (operands[0], operands[9])
5948 && !reg_set_p (operands[0], operands[9])
5949 && !reg_set_p (operands[7], operands[9])"
5950 [(set (match_dup 0) (match_dup 1))
5951 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5952 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
5953 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5954 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
5958 [(set (match_operand:SI 0 "register_operand" "")
5959 (match_operand:SI 1 "register_operand" ""))
5960 (set (zero_extract:SI (match_dup 0)
5961 (match_operand:SI 2 "const_int_operand" "")
5962 (match_operand:SI 3 "const_int_operand" ""))
5963 (zero_extract:SI (match_dup 1)
5965 (match_operand:SI 4 "const_int_operand" "")))
5966 (set (match_dup 1) (match_operand 8))
5967 (set (zero_extract:SI (match_dup 0)
5968 (match_operand:SI 5 "const_int_operand" "")
5969 (match_operand:SI 6 "const_int_operand" ""))
5970 (zero_extract:SI (match_dup 1) (match_dup 5)
5971 (match_operand:SI 7 "const_int_operand" "")))]
5973 && !reg_overlap_mentioned_p (operands[0], operands[8])"
5974 [(set (match_dup 0) (match_dup 1))
5975 (set (match_dup 1) (match_dup 8))
5976 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
5977 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
5978 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
5979 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
5982 (define_insn "rotrsi3_cnt1"
5983 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5984 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5988 [(set_attr "type" "shift")
5989 (set_attr "predicable" "no")
5990 (set_attr "length" "4")])
5992 (define_insn "*rotrsi3_cnt8"
5993 [(set (match_operand:SI 0 "register_operand" "=r")
5994 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5996 "TARGET_BARREL_SHIFTER && TARGET_V2"
5998 [(set_attr "type" "shift")
5999 (set_attr "predicable" "no")
6000 (set_attr "length" "4")])
6002 (define_insn "ashlsi3_cnt1"
6003 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6004 (ashift:SI (match_operand:SI 1 "register_operand" "q,c")
6008 [(set_attr "type" "unary")
6009 (set_attr "iscompact" "maybe,false")
6010 (set_attr "length" "*,4")
6011 (set_attr "predicable" "no,no")])
6013 (define_insn "*ashlsi2_cnt8"
6014 [(set (match_operand:SI 0 "register_operand" "=r")
6015 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6017 "TARGET_BARREL_SHIFTER && TARGET_V2"
6019 [(set_attr "type" "shift")
6020 (set_attr "iscompact" "false")
6021 (set_attr "length" "4")
6022 (set_attr "predicable" "no")])
6024 (define_insn "*ashlsi2_cnt16"
6025 [(set (match_operand:SI 0 "register_operand" "=r")
6026 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6028 "TARGET_SWAP && TARGET_V2"
6030 [(set_attr "type" "shift")
6031 (set_attr "iscompact" "false")
6032 (set_attr "length" "4")
6033 (set_attr "predicable" "no")])
6035 (define_insn "lshrsi3_cnt1"
6036 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6037 (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6041 [(set_attr "type" "unary")
6042 (set_attr "iscompact" "maybe,false")
6043 (set_attr "predicable" "no,no")])
6045 (define_insn "ashrsi3_cnt1"
6046 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6047 (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6051 [(set_attr "type" "unary")
6052 (set_attr "iscompact" "maybe,false")
6053 (set_attr "predicable" "no,no")])
6056 [(set (match_operand:SI 0 "register_operand" "")
6057 (zero_extract:SI (match_dup 0)
6058 (match_operand:SI 1 "const_int_operand" "")
6059 (match_operand:SI 2 "const_int_operand" "")))
6060 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6065 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6066 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6067 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6069 ;; Dummy pattern used as a place holder for automatically saved
6071 (define_insn "stack_irq_dwarf"
6072 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6075 [(set_attr "length" "0")])
6077 ;; MAC and DMPY instructions
6079 ; Use VMAC2H(U) instruction to emulate scalar 16bit mac.
6080 (define_expand "maddhisi4"
6081 [(match_operand:SI 0 "register_operand" "")
6082 (match_operand:HI 1 "register_operand" "")
6083 (match_operand:HI 2 "register_operand" "")
6084 (match_operand:SI 3 "register_operand" "")]
6087 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6089 emit_move_insn (acc_reg, operands[3]);
6090 emit_insn (gen_machi (operands[0], operands[1], operands[2], acc_reg));
6094 (define_insn "machi"
6095 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6097 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6098 (sign_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6099 (match_operand:SI 3 "accl_operand" "")))
6100 (clobber (reg:DI ARCV2_ACC))]
6103 [(set_attr "length" "4")
6104 (set_attr "type" "multi")
6105 (set_attr "predicable" "no")
6106 (set_attr "cond" "nocond")])
6108 ; The same for the unsigned variant, but using VMAC2HU instruction.
6109 (define_expand "umaddhisi4"
6110 [(match_operand:SI 0 "register_operand" "")
6111 (match_operand:HI 1 "register_operand" "")
6112 (match_operand:HI 2 "register_operand" "")
6113 (match_operand:SI 3 "register_operand" "")]
6116 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6118 emit_move_insn (acc_reg, operands[3]);
6119 emit_insn (gen_umachi (operands[0], operands[1], operands[2], acc_reg));
6123 (define_insn "umachi"
6124 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6126 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6127 (zero_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6128 (match_operand:SI 3 "accl_operand" "")))
6129 (clobber (reg:DI ARCV2_ACC))]
6132 [(set_attr "length" "4")
6133 (set_attr "type" "multi")
6134 (set_attr "predicable" "no")
6135 (set_attr "cond" "nocond")])
6137 (define_expand "maddsidi4"
6138 [(match_operand:DI 0 "register_operand" "")
6139 (match_operand:SI 1 "register_operand" "")
6140 (match_operand:SI 2 "extend_operand" "")
6141 (match_operand:DI 3 "register_operand" "")]
6144 emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6148 (define_insn_and_split "maddsidi4_split"
6149 [(set (match_operand:DI 0 "register_operand" "=r")
6152 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6153 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6154 (match_operand:DI 3 "register_operand" "r")))
6155 (clobber (reg:DI ARCV2_ACC))]
6158 "TARGET_PLUS_DMPY && reload_completed"
6161 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6162 emit_move_insn (acc_reg, operands[3]);
6163 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6164 && REGNO (operands[0]) != ACC_REG_FIRST)
6165 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6168 emit_insn (gen_mac (operands[1], operands[2]));
6169 if (REGNO (operands[0]) != ACC_REG_FIRST)
6170 emit_move_insn (operands[0], acc_reg);
6174 [(set_attr "type" "multi")
6175 (set_attr "length" "36")])
6178 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6181 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6182 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,Cal")))
6183 (reg:DI ARCV2_ACC)))
6184 (set (reg:DI ARCV2_ACC)
6186 (mult:DI (sign_extend:DI (match_dup 1))
6187 (sign_extend:DI (match_dup 2)))
6188 (reg:DI ARCV2_ACC)))]
6191 [(set_attr "length" "4,4,8")
6192 (set_attr "type" "multi")
6193 (set_attr "predicable" "yes,no,no")
6194 (set_attr "cond" "canuse,nocond,nocond")])
6197 [(set (reg:DI ARCV2_ACC)
6199 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6200 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6201 (reg:DI ARCV2_ACC)))]
6204 [(set_attr "length" "4,8")
6205 (set_attr "type" "multi")
6206 (set_attr "predicable" "no")
6207 (set_attr "cond" "nocond")])
6210 [(set (reg:DI ARCV2_ACC)
6212 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6213 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6214 (reg:DI ARCV2_ACC)))
6215 (set (match_operand:SI 2 "register_operand" "")
6216 (match_operand:SI 3 "accl_operand" ""))]
6220 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6224 (define_insn "mac_r"
6225 [(set (match_operand:SI 0 "register_operand" "=r,r")
6228 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6229 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6230 (reg:DI ARCV2_ACC))))
6231 (clobber (reg:DI ARCV2_ACC))]
6234 [(set_attr "length" "4,8")
6235 (set_attr "type" "multi")
6236 (set_attr "predicable" "no")
6237 (set_attr "cond" "nocond")])
6239 (define_expand "umaddsidi4"
6240 [(match_operand:DI 0 "register_operand" "")
6241 (match_operand:SI 1 "register_operand" "")
6242 (match_operand:SI 2 "extend_operand" "")
6243 (match_operand:DI 3 "register_operand" "")]
6246 emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6250 (define_insn_and_split "umaddsidi4_split"
6251 [(set (match_operand:DI 0 "register_operand" "=r")
6254 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6255 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6256 (match_operand:DI 3 "register_operand" "r")))
6257 (clobber (reg:DI ARCV2_ACC))]
6260 "TARGET_PLUS_DMPY && reload_completed"
6263 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6264 emit_move_insn (acc_reg, operands[3]);
6265 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6266 && REGNO (operands[0]) != ACC_REG_FIRST)
6267 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6270 emit_insn (gen_macu (operands[1], operands[2]));
6271 if (REGNO (operands[0]) != ACC_REG_FIRST)
6272 emit_move_insn (operands[0], acc_reg);
6276 [(set_attr "type" "multi")
6277 (set_attr "length" "36")])
6279 (define_insn "macdu"
6280 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6283 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6284 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,i")))
6285 (reg:DI ARCV2_ACC)))
6286 (set (reg:DI ARCV2_ACC)
6288 (mult:DI (zero_extend:DI (match_dup 1))
6289 (zero_extend:DI (match_dup 2)))
6290 (reg:DI ARCV2_ACC)))]
6293 [(set_attr "length" "4,4,8")
6294 (set_attr "type" "multi")
6295 (set_attr "predicable" "yes,no,no")
6296 (set_attr "cond" "canuse,nocond,nocond")])
6299 [(set (reg:DI ARCV2_ACC)
6301 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6302 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6303 (reg:DI ARCV2_ACC)))]
6306 [(set_attr "length" "4,8")
6307 (set_attr "type" "multi")
6308 (set_attr "predicable" "no")
6309 (set_attr "cond" "nocond")])
6312 [(set (reg:DI ARCV2_ACC)
6314 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6315 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6316 (reg:DI ARCV2_ACC)))
6317 (set (match_operand:SI 2 "register_operand" "")
6318 (match_operand:SI 3 "accl_operand" ""))]
6322 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6326 (define_insn "macu_r"
6327 [(set (match_operand:SI 0 "register_operand" "=r,r")
6330 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6331 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6332 (reg:DI ARCV2_ACC))))
6333 (clobber (reg:DI ARCV2_ACC))]
6336 [(set_attr "length" "4,8")
6337 (set_attr "type" "multi")
6338 (set_attr "predicable" "no")
6339 (set_attr "cond" "nocond")])
6341 (define_insn "mpyd<su_optab>_arcv2hs"
6342 [(set (match_operand:DI 0 "even_register_operand" "=r")
6343 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r"))
6344 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6345 (set (reg:DI ARCV2_ACC)
6347 (SEZ:DI (match_dup 1))
6348 (SEZ:DI (match_dup 2))))]
6350 "mpyd<su_optab>%?\\t%0,%1,%2"
6351 [(set_attr "length" "4")
6352 (set_attr "iscompact" "false")
6353 (set_attr "type" "multi")
6354 (set_attr "predicable" "no")])
6356 (define_insn "*pmpyd<su_optab>_arcv2hs"
6357 [(set (match_operand:DI 0 "even_register_operand" "=r")
6359 (SEZ:DI (match_operand:SI 1 "even_register_operand" "%0"))
6360 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6361 (set (reg:DI ARCV2_ACC)
6363 (SEZ:DI (match_dup 1))
6364 (SEZ:DI (match_dup 2))))]
6366 "mpyd<su_optab>%?\\t%0,%1,%2"
6367 [(set_attr "length" "4")
6368 (set_attr "iscompact" "false")
6369 (set_attr "type" "multi")
6370 (set_attr "predicable" "yes")])
6372 (define_insn "mpyd<su_optab>_imm_arcv2hs"
6373 [(set (match_operand:DI 0 "even_register_operand" "=r,r, r")
6374 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r,0, r"))
6375 (match_operand 2 "immediate_operand" "L,I,Cal")))
6376 (set (reg:DI ARCV2_ACC)
6377 (mult:DI (SEZ:DI (match_dup 1))
6380 "mpyd<su_optab>%?\\t%0,%1,%2"
6381 [(set_attr "length" "4,4,8")
6382 (set_attr "iscompact" "false")
6383 (set_attr "type" "multi")
6384 (set_attr "predicable" "no")])
6386 (define_insn "*pmpyd<su_optab>_imm_arcv2hs"
6387 [(set (match_operand:DI 0 "even_register_operand" "=r,r")
6389 (SEZ:DI (match_operand:SI 1 "even_register_operand" "0,0"))
6390 (match_operand 2 "immediate_operand" "L,Cal")))
6391 (set (reg:DI ARCV2_ACC)
6392 (mult:DI (SEZ:DI (match_dup 1))
6395 "mpyd<su_optab>%?\\t%0,%1,%2"
6396 [(set_attr "length" "4,8")
6397 (set_attr "iscompact" "false")
6398 (set_attr "type" "multi")
6399 (set_attr "predicable" "yes")])
6401 (define_insn "add_shift"
6402 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6403 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
6404 (match_operand:SI 2 "_1_2_3_operand" ""))
6405 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
6407 "add%2%?\\t%0,%3,%1"
6408 [(set_attr "length" "*,4,8")
6409 (set_attr "predicable" "yes,no,no")
6410 (set_attr "iscompact" "maybe,false,false")
6411 (set_attr "cond" "canuse,nocond,nocond")])
6413 (define_insn "*add_shift2"
6414 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6415 (plus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6416 (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r")
6417 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6419 "add%3%?\\t%0,%1,%2"
6420 [(set_attr "length" "*,4,8")
6421 (set_attr "predicable" "yes,no,no")
6422 (set_attr "iscompact" "maybe,false,false")
6423 (set_attr "cond" "canuse,nocond,nocond")])
6425 (define_insn "*sub_shift"
6426 [(set (match_operand:SI 0"register_operand" "=r,r,r")
6427 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6428 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
6429 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6432 [(set_attr "length" "4,4,8")
6433 (set_attr "cond" "canuse,nocond,nocond")
6434 (set_attr "predicable" "yes,no,no")])
6436 (define_insn "*sub_shift_cmp0_noout"
6437 [(set (match_operand 0 "cc_set_register" "")
6439 (minus:SI (match_operand:SI 1 "register_operand" "r")
6440 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6441 (match_operand:SI 3 "_1_2_3_operand" "")))
6445 [(set_attr "length" "4")])
6447 (define_insn "*compare_si_ashiftsi"
6448 [(set (match_operand 0 "cc_set_register" "")
6449 (compare:CC (match_operand:SI 1 "register_operand" "r")
6450 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6451 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6454 [(set_attr "length" "4")])
6456 ;; Convert the sequence
6460 ;; sub{123}.f 0,ra,rn
6462 [(set (match_operand:SI 0 "register_operand" "")
6463 (ashift:SI (match_operand:SI 1 "register_operand" "")
6464 (match_operand:SI 2 "_1_2_3_operand" "")))
6465 (set (reg:CC CC_REG)
6466 (compare:CC (match_operand:SI 3 "register_operand" "")
6468 "peep2_reg_dead_p (2, operands[0])"
6469 [(set (reg:CC CC_REG) (compare:CC (match_dup 3)
6470 (ashift:SI (match_dup 1) (match_dup 2))))])
6472 (define_peephole2 ; std
6473 [(set (match_operand:SI 2 "memory_operand" "")
6474 (match_operand:SI 0 "register_operand" ""))
6475 (set (match_operand:SI 3 "memory_operand" "")
6476 (match_operand:SI 1 "register_operand" ""))]
6480 if (!gen_operands_ldd_std (operands, false, false))
6482 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6483 operands[2] = adjust_address (operands[2], DImode, 0);
6484 emit_insn (gen_rtx_SET (operands[2], operands[0]));
6488 (define_peephole2 ; ldd
6489 [(set (match_operand:SI 0 "register_operand" "")
6490 (match_operand:SI 2 "memory_operand" ""))
6491 (set (match_operand:SI 1 "register_operand" "")
6492 (match_operand:SI 3 "memory_operand" ""))]
6496 if (!gen_operands_ldd_std (operands, true, false))
6498 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6499 operands[2] = adjust_address (operands[2], DImode, 0);
6500 emit_insn (gen_rtx_SET (operands[0], operands[2]));
6504 ;; We require consecutive registers for LDD instruction. Check if we
6505 ;; can reorder them and use an LDD.
6507 (define_peephole2 ; swap the destination registers of two loads
6508 ; before a commutative operation.
6509 [(set (match_operand:SI 0 "register_operand" "")
6510 (match_operand:SI 2 "memory_operand" ""))
6511 (set (match_operand:SI 1 "register_operand" "")
6512 (match_operand:SI 3 "memory_operand" ""))
6513 (set (match_operand:SI 4 "register_operand" "")
6514 (match_operator:SI 5 "commutative_operator"
6515 [(match_operand 6 "register_operand" "")
6516 (match_operand 7 "register_operand" "") ]))]
6518 && (((rtx_equal_p (operands[0], operands[6]))
6519 && (rtx_equal_p (operands[1], operands[7])))
6520 || ((rtx_equal_p (operands[0], operands[7]))
6521 && (rtx_equal_p (operands[1], operands[6]))))
6522 && (peep2_reg_dead_p (3, operands[0])
6523 || rtx_equal_p (operands[0], operands[4]))
6524 && (peep2_reg_dead_p (3, operands[1])
6525 || rtx_equal_p (operands[1], operands[4]))"
6526 [(set (match_dup 0) (match_dup 2))
6527 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]
6529 if (!gen_operands_ldd_std (operands, true, true))
6535 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6536 operands[2] = adjust_address (operands[2], DImode, 0);
6541 (define_insn "*push_multi_fp"
6542 [(match_parallel 0 "push_multi_operand"
6543 [(set (reg:SI SP_REG)
6544 (plus:SI (reg:SI SP_REG)
6545 (match_operand 1 "immediate_operand" "")))
6546 (set (mem:SI (plus:SI (reg:SI SP_REG)
6547 (match_operand 2 "immediate_operand"
6550 "TARGET_CODE_DENSITY"
6552 int len = XVECLEN (operands[0], 0);
6553 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6554 if (MEM_P (XEXP (tmp, 0)))
6556 operands[3] = XEXP (tmp, 1);
6557 return "enter_s\\t{r13-%3} ; sp=sp+(%1)";
6561 tmp = XVECEXP (operands[0], 0, len - 3);
6562 operands[3] = XEXP (tmp, 1);
6563 return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)";
6566 [(set_attr "type" "call_no_delay_slot")
6567 (set_attr "length" "2")])
6569 (define_insn "*push_multi_fp_blink"
6570 [(match_parallel 0 "push_multi_operand"
6571 [(set (reg:SI SP_REG)
6572 (plus:SI (reg:SI SP_REG)
6573 (match_operand 1 "immediate_operand" "")))
6574 (set (mem:SI (plus:SI (reg:SI SP_REG)
6575 (match_operand 2 "immediate_operand"
6577 (reg:SI RETURN_ADDR_REGNUM))])]
6578 "TARGET_CODE_DENSITY"
6580 int len = XVECLEN (operands[0], 0);
6581 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6582 if (MEM_P (XEXP (tmp, 0)))
6584 operands[3] = XEXP (tmp, 1);
6585 return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)";
6589 tmp = XVECEXP (operands[0], 0, len - 3);
6590 operands[3] = XEXP (tmp, 1);
6591 return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)";
6594 [(set_attr "type" "call_no_delay_slot")
6595 (set_attr "length" "2")])
6597 (define_insn "*pop_multi_fp"
6598 [(match_parallel 0 "pop_multi_operand"
6599 [(set (reg:SI SP_REG)
6600 (plus:SI (reg:SI SP_REG)
6601 (match_operand 1 "immediate_operand" "")))
6606 (match_operand 2 "immediate_operand" ""))))])]
6607 "TARGET_CODE_DENSITY"
6609 int len = XVECLEN (operands[0], 0);
6610 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6611 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6613 operands[3] = XEXP (tmp, 0);
6614 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6615 return "leave_s\\t{r13-%3} ; sp=sp+%1";
6619 tmp = XVECEXP (operands[0], 0, len - 2);
6620 operands[3] = XEXP (tmp, 0);
6621 return "leave_s\\t{r13-%3, fp} ; sp=sp+%1";
6624 [(set_attr "type" "call_no_delay_slot")
6625 (set_attr "length" "2")])
6627 (define_insn "*pop_multi_fp_blink"
6628 [(match_parallel 0 "pop_multi_operand"
6629 [(set (reg:SI SP_REG)
6630 (plus:SI (reg:SI SP_REG)
6631 (match_operand 1 "immediate_operand" "")))
6632 (set (reg:SI RETURN_ADDR_REGNUM)
6636 (match_operand 2 "immediate_operand" ""))))])]
6637 "TARGET_CODE_DENSITY"
6639 int len = XVECLEN (operands[0], 0);
6640 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6641 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6643 operands[3] = XEXP (tmp, 0);
6644 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6645 return "leave_s\\t{r13-%3, blink} ; sp=sp+%1";
6649 tmp = XVECEXP (operands[0], 0, len - 2);
6650 operands[3] = XEXP (tmp, 0);
6651 return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1";
6654 [(set_attr "type" "call_no_delay_slot")
6655 (set_attr "length" "2")])
6657 (define_insn "*pop_multi_fp_ret"
6658 [(match_parallel 0 "pop_multi_operand"
6660 (set (reg:SI SP_REG)
6661 (plus:SI (reg:SI SP_REG)
6662 (match_operand 1 "immediate_operand" "")))
6667 (match_operand 2 "immediate_operand" ""))))])]
6668 "TARGET_CODE_DENSITY"
6670 int len = XVECLEN (operands[0], 0);
6671 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6672 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6674 operands[3] = XEXP (tmp, 0);
6675 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6676 return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1";
6680 tmp = XVECEXP (operands[0], 0, len - 2);
6681 operands[3] = XEXP (tmp, 0);
6682 return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1";
6685 [(set_attr "type" "call_no_delay_slot")
6686 (set_attr "length" "2")])
6688 (define_insn "*pop_multi_fp_blink_ret"
6689 [(match_parallel 0 "pop_multi_operand"
6691 (set (reg:SI SP_REG)
6692 (plus:SI (reg:SI SP_REG)
6693 (match_operand 1 "immediate_operand" "")))
6694 (set (reg:SI RETURN_ADDR_REGNUM)
6698 (match_operand 2 "immediate_operand" ""))))])]
6699 "TARGET_CODE_DENSITY"
6701 int len = XVECLEN (operands[0], 0);
6702 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6703 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6705 operands[3] = XEXP (tmp, 0);
6706 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6707 return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1";
6711 tmp = XVECEXP (operands[0], 0, len - 2);
6712 operands[3] = XEXP (tmp, 0);
6713 return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1";
6716 [(set_attr "type" "call_no_delay_slot")
6717 (set_attr "length" "2")])
6719 ;; Patterns for exception handling
6720 (define_insn_and_split "eh_return"
6721 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6722 VUNSPEC_ARC_EH_RETURN)]
6729 arc_eh_return_address_location (operands[0]);
6732 [(set_attr "length" "8")]
6735 ;; include the arc-FPX instructions
6738 ;; include the arc-FPU instructions
6741 (include "simdext.md")
6743 ;; include atomic extensions
6744 (include "atomic.md")