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 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
246 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
247 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
248 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
249 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
250 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
251 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
252 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
253 simd_valign, simd_valign_with_acc, simd_vcontrol,
254 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
255 fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block"
256 (cond [(eq_attr "is_sfunc" "yes")
257 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
258 (match_test "flag_pic") (const_string "sfunc")]
259 (const_string "call_no_delay_slot"))]
260 (const_string "binary")))
262 ;; The following three attributes are mixed case so that they can be
263 ;; used conveniently with the CALL_ATTR macro.
264 (define_attr "is_CALL" "no,yes"
265 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
266 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
267 (const_string "no")))
269 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
271 (define_attr "is_NON_SIBCALL" "no,yes"
272 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
273 (eq_attr "is_CALL" "yes") (const_string "yes")]
274 (const_string "no")))
276 ;; true for compact instructions (those with _s suffix)
277 ;; "maybe" means compact unless we conditionalize the insn.
278 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
279 (cond [(eq_attr "type" "sfunc")
280 (const_string "maybe")]
281 (const_string "false")))
284 ; Is there an instruction that we are actually putting into the delay slot?
285 (define_attr "delay_slot_filled" "no,yes"
286 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
288 (match_test "!TARGET_AT_DBR_CONDEXEC
290 && INSN_ANNULLED_BRANCH_P (insn)
291 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
293 (const_string "yes")))
295 ; Is a delay slot present for purposes of shorten_branches?
296 ; We have to take the length of this insn into account for forward branches
297 ; even if we don't put the insn actually into a delay slot.
298 (define_attr "delay_slot_present" "no,yes"
299 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
301 (const_string "yes")))
303 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
304 ; length of a different insn with the same uid.
305 (define_attr "delay_slot_length" ""
306 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
308 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
309 - get_attr_length (insn)")))
311 ; for ARCv2 we need to disable/enable different instruction alternatives
312 (define_attr "cpu_facility" "std,av1,av2,fpx,cd"
313 (const_string "std"))
315 ; We should consider all the instructions enabled until otherwise
316 (define_attr "enabled" "no,yes"
317 (cond [(and (eq_attr "cpu_facility" "av1")
318 (match_test "TARGET_V2"))
321 (and (eq_attr "cpu_facility" "av2")
322 (not (match_test "TARGET_V2")))
325 (and (eq_attr "cpu_facility" "fpx")
326 (match_test "TARGET_FP_DP_AX"))
329 (and (eq_attr "cpu_facility" "cd")
330 (not (and (match_test "TARGET_V2")
331 (match_test "TARGET_CODE_DENSITY"))))
334 (const_string "yes")))
336 (define_attr "predicable" "no,yes" (const_string "no"))
337 ;; if 'predicable' were not so brain-dead, we would specify:
338 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
339 ;; (eq_attr "iscompact" "maybe") (const_string "no")]
340 ;; (const_string "yes"))
341 ;; and then for everything but calls, we could just set the cond attribute.
343 ;; Condition codes: this one is used by final_prescan_insn to speed up
344 ;; conditionalizing instructions. It saves having to scan the rtl to see if
345 ;; it uses or alters the condition codes.
347 ;; USE: This insn uses the condition codes (eg: a conditional branch).
348 ;; CANUSE: This insn can use the condition codes (for conditional execution).
349 ;; SET: All condition codes are set by this insn.
350 ;; SET_ZN: the Z and N flags are set by this insn.
351 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
352 ;; CLOB: The condition codes are set to unknown values by this insn.
353 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
355 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
357 [(and (eq_attr "predicable" "yes")
358 (eq_attr "is_sfunc" "no")
359 (eq_attr "delay_slot_filled" "no"))
360 (const_string "canuse")
362 (eq_attr "type" "call")
363 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
364 (match_test "!flag_pic") (const_string "canuse_limm")]
365 (const_string "nocond"))
367 (eq_attr "iscompact" "maybe,false")
368 (cond [ (and (eq_attr "type" "move")
369 (match_operand 1 "immediate_operand" ""))
371 (ior (match_operand 1 "u6_immediate_operand" "")
372 (match_operand 1 "long_immediate_operand" ""))
373 (const_string "canuse")
374 (const_string "canuse_limm"))
376 (eq_attr "type" "binary")
377 (cond [(ne (symbol_ref "REGNO (operands[0])")
378 (symbol_ref "REGNO (operands[1])"))
379 (const_string "nocond")
380 (match_operand 2 "register_operand" "")
381 (const_string "canuse")
382 (match_operand 2 "u6_immediate_operand" "")
383 (const_string "canuse")
384 (match_operand 2 "long_immediate_operand" "")
385 (const_string "canuse")
386 (match_operand 2 "const_int_operand" "")
387 (const_string "canuse_limm")]
388 (const_string "nocond"))
390 (eq_attr "type" "compare")
393 (eq_attr "type" "cmove,branch")
396 (eq_attr "is_sfunc" "yes")
397 (cond [(match_test "(TARGET_MEDIUM_CALLS
398 && !TARGET_LONG_CALLS_SET
400 (const_string "canuse_limm_add")
401 (match_test "(TARGET_MEDIUM_CALLS
402 && !TARGET_LONG_CALLS_SET)")
403 (const_string "canuse_limm")]
404 (const_string "canuse"))
408 (const_string "nocond"))]
410 (cond [(eq_attr "type" "compare")
413 (eq_attr "type" "cmove,branch")
418 (const_string "nocond"))))
420 /* ??? Having all these patterns gives ifcvt more freedom to generate
421 inefficient code. It seem to operate on the premise that
422 register-register copies and registers are free. I see better code
423 with -fno-if-convert now than without. */
425 [(match_operator 0 "proper_comparison_operator"
426 [(reg CC_REG) (const_int 0)])]
430 ;; Length (in # of bytes, long immediate constants counted too).
431 ;; ??? There's a nasty interaction between the conditional execution fsm
432 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
433 (define_attr "length" ""
435 [(eq_attr "iscompact" "true")
438 (eq_attr "iscompact" "maybe")
440 [(eq_attr "type" "sfunc")
441 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
444 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)
445 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (1))")
449 (eq_attr "iscompact" "true_limm")
452 (eq_attr "iscompact" "maybe_limm")
453 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
456 (eq_attr "type" "load")
458 (match_operand 1 "long_immediate_loadstore_operand" "")
459 (const_int 8) (const_int 4))
461 (eq_attr "type" "store")
463 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
464 (match_operand 1 "immediate_operand" ""))
465 (const_int 8) (const_int 4))
467 (eq_attr "type" "move,unary")
469 [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
470 (match_operand 1 "register_operand" "") (const_int 4)
471 (match_operand 1 "long_immediate_operand" "") (const_int 8)
472 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
475 (and (eq_attr "type" "shift")
476 (match_operand 1 "immediate_operand"))
478 (eq_attr "type" "binary,shift")
480 (ior (match_operand 2 "long_immediate_operand" "")
481 (and (ne (symbol_ref "REGNO (operands[0])")
482 (symbol_ref "REGNO (operands[1])"))
483 (eq (match_operand 2 "u6_immediate_operand" "")
486 (const_int 8) (const_int 4))
488 (eq_attr "type" "cmove")
489 (if_then_else (match_operand 1 "register_operand" "")
490 (const_int 4) (const_int 8))
492 (eq_attr "type" "call_no_delay_slot") (const_int 8)
498 ;; The length here is the length of a single asm. Unfortunately it might be
499 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
500 ;; lament asm's not being put in delay slots?
502 (define_asm_attributes
503 [(set_attr "length" "8")
504 (set_attr "type" "multi")
505 (set_attr "cond" "clob") ])
508 ;; The first two cond clauses and the default are necessary for correctness;
509 ;; the remaining cond clause is mainly an optimization, as otherwise nops
510 ;; would be inserted; however, if we didn't do this optimization, we would
511 ;; have to be more conservative in our length calculations.
513 (define_attr "in_delay_slot" "false,true"
514 (cond [(eq_attr "type" "uncond_branch,jump,branch,
515 call,sfunc,call_no_delay_slot,
516 brcc, brcc_no_delay_slot,loop_setup,loop_end")
517 (const_string "false")
518 (match_test "arc_write_ext_corereg (insn)")
519 (const_string "false")
520 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
521 next_active_insn (insn))")
522 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
523 + arc_hazard (insn, next_active_insn (insn)))"))
524 (const_string "false")
525 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
526 (const_string "false")
527 (eq_attr "iscompact" "maybe") (const_string "true")
530 (if_then_else (eq_attr "length" "2,4")
531 (const_string "true")
532 (const_string "false"))))
534 ; must not put an insn inside that refers to blink.
535 (define_attr "in_call_delay_slot" "false,true"
536 (cond [(eq_attr "in_delay_slot" "false")
537 (const_string "false")
538 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
539 (const_string "false")]
540 (const_string "true")))
542 (define_attr "in_sfunc_delay_slot" "false,true"
543 (cond [(eq_attr "in_call_delay_slot" "false")
544 (const_string "false")
545 (match_test "arc_regno_use_in (12, PATTERN (insn))")
546 (const_string "false")]
547 (const_string "true")))
549 ;; Instructions that we can put into a delay slot and conditionalize.
550 (define_attr "cond_delay_insn" "no,yes"
551 (cond [(eq_attr "cond" "!canuse") (const_string "no")
552 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
554 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
556 (eq_attr "length" "2,4") (const_string "yes")]
557 (const_string "no")))
559 (define_attr "in_ret_delay_slot" "no,yes"
560 (cond [(eq_attr "in_delay_slot" "false")
562 (match_test "regno_clobbered_p
563 (RETURN_ADDR_REGNUM, insn, SImode, 1)")
565 (const_string "yes")))
567 (define_attr "cond_ret_delay_insn" "no,yes"
568 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
569 (eq_attr "cond_delay_insn" "no") (const_string "no")]
570 (const_string "yes")))
572 (define_attr "annul_ret_delay_insn" "no,yes"
573 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
574 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
575 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
576 (const_string "yes")]
577 (const_string "no")))
580 ;; Delay slot definition for ARCompact ISA
582 ;; When outputting an annul-true insn elegible for cond-exec
583 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
584 ;; for ARC600; we could also use this for ARC700 if the branch can't be
585 ;; unaligned and is at least somewhat likely (add parameter for this).
587 (define_delay (eq_attr "type" "call")
588 [(eq_attr "in_call_delay_slot" "true")
589 (eq_attr "in_call_delay_slot" "true")
592 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
593 (eq_attr "type" "brcc"))
594 [(eq_attr "in_delay_slot" "true")
595 (eq_attr "in_delay_slot" "true")
598 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
599 (eq_attr "type" "brcc"))
600 [(eq_attr "in_delay_slot" "true")
605 (eq_attr "type" "return")
606 [(eq_attr "in_ret_delay_slot" "yes")
607 (eq_attr "annul_ret_delay_insn" "yes")
608 (eq_attr "cond_ret_delay_insn" "yes")])
610 (define_delay (eq_attr "type" "loop_end")
611 [(eq_attr "in_delay_slot" "true")
612 (eq_attr "in_delay_slot" "true")
615 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
616 ;; non-taken case, so the only meaningful way to have an annull-true
617 ;; filled delay slot is to conditionalize the delay slot insn.
618 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
619 (eq_attr "type" "branch,uncond_branch,jump")
620 (match_test "!optimize_size"))
621 [(eq_attr "in_delay_slot" "true")
622 (eq_attr "cond_delay_insn" "yes")
623 (eq_attr "cond_delay_insn" "yes")])
625 ;; For ARC700, anything goes for annulled-true insns, since there is no
626 ;; penalty for the unexposed delay slot when the branch is not taken,
627 ;; however, we must avoid things that have a delay slot themselvese to
628 ;; avoid confusing gcc.
629 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
630 (eq_attr "type" "branch,uncond_branch,jump")
631 (match_test "!optimize_size"))
632 [(eq_attr "in_delay_slot" "true")
633 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
634 (eq_attr "cond_delay_insn" "yes")])
636 ;; -mlongcall -fpic sfuncs use r12 to load the function address
637 (define_delay (eq_attr "type" "sfunc")
638 [(eq_attr "in_sfunc_delay_slot" "true")
639 (eq_attr "in_sfunc_delay_slot" "true")
641 ;; ??? need to use a working strategy for canuse_limm:
642 ;; - either canuse_limm is not eligible for delay slots, and has no
643 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
644 ;; somehow modify them to become inelegible for delay slots if a decision
645 ;; is made that makes conditional execution required.
647 (define_attr "tune" "none,arc600,arc7xx,arc700_4_2_std,arc700_4_2_xmac, \
650 (cond [(symbol_ref "arc_tune == ARC_TUNE_ARC600")
651 (const_string "arc600")
652 (symbol_ref "arc_tune == ARC_TUNE_ARC7XX")
653 (const_string "arc7xx")
654 (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_STD")
655 (const_string "arc700_4_2_std")
656 (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_XMAC")
657 (const_string "arc700_4_2_xmac")
658 (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
659 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A"))
660 (const_string "archs4x")
661 (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD")
662 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW"))
663 (const_string "archs4xd")]
664 (const_string "none"))))
666 (define_attr "tune_arc700" "false,true"
667 (if_then_else (eq_attr "tune" "arc7xx, arc700_4_2_std, arc700_4_2_xmac")
668 (const_string "true")
669 (const_string "false")))
671 (define_attr "tune_dspmpy" "none, slow, fast"
673 (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
674 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
675 (const_string "fast")
676 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW")
677 (const_string "slow")]
678 (const_string "none"))))
680 (define_attr "tune_store" "none, normal, rel31a"
682 (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
683 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
684 (const_string "normal")
685 (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A")
686 (const_string "rel31a")]
687 (const_string "none"))))
689 ;; Move instructions.
690 (define_expand "movqi"
691 [(set (match_operand:QI 0 "move_dest_operand" "")
692 (match_operand:QI 1 "general_operand" ""))]
694 "if (prepare_move_operands (operands, QImode)) DONE;")
696 ; In order to allow the ccfsm machinery to do its work, the leading compact
697 ; alternatives say 'canuse' - there is another alternative that will match
698 ; when the condition codes are used.
699 ; Likewise, the length of an alternative that might be shifted to conditional
700 ; execution must reflect this, lest out-of-range branches are created.
701 ; The iscompact attribute allows the epilogue expander to know for which
702 ; insns it should lengthen the return insn.
703 (define_insn "*movqi_insn"
704 [(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")
705 (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"))]
706 "register_operand (operands[0], QImode)
707 || register_operand (operands[1], QImode)
708 || (satisfies_constraint_Cm3 (operands[1])
709 && memory_operand (operands[0], QImode))"
731 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
732 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
733 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
734 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
736 (define_expand "movhi"
737 [(set (match_operand:HI 0 "move_dest_operand" "")
738 (match_operand:HI 1 "general_operand" ""))]
740 "if (prepare_move_operands (operands, HImode)) DONE;")
742 (define_insn "*movhi_insn"
743 [(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")
744 (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"))]
745 "register_operand (operands[0], HImode)
746 || register_operand (operands[1], HImode)
747 || (CONSTANT_P (operands[1])
748 /* Don't use a LIMM that we could load with a single insn - we loose
749 delay-slot filling opportunities. */
750 && !satisfies_constraint_I (operands[1])
751 && satisfies_constraint_Usc (operands[0]))
752 || (satisfies_constraint_Cm3 (operands[1])
753 && memory_operand (operands[0], HImode))"
775 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
776 (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")
777 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
778 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
780 (define_expand "movsi"
781 [(set (match_operand:SI 0 "move_dest_operand" "")
782 (match_operand:SI 1 "general_operand" ""))]
784 "if (prepare_move_operands (operands, SImode)) DONE;")
786 ; In order to allow the ccfsm machinery to do its work, the leading compact
787 ; alternatives say 'canuse' - there is another alternative that will match
788 ; when the condition codes are used.
789 ; The length of an alternative that might be shifted to conditional
790 ; execution must reflect this, lest out-of-range branches are created.
791 ; the iscompact attribute allows the epilogue expander to know for which
792 ; insns it should lengthen the return insn.
793 (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
794 [(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")
795 (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"))]
796 "register_operand (operands[0], SImode)
797 || register_operand (operands[1], SImode)
798 || (CONSTANT_P (operands[1])
799 && (!satisfies_constraint_I (operands[1]) || !optimize_size)
800 && satisfies_constraint_Usc (operands[0]))
801 || (satisfies_constraint_Cm3 (operands[1])
802 && memory_operand (operands[0], SImode))"
812 movh.cl\\t%0,%L1>>16 ;8
813 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl\\t%0,%1 >> %p1,%p1,8;9\" : \"movbi.cl\\t%0,%L1 >> 24,24,8;9\";
815 add\\t%0,pcl,%1@pcl ;11
821 * return arc_short_long (insn, \"push%?\\t%1%&\", \"st%U0\\t%1,%0%&\");
822 * return arc_short_long (insn, \"pop%?\\t%0%&\", \"ld%U1\\t%0,%1%&\");
832 st%U0%V0\\t%1,%0 ;28"
834 && GET_CODE (PATTERN (insn)) != COND_EXEC
835 && register_operand (operands[0], SImode)
836 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
837 && satisfies_constraint_Cax (operands[1])"
840 arc_split_mov_const (operands);
843 ; 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
844 [(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")
845 (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")
846 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,8,8,*,6,*,*,*,*,*,*,4,*,4,*,*,*,*,*,8")
847 (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")
848 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,av2,*")])
850 ;; Sometimes generated by the epilogue code. We don't want to
851 ;; recognize these addresses in general, because the limm is costly,
852 ;; and we can't use them for stores. */
853 (define_insn "*movsi_pre_mod"
854 [(set (match_operand:SI 0 "register_operand" "=w")
857 (plus:SI (reg:SI SP_REG)
858 (match_operand 1 "immediate_operand" "Cal")))))]
861 [(set_attr "type" "load")
862 (set_attr "length" "8")])
864 ;; Store a value to directly to memory. The location might also be cached.
865 ;; Since the cached copy can cause a write-back at unpredictable times,
866 ;; we first write cached, then we write uncached.
867 (define_insn "store_direct"
868 [(set (match_operand:SI 0 "move_dest_operand" "=m")
869 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
872 "st%U0 %1,%0\;st%U0.di %1,%0"
873 [(set_attr "type" "store")])
875 ;; Combiner patterns for compare with zero
876 (define_mode_iterator SQH [QI HI])
877 (define_mode_attr SQH_postfix [(QI "b") (HI "%_")])
879 (define_code_iterator SEZ [sign_extend zero_extend])
880 (define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")])
881 ; Optab prefix for sign/zero-extending operations
882 (define_code_attr su_optab [(sign_extend "") (zero_extend "u")])
884 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout"
885 [(set (match_operand 0 "cc_set_register" "")
886 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
889 "<SEZ_prefix><SQH_postfix>.f\\t0,%1"
890 [(set_attr "type" "compare")
891 (set_attr "cond" "set_zn")])
893 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0"
894 [(set (match_operand 0 "cc_set_register" "")
895 (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
897 (set (match_operand:SI 2 "register_operand" "=r")
898 (SEZ:SI (match_dup 1)))]
900 "<SEZ_prefix><SQH_postfix>.f\\t%2,%1"
901 [(set_attr "type" "compare")
902 (set_attr "cond" "set_zn")])
904 (define_insn "*xbfu_cmp0_noout"
905 [(set (match_operand 0 "cc_set_register" "")
908 (match_operand:SI 1 "register_operand" " r,r")
909 (match_operand:SI 2 "const_int_operand" "C3p,n")
910 (match_operand:SI 3 "const_int_operand" " n,n"))
912 "TARGET_HS && TARGET_BARREL_SHIFTER"
914 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
915 operands[2] = GEN_INT (assemble_op2);
916 return "xbfu%?.f\\t0,%1,%2";
918 [(set_attr "type" "shift")
919 (set_attr "iscompact" "false")
920 (set_attr "length" "4,8")
921 (set_attr "predicable" "no")
922 (set_attr "cond" "set_zn")])
924 (define_insn "*xbfu_cmp0"
925 [(set (match_operand 4 "cc_set_register" "")
928 (match_operand:SI 1 "register_operand" "0 ,r,0")
929 (match_operand:SI 2 "const_int_operand" "C3p,n,n")
930 (match_operand:SI 3 "const_int_operand" "n ,n,n"))
932 (set (match_operand:SI 0 "register_operand" "=r,r,r")
933 (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
934 "TARGET_HS && TARGET_BARREL_SHIFTER"
936 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
937 operands[2] = GEN_INT (assemble_op2);
938 return "xbfu%?.f\\t%0,%1,%2";
940 [(set_attr "type" "shift")
941 (set_attr "iscompact" "false")
942 (set_attr "length" "4,8,8")
943 (set_attr "predicable" "yes,no,yes")
944 (set_attr "cond" "set_zn")])
946 ; splitting to 'tst' allows short insns and combination into brcc.
947 (define_insn_and_split "*movsi_set_cc_insn"
948 [(set (match_operand 2 "cc_set_register" "")
949 (match_operator 3 "zn_compare_operator"
950 [(match_operand:SI 1 "nonmemory_operand" "rL,rI,Cal")
952 (set (match_operand:SI 0 "register_operand" "=r,r,r")
956 "reload_completed && operands_match_p (operands[0], operands[1])"
957 [(set (match_dup 2) (match_dup 3))]
959 [(set_attr "type" "compare")
960 (set_attr "predicable" "yes,no,yes")
961 (set_attr "cond" "set_zn")
962 (set_attr "length" "4,4,8")])
964 (define_insn "unary_comparison"
965 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
966 (match_operator:CC_ZN 3 "zn_compare_operator"
967 [(match_operator:SI 2 "unary_operator"
968 [(match_operand:SI 1 "register_operand" "c")])
972 [(set_attr "type" "compare")
973 (set_attr "cond" "set_zn")])
976 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
977 (define_insn "*unary_comparison_result_used"
978 [(set (match_operand 2 "cc_register" "")
979 (match_operator 4 "zn_compare_operator"
980 [(match_operator:SI 3 "unary_operator"
981 [(match_operand:SI 1 "register_operand" "c")])
983 (set (match_operand:SI 0 "register_operand" "=w")
987 [(set_attr "type" "compare")
988 (set_attr "cond" "set_zn")
989 (set_attr "length" "4")])
991 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
992 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
993 ; even if we don't need the clobber.
994 (define_insn_and_split "*tst_movb"
996 (match_operand 0 "cc_register" "")
997 (match_operator 4 "zn_compare_operator"
999 (match_operand:SI 1 "register_operand" "%q, q, c, c, c, c, q, q, c")
1000 (match_operand:SI 2 "nonmemory_operand" "q,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
1002 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))]
1004 "movb.f.cl %3,%1,%p2,%p2,%s2"
1005 "TARGET_NPS_BITOPS && reload_completed
1006 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
1007 [(set (match_dup 0) (match_dup 4))])
1011 (match_operand 0 "cc_register" "")
1012 (match_operator 3 "zn_compare_operator"
1014 (match_operand:SI 1 "register_operand"
1015 "%q, q, c, c, c, c, c, c")
1016 (match_operand:SI 2 "nonmemory_operand"
1017 " q,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
1020 || !satisfies_constraint_Cbf (operands[2])
1021 || satisfies_constraint_C0p (operands[2])
1022 || satisfies_constraint_I (operands[2])
1023 || satisfies_constraint_C1p (operands[2])
1024 || satisfies_constraint_Chs (operands[2])"
1026 switch (which_alternative)
1028 case 0: case 2: case 3: case 7:
1029 return \"tst%? %1,%2\";
1031 return \"btst%? %1,%z2\";
1033 return \"bmsk%?.f 0,%1,%Z2%&\";
1035 return \"bclr%?.f 0,%1,%M2%&\";
1037 return \"asr.f 0,%1,%p2\";
1042 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
1043 (set_attr "type" "compare,compare,compare,compare,compare,compare,binary,compare")
1044 (set_attr "length" "*,*,4,4,4,4,4,8")
1045 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
1046 (set_attr "cond" "set_zn")])
1048 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
1049 ; combine will do that and not try the AND.
1051 ; It would take 66 constraint combinations to describe the zero_extract
1052 ; constants that are covered by the 12-bit signed constant for tst
1053 ; (excluding the ones that are better done by mov or btst).
1054 ; so we rather use an extra pattern for tst;
1055 ; since this is about constants, reload shouldn't care.
1056 (define_insn "*tst_bitfield_tst"
1057 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1058 (match_operator 4 "zn_compare_operator"
1060 (match_operand:SI 1 "register_operand" "c")
1061 (match_operand:SI 2 "const_int_operand" "n")
1062 (match_operand:SI 3 "const_int_operand" "n"))
1064 "INTVAL (operands[2]) > 1
1065 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
1066 || (INTVAL (operands[3]) <= 11
1067 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
1068 "tst %1,((1<<%2)-1)<<%3"
1069 [(set_attr "type" "compare")
1070 (set_attr "cond" "set_zn")
1071 (set_attr "length" "4")])
1073 ; Likewise for asr.f.
1074 (define_insn "*tst_bitfield_asr"
1075 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1076 (match_operator 4 "zn_compare_operator"
1078 (match_operand:SI 1 "register_operand" "c")
1079 (match_operand:SI 2 "const_int_operand" "n")
1080 (match_operand:SI 3 "const_int_operand" "n"))
1082 "INTVAL (operands[2]) > 1
1083 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
1085 [(set_attr "type" "shift")
1086 (set_attr "cond" "set_zn")
1087 (set_attr "length" "4")])
1089 (define_insn "*tst_bitfield"
1090 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1091 (match_operator 5 "zn_compare_operator"
1093 (match_operand:SI 1 "register_operand" "%q,c, c,Rrq,c")
1094 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
1095 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
1097 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
1103 movb.f.cl %4,%1,%3,%3,%2
1104 and.f 0,%1,((1<<%2)-1)<<%3"
1105 [(set_attr "iscompact" "maybe,false,false,false,false")
1106 (set_attr "type" "compare,compare,compare,shift,compare")
1107 (set_attr "cond" "set_zn")
1108 (set_attr "length" "*,4,4,4,8")])
1110 ;; The next two patterns are for plos, ior, xor, and, and mult.
1111 (define_insn "*commutative_binary_cmp0_noout"
1112 [(set (match_operand 0 "cc_set_register" "")
1113 (match_operator 4 "zn_compare_operator"
1114 [(match_operator:SI 3 "commutative_operator"
1115 [(match_operand:SI 1 "register_operand" "%r,r")
1116 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1120 [(set_attr "type" "compare")
1121 (set_attr "cond" "set_zn")
1122 (set_attr "length" "4,8")])
1124 (define_insn "*commutative_binary_cmp0"
1125 [(set (match_operand 3 "cc_set_register" "")
1126 (match_operator 5 "zn_compare_operator"
1127 [(match_operator:SI 4 "commutative_operator"
1128 [(match_operand:SI 1 "register_operand" "%0, 0,r,r")
1129 (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")])
1131 (set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1135 [(set_attr "type" "compare")
1136 (set_attr "cond" "set_zn")
1137 (set_attr "predicable" "yes,yes,no,no")
1138 (set_attr "length" "4,4,4,8")])
1140 ; for flag setting 'add' instructions like if (a+b) { ...}
1141 ; the combiner needs this pattern
1142 (define_insn "*addsi_compare"
1143 [(set (reg:CC_ZN CC_REG)
1144 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
1145 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
1148 [(set_attr "cond" "set")
1149 (set_attr "type" "compare")
1150 (set_attr "length" "4")])
1152 ; for flag setting 'add' instructions like if (a+b < a) { ...}
1153 ; the combiner needs this pattern
1154 (define_insn "addsi_compare_2"
1155 [(set (reg:CC_C CC_REG)
1156 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
1157 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
1161 [(set_attr "cond" "set")
1162 (set_attr "type" "compare")
1163 (set_attr "length" "4,8")])
1165 (define_insn "*addsi_compare_3"
1166 [(set (reg:CC_C CC_REG)
1167 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
1168 (match_operand:SI 1 "register_operand" "c"))
1172 [(set_attr "cond" "set")
1173 (set_attr "type" "compare")
1174 (set_attr "length" "4")])
1176 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1177 (define_insn "*commutative_binary_comparison_result_used"
1178 [(set (match_operand 3 "cc_register" "")
1179 (match_operator 5 "zn_compare_operator"
1180 ; We can accept any commutative operator except mult because
1181 ; our 'w' class below could try to use LP_COUNT.
1182 [(match_operator:SI 4 "commutative_operator_sans_mult"
1183 [(match_operand:SI 1 "register_operand" "c,0,c")
1184 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1186 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1189 "%O4.f %0,%1,%2 ; non-mult commutative"
1190 [(set_attr "type" "compare,compare,compare")
1191 (set_attr "cond" "set_zn,set_zn,set_zn")
1192 (set_attr "length" "4,4,8")])
1194 ; a MULT-specific version of this pattern to avoid touching the
1196 (define_insn "*commutative_binary_mult_comparison_result_used"
1197 [(set (match_operand 3 "cc_register" "")
1198 (match_operator 5 "zn_compare_operator"
1199 [(match_operator:SI 4 "mult_operator"
1200 [(match_operand:SI 1 "register_operand" "c,0,c")
1201 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1203 ; Make sure to use the W class to not touch LP_COUNT.
1204 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1206 "!TARGET_ARC600_FAMILY"
1207 "%O4.f %0,%1,%2 ; mult commutative"
1208 [(set_attr "type" "compare,compare,compare")
1209 (set_attr "cond" "set_zn,set_zn,set_zn")
1210 (set_attr "length" "4,4,8")])
1212 (define_insn "*noncommutative_binary_cmp0"
1213 [(set (match_operand 3 "cc_set_register" "")
1214 (match_operator 5 "zn_compare_operator"
1215 [(match_operator:SI 4 "noncommutative_operator"
1216 [(match_operand:SI 1 "register_operand" "0,r,0, 0,r")
1217 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,Cal,Cal")])
1219 (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1222 "%O4%?.f\\t%0,%1,%2"
1223 [(set_attr "type" "compare")
1224 (set_attr "cond" "set_zn")
1225 (set_attr "predicable" "yes,no,no,yes,no")
1226 (set_attr "length" "4,4,4,8,8")])
1228 (define_insn "*noncommutative_binary_cmp0_noout"
1229 [(set (match_operand 0 "cc_set_register" "")
1230 (match_operator 3 "zn_compare_operator"
1231 [(match_operator:SI 4 "noncommutative_operator"
1232 [(match_operand:SI 1 "register_operand" "r,r")
1233 (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1237 [(set_attr "type" "compare")
1238 (set_attr "cond" "set_zn")
1239 (set_attr "length" "4,8")])
1242 (define_insn "*rsub_cmp0"
1243 [(set (match_operand 4 "cc_set_register" "")
1244 (match_operator 3 "zn_compare_operator"
1246 (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1247 (match_operand:SI 2 "register_operand" "r,r"))
1249 (set (match_operand:SI 0 "register_operand" "=r,r")
1250 (minus:SI (match_dup 1) (match_dup 2)))]
1253 [(set_attr "type" "compare")
1254 (set_attr "cond" "set_zn")
1255 (set_attr "length" "4,8")])
1257 (define_insn "*rsub_cmp0_noout"
1258 [(set (match_operand 0 "cc_set_register" "")
1259 (match_operator 3 "zn_compare_operator"
1261 (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1262 (match_operand:SI 2 "register_operand" "r,r"))
1266 [(set_attr "type" "compare")
1267 (set_attr "cond" "set_zn")
1268 (set_attr "length" "4,8")])
1270 (define_expand "bic_f_zn"
1272 [(set (reg:CC_ZN CC_REG)
1274 (and:SI (match_operand:SI 1 "register_operand" "")
1275 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1277 (set (match_operand:SI 0 "register_operand" "")
1278 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1281 (define_insn "*bic_f"
1282 [(set (match_operand 3 "cc_set_register" "")
1283 (match_operator 4 "zn_compare_operator"
1284 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1286 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1288 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1289 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1292 [(set_attr "type" "compare,compare,compare")
1293 (set_attr "cond" "set_zn,set_zn,set_zn")
1294 (set_attr "length" "4,4,8")])
1296 (define_insn "*bic_cmp0_noout"
1297 [(set (match_operand 0 "cc_set_register" "")
1299 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1300 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1302 "register_operand (operands[1], SImode)
1303 || register_operand (operands[2], SImode)"
1305 [(set_attr "type" "unary")
1306 (set_attr "cond" "set_zn")
1307 (set_attr "length" "4,8,8")])
1309 (define_insn "*bic_cmp0"
1310 [(set (match_operand 0 "cc_set_register" "")
1312 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1313 (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1315 (set (match_operand:SI 3 "register_operand" "=r,r,r")
1316 (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1317 "register_operand (operands[1], SImode)
1318 || register_operand (operands[2], SImode)"
1320 [(set_attr "type" "unary")
1321 (set_attr "cond" "set_zn")
1322 (set_attr "length" "4,8,8")])
1324 (define_expand "movdi"
1325 [(set (match_operand:DI 0 "move_dest_operand" "")
1326 (match_operand:DI 1 "general_operand" ""))]
1329 if (prepare_move_operands (operands, DImode))
1333 (define_insn_and_split "*movdi_insn"
1334 [(set (match_operand:DI 0 "move_dest_operand" "=r, r,r, m")
1335 (match_operand:DI 1 "move_double_src_operand" "r,Hi,m,rCm3"))]
1336 "register_operand (operands[0], DImode)
1337 || register_operand (operands[1], DImode)
1338 || (satisfies_constraint_Cm3 (operands[1])
1339 && memory_operand (operands[0], DImode))"
1345 "&& reload_completed && arc_split_move_p (operands)"
1348 arc_split_move (operands);
1351 [(set_attr "type" "move,move,load,store")
1352 (set_attr "length" "8,16,16,16")])
1354 ;; Floating point move insns.
1356 (define_expand "movsf"
1357 [(set (match_operand:SF 0 "move_dest_operand" "")
1358 (match_operand:SF 1 "general_operand" ""))]
1360 "if (prepare_move_operands (operands, SFmode)) DONE;")
1362 (define_insn "*movsf_insn"
1363 [(set (match_operand:SF 0 "move_dest_operand" "=h,h, r,r, q,S,Usc,r,m")
1364 (match_operand:SF 1 "move_src_operand" "hCfZ,E,rCfZ,E,Uts,q, E,m,r"))]
1365 "register_operand (operands[0], SFmode)
1366 || register_operand (operands[1], SFmode)"
1377 [(set_attr "type" "move,move,move,move,load,store,store,load,store")
1378 (set_attr "predicable" "no,no,yes,yes,no,no,no,no,no")
1379 (set_attr "length" "*,*,4,*,*,*,*,*,*")
1380 (set_attr "iscompact" "true,true_limm,false,false,true,true,false,false,false")])
1382 (define_expand "movdf"
1383 [(set (match_operand:DF 0 "move_dest_operand" "")
1384 (match_operand:DF 1 "general_operand" ""))]
1386 "if (prepare_move_operands (operands, DFmode)) DONE;")
1388 (define_insn_and_split "*movdf_insn"
1389 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,r,r,r,m")
1390 (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))]
1391 "(register_operand (operands[0], DFmode)
1392 || register_operand (operands[1], DFmode))"
1400 "&& reload_completed && arc_split_move_p (operands)"
1403 arc_split_move (operands);
1406 [(set_attr "type" "move,move,move,move,load,store")
1407 (set_attr "length" "4,16,8,16,16,16")])
1409 (define_insn_and_split "*movdf_insn_nolrsr"
1410 [(set (match_operand:DF 0 "register_operand" "=r")
1411 (match_operand:DF 1 "arc_double_register_operand" "D"))
1412 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1414 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1419 (set (match_dup 0) (match_dup 3))
1421 ; daddh?? r1, r0, r0
1423 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1426 (use (match_dup 0)) ; used to block can_combine_p
1427 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1430 ; We have to do this twice, once to read the value into R0 and
1431 ; second time to put back the contents which the first DEXCLx
1432 ; will have overwritten
1435 (set (match_dup 4) ; aka r0result
1437 (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1439 (clobber (match_dup 1))
1441 ; Generate the second, which makes sure operand5 and operand4 values
1442 ; are put back in the Dx register properly.
1443 (set (match_dup 1) (unspec_volatile:DF
1444 [(match_dup 5) (match_dup 4)]
1445 VUNSPEC_ARC_DEXCL_NORES))
1447 ; Note: we cannot use a (clobber (match_scratch)) here because
1448 ; the combine pass will end up replacing uses of it with 0
1450 "operands[3] = CONST0_RTX (DFmode);
1451 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1452 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1453 [(set_attr "type" "move")])
1455 ;; Load/Store with update instructions.
1457 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1458 ;; hardware can also do cases where the increment is not the size of the
1461 ;; In all these cases, we use operands 0 and 1 for the register being
1462 ;; incremented because those are the operands that local-alloc will
1463 ;; tie and these are the pair most likely to be tieable (and the ones
1464 ;; that will benefit the most).
1466 ;; We use match_operator here because we need to know whether the memory
1467 ;; object is volatile or not.
1470 ;; Note: loadqi_update has no 16-bit variant
1471 (define_insn "*loadqi_update"
1472 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1473 (match_operator:QI 4 "any_mem_operand"
1474 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1475 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1476 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1477 (plus:SI (match_dup 1) (match_dup 2)))]
1479 "ldb.a%V4 %3,[%0,%2]"
1480 [(set_attr "type" "load,load")
1481 (set_attr "length" "4,8")])
1483 (define_insn "*load_zeroextendqisi_update"
1484 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1485 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1486 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1487 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1488 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1489 (plus:SI (match_dup 1) (match_dup 2)))]
1491 "ldb.a%V4 %3,[%0,%2]"
1492 [(set_attr "type" "load,load")
1493 (set_attr "length" "4,8")])
1495 (define_insn "*load_signextendqisi_update"
1496 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1497 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1498 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1499 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1500 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1501 (plus:SI (match_dup 1) (match_dup 2)))]
1503 "ldb.x.a%V4 %3,[%0,%2]"
1504 [(set_attr "type" "load,load")
1505 (set_attr "length" "4,8")])
1507 (define_insn "*storeqi_update"
1508 [(set (match_operator:QI 4 "any_mem_operand"
1509 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1510 (match_operand:SI 2 "short_immediate_operand" "I"))])
1511 (match_operand:QI 3 "register_operand" "c"))
1512 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1513 (plus:SI (match_dup 1) (match_dup 2)))]
1515 "stb.a%V4 %3,[%0,%2]"
1516 [(set_attr "type" "store")
1517 (set_attr "length" "4")])
1519 ;; ??? pattern may have to be re-written
1520 ;; Note: no 16-bit variant for this pattern
1521 (define_insn "*loadhi_update"
1522 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1523 (match_operator:HI 4 "any_mem_operand"
1524 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1525 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1526 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1527 (plus:SI (match_dup 1) (match_dup 2)))]
1529 "ld%_.a%V4 %3,[%0,%2]"
1530 [(set_attr "type" "load,load")
1531 (set_attr "length" "4,8")])
1533 (define_insn "*load_zeroextendhisi_update"
1534 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1535 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1536 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1537 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1538 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1539 (plus:SI (match_dup 1) (match_dup 2)))]
1541 "ld%_.a%V4 %3,[%0,%2]"
1542 [(set_attr "type" "load,load")
1543 (set_attr "length" "4,8")])
1545 ;; Note: no 16-bit variant for this instruction
1546 (define_insn "*load_signextendhisi_update"
1547 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1548 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1549 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1550 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1551 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1552 (plus:SI (match_dup 1) (match_dup 2)))]
1554 "ld%_.x.a%V4 %3,[%0,%2]"
1555 [(set_attr "type" "load,load")
1556 (set_attr "length" "4,8")])
1558 (define_insn "*storehi_update"
1559 [(set (match_operator:HI 4 "any_mem_operand"
1560 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1561 (match_operand:SI 2 "short_immediate_operand" "I"))])
1562 (match_operand:HI 3 "register_operand" "c"))
1563 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1564 (plus:SI (match_dup 1) (match_dup 2)))]
1566 "st%_.a%V4 %3,[%0,%2]"
1567 [(set_attr "type" "store")
1568 (set_attr "length" "4")])
1570 ;; No 16-bit variant for this instruction pattern
1571 (define_insn "*loadsi_update"
1572 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1573 (match_operator:SI 4 "any_mem_operand"
1574 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1575 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1576 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1577 (plus:SI (match_dup 1) (match_dup 2)))]
1579 "ld.a%V4 %3,[%0,%2]"
1580 [(set_attr "type" "load,load")
1581 (set_attr "length" "4,8")])
1583 (define_insn "*storesi_update"
1584 [(set (match_operator:SI 4 "any_mem_operand"
1585 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1586 (match_operand:SI 2 "short_immediate_operand" "I"))])
1587 (match_operand:SI 3 "register_operand" "c"))
1588 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1589 (plus:SI (match_dup 1) (match_dup 2)))]
1591 "st.a%V4 %3,[%0,%2]"
1592 [(set_attr "type" "store")
1593 (set_attr "length" "4")])
1595 (define_insn "*loadsf_update"
1596 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1597 (match_operator:SF 4 "any_mem_operand"
1598 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1599 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1600 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1601 (plus:SI (match_dup 1) (match_dup 2)))]
1603 "ld.a%V4 %3,[%0,%2]"
1604 [(set_attr "type" "load,load")
1605 (set_attr "length" "4,8")])
1607 (define_insn "*storesf_update"
1608 [(set (match_operator:SF 4 "any_mem_operand"
1609 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1610 (match_operand:SI 2 "short_immediate_operand" "I"))])
1611 (match_operand:SF 3 "register_operand" "c"))
1612 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1613 (plus:SI (match_dup 1) (match_dup 2)))]
1615 "st.a%V4 %3,[%0,%2]"
1616 [(set_attr "type" "store")
1617 (set_attr "length" "4")])
1619 ;; Conditional move instructions.
1621 (define_expand "movsicc"
1622 [(set (match_operand:SI 0 "dest_reg_operand" "")
1623 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1624 (match_operand:SI 2 "nonmemory_operand" "")
1625 (match_operand:SI 3 "register_operand" "")))]
1628 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1629 if (operands[1] == NULL_RTX)
1633 (define_expand "movdicc"
1634 [(set (match_operand:DI 0 "dest_reg_operand" "")
1635 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1636 (match_operand:DI 2 "nonmemory_operand" "")
1637 (match_operand:DI 3 "register_operand" "")))]
1640 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1641 if (operands[1] == NULL_RTX)
1646 (define_expand "movsfcc"
1647 [(set (match_operand:SF 0 "dest_reg_operand" "")
1648 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1649 (match_operand:SF 2 "nonmemory_operand" "")
1650 (match_operand:SF 3 "register_operand" "")))]
1653 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1654 if (operands[1] == NULL_RTX)
1658 (define_expand "movdfcc"
1659 [(set (match_operand:DF 0 "dest_reg_operand" "")
1660 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1661 (match_operand:DF 2 "nonmemory_operand" "")
1662 (match_operand:DF 3 "register_operand" "")))]
1665 operands[1] = gen_compare_reg (operands[1], VOIDmode);
1666 if (operands[1] == NULL_RTX)
1670 (define_insn "*movsicc_insn"
1671 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1672 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1673 [(match_operand 4 "cc_register" "") (const_int 0)])
1674 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1675 (match_operand:SI 2 "register_operand" "0,0")))]
1678 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1679 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11))
1680 return "sub%?.ne %0,%0,%0";
1681 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1682 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1683 && rtx_equal_p (operands[1], constm1_rtx)
1684 && GET_CODE (operands[3]) == LTU)
1685 return "sbc.cs %0,%0,%0";
1686 return "mov.%d3 %0,%1";
1688 [(set_attr "type" "cmove,cmove")
1689 (set_attr "length" "4,8")])
1691 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1692 ;; if the single bit is the sign bit, then GCC likes to convert this
1693 ;; into a sign extend and a compare less than, or greater to zero.
1694 ;; This is usually fine, except for the NXP400 where we have access to
1695 ;; a bit test instruction, along with a special short load instruction
1696 ;; (from CMEM), that doesn't support sign-extension on load.
1698 ;; This peephole optimisation attempts to restore the use of bit-test
1699 ;; in those cases where it is useful to do so.
1701 [(set (match_operand:SI 0 "register_operand" "")
1703 (match_operand:QI 1 "any_mem_operand" "")))
1704 (set (reg:CC_ZN CC_REG)
1705 (compare:CC_ZN (match_dup 0)
1708 (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1709 [(reg:CC_ZN CC_REG) (const_int 0)])
1710 (match_operand 3 "" "")
1711 (match_operand 4 "" "")))]
1713 && cmem_address (XEXP (operands[1], 0), SImode)
1714 && peep2_reg_dead_p (2, operands[0])
1715 && peep2_regno_dead_p (3, CC_REG)"
1719 (set (reg:CC_ZN CC_REG)
1720 (compare:CC_ZN (zero_extract:SI
1726 (if_then_else (match_dup 2)
1729 "if (GET_CODE (operands[2]) == GE)
1730 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1732 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1734 ; Try to generate more short moves, and/or less limms, by substituting a
1735 ; conditional move with a conditional sub.
1737 [(set (match_operand:SI 0 "compact_register_operand")
1738 (match_operand:SI 1 "const_int_operand"))
1740 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1741 [(match_operand 4 "cc_register" "") (const_int 0)])
1742 (match_operand:SI 2 "const_int_operand" "")
1744 "!satisfies_constraint_P (operands[1])
1745 && satisfies_constraint_P (operands[2])
1746 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1747 [(set (match_dup 0) (match_dup 2))
1751 (plus:SI (match_dup 0) (match_dup 1))))]
1752 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1753 GET_MODE (operands[4])),
1754 VOIDmode, operands[4], const0_rtx);
1755 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1757 (define_insn "*movdicc_insn"
1758 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1759 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1760 [(match_operand 4 "cc_register" "") (const_int 0)])
1761 (match_operand:DI 1 "nonmemory_operand" "c,i")
1762 (match_operand:DI 2 "register_operand" "0,0")))]
1766 switch (which_alternative)
1770 /* We normally copy the low-numbered register first. However, if
1771 the first register operand 0 is the same as the second register of
1772 operand 1, we must copy in the opposite order. */
1773 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1774 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1776 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1778 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1783 [(set_attr "type" "cmove,cmove")
1784 (set_attr "length" "8,16")])
1787 (define_insn "*movsfcc_insn"
1788 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1789 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1790 [(match_operand 4 "cc_register" "") (const_int 0)])
1791 (match_operand:SF 1 "nonmemory_operand" "c,E")
1792 (match_operand:SF 2 "register_operand" "0,0")))]
1796 mov.%d3 %0,%1 ; %A1"
1797 [(set_attr "type" "cmove,cmove")])
1799 (define_insn "*movdfcc_insn"
1800 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1801 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1802 [(match_operand 4 "cc_register" "") (const_int 0)])
1803 (match_operand:DF 2 "nonmemory_operand" "c,E")
1804 (match_operand:DF 3 "register_operand" "0,0")))]
1808 switch (which_alternative)
1812 /* We normally copy the low-numbered register first. However, if
1813 the first register operand 0 is the same as the second register of
1814 operand 1, we must copy in the opposite order. */
1815 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1816 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1818 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1820 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1824 [(set_attr "type" "cmove,cmove")
1825 (set_attr "length" "8,16")])
1827 ;; -------------------------------------------------------------------
1828 ;; Sign/Zero extension
1829 ;; -------------------------------------------------------------------
1831 (define_insn "*zero_extendqihi2_i"
1832 [(set (match_operand:HI 0 "dest_reg_operand" "=q,q,r,r,r,r")
1834 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,Ucm,m")))]
1843 [(set_attr "type" "unary,unary,unary,unary,load,load")
1844 (set_attr "iscompact" "maybe,true,false,false,false,false")
1845 (set_attr "predicable" "no,no,yes,no,no,no")])
1847 (define_expand "zero_extendqihi2"
1848 [(set (match_operand:HI 0 "dest_reg_operand" "")
1849 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1854 (define_insn "*zero_extendqisi2_ac"
1855 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,q,!*x,r,r")
1857 (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,T,Usd,Ucm,m")))]
1868 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1869 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1870 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1872 (define_expand "zero_extendqisi2"
1873 [(set (match_operand:SI 0 "dest_reg_operand" "")
1874 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1879 (define_insn "*zero_extendhisi2_i"
1880 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,!x,q,r,r")
1882 (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,r,Usd,T,Ucm,m")))]
1893 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1894 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1895 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1897 (define_expand "zero_extendhisi2"
1898 [(set (match_operand:SI 0 "dest_reg_operand" "")
1899 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1904 ;; Sign extension instructions.
1906 (define_insn "*extendqihi2_i"
1907 [(set (match_operand:HI 0 "dest_reg_operand" "=q,r,r,r")
1909 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1916 [(set_attr "type" "unary,unary,load,load")
1917 (set_attr "iscompact" "true,false,false,false")
1918 (set_attr "length" "*,*,*,8")])
1920 (define_expand "extendqihi2"
1921 [(set (match_operand:HI 0 "dest_reg_operand" "")
1922 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1927 (define_insn "*extendqisi2_ac"
1928 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r")
1930 (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1937 [(set_attr "type" "unary,unary,load,load")
1938 (set_attr "iscompact" "true,false,false,false")
1939 (set_attr "length" "*,*,*,8")])
1941 (define_expand "extendqisi2"
1942 [(set (match_operand:SI 0 "dest_reg_operand" "")
1943 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1948 (define_insn "*extendhisi2_i"
1949 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,q,r,r")
1951 (match_operand:HI 1 "nonvol_nonimm_operand" "q,r,Ucd,Uex,m")))]
1957 ld%_.x%U1%V1\\t%0,%1
1958 ld%_.x%U1%V1\\t%0,%1"
1959 [(set_attr "type" "unary,unary,load,load,load")
1960 (set_attr "iscompact" "true,false,true,false,false")
1961 (set_attr "length" "*,*,*,4,8")])
1963 (define_expand "extendhisi2"
1964 [(set (match_operand:SI 0 "dest_reg_operand" "")
1965 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1970 ;; Unary arithmetic insns
1972 ;; We allow constant operands to enable late constant propagation, but it is
1973 ;; not worth while to have more than one dedicated alternative to output them -
1974 ;; if we are really worried about getting these the maximum benefit of all
1975 ;; the available alternatives, we should add an extra pass to fold such
1976 ;; operations to movsi.
1978 ;; Absolute instructions
1980 (define_insn "abssi2"
1981 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w,w")
1982 (abs:SI (match_operand:SI 1 "nonmemory_operand" "q,cL,Cal")))]
1985 [(set_attr "type" "two_cycle_core")
1986 (set_attr "length" "*,4,8")
1987 (set_attr "iscompact" "true,false,false")])
1989 ;; Maximum and minimum insns
1991 (define_insn "smaxsi3"
1992 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
1993 (smax:SI (match_operand:SI 1 "register_operand" "%0, r, r")
1994 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1997 [(set_attr "type" "two_cycle_core")
1998 (set_attr "length" "4,4,8")
1999 (set_attr "predicable" "yes,no,no")]
2002 (define_insn "sminsi3"
2003 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
2004 (smin:SI (match_operand:SI 1 "register_operand" "%0, r, r")
2005 (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
2008 [(set_attr "type" "two_cycle_core")
2009 (set_attr "length" "4,4,8")
2010 (set_attr "predicable" "yes,no,no")]
2013 ;; Arithmetic instructions.
2015 ; We say an insn can be conditionalized if this doesn't introduce a long
2016 ; immediate. We set the type such that we still have good scheduling if the
2017 ; insn is conditionalized.
2018 ; ??? It would make sense to allow introduction of long immediates, but
2019 ; we'd need to communicate to the ccfsm machinery the extra cost.
2020 ; The alternatives in the constraints still serve three purposes:
2021 ; - estimate insn size assuming conditional execution
2022 ; - guide reload to re-order the second and third operand to get a better fit.
2023 ; - give tentative insn type to guide scheduling
2024 ; N.B. "%" for commutativity doesn't help when there is another matching
2025 ; (but longer) alternative.
2026 ; We avoid letting this pattern use LP_COUNT as a register by specifying
2027 ; register class 'W' instead of 'w'.
2028 (define_insn_and_split "*addsi3_mixed"
2029 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12
2030 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, h,!*Rsd, q,Rcb, q, q, q, r,r, r, W, W,W, W, q, r, W")
2031 (plus:SI (match_operand:SI 1 "register_operand" "%0,c, 0, q, 0, 0,Rcb, q, 0, 0,r, 0, c, c,0, 0, 0, 0, c")
2032 (match_operand:SI 2 "nonmemory_operand" "cL,0, Cm1, L,CL2,Csp,CM4,qK,cO,rL,0,rCca,cLCmL,Cca,I,C2a,Cal,Cal,Cal")))]
2035 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
2038 "&& reload_completed && get_attr_length (insn) == 8
2039 && satisfies_constraint_I (operands[2])
2040 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2041 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2042 "split_addsi (operands);"
2043 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
2044 (set (attr "iscompact")
2045 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
2046 (const_string "false")
2047 (match_operand 2 "long_immediate_operand" "")
2048 (const_string "maybe_limm")]
2049 (const_string "maybe")))
2050 (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
2051 (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
2052 (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
2055 ;; ARCv2 MPYW and MPYUW
2056 (define_expand "mulhisi3"
2057 [(set (match_operand:SI 0 "register_operand" "")
2058 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
2059 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
2062 if (CONSTANT_P (operands[2]))
2064 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
2070 (define_insn "mulhisi3_imm"
2071 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
2072 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
2073 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
2076 [(set_attr "length" "4,4,4,8,8")
2077 (set_attr "iscompact" "false")
2078 (set_attr "type" "mul16_em")
2079 (set_attr "predicable" "yes,no,no,yes,no")
2080 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2083 (define_insn "mulhisi3_reg"
2084 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
2085 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,0,r"))
2086 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "q,r,r"))))]
2089 [(set_attr "length" "*,4,4")
2090 (set_attr "iscompact" "maybe,false,false")
2091 (set_attr "type" "mul16_em")
2092 (set_attr "predicable" "yes,yes,no")
2093 (set_attr "cond" "canuse,canuse,nocond")
2096 (define_expand "umulhisi3"
2097 [(set (match_operand:SI 0 "register_operand" "")
2098 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2099 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
2102 if (CONSTANT_P (operands[2]))
2104 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
2110 (define_insn "umulhisi3_imm"
2111 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
2112 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
2113 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
2116 [(set_attr "length" "4,4,4,8,8")
2117 (set_attr "iscompact" "false")
2118 (set_attr "type" "mul16_em")
2119 (set_attr "predicable" "yes,no,no,yes,no")
2120 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2123 (define_insn "umulhisi3_reg"
2124 [(set (match_operand:SI 0 "register_operand" "=q, r, r")
2125 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, 0, r"))
2126 (zero_extend:SI (match_operand:HI 2 "register_operand" "q, r, r"))))]
2129 [(set_attr "length" "*,4,4")
2130 (set_attr "iscompact" "maybe,false,false")
2131 (set_attr "type" "mul16_em")
2132 (set_attr "predicable" "yes,yes,no")
2133 (set_attr "cond" "canuse,canuse,nocond")
2136 ;; ARC700/ARC600/V2 multiply
2139 (define_expand "mulsi3"
2140 [(set (match_operand:SI 0 "register_operand" "")
2141 (mult:SI (match_operand:SI 1 "register_operand" "")
2142 (match_operand:SI 2 "nonmemory_operand" "")))]
2145 if (TARGET_MUL64_SET)
2147 emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2]));
2150 else if (TARGET_MULMAC_32BY16_SET)
2152 emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2]));
2157 (define_insn_and_split "mulsi32x16"
2158 [(set (match_operand:SI 0 "register_operand" "=w")
2159 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2160 (match_operand:SI 2 "nonmemory_operand" "ci")))
2161 (clobber (reg:DI MUL32x16_REG))]
2162 "TARGET_MULMAC_32BY16_SET"
2164 "TARGET_MULMAC_32BY16_SET && reload_completed"
2167 if (immediate_operand (operands[2], SImode)
2168 && INTVAL (operands[2]) >= 0
2169 && INTVAL (operands[2]) <= 65535)
2171 emit_insn (gen_umul_600 (operands[1], operands[2],
2172 gen_acc2 (), gen_acc1 ()));
2173 emit_move_insn (operands[0], gen_acc2 ());
2176 emit_insn (gen_umul_600 (operands[1], operands[2],
2177 gen_acc2 (), gen_acc1 ()));
2178 emit_insn (gen_mac_600 (operands[1], operands[2],
2179 gen_acc2 (), gen_acc1 ()));
2180 emit_move_insn (operands[0], gen_acc2 ());
2183 [(set_attr "type" "multi")
2184 (set_attr "length" "8")])
2186 ; mululw conditional execution without a LIMM clobbers an input register;
2187 ; we'd need a different pattern to describe this.
2188 ; To make the conditional execution valid for the LIMM alternative, we
2189 ; have to emit the LIMM before the register operand.
2190 (define_insn "umul_600"
2191 [(set (match_operand:SI 2 "acc2_operand" "")
2192 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2193 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2197 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2198 "TARGET_MULMAC_32BY16_SET"
2200 [(set_attr "length" "4,4,8")
2201 (set_attr "type" "mulmac_600")
2202 (set_attr "predicable" "no")
2203 (set_attr "cond" "nocond")])
2205 (define_insn "mac_600"
2206 [(set (match_operand:SI 2 "acc2_operand" "")
2208 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2210 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2215 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2216 "TARGET_MULMAC_32BY16_SET"
2217 "machlw%? 0, %0, %1"
2218 [(set_attr "length" "4,4,8")
2219 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2220 (set_attr "predicable" "no, no, yes")
2221 (set_attr "cond" "nocond, canuse_limm, canuse")])
2223 ; The gcc-internal representation may differ from the hardware
2224 ; register number in order to allow the generic code to correctly
2225 ; split the concatenation of mhi and mlo.
2226 (define_insn_and_split "mulsi64"
2227 [(set (match_operand:SI 0 "register_operand" "=w")
2228 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2229 (match_operand:SI 2 "nonmemory_operand" "ci")))
2230 (clobber (reg:DI MUL64_OUT_REG))]
2233 "TARGET_MUL64_SET && reload_completed"
2236 rtx mhi = gen_rtx_REG (SImode, R59_REG);
2237 rtx mlo = gen_rtx_REG (SImode, R58_REG);
2238 emit_insn (gen_mulsi_600 (operands[1], operands[2], mlo, mhi));
2239 emit_move_insn (operands[0], mlo);
2242 [(set_attr "type" "multi")
2243 (set_attr "length" "8")])
2245 (define_insn "mulsi_600"
2246 [(set (match_operand:SI 2 "mlo_operand" "")
2247 (mult:SI (match_operand:SI 0 "register_operand" "%q,c,c,c")
2248 (match_operand:SI 1 "nonmemory_operand" "q,cL,I,Cal")))
2249 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2252 [(set_attr "length" "*,4,4,8")
2253 (set_attr "iscompact" "maybe,false,false,false")
2254 (set_attr "type" "multi,multi,multi,multi")
2255 (set_attr "predicable" "yes,yes,no,yes")
2256 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2258 (define_insn_and_split "mulsidi_600"
2259 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2260 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2261 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2262 (clobber (reg:DI R58_REG))]
2265 "TARGET_MUL64_SET && reload_completed"
2268 int hi = !TARGET_BIG_ENDIAN;
2270 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2271 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2272 emit_insn (gen_mul64 (operands[1], operands[2]));
2273 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2274 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2277 [(set_attr "type" "multi")
2278 (set_attr "length" "4,4,8")])
2280 (define_insn "mul64"
2281 [(set (reg:DI MUL64_OUT_REG)
2283 (sign_extend:DI (match_operand:SI 0 "register_operand" "%q, c,c, c"))
2284 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "q,cL,L,C32"))))]
2286 "mul64%? \t0, %0, %1%&"
2287 [(set_attr "length" "*,4,4,8")
2288 (set_attr "iscompact" "maybe,false,false,false")
2289 (set_attr "type" "multi,multi,multi,multi")
2290 (set_attr "predicable" "yes,yes,no,yes")
2291 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2293 (define_insn_and_split "umulsidi_600"
2294 [(set (match_operand:DI 0 "register_operand" "=r,r, r")
2295 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r, r"))
2296 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2297 (clobber (reg:DI R58_REG))]
2300 "TARGET_MUL64_SET && reload_completed"
2303 int hi = !TARGET_BIG_ENDIAN;
2305 rtx lr = operand_subword (operands[0], lo, 0, DImode);
2306 rtx hr = operand_subword (operands[0], hi, 0, DImode);
2307 emit_insn (gen_mulu64 (operands[1], operands[2]));
2308 emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2309 emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2312 [(set_attr "type" "umulti")
2313 (set_attr "length" "4,4,8")])
2315 (define_insn "mulu64"
2316 [(set (reg:DI MUL64_OUT_REG)
2318 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2319 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2321 "mulu64%? \t0, %0, %1%&"
2322 [(set_attr "length" "4,4,8")
2323 (set_attr "iscompact" "false")
2324 (set_attr "type" "umulti")
2325 (set_attr "predicable" "yes,no,yes")
2326 (set_attr "cond" "canuse,canuse_limm,canuse")])
2328 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2329 ; may not be used as destination constraint.
2331 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2332 ; but mpyu is faster for the standard multiplier.
2333 ; Note: we must make sure LP_COUNT is not one of the destination
2334 ; registers, since it cannot be the destination of a multi-cycle insn
2336 (define_insn "mulsi3_700"
2337 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=r, r,r, r,r")
2338 (mult:SI (match_operand:SI 1 "register_operand" "%0, r,0, 0,r")
2339 (match_operand:SI 2 "nonmemory_operand" "rL,rL,I,Cal,Cal")))]
2342 [(set_attr "length" "4,4,4,8,8")
2343 (set_attr "type" "umulti")
2344 (set_attr "predicable" "yes,no,no,yes,no")
2345 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2347 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2348 ; short variant. LP_COUNT constraints are still valid.
2349 (define_insn "mulsi3_v2"
2350 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=q,q, r, r,r, r, r")
2351 (mult:SI (match_operand:SI 1 "register_operand" "%0,q, 0, r,0, 0, c")
2352 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,rL,I,Cal,Cal")))]
2362 [(set_attr "length" "*,*,4,4,4,8,8")
2363 (set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
2364 (set_attr "type" "umulti")
2365 (set_attr "predicable" "no,no,yes,no,no,yes,no")
2366 (set_attr "cond" "nocond,nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2368 (define_expand "mulsidi3"
2369 [(set (match_operand:DI 0 "register_operand" "")
2370 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2371 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2374 if (TARGET_PLUS_MACD)
2376 if (CONST_INT_P (operands[2]))
2378 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2382 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2388 operands[2] = force_reg (SImode, operands[2]);
2389 if (!register_operand (operands[0], DImode))
2391 rtx result = gen_reg_rtx (DImode);
2393 operands[2] = force_reg (SImode, operands[2]);
2394 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2395 emit_move_insn (operands[0], result);
2399 else if (TARGET_MUL64_SET)
2401 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2404 else if (TARGET_MULMAC_32BY16_SET)
2406 operands[2] = force_reg (SImode, operands[2]);
2407 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2410 operands[2] = force_reg (SImode, operands[2]);
2413 (define_insn_and_split "mulsidi64"
2414 [(set (match_operand:DI 0 "register_operand" "=w")
2415 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2416 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2417 (clobber (reg:DI MUL32x16_REG))]
2418 "TARGET_MULMAC_32BY16_SET"
2420 "TARGET_MULMAC_32BY16_SET && reload_completed"
2423 rtx result_hi = gen_highpart (SImode, operands[0]);
2424 rtx result_low = gen_lowpart (SImode, operands[0]);
2426 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2427 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2428 emit_move_insn (result_low, gen_acc2 ());
2431 [(set_attr "type" "multi")
2432 (set_attr "length" "8")])
2435 (define_insn "mul64_600"
2436 [(set (reg:DI MUL32x16_REG)
2437 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2439 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2444 "TARGET_MULMAC_32BY16_SET"
2446 [(set_attr "length" "4,4,8")
2447 (set_attr "type" "mulmac_600")
2448 (set_attr "predicable" "no,no,yes")
2449 (set_attr "cond" "nocond, canuse_limm, canuse")])
2452 ;; ??? check if this is canonical rtl
2453 (define_insn "mac64_600"
2454 [(set (reg:DI MUL32x16_REG)
2456 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2458 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2459 (const_int 16) (const_int 16))
2461 (reg:DI MUL32x16_REG)))
2462 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2465 (mult:DI (sign_extend:DI (match_dup 1))
2467 (sign_extract:DI (match_dup 2)
2468 (const_int 16) (const_int 16))
2470 (reg:DI MUL32x16_REG))
2471 (const_int 32) (const_int 32)))]
2472 "TARGET_MULMAC_32BY16_SET"
2473 "machlw%? %0, %1, %2"
2474 [(set_attr "length" "4,4,8")
2475 (set_attr "type" "mulmac_600")
2476 (set_attr "predicable" "no,no,yes")
2477 (set_attr "cond" "nocond, canuse_limm, canuse")])
2480 ;; DI <- DI(signed SI) * DI(signed SI)
2481 (define_insn_and_split "mulsidi3_700"
2482 [(set (match_operand:DI 0 "register_operand" "=&r")
2483 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2484 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2485 "TARGET_MPY && !TARGET_PLUS_MACD"
2487 "&& reload_completed"
2490 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2491 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2492 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2493 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2494 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2495 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2498 [(set_attr "type" "multi")
2499 (set_attr "length" "8")])
2501 (define_insn "mulsi3_highpart"
2502 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2506 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2507 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2510 "mpy%+%?\\t%0,%1,%2"
2511 [(set_attr "length" "4,4,8,8")
2512 (set_attr "type" "multi")
2513 (set_attr "predicable" "yes,no,yes,no")
2514 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2516 ; Note that mpyhu has the same latency as mpy / mpyh,
2517 ; thus we use the type multi.
2518 (define_insn "*umulsi3_highpart_i"
2519 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2523 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2524 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,r,i,i")))
2527 "mpy%+u%?\\t%0,%1,%2"
2528 [(set_attr "length" "4,4,8,8")
2529 (set_attr "type" "multi")
2530 (set_attr "predicable" "yes,no,yes,no")
2531 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2533 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2534 ;; need a separate pattern for immediates
2535 ;; ??? This is fine for combine, but not for reload.
2536 (define_insn "umulsi3_highpart_int"
2537 [(set (match_operand:SI 0 "register_operand" "=r, r, r,r, r")
2541 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, r, 0, 0, r"))
2542 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I,Cal,Cal"))
2545 "mpy%+u%?\\t%0,%1,%2"
2546 [(set_attr "length" "4,4,4,8,8")
2547 (set_attr "type" "multi")
2548 (set_attr "predicable" "yes,no,no,yes,no")
2549 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2551 (define_expand "umulsi3_highpart"
2552 [(set (match_operand:SI 0 "general_operand" "")
2556 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2557 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2562 rtx target = operands[0];
2564 if (!register_operand (target, SImode))
2565 target = gen_reg_rtx (SImode);
2567 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2568 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2569 operands[2], SImode);
2570 else if (!immediate_operand (operands[2], SImode))
2571 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2572 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2573 if (target != operands[0])
2574 emit_move_insn (operands[0], target);
2578 (define_expand "umulsidi3"
2579 [(set (match_operand:DI 0 "register_operand" "")
2580 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2581 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2584 if (TARGET_PLUS_MACD)
2586 if (CONST_INT_P (operands[2]))
2588 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2592 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2598 operands[2] = force_reg (SImode, operands[2]);
2599 if (!register_operand (operands[0], DImode))
2601 rtx result = gen_reg_rtx (DImode);
2603 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2604 emit_move_insn (operands[0], result);
2608 else if (TARGET_MUL64_SET)
2610 operands[2] = force_reg (SImode, operands[2]);
2611 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2614 else if (TARGET_MULMAC_32BY16_SET)
2616 operands[2] = force_reg (SImode, operands[2]);
2617 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2626 (define_insn_and_split "umulsidi64"
2627 [(set (match_operand:DI 0 "register_operand" "=w")
2628 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2629 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2630 (clobber (reg:DI MUL32x16_REG))]
2631 "TARGET_MULMAC_32BY16_SET"
2633 "TARGET_MULMAC_32BY16_SET && reload_completed"
2639 result_hi = gen_highpart (SImode, operands[0]);
2640 result_low = gen_lowpart (SImode, operands[0]);
2642 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2643 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2644 emit_move_insn (result_low, gen_acc2 ());
2647 [(set_attr "type" "multi")
2648 (set_attr "length" "8")])
2650 (define_insn "umul64_600"
2651 [(set (reg:DI MUL32x16_REG)
2652 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2654 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2659 "TARGET_MULMAC_32BY16_SET"
2661 [(set_attr "length" "4,4,8")
2662 (set_attr "type" "mulmac_600")
2663 (set_attr "predicable" "no")
2664 (set_attr "cond" "nocond")])
2667 (define_insn "umac64_600"
2668 [(set (reg:DI MUL32x16_REG)
2670 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2672 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2673 (const_int 16) (const_int 16))
2675 (reg:DI MUL32x16_REG)))
2676 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2679 (mult:DI (zero_extend:DI (match_dup 1))
2681 (zero_extract:DI (match_dup 2)
2682 (const_int 16) (const_int 16))
2684 (reg:DI MUL32x16_REG))
2685 (const_int 32) (const_int 32)))]
2686 "TARGET_MULMAC_32BY16_SET"
2687 "machulw%? %0, %1, %2"
2688 [(set_attr "length" "4,4,8")
2689 (set_attr "type" "mulmac_600")
2690 (set_attr "predicable" "no,no,yes")
2691 (set_attr "cond" "nocond, canuse_limm, canuse")])
2693 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2694 (define_insn_and_split "umulsidi3_700"
2695 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2696 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2697 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2698 "TARGET_MPY && !TARGET_PLUS_MACD"
2700 "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed"
2703 int hi = !TARGET_BIG_ENDIAN;
2705 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2706 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2707 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2708 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2711 [(set_attr "type" "umulti")
2712 (set_attr "length" "8")])
2714 (define_expand "addsi3"
2715 [(set (match_operand:SI 0 "dest_reg_operand" "")
2716 (plus:SI (match_operand:SI 1 "register_operand" "")
2717 (match_operand:SI 2 "nonmemory_operand" "")))]
2719 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2721 operands[2]=force_reg(SImode, operands[2]);
2725 (define_expand "adddi3"
2726 [(set (match_operand:DI 0 "register_operand" "")
2727 (plus:DI (match_operand:DI 1 "register_operand" "")
2728 (match_operand:DI 2 "nonmemory_operand" "")))
2729 (clobber (reg:CC CC_REG))]
2732 rtx l0 = gen_lowpart (SImode, operands[0]);
2733 rtx h0 = gen_highpart (SImode, operands[0]);
2734 rtx l1 = gen_lowpart (SImode, operands[1]);
2735 rtx h1 = gen_highpart (SImode, operands[1]);
2736 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2737 subreg_lowpart_offset (SImode, DImode));
2738 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2739 subreg_highpart_offset (SImode, DImode));
2741 if (l2 == const0_rtx)
2743 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2744 emit_move_insn (l0, l1);
2745 emit_insn (gen_addsi3 (h0, h1, h2));
2746 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2747 emit_move_insn (l0, l1);
2750 if (rtx_equal_p (l0, h1))
2752 if (h2 != const0_rtx)
2753 emit_insn (gen_addsi3 (h0, h1, h2));
2754 else if (!rtx_equal_p (h0, h1))
2755 emit_move_insn (h0, h1);
2756 emit_insn (gen_add_f (l0, l1, l2));
2760 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2761 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2764 emit_insn (gen_add_f (l0, l1, l2));
2765 emit_insn (gen_adc (h0, h1, h2));
2769 (define_insn "add_f"
2770 [(set (reg:CC_C CC_REG)
2772 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,L,0,I,Cal,r")
2773 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0, r,rCal"))
2775 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2776 (plus:SI (match_dup 1) (match_dup 2)))]
2777 "register_operand (operands[1], SImode)
2778 || register_operand (operands[2], SImode)"
2786 [(set_attr "cond" "set")
2787 (set_attr "type" "compare")
2788 (set_attr "length" "4,4,4,4,8,8")])
2790 (define_insn "*add_f_2"
2791 [(set (reg:CC_C CC_REG)
2793 (plus:SI (match_operand:SI 1 "register_operand" "r ,0,r")
2794 (match_operand:SI 2 "nonmemory_operand" "rL,I,rCal"))
2796 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
2797 (plus:SI (match_dup 1) (match_dup 2)))]
2800 [(set_attr "cond" "set")
2801 (set_attr "type" "compare")
2802 (set_attr "length" "4,4,8")])
2805 [(set (match_operand:SI 0 "register_operand" "=r, r,r,r, r,r")
2808 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2809 (match_operand:SI 1 "nonmemory_operand" "%r, 0,r,0,Cal,r"))
2810 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I, r,Cal")))]
2811 "register_operand (operands[1], SImode)
2812 || register_operand (operands[2], SImode)"
2820 [(set_attr "cond" "use")
2821 (set_attr "type" "cc_arith")
2822 (set_attr "length" "4,4,4,4,8,8")])
2824 ; combiner-splitter cmp / scc -> cmp / adc
2826 [(set (match_operand:SI 0 "dest_reg_operand" "")
2827 (gtu:SI (match_operand:SI 1 "register_operand" "")
2828 (match_operand:SI 2 "register_operand" "")))
2829 (clobber (reg CC_REG))]
2831 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2832 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2834 ; combine won't work when an intermediate result is used later...
2835 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2837 [(set (match_operand:SI 0 "dest_reg_operand" "")
2838 (plus:SI (match_operand:SI 1 "register_operand" "")
2839 (match_operand:SI 2 "nonmemory_operand" "")))
2840 (set (reg:CC_C CC_REG)
2841 (compare:CC_C (match_dup 0)
2842 (match_operand:SI 3 "nonmemory_operand" "")))]
2843 "rtx_equal_p (operands[1], operands[3])
2844 || rtx_equal_p (operands[2], operands[3])"
2846 [(set (reg:CC_C CC_REG)
2847 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2849 (plus:SI (match_dup 1) (match_dup 2)))])])
2851 ; ??? need to delve into combine to find out why this is not useful.
2852 ; We'd like to be able to grok various C idioms for carry bit usage.
2853 ;(define_insn "*adc_0"
2854 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2855 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2856 ; (match_operand:SI 1 "register_operand" "c")))]
2859 ; [(set_attr "cond" "use")
2860 ; (set_attr "type" "cc_arith")
2861 ; (set_attr "length" "4")])
2864 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2865 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2866 ; (match_operand:SI 2 "register_operand" "c"))
2867 ; (match_operand:SI 3 "register_operand" "c")))
2868 ; (clobber (reg CC_REG))]
2870 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2871 ; (set (match_dup 0)
2872 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2875 (define_expand "subsi3"
2876 [(set (match_operand:SI 0 "dest_reg_operand" "")
2877 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2878 (match_operand:SI 2 "nonmemory_operand" "")))]
2884 if (!register_operand (operands[2], SImode))
2886 operands[1] = force_reg (SImode, operands[1]);
2889 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2890 operands[c] = force_reg (SImode, operands[c]);
2893 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2894 ; combine should make such an insn go away.
2895 (define_insn_and_split "subsi3_insn"
2896 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r, r,r,r,r, r, r, r")
2897 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,q,0,rL,r,L,I,Cal,Cal, r")
2898 (match_operand:SI 2 "nonmemory_operand" "q,q,r, 0,r,r,0, 0, r,Cal")))]
2899 "register_operand (operands[1], SImode)
2900 || register_operand (operands[2], SImode)"
2912 "reload_completed && get_attr_length (insn) == 8
2913 && satisfies_constraint_I (operands[1])
2914 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2915 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2916 "split_subsi (operands);"
2917 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2918 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2919 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2920 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2921 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2924 (define_expand "subdi3"
2925 [(set (match_operand:DI 0 "register_operand" "")
2926 (minus:DI (match_operand:DI 1 "register_operand" "")
2927 (match_operand:DI 2 "nonmemory_operand" "")))
2928 (clobber (reg:CC CC_REG))]
2931 rtx l0 = gen_lowpart (SImode, operands[0]);
2932 rtx h0 = gen_highpart (SImode, operands[0]);
2933 rtx l1 = gen_lowpart (SImode, operands[1]);
2934 rtx h1 = gen_highpart (SImode, operands[1]);
2935 rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2936 subreg_lowpart_offset (SImode, DImode));
2937 rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2938 subreg_highpart_offset (SImode, DImode));
2940 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2942 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2943 if (!rtx_equal_p (h0, h1))
2944 emit_insn (gen_rtx_SET (h0, h1));
2945 emit_insn (gen_sub_f (l0, l1, l2));
2949 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2950 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2953 emit_insn (gen_sub_f (l0, l1, l2));
2954 emit_insn (gen_sbc (h0, h1, h2));
2958 (define_insn "*sbc_0"
2959 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2960 (minus:SI (match_operand:SI 1 "register_operand" "c")
2961 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2965 [(set_attr "cond" "use")
2966 (set_attr "type" "cc_arith")
2967 (set_attr "length" "4")])
2970 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2973 (match_operand:SI 1 "nonmemory_operand" "r, 0,r,0, r,Cal")
2974 (ltu:SI (reg:CC_C CC_REG) (const_int 0)))
2975 (match_operand:SI 2 "nonmemory_operand" "r,C_0,L,I,Cal,r")))]
2976 "register_operand (operands[1], SImode)
2977 || register_operand (operands[2], SImode)"
2985 [(set_attr "cond" "use")
2986 (set_attr "type" "cc_arith")
2987 (set_attr "length" "4,4,4,4,8,8")])
2989 (define_insn "sub_f"
2990 [(set (reg:CC CC_REG)
2991 (compare:CC (match_operand:SI 1 "nonmemory_operand" " r,L,0,I,r,Cal")
2992 (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0,Cal,r")))
2993 (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2994 (minus:SI (match_dup 1) (match_dup 2)))]
2995 "register_operand (operands[1], SImode)
2996 || register_operand (operands[2], SImode)"
3004 [(set_attr "type" "compare")
3005 (set_attr "length" "4,4,4,4,8,8")])
3007 ; combine won't work when an intermediate result is used later...
3008 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3010 [(set (reg:CC CC_REG)
3011 (compare:CC (match_operand:SI 1 "register_operand" "")
3012 (match_operand:SI 2 "nonmemory_operand" "")))
3013 (set (match_operand:SI 0 "dest_reg_operand" "")
3014 (minus:SI (match_dup 1) (match_dup 2)))]
3017 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3018 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3021 [(set (reg:CC CC_REG)
3022 (compare:CC (match_operand:SI 1 "register_operand" "")
3023 (match_operand:SI 2 "nonmemory_operand" "")))
3024 (set (match_operand 3 "" "") (match_operand 4 "" ""))
3025 (set (match_operand:SI 0 "dest_reg_operand" "")
3026 (minus:SI (match_dup 1) (match_dup 2)))]
3027 "!reg_overlap_mentioned_p (operands[3], operands[1])
3028 && !reg_overlap_mentioned_p (operands[3], operands[2])
3029 && !reg_overlap_mentioned_p (operands[0], operands[4])
3030 && !reg_overlap_mentioned_p (operands[0], operands[3])"
3032 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3033 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3034 (set (match_dup 3) (match_dup 4))])
3036 (define_insn "*add_n"
3037 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
3038 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
3039 (match_operand:SI 2 "_2_4_8_operand" ""))
3040 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
3042 "add%z2%?\\t%0,%3,%1"
3043 [(set_attr "type" "shift")
3044 (set_attr "length" "*,4,8")
3045 (set_attr "predicable" "yes,no,no")
3046 (set_attr "cond" "canuse,nocond,nocond")
3047 (set_attr "iscompact" "maybe,false,false")])
3049 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3050 ;; what synth_mult likes.
3051 (define_insn "*sub_n"
3052 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3053 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3054 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
3055 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3057 "sub%c3%?\\t%0,%1,%2"
3058 [(set_attr "type" "shift")
3059 (set_attr "length" "4,4,8")
3060 (set_attr "predicable" "yes,no,no")
3061 (set_attr "cond" "canuse,nocond,nocond")
3062 (set_attr "iscompact" "false")])
3064 (define_insn "*sub_n"
3065 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3066 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3067 (mult:SI (match_operand:SI 2 "register_operand" "r,r,r")
3068 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3070 "sub%z3%?\\t%0,%1,%2"
3071 [(set_attr "type" "shift")
3072 (set_attr "length" "4,4,8")
3073 (set_attr "predicable" "yes,no,no")
3074 (set_attr "cond" "canuse,nocond,nocond")
3075 (set_attr "iscompact" "false")])
3077 ; ??? check if combine matches this.
3078 (define_insn "*bset"
3079 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3080 (ior:SI (ashift:SI (const_int 1)
3081 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3082 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3085 [(set_attr "length" "4,4,8")
3086 (set_attr "predicable" "yes,no,no")
3087 (set_attr "cond" "canuse,nocond,nocond")]
3090 ; ??? check if combine matches this.
3091 (define_insn "*bxor"
3092 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3093 (xor:SI (ashift:SI (const_int 1)
3094 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3095 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3098 [(set_attr "length" "4,4,8")
3099 (set_attr "predicable" "yes,no,no")
3100 (set_attr "cond" "canuse,nocond,nocond")]
3103 ; ??? check if combine matches this.
3104 (define_insn "*bclr"
3105 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3106 (and:SI (not:SI (ashift:SI (const_int 1)
3107 (match_operand:SI 1 "nonmemory_operand" "rL,rL,r")))
3108 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3111 [(set_attr "length" "4,4,8")
3112 (set_attr "predicable" "yes,no,no")
3113 (set_attr "cond" "canuse,nocond,nocond")]
3116 ; ??? FIXME: find combine patterns for bmsk.
3118 ;;Following are the define_insns added for the purpose of peephole2's
3120 ; see also iorsi3 for use with constant bit number.
3121 (define_insn "*bset_insn"
3122 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3123 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3124 (ashift:SI (const_int 1)
3125 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3128 bset%?\\t%0,%1,%2 ;;peep2, constr 1
3129 bset\\t%0,%1,%2 ;;peep2, constr 2
3130 bset\\t%0,%1,%2 ;;peep2, constr 3"
3131 [(set_attr "length" "4,4,8")
3132 (set_attr "predicable" "yes,no,no")
3133 (set_attr "cond" "canuse,nocond,nocond")]
3136 ; see also xorsi3 for use with constant bit number.
3137 (define_insn "*bxor_insn"
3138 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3139 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3140 (ashift:SI (const_int 1)
3141 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3147 [(set_attr "length" "4,4,8")
3148 (set_attr "predicable" "yes,no,no")
3149 (set_attr "cond" "canuse,nocond,nocond")]
3152 ; see also andsi3 for use with constant bit number.
3153 (define_insn "*bclr_insn"
3154 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3155 (and:SI (not:SI (ashift:SI (const_int 1)
3156 (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")))
3157 (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")))]
3163 [(set_attr "length" "4,4,8")
3164 (set_attr "predicable" "yes,no,no")
3165 (set_attr "cond" "canuse,nocond,nocond")]
3168 ; see also andsi3 for use with constant bit number.
3169 (define_insn "*bmsk_insn"
3170 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3171 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3172 (plus:SI (ashift:SI (const_int 1)
3173 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3181 [(set_attr "length" "4,4,8")
3182 (set_attr "predicable" "yes,no,no")
3183 (set_attr "cond" "canuse,nocond,nocond")]
3186 ;;Instructions added for peephole2s end
3188 ;; Boolean instructions.
3190 (define_expand "andsi3"
3191 [(set (match_operand:SI 0 "dest_reg_operand" "")
3192 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3193 (match_operand:SI 2 "nonmemory_operand" "")))]
3195 "if (!satisfies_constraint_Cux (operands[2]))
3196 operands[1] = force_reg (SImode, operands[1]);
3199 (define_insn "andsi3_i" ;0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
3200 [(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")
3201 (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")
3202 (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")))]
3203 "(register_operand (operands[1], SImode)
3204 && nonmemory_operand (operands[2], SImode))
3205 || (memory_operand (operands[1], SImode)
3206 && satisfies_constraint_Cux (operands[2]))"
3208 switch (which_alternative)
3210 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3211 return "and%? %0,%1,%2%&";
3213 return "and%? %0,%2,%1%&";
3215 return "bmsk%? %0,%1,%Z2%&";
3217 if (satisfies_constraint_C2p (operands[2]))
3219 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3220 return "bmskn%? %0,%1,%Z2%&";
3224 return "bmsk%? %0,%1,%Z2%&";
3226 case 3: case 8: case 13:
3227 return "bclr%? %0,%1,%M2%&";
3229 return (INTVAL (operands[2]) == 0xff
3230 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3231 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3233 return "movb.cl %0,%1,%p2,%p2,%s2";
3238 if (satisfies_constraint_Ucm (operands[1]))
3239 tmpl = (INTVAL (operands[2]) == 0xff
3240 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3242 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3244 if (TARGET_BIG_ENDIAN)
3248 xop[0] = operands[0];
3249 xop[1] = adjust_address (operands[1], QImode,
3250 INTVAL (operands[2]) == 0xff ? 3 : 2);
3251 output_asm_insn (tmpl, xop);
3259 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3260 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3261 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3262 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3263 (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")])
3265 ; combiner splitter, pattern found in ldtoa.c .
3266 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3268 [(set (reg:CC_Z CC_REG)
3269 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3270 (match_operand 1 "const_int_operand" ""))
3271 (match_operand 2 "const_int_operand" "")))
3272 (clobber (match_operand:SI 3 "register_operand" ""))]
3273 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3275 (plus:SI (match_dup 0) (match_dup 4)))
3276 (set (reg:CC_Z CC_REG)
3277 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3279 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3281 ;;bic define_insn that allows limm to be the first operand
3282 (define_insn "*bicsi3_insn"
3283 [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r,r,r,r")
3284 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "q,Lr,I,Cal,Lr,Cal,r"))
3285 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,r,r,Cal")))]
3288 bic%?\\t%0, %2, %1%& ;;constraint 0
3289 bic%?\\t%0,%2,%1 ;;constraint 1
3290 bic\\t%0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3291 bic%?\\t%0,%2,%1 ;;constraint 3, FIXME: will it ever get generated ???
3292 bic\\t%0,%2,%1 ;;constraint 4
3293 bic\\t%0,%2,%1 ;;constraint 5, FIXME: will it ever get generated ???
3294 bic\\t%0,%2,%1 ;;constraint 6"
3295 [(set_attr "length" "*,4,4,8,4,8,8")
3296 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3297 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3298 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3300 (define_insn_and_split "iorsi3"
3301 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r,r, r,r, r, r,r, q, r, r")
3302 (ior:SI (match_operand:SI 1 "register_operand" "%0,q, 0, 0,r, 0,0, r, r,0, r, 0, r")
3303 (match_operand:SI 2 "nonmemory_operand" "q,0,C0p,rL,0,C0p,I,rL,C0p,I,C0x,Cal,Cal")))]
3320 && GET_CODE (PATTERN (insn)) != COND_EXEC
3321 && register_operand (operands[0], SImode)
3322 && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
3323 && satisfies_constraint_C0x (operands[2])"
3326 arc_split_ior (operands);
3329 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,false")
3330 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,*,8,8")
3331 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
3332 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,nocond,canuse,nocond")])
3334 (define_insn "xorsi3"
3335 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, r,r, r,r, r, r,r, r, r")
3336 (xor:SI (match_operand:SI 1 "register_operand" "%0,q, 0,r, 0,0, r, r,0, 0, r")
3337 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,0,C0p,I,rL,C0p,I,Cal,Cal")))]
3340 switch (which_alternative)
3342 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3343 return \"xor%?\\t%0,%1,%2%&\";
3345 return \"xor%?\\t%0,%2,%1%&\";
3347 return \"bxor%?\\t%0,%1,%z2\";
3352 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3353 (set_attr "type" "binary")
3354 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3355 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3356 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3358 (define_insn "negsi2"
3359 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r")
3360 (neg:SI (match_operand:SI 1 "register_operand" "0,q,0,r")))]
3363 [(set_attr "type" "unary")
3364 (set_attr "iscompact" "maybe,true,false,false")
3365 (set_attr "predicable" "no,no,yes,no")])
3367 (define_insn "one_cmplsi2"
3368 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
3369 (not:SI (match_operand:SI 1 "register_operand" "q,c")))]
3372 [(set_attr "type" "unary,unary")
3373 (set_attr "iscompact" "true,false")])
3375 (define_insn_and_split "one_cmpldi2"
3376 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3377 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3380 "&& reload_completed"
3381 [(set (match_dup 2) (not:SI (match_dup 3)))
3382 (set (match_dup 4) (not:SI (match_dup 5)))]
3384 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3386 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3387 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3388 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3389 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3391 [(set_attr "type" "unary,unary")
3392 (set_attr "cond" "nocond,nocond")
3393 (set_attr "length" "4,8")])
3395 ;; Shift instructions.
3397 (define_expand "ashlsi3"
3398 [(set (match_operand:SI 0 "dest_reg_operand" "")
3399 (ashift:SI (match_operand:SI 1 "register_operand" "")
3400 (match_operand:SI 2 "nonmemory_operand" "")))]
3404 if (!TARGET_BARREL_SHIFTER)
3406 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3411 (define_expand "ashrsi3"
3412 [(set (match_operand:SI 0 "dest_reg_operand" "")
3413 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3414 (match_operand:SI 2 "nonmemory_operand" "")))]
3418 if (!TARGET_BARREL_SHIFTER)
3420 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3425 (define_expand "lshrsi3"
3426 [(set (match_operand:SI 0 "dest_reg_operand" "")
3427 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3428 (match_operand:SI 2 "nonmemory_operand" "")))]
3432 if (!TARGET_BARREL_SHIFTER)
3434 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3439 (define_insn "shift_si3"
3440 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3441 (match_operator:SI 3 "shift4_operator"
3442 [(match_operand:SI 1 "register_operand" "0")
3443 (match_operand:SI 2 "const_int_operand" "n")]))
3444 (clobber (match_scratch:SI 4 "=&r"))
3445 (clobber (reg:CC CC_REG))
3447 "!TARGET_BARREL_SHIFTER"
3448 "* return output_shift (operands);"
3449 [(set_attr "type" "shift")
3450 (set_attr "length" "16")])
3452 (define_insn "shift_si3_loop"
3453 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3454 (match_operator:SI 3 "shift_operator"
3455 [(match_operand:SI 1 "register_operand" "0,0")
3456 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3457 (clobber (match_scratch:SI 4 "=X,X"))
3458 (clobber (reg:SI LP_COUNT))
3459 (clobber (reg:CC CC_REG))
3461 "!TARGET_BARREL_SHIFTER"
3462 "* return output_shift (operands);"
3463 [(set_attr "type" "shift")
3464 (set_attr "length" "16,20")])
3466 ; asl, asr, lsr patterns:
3467 ; There is no point in including an 'I' alternative since only the lowest 5
3468 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3469 ; is defined in an external symbol, as we don't have special relocations
3470 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3471 ; provide one alternatice for this, without condexec support.
3472 (define_insn "*ashlsi3_insn"
3473 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3474 (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3475 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3476 "TARGET_BARREL_SHIFTER
3477 && (register_operand (operands[1], SImode)
3478 || register_operand (operands[2], SImode))"
3480 [(set_attr "type" "shift")
3481 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3482 (set_attr "predicable" "no,no,no,yes,no,no")
3483 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3485 (define_insn "*ashrsi3_insn"
3486 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3487 (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3488 (match_operand:SI 2 "nonmemory_operand" "K,K,qM,rL,rL,rCal")))]
3489 "TARGET_BARREL_SHIFTER
3490 && (register_operand (operands[1], SImode)
3491 || register_operand (operands[2], SImode))"
3493 [(set_attr "type" "shift")
3494 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3495 (set_attr "predicable" "no,no,no,yes,no,no")
3496 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3498 (define_insn "*lshrsi3_insn"
3499 [(set (match_operand:SI 0 "dest_reg_operand" "=q,q, q, r, r, r")
3500 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,q, 0, 0, r,rCal")
3501 (match_operand:SI 2 "nonmemory_operand" "N,N,qM,rL,rL,rCal")))]
3502 "TARGET_BARREL_SHIFTER
3503 && (register_operand (operands[1], SImode)
3504 || register_operand (operands[2], SImode))"
3505 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3506 ? \"lsr%?\\t%0,%1%&\" : \"lsr%?\\t%0,%1,%2%&\");"
3507 [(set_attr "type" "shift")
3508 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3509 (set_attr "predicable" "no,no,no,yes,no,no")
3510 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3512 (define_insn "rotrsi3"
3513 [(set (match_operand:SI 0 "dest_reg_operand" "=r, r, r")
3514 (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand" " 0,rL,rCsz")
3515 (match_operand:SI 2 "nonmemory_operand" "rL,rL,rCal")))]
3516 "TARGET_BARREL_SHIFTER"
3518 [(set_attr "type" "shift,shift,shift")
3519 (set_attr "predicable" "yes,no,no")
3520 (set_attr "length" "4,4,8")])
3522 ;; Compare / branch instructions.
3524 (define_expand "cbranchsi4"
3525 [(set (reg:CC CC_REG)
3526 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3527 (match_operand:SI 2 "nonmemory_operand" "")))
3530 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3532 (label_ref (match_operand 3 "" ""))
3536 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3537 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3538 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3539 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3543 ;; ??? Could add a peephole to generate compare with swapped operands and
3544 ;; modifed cc user if second, but not first operand is a compact register.
3545 (define_insn "cmpsi_cc_insn_mixed"
3546 [(set (reg:CC CC_REG)
3547 (compare:CC (match_operand:SI 0 "register_operand" "q, q, h, c, c, q,c")
3548 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,cL,Cal,Cal")))]
3551 [(set_attr "type" "compare")
3552 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3553 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3554 (set_attr "cond" "set")
3555 (set_attr "length" "*,*,*,4,4,*,8")
3556 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3558 (define_insn "*cmpsi_cc_zn_insn"
3559 [(set (reg:CC_ZN CC_REG)
3560 (compare:CC_ZN (match_operand:SI 0 "register_operand" "q,c")
3564 [(set_attr "type" "compare,compare")
3565 (set_attr "iscompact" "true,false")
3566 (set_attr "predicable" "no,yes")
3567 (set_attr "cond" "set_zn")
3568 (set_attr "length" "*,4")])
3570 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3571 (define_insn "*btst"
3572 [(set (reg:CC_ZN CC_REG)
3574 (zero_extract:SI (match_operand:SI 0 "register_operand" "q,c")
3576 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3580 [(set_attr "iscompact" "true,false")
3581 (set_attr "predicable" "no,yes")
3582 (set_attr "cond" "set")
3583 (set_attr "type" "compare")
3584 (set_attr "length" "*,4")])
3586 ; combine suffers from 'simplifications' that replace a one-bit zero
3587 ; extract with a shift if it can prove that the upper bits are zero.
3588 ; arc_reorg sees the code after sched2, which can have caused our
3589 ; inputs to be clobbered even if they were not clobbered before.
3590 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3591 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3592 ; bbit (i.e. bad scheduling) and missed conditional execution,
3593 ; so make this an option.
3595 [(set (reg:CC_ZN CC_REG)
3597 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3599 (match_operand:SI 1 "nonmemory_operand" ""))
3602 (if_then_else (match_operator 3 "equality_comparison_operator"
3603 [(reg:CC_ZN CC_REG) (const_int 0)])
3604 (label_ref (match_operand 2 "" ""))
3606 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3607 [(parallel [(set (pc)
3610 [(zero_extract:SI (match_dup 0)
3611 (const_int 1) (match_dup 1))
3613 (label_ref (match_dup 2))
3615 (clobber (reg:CC_ZN CC_REG))])])
3617 (define_insn "*cmpsi_cc_z_insn"
3618 [(set (reg:CC_Z CC_REG)
3619 (compare:CC_Z (match_operand:SI 0 "register_operand" "q,c")
3620 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3625 [(set_attr "type" "compare,compare")
3626 (set_attr "iscompact" "true,false")
3627 (set_attr "cond" "set,set_zn")
3628 (set_attr "length" "*,4")])
3630 (define_insn "*cmpsi_cc_c_insn"
3631 [(set (reg:CC_C CC_REG)
3632 (compare:CC_C (match_operand:SI 0 "register_operand" "q, q, h, c, q, c")
3633 (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,Cal,Cal")))]
3636 [(set_attr "type" "compare")
3637 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3638 (set_attr "cond" "set")
3639 (set_attr "length" "*,*,*,4,*,8")
3640 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3642 ;; Next come the scc insns.
3644 (define_expand "cstoresi4"
3645 [(set (match_operand:SI 0 "dest_reg_operand" "")
3646 (match_operator:SI 1 "ordered_comparison_operator"
3647 [(match_operand:SI 2 "nonmemory_operand" "")
3648 (match_operand:SI 3 "nonmemory_operand" "")]))]
3651 if (!TARGET_CODE_DENSITY)
3653 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3654 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3655 operands[1] = gen_compare_reg (operands[1], SImode);
3656 emit_insn (gen_scc_insn (operands[0], operands[1]));
3659 if (!register_operand (operands[2], SImode))
3660 operands[2] = force_reg (SImode, operands[2]);
3664 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3665 (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")])
3667 (define_expand "cstore<mode>4"
3668 [(set (reg:CC CC_REG)
3669 (compare:CC (match_operand:SDF 2 "register_operand" "")
3670 (match_operand:SDF 3 "register_operand" "")))
3671 (set (match_operand:SI 0 "dest_reg_operand" "")
3672 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3675 "TARGET_HARD_FLOAT || TARGET_OPTFPE"
3677 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3678 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3679 operands[1] = gen_compare_reg (operands[1], SImode);
3680 emit_insn (gen_scc_insn (operands[0], operands[1]));
3684 ; We need a separate expander for this lest we loose the mode of CC_REG
3685 ; when match_operator substitutes the literal operand into the comparison.
3686 (define_expand "scc_insn"
3687 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3689 (define_insn_and_split "*scc_insn"
3690 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3691 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3695 [(set (match_dup 0) (const_int 1))
3698 (set (match_dup 0) (const_int 0)))]
3701 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3702 GET_MODE (XEXP (operands[1], 0))),
3704 XEXP (operands[1], 0), XEXP (operands[1], 1));
3706 [(set_attr "type" "unary")])
3708 ; cond_exec patterns
3709 (define_insn "*movsi_ne"
3711 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0))
3712 (set (match_operand:SI 0 "dest_reg_operand" "=q, q, r, q, r")
3713 (match_operand:SI 1 "nonmemory_operand" "C_0, h, Lr,Cal,Cal")))]
3716 * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\";
3717 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3719 * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3721 [(set_attr "type" "cmove")
3722 (set_attr "iscompact" "true,true,false,true_limm,false")
3723 (set_attr "length" "2,2,4,6,8")
3724 (set_attr "cpu_facility" "*,av2,*,av2,*")])
3726 (define_insn "*movsi_cond_exec"
3728 (match_operator 3 "proper_comparison_operator"
3729 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3730 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3731 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3734 [(set_attr "type" "cmove")
3735 (set_attr "length" "4,8")])
3737 (define_insn "*commutative_cond_exec"
3739 (match_operator 5 "proper_comparison_operator"
3740 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3741 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3742 (match_operator:SI 3 "commutative_operator"
3743 [(match_operand:SI 1 "register_operand" "%0,0")
3744 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3747 arc_output_commutative_cond_exec (operands, true);
3750 [(set_attr "cond" "use")
3751 (set_attr "type" "cmove")
3752 (set_attr_alternative "length"
3755 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3760 (define_insn "*sub_cond_exec"
3762 (match_operator 4 "proper_comparison_operator"
3763 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3764 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3765 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3766 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3772 [(set_attr "cond" "use")
3773 (set_attr "type" "cmove")
3774 (set_attr "length" "4,4,8")])
3776 (define_insn "*noncommutative_cond_exec"
3778 (match_operator 5 "proper_comparison_operator"
3779 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3780 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3781 (match_operator:SI 3 "noncommutative_operator"
3782 [(match_operand:SI 1 "register_operand" "0,0")
3783 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3786 [(set_attr "cond" "use")
3787 (set_attr "type" "cmove")
3788 (set_attr "length" "4,8")])
3790 ;; These control RTL generation for conditional jump insns
3791 ;; Match both normal and inverted jump.
3793 ; We need a separate expander for this lest we loose the mode of CC_REG
3794 ; when match_operator substitutes the literal operand into the comparison.
3795 (define_expand "branch_insn"
3797 (if_then_else (match_operand 1 "" "")
3798 (label_ref (match_operand 0 "" ""))
3801 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3802 ; are three reasons why we need to consider branches to be length 6:
3803 ; - annull-false delay slot insns are implemented using conditional execution,
3804 ; thus preventing short insn formation where used.
3805 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3806 ; using conditional execution, preventing short insn formation where used.
3807 ; - for ARC700: likely or somewhat likely taken branches are made long and
3808 ; unaligned if possible to avoid branch penalty.
3809 (define_insn "*branch_insn"
3811 (if_then_else (match_operator 1 "proper_comparison_operator"
3812 [(reg CC_REG) (const_int 0)])
3813 (label_ref (match_operand 0 "" ""))
3818 if (arc_ccfsm_branch_deleted_p ())
3820 arc_ccfsm_record_branch_deleted ();
3821 return \"; branch deleted, next insns conditionalized\";
3825 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3826 if (get_attr_length (insn) == 2)
3827 return \"b%d1%? %^%l0%&\";
3829 return \"b%d1%# %^%l0\";
3832 [(set_attr "type" "branch")
3836 (eq_attr "delay_slot_filled" "yes")
3841 (match_operand 1 "equality_comparison_operator" "")
3842 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3843 (gt (minus (match_dup 0) (pc))
3844 (minus (const_int 506)
3845 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3846 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3847 (lt (minus (match_dup 0) (pc)) (const_int -64))
3848 (gt (minus (match_dup 0) (pc))
3849 (minus (const_int 58)
3850 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3855 (set (attr "iscompact")
3856 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3857 (const_string "false")))])
3859 (define_insn "*rev_branch_insn"
3861 (if_then_else (match_operator 1 "proper_comparison_operator"
3862 [(reg CC_REG) (const_int 0)])
3864 (label_ref (match_operand 0 "" ""))))]
3865 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3868 if (arc_ccfsm_branch_deleted_p ())
3870 arc_ccfsm_record_branch_deleted ();
3871 return \"; branch deleted, next insns conditionalized\";
3875 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3876 if (get_attr_length (insn) == 2)
3877 return \"b%D1%? %^%l0\";
3879 return \"b%D1%# %^%l0\";
3882 [(set_attr "type" "branch")
3886 (eq_attr "delay_slot_filled" "yes")
3891 (match_operand 1 "equality_comparison_operator" "")
3892 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3893 (gt (minus (match_dup 0) (pc))
3894 (minus (const_int 506)
3895 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3896 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3897 (lt (minus (match_dup 0) (pc)) (const_int -64))
3898 (gt (minus (match_dup 0) (pc))
3899 (minus (const_int 58)
3900 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3905 (set (attr "iscompact")
3906 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3907 (const_string "false")))])
3909 ;; Unconditional and other jump instructions.
3911 (define_expand "jump"
3912 [(set (pc) (label_ref (match_operand 0 "" "")))]
3916 (define_insn "jump_i"
3917 [(set (pc) (label_ref (match_operand 0 "" "")))]
3918 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3920 [(set_attr "type" "uncond_branch")
3921 (set (attr "iscompact")
3922 (if_then_else (match_test "get_attr_length (insn) == 2")
3923 (const_string "true") (const_string "false")))
3924 (set_attr "cond" "canuse")
3925 (set (attr "length")
3927 ; In arc_reorg we just guesstimate; might be more or less than 4.
3928 (match_test "arc_branch_size_unknown_p ()")
3931 (eq_attr "delay_slot_filled" "yes")
3934 (match_test "CROSSING_JUMP_P (insn)")
3937 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3938 (gt (minus (match_dup 0) (pc))
3939 (minus (const_int 506)
3940 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3944 (define_insn "indirect_jump"
3945 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,q,r"))]
3953 [(set_attr "type" "jump")
3954 (set_attr "iscompact" "false,false,false,maybe,false")
3955 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3957 ;; Implement a switch statement.
3958 (define_expand "casesi"
3959 [(match_operand:SI 0 "register_operand" "") ; Index
3960 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
3961 (match_operand:SI 2 "const_int_operand" "") ; Total range
3962 (match_operand:SI 3 "" "") ; Table label
3963 (match_operand:SI 4 "" "")] ; Out of range label
3966 if (operands[1] != const0_rtx)
3968 rtx reg = gen_reg_rtx (SImode);
3969 emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
3972 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0],
3974 operands[0], operands[2], operands[4]));
3976 emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3]));
3979 rtx reg = gen_reg_rtx (SImode);
3980 rtx lbl = operands[3];
3981 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3983 operands[3] = force_reg (Pmode, operands[3]);
3984 emit_insn (gen_casesi_load (reg,
3985 operands[3], operands[0], lbl));
3986 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
3987 emit_insn (gen_addsi3 (reg, reg, operands[3]));
3988 emit_jump_insn (gen_casesi_jump (reg, lbl));
3993 (define_insn "casesi_dispatch"
3995 (unspec:SI [(match_operand:SI 0 "register_operand" "r")
3996 (label_ref (match_operand 1 "" ""))]
3997 UNSPEC_ARC_CASESI))]
4000 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4001 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4002 switch (GET_MODE (diff_vec))
4005 return \"bi\\t[%0]\";
4008 return \"bih\\t[%0]\";
4009 default: gcc_unreachable ();
4012 [(set_attr "type" "brcc_no_delay_slot")
4013 (set_attr "iscompact" "false")
4014 (set_attr "length" "4")])
4016 (define_insn "casesi_load"
4017 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
4018 (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal")
4019 (match_operand:SI 2 "register_operand" "q,r,r")]
4020 UNSPEC_ARC_CASESI)))
4021 (use (label_ref (match_operand 3 "" "")))]
4025 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4027 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4029 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4030 gcc_assert (GET_MODE (diff_vec) == SImode);
4031 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4034 switch (GET_MODE (diff_vec))
4037 return \"ld.as\\t%0,[%1,%2]%&\";
4039 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4040 return \"ld%_.as\\t%0,[%1,%2]\";
4041 return \"ld%_.x.as\\t%0,[%1,%2]\";
4043 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4044 return \"ldb%?\\t%0,[%1,%2]%&\";
4045 return \"ldb.x\\t%0,[%1,%2]\";
4050 [(set_attr "type" "load")
4051 (set_attr_alternative "iscompact"
4053 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4054 (as_a<rtx_insn *> (operands[3]))))")
4055 (symbol_ref "QImode"))
4056 (const_string "false")
4057 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4058 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4059 (const_string "false")]
4060 (const_string "true"))
4061 (const_string "false")
4062 (const_string "false")])
4063 (set_attr_alternative "length"
4065 [(eq_attr "iscompact" "false") (const_int 4)
4066 ; We have to mention (match_dup 3) to convince genattrtab.cc that this
4067 ; is a varying length insn.
4068 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4069 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4074 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4075 ; even for CASE_VECTOR_PC_RELATIVE.
4076 (define_insn "casesi_jump"
4077 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,q,c"))
4078 (use (label_ref (match_operand 1 "" "")))]
4081 [(set_attr "type" "jump")
4082 (set_attr "iscompact" "false,maybe,false")
4083 (set_attr "cond" "canuse")])
4085 (define_expand "call"
4086 ;; operands[1] is stack_size_rtx
4087 ;; operands[2] is next_arg_register
4088 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4089 (match_operand 1 "" ""))
4090 (clobber (reg:SI 31))])]
4095 gcc_assert (MEM_P (operands[0]));
4096 callee = XEXP (operands[0], 0);
4097 /* This is to decide if we should generate indirect calls by loading the
4098 32 bit address of the callee into a register before performing the
4099 branch and link - this exposes cse opportunities.
4100 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4101 if (GET_CODE (callee) != REG
4102 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4103 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4107 ; At instruction output time, if it doesn't match and we end up with
4108 ; alternative 1 ("q"), that means that we can't use the short form.
4109 (define_insn "*call_i"
4110 [(call (mem:SI (match_operand:SI 0
4111 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4112 (match_operand 1 "" ""))
4113 (clobber (reg:SI 31))]
4125 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4126 (set_attr "iscompact" "maybe,*,true,*,*,*,*,*,*")
4127 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4128 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4130 (define_expand "call_value"
4131 ;; operand 2 is stack_size_rtx
4132 ;; operand 3 is next_arg_register
4133 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4134 (call (match_operand:SI 1 "call_operand" "")
4135 (match_operand 2 "" "")))
4136 (clobber (reg:SI 31))])]
4142 gcc_assert (MEM_P (operands[1]));
4143 callee = XEXP (operands[1], 0);
4144 /* See the comment in define_expand \"call\". */
4145 if (GET_CODE (callee) != REG
4146 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4147 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4150 ; At instruction output time, if it doesn't match and we end up with
4151 ; alternative 1 ("q"), that means that we can't use the short form.
4152 (define_insn "*call_value_i"
4153 [(set (match_operand 0 "dest_reg_operand" "=q,w, w, w, w, w,w,w, w")
4154 (call (mem:SI (match_operand:SI 1
4155 "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4156 (match_operand 2 "" "")))
4157 (clobber (reg:SI 31))]
4169 [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4170 (set_attr "iscompact" "maybe,*,true,false,*,*,*,*,*")
4171 (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4172 (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4174 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4175 ; use it for lack of inter-procedural branch shortening.
4176 ; Link-time relaxation would help...
4179 [(trap_if (const_int 1) (const_int 0))]
4180 "!TARGET_ARC600_FAMILY"
4182 [(set_attr "type" "misc")
4183 (set_attr "length" "2")])
4189 [(set_attr "type" "misc")
4190 (set_attr "iscompact" "true")
4191 (set_attr "cond" "canuse")
4192 (set_attr "length" "2")])
4195 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4198 [(set_attr "type" "misc")
4199 (set_attr "iscompact" "maybe")
4200 (set_attr "length" "*")])
4202 (define_insn "blockage"
4203 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)]
4206 [(set_attr "length" "0")
4207 (set_attr "type" "block")]
4210 (define_insn "arc600_stall"
4211 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_ARC600_STALL)]
4213 "mov\\t0,mlo\t;wait until multiply complete."
4214 [(set_attr "length" "4")
4215 (set_attr "type" "move")]
4218 ;; Split up troublesome insns for better scheduling.
4220 ;; Peepholes go at the end.
4221 ;;asl followed by add can be replaced by an add{1,2,3}
4222 ;; Three define_peepholes have been added for this optimization
4223 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4224 ;; can be generated by combine. Check if these peepholes still provide
4227 ;; -------------------------------------------------------------
4228 ;; Pattern 1 : r0 = r1 << {i}
4229 ;; r3 = r4/INT + r0 ;;and commutative
4232 ;; add{i} r3,r4/INT,r1
4233 ;; -------------------------------------------------------------
4234 ;; ??? This should be covered by combine, alas, at times combine gets
4235 ;; too clever for it's own good: when the shifted input is known to be
4236 ;; either 0 or 1, the operation will be made into an if-then-else, and
4237 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4238 ;; newlib/libc/time/mktm_r.c .
4241 [(set (match_operand:SI 0 "dest_reg_operand" "")
4242 (ashift:SI (match_operand:SI 1 "register_operand" "")
4243 (match_operand:SI 2 "_1_2_3_operand" "")))
4244 (set (match_operand:SI 3 "dest_reg_operand" "")
4245 (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
4246 (match_operand:SI 5 "arc_nonmemory_operand" "")))]
4247 "(true_regnum (operands[4]) == true_regnum (operands[0])
4248 || true_regnum (operands[5]) == true_regnum (operands[0]))
4249 && (peep2_reg_dead_p (2, operands[0])
4250 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4251 ;; the preparation statements take care to put proper operand in
4252 ;; operands[4] operands[4] will always contain the correct
4253 ;; operand. This is added to satisfy commutativity
4255 (plus:SI (mult:SI (match_dup 1)
4258 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4259 operands[4] = operands[5];
4260 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4263 ;; -------------------------------------------------------------
4264 ;; Pattern 1 : r0 = r1 << {i}
4269 ;; -------------------------------------------------------------
4270 ;; ??? This should be covered by combine, alas, at times combine gets
4271 ;; too clever for it's own good: when the shifted input is known to be
4272 ;; either 0 or 1, the operation will be made into an if-then-else, and
4273 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4274 ;; newlib/libm/math/e_jn.c .
4277 [(set (match_operand:SI 0 "dest_reg_operand" "")
4278 (ashift:SI (match_operand:SI 1 "register_operand" "")
4279 (match_operand:SI 2 "const_int_operand" "")))
4280 (set (match_operand:SI 3 "dest_reg_operand" "")
4281 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4283 "(INTVAL (operands[2]) == 1
4284 || INTVAL (operands[2]) == 2
4285 || INTVAL (operands[2]) == 3)
4286 && (peep2_reg_dead_p (2, operands[0])
4287 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4289 (minus:SI (match_dup 4)
4290 (mult:SI (match_dup 1)
4292 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4297 ; When using the high single bit, the result of a multiply is either
4298 ; the original number or zero. But MPY costs 4 cycles, which we
4299 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4301 [(set (match_operand:SI 0 "dest_reg_operand" "")
4302 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4304 (set (match_operand:SI 4 "register_operand" "")
4305 (mult:SI (match_operand:SI 2 "register_operand")
4306 (match_operand:SI 3 "nonmemory_operand" "")))]
4308 && (rtx_equal_p (operands[0], operands[2])
4309 || rtx_equal_p (operands[0], operands[3]))
4310 && peep2_regno_dead_p (0, CC_REG)
4311 && (rtx_equal_p (operands[0], operands[4])
4312 || (peep2_reg_dead_p (2, operands[0])
4313 && peep2_reg_dead_p (1, operands[4])))"
4314 [(parallel [(set (reg:CC_Z CC_REG)
4315 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4317 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4319 (ne (reg:CC_Z CC_REG) (const_int 0))
4320 (set (match_dup 4) (match_dup 5)))]
4322 if (!rtx_equal_p (operands[0], operands[2]))
4323 operands[5] = operands[2];
4324 else if (!rtx_equal_p (operands[0], operands[3]))
4325 operands[5] = operands[3];
4327 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4331 [(set (match_operand:SI 0 "dest_reg_operand" "")
4332 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4334 (set (match_operand:SI 4 "register_operand" "")
4335 (mult:SI (match_operand:SI 2 "register_operand")
4336 (match_operand:SI 3 "nonmemory_operand" "")))]
4338 && (rtx_equal_p (operands[0], operands[2])
4339 || rtx_equal_p (operands[0], operands[3]))
4340 && peep2_regno_dead_p (2, CC_REG)"
4341 [(parallel [(set (reg:CC_Z CC_REG)
4342 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4344 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4345 (set (match_dup 4) (match_dup 5))
4347 (eq (reg:CC_Z CC_REG) (const_int 0))
4348 (set (match_dup 4) (const_int 0)))]
4349 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4351 ;; Instructions generated through builtins
4353 (define_insn "clrsbsi2"
4354 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4355 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))]
4358 [(set_attr "length" "4,8")
4359 (set_attr "type" "two_cycle_core,two_cycle_core")])
4361 (define_insn "norm_f"
4362 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4363 (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))
4364 (set (reg:CC_ZN CC_REG)
4365 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4368 [(set_attr "length" "4,8")
4369 (set_attr "type" "two_cycle_core,two_cycle_core")])
4371 (define_insn_and_split "clrsbhi2"
4372 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4373 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4377 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4378 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4380 (define_insn "normw"
4381 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4383 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4388 [(set_attr "length" "4,8")
4389 (set_attr "type" "two_cycle_core,two_cycle_core")])
4391 (define_expand "clzsi2"
4393 [(set (match_operand:SI 0 "register_operand" "")
4394 (clz:SI (match_operand:SI 1 "register_operand" "")))
4395 (clobber (match_dup 2))])]
4400 /* ARCv2's FLS is a bit more optimal than using norm. */
4401 rtx tmp = gen_reg_rtx (SImode);
4402 emit_insn (gen_fls (tmp, operands[1]));
4403 emit_insn (gen_subsi3 (operands[0], GEN_INT (31), tmp));
4406 operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);
4409 (define_insn_and_split "*arc_clzsi2"
4410 [(set (match_operand:SI 0 "register_operand" "=r")
4411 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4412 (clobber (reg:CC_ZN CC_REG))]
4418 emit_insn (gen_norm_f (operands[0], operands[1]));
4422 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4423 gen_rtx_SET (operands[0], const0_rtx)));
4427 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4428 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4431 [(set_attr "type" "unary")
4432 (set_attr "length" "12")])
4434 (define_expand "ctzsi2"
4435 [(match_operand:SI 0 "register_operand" "")
4436 (match_operand:SI 1 "register_operand" "")]
4441 emit_insn (gen_ffs (operands[0], operands[1]));
4444 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4448 (define_insn_and_split "arc_ctzsi2"
4449 [(set (match_operand:SI 0 "register_operand" "=r")
4450 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4451 (clobber (reg:CC_ZN CC_REG))
4452 (clobber (match_scratch:SI 2 "=&r"))]
4458 rtx temp = operands[0];
4460 if (reg_overlap_mentioned_p (temp, operands[1])
4461 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4462 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4465 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4466 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4467 emit_insn (gen_clrsbsi2 (operands[0], temp));
4471 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4472 gen_rtx_SET (operands[0], GEN_INT (32))));
4476 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4477 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4481 [(set_attr "type" "unary")
4482 (set_attr "length" "20")])
4485 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4486 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4493 [(set_attr "length" "4,8,4")
4494 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4496 (define_insn "divaw"
4497 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4498 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4499 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4501 "TARGET_ARC700 || TARGET_EA_SET"
4506 [(set_attr "length" "4,8,8")
4507 (set_attr "type" "divaw,divaw,divaw")])
4510 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4517 [(set_attr "length" "4,4,8")
4518 (set_attr "type" "misc,misc,misc")
4519 (set_attr "predicable" "yes,no,yes")
4520 (set_attr "cond" "clob,clob,clob")])
4523 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4527 [(set_attr "length" "4")
4528 (set_attr "type" "misc")])
4532 (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)]
4533 "!TARGET_ARC600_FAMILY"
4535 [(set_attr "length" "4")
4536 (set_attr "type" "rtie")
4537 (set_attr "cond" "clob")])
4540 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4544 [(set_attr "length" "4")
4545 (set_attr "type" "misc")])
4548 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4558 [(set_attr "length" "4")
4559 (set_attr "type" "misc")])
4562 (define_insn "sleep"
4563 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "Lr")]
4567 [(set_attr "length" "4")
4568 (set_attr "type" "misc")])
4570 (define_insn "core_read"
4571 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4572 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4573 VUNSPEC_ARC_CORE_READ))]
4576 if (check_if_valid_regno_const (operands, 1))
4577 return \"mov \t%0, r%1\";
4578 return \"mov \t%0, r%1\";
4580 [(set_attr "length" "4")
4581 (set_attr "type" "unary")])
4583 (define_insn "core_write"
4584 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4585 (match_operand:SI 1 "general_operand" "Hn,!r")]
4586 VUNSPEC_ARC_CORE_WRITE)]
4589 if (check_if_valid_regno_const (operands, 1))
4590 return \"mov \tr%1, %0\";
4591 return \"mov \tr%1, %0\";
4593 [(set_attr "length" "4")
4594 (set_attr "type" "unary")])
4597 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4598 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4602 [(set_attr "length" "4,8,4,8")
4603 (set_attr "type" "lr,lr,lr,lr")])
4606 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4607 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4611 [(set_attr "length" "8,4,8,4")
4612 (set_attr "type" "sr,sr,sr,sr")])
4614 (define_mode_iterator ALLI [QI HI SI (DI "TARGET_LL64")])
4615 (define_mode_attr mALLI [(QI "b") (HI "%_") (SI "") (DI "d")])
4617 (define_insn "lddi<mode>"
4618 [(set (match_operand:ALLI 0 "register_operand" "=r")
4619 (unspec_volatile:ALLI [(match_operand:ALLI 1 "memory_operand" "m")]
4622 "ld<mALLI>%U1.di\\t%0,%1"
4623 [(set_attr "type" "load")])
4625 (define_insn "stdi<mode>"
4626 [(unspec_volatile [(match_operand:ALLI 0 "memory_operand" "m,m,Usc")
4627 (match_operand:ALLI 1 "nonmemory_operand" "r,Cm3,i")]
4630 "st<mALLI>%U0.di\\t%1,%0"
4631 [(set_attr "length" "*,*,8")
4632 (set_attr "type" "store")])
4634 (define_insn_and_split "*stdidi_split"
4635 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")
4636 (match_operand:DI 1 "register_operand" "r")]
4640 "&& reload_completed"
4641 [(unspec_volatile:SI [(match_dup 2) (match_dup 3)] VUNSPEC_ARC_STDI)
4642 (unspec_volatile:SI [(match_dup 4) (match_dup 5)] VUNSPEC_ARC_STDI)]
4645 operands[3] = gen_lowpart (SImode, operands[1]);
4646 operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
4647 operands[2] = gen_lowpart (SImode, operands[0]);
4648 operands[4] = gen_highpart (SImode, operands[0]);
4653 (define_insn_and_split "*lddidi_split"
4654 [(set (match_operand:DI 0 "register_operand" "=r")
4655 (unspec_volatile:DI [(match_operand:DI 1 "memory_operand" "m")]
4659 "&& reload_completed"
4660 [(set (match_dup 2) (unspec_volatile:SI [(match_dup 3)] VUNSPEC_ARC_LDDI))
4661 (set (match_dup 4) (unspec_volatile:SI [(match_dup 5)] VUNSPEC_ARC_LDDI))]
4664 operands[3] = gen_lowpart (SImode, operands[1]);
4665 operands[5] = gen_highpart (SImode, operands[1]);
4666 operands[2] = gen_lowpart (SImode, operands[0]);
4667 operands[4] = gen_highpart (SImode, operands[0]);
4672 (define_insn "trap_s"
4673 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4674 VUNSPEC_ARC_TRAP_S)]
4675 "!TARGET_ARC600_FAMILY"
4677 if (which_alternative == 0)
4679 arc_toggle_unalign ();
4680 return \"trap_s %0\";
4683 /* Keep this message in sync with the one in arc.cc:arc_expand_builtin,
4684 because *.md files do not get scanned by exgettext. */
4685 fatal_error (input_location,
4686 \"operand to %<trap_s%> should be an unsigned 6-bit value\");
4688 [(set_attr "length" "2")
4689 (set_attr "type" "misc")])
4691 (define_insn "unimp_s"
4692 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4693 VUNSPEC_ARC_UNIMP_S)]
4694 "!TARGET_ARC600_FAMILY"
4696 [(set_attr "length" "4")
4697 (set_attr "type" "misc")])
4699 ;; End of instructions generated through builtins
4701 ; Since the demise of REG_N_SETS as reliable data readily available to the
4702 ; target, it is no longer possible to find out
4703 ; in the prologue / epilogue expanders how many times blink is set.
4704 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4705 ; any explicit use of blink will cause it to be saved; hence we cannot
4706 ; represent the blink use in return / sibcall instructions themselves, and
4707 ; instead have to show it in EPILOGUE_USES and must explicitly
4708 ; forbid instructions that change blink in the return / sibcall delay slot.
4709 (define_expand "sibcall"
4710 [(parallel [(call (match_operand 0 "memory_operand" "")
4711 (match_operand 1 "general_operand" ""))
4713 (use (match_operand 2 "" ""))])]
4717 rtx callee = XEXP (operands[0], 0);
4719 if (operands[2] == NULL_RTX)
4720 operands[2] = const0_rtx;
4721 if (GET_CODE (callee) != REG
4722 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4723 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4727 (define_expand "sibcall_value"
4728 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4729 (call (match_operand 1 "memory_operand" "")
4730 (match_operand 2 "general_operand" "")))
4732 (use (match_operand 3 "" ""))])]
4736 rtx callee = XEXP (operands[1], 0);
4738 if (operands[3] == NULL_RTX)
4739 operands[3] = const0_rtx;
4740 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4741 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4745 (define_insn "*sibcall_insn"
4746 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4747 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4748 (match_operand 1 "" ""))
4750 (use (match_operand 2 "" ""))]
4758 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4759 (set_attr "predicable" "yes,no,no,yes,yes")
4760 (set_attr "iscompact" "false,false,maybe,false,false")
4761 (set_attr "is_SIBCALL" "yes")]
4764 (define_insn "*sibcall_value_insn"
4765 [(set (match_operand 0 "dest_reg_operand" "")
4766 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4767 "Cbp,Cbr,!Rcd,Rsc,Cal"))
4768 (match_operand 2 "" "")))
4770 (use (match_operand 3 "" ""))]
4778 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4779 (set_attr "predicable" "yes,no,no,yes,yes")
4780 (set_attr "iscompact" "false,false,maybe,false,false")
4781 (set_attr "is_SIBCALL" "yes")]
4784 (define_expand "prologue"
4788 arc_expand_prologue ();
4792 (define_expand "epilogue"
4796 arc_expand_epilogue (0);
4800 (define_expand "sibcall_epilogue"
4804 arc_expand_epilogue (1);
4808 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4809 ; in the prologue / epilogue expanders how many times blink is set.
4810 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4811 ; any explicit use of blink will cause it to be saved; hence we cannot
4812 ; represent the blink use in return / sibcall instructions themselves, and
4813 ; instead have to show it in EPILOGUE_USES and must explicitly
4814 ; forbid instructions that change blink in the return / sibcall delay slot.
4815 (define_insn "simple_return"
4819 [(set_attr "type" "return")
4820 (set_attr "cond" "canuse")
4821 (set_attr "iscompact" "maybe")
4822 (set_attr "length" "*")])
4824 (define_insn "arc600_rtie"
4826 (unspec_volatile [(match_operand 0 "pmode_register_operand" "")]
4827 VUNSPEC_ARC_ARC600_RTIE)]
4828 "TARGET_ARC600_FAMILY"
4830 [(set_attr "length" "4")
4831 (set_attr "type" "rtie")
4832 (set_attr "cond" "clob")])
4834 (define_insn "p_return_i"
4836 (if_then_else (match_operator 0 "proper_comparison_operator"
4837 [(reg CC_REG) (const_int 0)])
4838 (simple_return) (pc)))]
4841 output_asm_insn (\"j%d0%!%#\\t[blink]\", operands);
4842 /* record the condition in case there is a delay insn. */
4843 arc_ccfsm_record_condition (operands[0], false, insn, 0);
4846 [(set_attr "type" "return")
4847 (set_attr "cond" "use")
4848 (set_attr "iscompact" "maybe" )
4849 (set (attr "length")
4850 (cond [(not (match_operand 0 "equality_comparison_operator" ""))
4852 (eq_attr "delay_slot_filled" "yes")
4856 ;; Return nonzero if this function is known to have a null epilogue.
4857 ;; This allows the optimizer to omit jumps to jumps if no stack
4859 (define_expand "return"
4861 "arc_can_use_return_insn ()"
4864 ;; Comment in final.cc (insn_current_reference_address) says
4865 ;; forward branch addresses are calculated from the next insn after branch
4866 ;; and for backward branches, it is calculated from the branch insn start.
4867 ;; The shortening logic here is tuned to accomodate this behavior
4868 ;; ??? This should be grokked by the ccfsm machinery.
4869 (define_insn "cbranchsi4_scratch"
4871 (if_then_else (match_operator 0 "proper_comparison_operator"
4872 [(match_operand:SI 1 "register_operand" "c,c, c")
4873 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4874 (label_ref (match_operand 3 "" ""))
4876 (clobber (match_operand 4 "cc_register" ""))]
4878 || (TARGET_EARLY_CBRANCHSI
4879 && brcc_nolimm_operator (operands[0], VOIDmode)))
4880 && !CROSSING_JUMP_P (insn)"
4882 switch (get_attr_length (insn))
4884 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4885 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4886 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4887 return \"br%d0%* %1, %B2, %^%l3\";
4890 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
4891 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4894 [(set_attr "cond" "clob, clob, clob")
4897 (match_test "valid_brcc_with_delay_p (operands)")
4898 (const_string "brcc")
4899 (const_string "brcc_no_delay_slot")))
4900 ; For forward branches, we need to account not only for the distance to
4901 ; the target, but also the difference between pcl and pc, the instruction
4902 ; length, and any delay insn, if present.
4905 (cond ; the outer cond does a test independent of branch shortening.
4906 [(match_operand 0 "brcc_nolimm_operator" "")
4908 [(and (match_operand:CC_Z 4 "cc_register")
4909 (eq_attr "delay_slot_filled" "no")
4910 (ge (minus (match_dup 3) (pc)) (const_int -128))
4911 (le (minus (match_dup 3) (pc))
4912 (minus (const_int 122)
4913 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4915 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4916 (le (minus (match_dup 3) (pc))
4917 (minus (const_int 244)
4918 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4920 (and (match_operand:SI 1 "compact_register_operand" "")
4921 (match_operand:SI 2 "compact_hreg_operand" ""))
4924 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4925 (le (minus (match_dup 3) (pc)) (const_int 244)))
4927 (and (match_operand:SI 1 "compact_register_operand" "")
4928 (match_operand:SI 2 "compact_hreg_operand" ""))
4931 (set (attr "iscompact")
4932 (if_then_else (match_test "get_attr_length (insn) & 2")
4933 (const_string "true") (const_string "false")))])
4935 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4936 (define_insn "*bbit"
4939 (match_operator 3 "equality_comparison_operator"
4940 [(zero_extract:SI (match_operand:SI 1 "register_operand" "q,c")
4942 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4944 (label_ref (match_operand 0 "" ""))
4946 (clobber (reg:CC_ZN CC_REG))]
4947 "!CROSSING_JUMP_P (insn)"
4949 switch (get_attr_length (insn))
4951 case 4: return (GET_CODE (operands[3]) == EQ
4952 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4954 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4955 default: gcc_unreachable ();
4958 [(set_attr "type" "brcc")
4959 (set_attr "cond" "clob")
4960 (set (attr "length")
4961 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
4962 (le (minus (match_dup 0) (pc))
4963 (minus (const_int 248)
4964 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4966 (eq (symbol_ref "which_alternative") (const_int 0))
4969 (set (attr "iscompact")
4970 (if_then_else (match_test "get_attr_length (insn) == 6")
4971 (const_string "true") (const_string "false")))])
4973 ;; -------------------------------------------------------------------
4975 ;; -------------------------------------------------------------------
4977 ; operand 0 is the loop count pseudo register
4978 ; operand 1 is the label to jump to at the top of the loop
4979 (define_expand "doloop_end"
4980 [(parallel [(set (pc)
4982 (ne (match_operand 0 "nonimmediate_operand")
4984 (label_ref (match_operand 1 "" ""))
4986 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
4987 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
4988 (clobber (match_dup 2))])]
4991 if (GET_MODE (operands[0]) != SImode)
4993 operands[2] = gen_rtx_SCRATCH (SImode);
4996 (define_insn "arc_lp"
4997 [(unspec:SI [(reg:SI LP_COUNT)]
4999 (use (label_ref (match_operand 0 "" "")))
5000 (use (label_ref (match_operand 1 "" "")))]
5002 "lp\\t@%l1\\t; lp_count:@%l0->@%l1"
5003 [(set_attr "type" "loop_setup")
5004 (set_attr "length" "4")])
5006 ;; if by any chance the lp_count is not used, then use an 'r'
5007 ;; register, instead of going to memory.
5008 ;; split pattern for the very slim chance when the loop register is
5010 (define_insn_and_split "loop_end"
5012 (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m")
5014 (label_ref (match_operand 1 "" ""))
5016 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5017 (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5018 (clobber (match_scratch:SI 2 "=X,&r"))]
5021 ; ZOL_END, begins @%l1
5023 "reload_completed && memory_operand (operands[0], Pmode)"
5024 [(set (match_dup 2) (match_dup 0))
5026 [(set (reg:CC_ZN CC_REG)
5027 (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1))
5029 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
5030 (set (match_dup 0) (match_dup 2))
5032 (if_then_else (ne (reg:CC_ZN CC_REG)
5034 (label_ref (match_dup 1))
5037 [(set_attr "length" "0,24")
5038 (set_attr "predicable" "no")
5039 (set_attr "type" "loop_end")])
5041 (define_insn "loop_fail"
5042 [(set (reg:SI LP_COUNT)
5043 (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5044 (set (reg:CC_ZN CC_REG)
5045 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5048 "sub.f%?\\tlp_count,lp_count,1"
5049 [(set_attr "iscompact" "false")
5050 (set_attr "type" "compare")
5051 (set_attr "cond" "set_zn")
5052 (set_attr "length" "4")
5053 (set_attr "predicable" "yes")])
5055 (define_insn_and_split "dbnz"
5058 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m")
5061 (label_ref (match_operand 1 "" ""))
5064 (plus:SI (match_dup 0)
5066 (clobber (match_scratch:SI 2 "=X,r"))]
5071 "TARGET_DBNZ && reload_completed && memory_operand (operands[0], SImode)"
5072 [(set (match_dup 2) (match_dup 0))
5073 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5074 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5075 (set (match_dup 0) (match_dup 2))
5076 (set (pc) (if_then_else (ge (reg:CC CC_REG)
5078 (label_ref (match_dup 1))
5081 [(set_attr "iscompact" "false")
5082 (set_attr "type" "loop_end")
5083 (set_attr "length" "4,20")])
5085 (define_expand "cpymemsi"
5086 [(match_operand:BLK 0 "" "")
5087 (match_operand:BLK 1 "" "")
5088 (match_operand:SI 2 "nonmemory_operand" "")
5089 (match_operand 3 "immediate_operand" "")]
5091 "if (arc_expand_cpymem (operands)) DONE; else FAIL;")
5093 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5094 ;; to the point that we can generate cmove instructions.
5095 (define_expand "cbranch<mode>4"
5096 [(set (reg:CC CC_REG)
5097 (compare:CC (match_operand:SDF 1 "register_operand" "")
5098 (match_operand:SDF 2 "register_operand" "")))
5101 (match_operator 0 "comparison_operator" [(reg CC_REG)
5103 (label_ref (match_operand 3 "" ""))
5106 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5108 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5109 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5110 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5111 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5115 (define_expand "cmp_float"
5116 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5117 (clobber (reg:SI RETURN_ADDR_REGNUM))
5118 (clobber (reg:SI R12_REG))])]
5122 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5123 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5124 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5126 (define_insn "*cmpsf_<cmp>"
5127 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5128 (clobber (reg:SI RETURN_ADDR_REGNUM))
5129 (clobber (reg:SI R12_REG))]
5130 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5131 && SFUNC_CHECK_PREDICABLE"
5132 "*return arc_output_libcall (\"__<cmp>sf2\");"
5133 [(set_attr "is_sfunc" "yes")
5134 (set_attr "predicable" "yes")])
5136 ;; N.B. for "*cmpdf_ord":
5137 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5138 ;; for the floating point emulation to recognize the NaN.
5139 (define_insn "*cmpdf_<cmp>"
5140 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5141 (clobber (reg:SI RETURN_ADDR_REGNUM))
5142 (clobber (reg:SI R12_REG))]
5143 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5144 && SFUNC_CHECK_PREDICABLE"
5145 "*return arc_output_libcall (\"__<cmp>df2\");"
5146 [(set_attr "is_sfunc" "yes")
5147 (set_attr "predicable" "yes")])
5149 (define_insn "abssf2"
5150 [(set (match_operand:SF 0 "dest_reg_operand" "=q,r,r")
5151 (abs:SF (match_operand:SF 1 "register_operand" "0,0,r")))]
5153 "bclr%?\\t%0,%1,31%&"
5154 [(set_attr "type" "unary")
5155 (set_attr "iscompact" "maybe,false,false")
5156 (set_attr "length" "2,4,4")
5157 (set_attr "predicable" "no,yes,no")])
5159 (define_insn "negsf2"
5160 [(set (match_operand:SF 0 "dest_reg_operand" "=r,r")
5161 (neg:SF (match_operand:SF 1 "register_operand" "0,r")))]
5164 [(set_attr "type" "unary")
5165 (set_attr "predicable" "yes,no")])
5167 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5168 (define_insn "*millicode_thunk_st"
5169 [(match_parallel 0 "millicode_store_operation"
5170 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5173 output_asm_insn ("bl%* __st_r13_to_%0",
5174 &SET_SRC (XVECEXP (operands[0], 0,
5175 XVECLEN (operands[0], 0) - 2)));
5178 [(set_attr "type" "call")])
5180 (define_insn "*millicode_thunk_ld"
5181 [(match_parallel 0 "millicode_load_clob_operation"
5182 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5185 output_asm_insn ("bl%* __ld_r13_to_%0",
5186 &SET_DEST (XVECEXP (operands[0], 0,
5187 XVECLEN (operands[0], 0) - 2)));
5190 [(set_attr "type" "call")])
5192 ; the sibthunk restores blink, so we use the return rtx.
5193 (define_insn "*millicode_sibthunk_ld"
5194 [(match_parallel 0 "millicode_load_operation"
5196 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5197 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5200 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5201 &SET_DEST (XVECEXP (operands[0], 0,
5202 XVECLEN (operands[0], 0) - 1)));
5205 [(set_attr "type" "call")
5206 (set_attr "is_SIBCALL" "yes")])
5208 ;; For thread pointer builtins
5209 (define_expand "get_thread_pointersi"
5210 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5212 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5214 (define_expand "set_thread_pointersi"
5215 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5217 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5219 ;; If hardware floating point is available, don't define a negdf pattern;
5220 ;; it would be something like:
5221 ;;(define_insn "negdf2"
5222 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5223 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5224 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5227 ;; bxor%? %H0,%H1,31
5228 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5229 ;; drsubh%F0%F1 0,0,0
5230 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5231 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5232 ;; (set_attr "iscompact" "false,false,false,false")
5233 ;; (set_attr "length" "4,4,8,12")
5234 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5235 ;; and this suffers from always requiring a long immediate when using
5236 ;; the floating point hardware.
5237 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5238 ;; constant zero efficiently into a register when we want to do the
5239 ;; computation using the floating point hardware. There should be a special
5240 ;; subdf alternative that matches a zero operand 1, which then can allow
5241 ;; to use bxor to flip the high bit of an integer register.
5242 ;; ??? we actually can't use the floating point hardware for neg, because
5243 ;; this would not work right for -0. OTOH optabs.cc has already code
5244 ;; to synthesyze negate by flipping the sign bit.
5247 (define_insn "bswapsi2"
5248 [(set (match_operand:SI 0 "register_operand" "= r,r")
5249 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5250 "TARGET_V2 && TARGET_SWAP"
5252 [(set_attr "length" "4,8")
5253 (set_attr "type" "two_cycle_core")])
5255 (define_expand "prefetch"
5256 [(prefetch (match_operand:SI 0 "address_operand" "")
5257 (match_operand:SI 1 "const_int_operand" "")
5258 (match_operand:SI 2 "const_int_operand" ""))]
5262 (define_insn "prefetch_1"
5263 [(prefetch (match_operand:SI 0 "register_operand" "r")
5264 (match_operand:SI 1 "const_int_operand" "n")
5265 (match_operand:SI 2 "const_int_operand" "n"))]
5268 if (INTVAL (operands[1]))
5269 return "prefetchw [%0]";
5271 return "prefetch [%0]";
5273 [(set_attr "type" "load")
5274 (set_attr "length" "4")])
5276 (define_insn "prefetch_2"
5277 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5278 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5279 (match_operand:SI 2 "const_int_operand" "n,n,n")
5280 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5283 if (INTVAL (operands[2]))
5284 return "prefetchw [%0, %1]";
5286 return "prefetch [%0, %1]";
5288 [(set_attr "type" "load")
5289 (set_attr "length" "4,4,8")])
5291 (define_insn "prefetch_3"
5292 [(prefetch (match_operand:SI 0 "address_operand" "p")
5293 (match_operand:SI 1 "const_int_operand" "n")
5294 (match_operand:SI 2 "const_int_operand" "n"))]
5297 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5298 if (INTVAL (operands[1]))
5299 return "prefetchw%U0 %0";
5301 return "prefetch%U0 %0";
5303 [(set_attr "type" "load")
5304 (set_attr "length" "8")])
5306 (define_insn "divsi3"
5307 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5308 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5309 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5312 [(set_attr "length" "4,4,8,4,4,4,8,8")
5313 (set_attr "iscompact" "false")
5314 (set_attr "type" "div_rem")
5315 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5316 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5319 (define_insn "udivsi3"
5320 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5321 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5322 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5325 [(set_attr "length" "4,4,8,4,4,4,8,8")
5326 (set_attr "iscompact" "false")
5327 (set_attr "type" "div_rem")
5328 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5329 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5332 (define_insn "modsi3"
5333 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5334 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5335 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5338 [(set_attr "length" "4,4,8,4,4,4,8,8")
5339 (set_attr "iscompact" "false")
5340 (set_attr "type" "div_rem")
5341 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5342 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5345 (define_insn "umodsi3"
5346 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5347 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5348 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5351 [(set_attr "length" "4,4,8,4,4,4,8,8")
5352 (set_attr "iscompact" "false")
5353 (set_attr "type" "div_rem")
5354 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5355 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5358 ;; SETcc instructions
5359 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5361 (define_insn "arcset<code>"
5362 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5363 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5364 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5365 "TARGET_V2 && TARGET_CODE_DENSITY"
5366 "set<code>%? %0, %1, %2"
5367 [(set_attr "length" "4,4,4,4,4,8,8")
5368 (set_attr "iscompact" "false")
5369 (set_attr "type" "compare")
5370 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5371 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5374 (define_insn "arcsetltu"
5375 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5376 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5377 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5378 "TARGET_V2 && TARGET_CODE_DENSITY"
5379 "setlo%? %0, %1, %2"
5380 [(set_attr "length" "4,4,4,4,4,8,8")
5381 (set_attr "iscompact" "false")
5382 (set_attr "type" "compare")
5383 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5384 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5387 (define_insn "arcsetgeu"
5388 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5389 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5390 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5391 "TARGET_V2 && TARGET_CODE_DENSITY"
5392 "seths%? %0, %1, %2"
5393 [(set_attr "length" "4,4,4,4,4,8,8")
5394 (set_attr "iscompact" "false")
5395 (set_attr "type" "compare")
5396 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5397 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5400 ;; Special cases of SETCC
5401 (define_insn_and_split "arcsethi"
5402 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5403 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5404 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5405 "TARGET_V2 && TARGET_CODE_DENSITY"
5406 "setlo%? %0, %2, %1"
5408 && CONST_INT_P (operands[2])
5409 && satisfies_constraint_C62 (operands[2])"
5412 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5413 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5414 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5417 [(set_attr "length" "4,4,4,8")
5418 (set_attr "iscompact" "false")
5419 (set_attr "type" "compare")
5420 (set_attr "predicable" "yes,no,no,no")
5421 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5424 (define_insn_and_split "arcsetls"
5425 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5426 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5427 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5428 "TARGET_V2 && TARGET_CODE_DENSITY"
5429 "seths%? %0, %2, %1"
5431 && CONST_INT_P (operands[2])
5432 && satisfies_constraint_C62 (operands[2])"
5435 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5436 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5437 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5440 [(set_attr "length" "4,4,4,8")
5441 (set_attr "iscompact" "false")
5442 (set_attr "type" "compare")
5443 (set_attr "predicable" "yes,no,no,no")
5444 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5447 ; Any mode that needs to be solved by secondary reload
5448 (define_mode_iterator SRI [QI HI])
5450 (define_expand "reload_<mode>_load"
5451 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5452 (match_operand:SRI 1 "memory_operand" "m")
5453 (match_operand:SI 2 "register_operand" "=&r")])]
5456 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5460 (define_expand "reload_<mode>_store"
5461 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5462 (match_operand:SRI 1 "register_operand" "r")
5463 (match_operand:SI 2 "register_operand" "=&r")])]
5466 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5470 (define_insn "extzvsi"
5471 [(set (match_operand:SI 0 "register_operand" "=r , r,r,r")
5472 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r,r,0")
5473 (match_operand:SI 2 "const_int_operand" "C3p,C3p,n,n")
5474 (match_operand:SI 3 "const_int_operand" "n , n,n,n")))]
5475 "TARGET_HS && TARGET_BARREL_SHIFTER"
5477 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5478 operands[2] = GEN_INT (assemble_op2);
5479 return "xbfu%?\\t%0,%1,%2";
5481 [(set_attr "type" "shift")
5482 (set_attr "iscompact" "false")
5483 (set_attr "length" "4,4,8,8")
5484 (set_attr "predicable" "yes,no,no,yes")
5485 (set_attr "cond" "canuse,nocond,nocond,canuse_limm")])
5487 (define_insn "kflag"
5488 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5495 [(set_attr "length" "4,4,8")
5496 (set_attr "type" "misc,misc,misc")
5497 (set_attr "predicable" "yes,no,yes")
5498 (set_attr "cond" "clob,clob,clob")])
5501 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5502 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5506 [(set_attr "length" "4")
5507 (set_attr "type" "misc")])
5510 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5511 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5513 "TARGET_NORM && TARGET_V2"
5515 [(set_attr "length" "4,8")
5516 (set_attr "type" "two_cycle_core,two_cycle_core")])
5518 (define_insn "ffs_f"
5519 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5520 (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5522 (set (reg:CC_ZN CC_REG)
5523 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5524 "TARGET_NORM && TARGET_V2"
5526 [(set_attr "length" "4,8")
5527 (set_attr "type" "two_cycle_core,two_cycle_core")])
5529 (define_expand "ffssi2"
5530 [(parallel [(set (match_dup 2)
5531 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5533 (set (reg:CC_ZN CC_REG)
5534 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5535 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5536 (set (match_operand:SI 0 "dest_reg_operand" "")
5537 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5540 "TARGET_NORM && TARGET_V2"
5542 operands[2] = gen_reg_rtx (SImode);
5546 [(set (match_operand:SI 0 "register_operand" "=r,r")
5547 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "rL,Cal")]
5549 "TARGET_NORM && TARGET_V2"
5551 [(set_attr "length" "4,8")
5552 (set_attr "type" "two_cycle_core,two_cycle_core")])
5555 [(unspec_volatile:SI [(match_operand:SI 0 "nonmemory_operand" "rL")]
5559 [(set_attr "length" "4")
5560 (set_attr "type" "misc")])
5565 (define_expand "addsf3"
5566 [(set (match_operand:SF 0 "register_operand" "")
5567 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5568 (match_operand:SF 2 "nonmemory_operand" "")))]
5569 "TARGET_FP_SP_BASE || TARGET_SPFP"
5571 if (!register_operand (operands[1], SFmode)
5572 && !register_operand (operands[2], SFmode))
5573 operands[1] = force_reg (SFmode, operands[1]);
5577 (define_expand "subsf3"
5578 [(set (match_operand:SF 0 "register_operand" "")
5579 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5580 (match_operand:SF 2 "nonmemory_operand" "")))]
5581 "TARGET_FP_SP_BASE || TARGET_SPFP"
5583 if (!register_operand (operands[1], SFmode)
5584 && !register_operand (operands[2], SFmode))
5585 operands[1] = force_reg (SFmode, operands[1]);
5589 (define_expand "mulsf3"
5590 [(set (match_operand:SF 0 "register_operand" "")
5591 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5592 (match_operand:SF 2 "nonmemory_operand" "")))]
5593 "TARGET_FP_SP_BASE || TARGET_SPFP"
5595 if (!register_operand (operands[1], SFmode)
5596 && !register_operand (operands[2], SFmode))
5597 operands[1] = force_reg (SFmode, operands[1]);
5601 (define_expand "adddf3"
5602 [(set (match_operand:DF 0 "double_register_operand" "")
5603 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5604 (match_operand:DF 2 "nonmemory_operand" "")))]
5605 "TARGET_FP_DP_BASE || TARGET_DPFP"
5609 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5611 rtx first, second, tmp;
5612 split_double (operands[2], &first, &second);
5613 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5614 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5615 operands[2], tmp, const0_rtx));
5618 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5619 operands[2], const1_rtx, const1_rtx));
5622 else if (TARGET_FP_DP_BASE)
5624 if (!even_register_operand (operands[2], DFmode))
5625 operands[2] = force_reg (DFmode, operands[2]);
5627 if (!even_register_operand (operands[1], DFmode))
5628 operands[1] = force_reg (DFmode, operands[1]);
5635 (define_expand "subdf3"
5636 [(set (match_operand:DF 0 "double_register_operand" "")
5637 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5638 (match_operand:DF 2 "nonmemory_operand" "")))]
5639 "TARGET_FP_DP_BASE || TARGET_DPFP"
5643 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5644 operands[1] = force_reg (DFmode, operands[1]);
5645 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5646 || GET_CODE (operands[2]) == CONST_DOUBLE)
5648 rtx first, second, tmp;
5649 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5650 split_double (operands[const_index], &first, &second);
5651 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5652 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5653 operands[2], tmp, const0_rtx));
5656 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5657 operands[2], const1_rtx, const1_rtx));
5660 else if (TARGET_FP_DP_BASE)
5662 if (!even_register_operand (operands[2], DFmode))
5663 operands[2] = force_reg (DFmode, operands[2]);
5665 if (!even_register_operand (operands[1], DFmode))
5666 operands[1] = force_reg (DFmode, operands[1]);
5673 (define_expand "muldf3"
5674 [(set (match_operand:DF 0 "double_register_operand" "")
5675 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5676 (match_operand:DF 2 "nonmemory_operand" "")))]
5677 "TARGET_FP_DP_BASE || TARGET_DPFP"
5681 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5683 rtx first, second, tmp;
5684 split_double (operands[2], &first, &second);
5685 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5686 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5687 operands[2], tmp, const0_rtx));
5690 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5691 operands[2], const1_rtx, const1_rtx));
5694 else if (TARGET_FP_DP_BASE)
5696 if (!even_register_operand (operands[2], DFmode))
5697 operands[2] = force_reg (DFmode, operands[2]);
5699 if (!even_register_operand (operands[1], DFmode))
5700 operands[1] = force_reg (DFmode, operands[1]);
5707 (define_expand "divsf3"
5708 [(set (match_operand:SF 0 "register_operand" "")
5709 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5710 (match_operand:SF 2 "nonmemory_operand" "")))]
5711 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5713 if (TARGET_FPX_QUARK)
5715 operands[1] = force_reg (SFmode, operands[1]);
5716 operands[2] = force_reg (SFmode, operands[2]);
5720 if (!register_operand (operands[1], SFmode)
5721 && !register_operand (operands[2], SFmode))
5722 operands[1] = force_reg (SFmode, operands[1]);
5727 (define_expand "sqrtsf2"
5728 [(set (match_operand:SF 0 "register_operand" "")
5729 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5730 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5732 if (TARGET_FPX_QUARK)
5734 operands[1] = force_reg (SFmode, operands[1]);
5738 ;; SF->SI (using rounding towards zero)
5739 (define_expand "fix_truncsfsi2"
5740 [(set (match_operand:SI 0 "register_operand" "")
5741 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5742 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5746 (define_expand "floatsisf2"
5747 [(set (match_operand:SF 0 "register_operand" "")
5748 (float:SF (match_operand:SI 1 "register_operand" "")))]
5749 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5752 (define_expand "extzv"
5753 [(set (match_operand:SI 0 "register_operand" "")
5754 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5755 (match_operand:SI 2 "const_int_operand" "")
5756 (match_operand:SI 3 "const_int_operand" "")))]
5757 "TARGET_NPS_BITOPS")
5759 ; We need a sanity check in the instuction predicate because combine
5760 ; will throw any old rubbish at us and see what sticks.
5761 (define_insn "*extzv_i"
5762 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5763 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5764 (match_operand:SI 2 "const_int_operand" "n")
5765 (match_operand:SI 3 "const_int_operand" "n")))]
5766 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5767 "movb.cl %0,%1,0,%3,%2"
5768 [(set_attr "type" "shift")
5769 (set_attr "length" "4")])
5771 (define_expand "insv"
5772 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5773 (match_operand:SI 1 "const_int_operand" "")
5774 (match_operand:SI 2 "const_int_operand" ""))
5775 (match_operand:SI 3 "nonmemory_operand" ""))]
5778 int size = INTVAL (operands[1]);
5780 if (size != 1 && size != 2 && size != 4 && size != 8)
5781 operands[3] = force_reg (SImode, operands[3]);
5784 (define_insn "*insv_i"
5785 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5786 (match_operand:SI 1 "const_int_operand" "C18,n")
5787 (match_operand:SI 2 "const_int_operand" "n,n"))
5788 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5790 && (register_operand (operands[3], SImode)
5791 || satisfies_constraint_C18 (operands[1]))"
5793 movbi %0,%0,%3,%2,%1
5794 movb %0,%0,%3,%2,0,%1"
5795 [(set_attr "type" "shift")
5796 (set_attr "length" "4")])
5798 (define_insn "*movb"
5799 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5800 (match_operand:SI 1 "const_int_operand" "n")
5801 (match_operand:SI 2 "const_int_operand" "n"))
5802 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5804 (match_operand:SI 4 "const_int_operand" "n")))]
5806 "movb %0,%0,%3,%2,%4,%1"
5807 [(set_attr "type" "shift")
5808 (set_attr "length" "4")])
5810 (define_insn "*movb_signed"
5811 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5812 (match_operand:SI 1 "const_int_operand" "n")
5813 (match_operand:SI 2 "const_int_operand" "n"))
5814 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5816 (match_operand:SI 4 "const_int_operand" "n")))]
5818 "movb %0,%0,%3,%2,%4,%1"
5819 [(set_attr "type" "shift")
5820 (set_attr "length" "4")])
5822 (define_insn "*movb_high"
5823 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5824 (match_operand:SI 1 "const_int_operand" "n")
5825 (match_operand:SI 2 "const_int_operand" "n"))
5826 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5827 (match_operand:SI 4 "const_int_operand" "n")))]
5829 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5830 "movb %0,%0,%3,%2,%4,%1"
5831 [(set_attr "type" "shift")
5832 (set_attr "length" "4")])
5834 ; N.B.: when processing signed bitfields that fit in the top half of
5835 ; a word, gcc will use a narrow sign extending load, and in this case
5836 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
5837 (define_insn "*movb_high_signed"
5838 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5839 (match_operand:SI 1 "const_int_operand" "n")
5840 (match_operand:SI 2 "const_int_operand" "n"))
5841 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5842 (match_operand:SI 4 "const_int_operand" "n")))]
5844 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5845 "movb %0,%0,%3,%2,%4,%1"
5846 [(set_attr "type" "shift")
5847 (set_attr "length" "4")])
5850 [(set (match_operand:SI 0 "register_operand" "")
5851 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5852 (match_operand:SI 2 "const_int_operand" ""))
5853 (subreg:SI (match_operand 3 "") 0)))]
5855 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
5856 && !reg_overlap_mentioned_p (operands[0], operands[1])"
5857 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
5858 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
5860 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
5862 (define_insn "*mrgb"
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 (zero_extract:SI (match_dup 0) (match_dup 1)
5867 (match_operand:SI 3 "const_int_operand" "n")))
5868 (set (zero_extract:SI (match_dup 0)
5869 (match_operand:SI 4 "const_int_operand" "n")
5870 (match_operand:SI 5 "const_int_operand" "n"))
5871 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
5873 (match_operand:SI 7 "const_int_operand" "n")))]
5876 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
5877 /* The ;%? updates the known unalignment. */
5878 return arc_short_long (insn, ";%?", "nop_s");
5880 [(set_attr "type" "shift")
5881 (set_attr "length" "6")
5882 (set_attr "iscompact" "true")])
5884 ;; combine fumbles combination of two movb patterns, and then the
5885 ;; combination is rejected by combinable_i3pat.
5886 ;; Thus, we can only use a peephole2 to combine two such insns.
5889 [(set (match_operand:SI 0 "register_operand" "")
5890 (match_operand:SI 1 "register_operand" ""))
5891 (set (zero_extract:SI (match_dup 0)
5892 (match_operand:SI 2 "const_int_operand" "")
5893 (match_operand:SI 3 "const_int_operand" ""))
5894 (zero_extract:SI (match_dup 1)
5896 (match_operand:SI 4 "const_int_operand" "")))
5897 (match_operand 9) ; unrelated insn scheduled here
5898 (set (zero_extract:SI (match_dup 0)
5899 (match_operand:SI 5 "const_int_operand" "")
5900 (match_operand:SI 6 "const_int_operand" ""))
5901 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
5903 (match_operand:SI 8 "const_int_operand" "")))]
5905 // Check that the second movb doesn't clobber an input of the extra insn.
5906 && !reg_overlap_mentioned_p (operands[0], operands[9])
5908 && !reg_set_p (operands[0], operands[9])
5909 && !reg_set_p (operands[7], operands[9])"
5910 [(set (match_dup 0) (match_dup 1))
5911 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5912 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
5913 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
5914 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
5918 [(set (match_operand:SI 0 "register_operand" "")
5919 (match_operand:SI 1 "register_operand" ""))
5920 (set (zero_extract:SI (match_dup 0)
5921 (match_operand:SI 2 "const_int_operand" "")
5922 (match_operand:SI 3 "const_int_operand" ""))
5923 (zero_extract:SI (match_dup 1)
5925 (match_operand:SI 4 "const_int_operand" "")))
5926 (set (match_dup 1) (match_operand 8))
5927 (set (zero_extract:SI (match_dup 0)
5928 (match_operand:SI 5 "const_int_operand" "")
5929 (match_operand:SI 6 "const_int_operand" ""))
5930 (zero_extract:SI (match_dup 1) (match_dup 5)
5931 (match_operand:SI 7 "const_int_operand" "")))]
5933 && !reg_overlap_mentioned_p (operands[0], operands[8])"
5934 [(set (match_dup 0) (match_dup 1))
5935 (set (match_dup 1) (match_dup 8))
5936 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
5937 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
5938 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
5939 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
5942 (define_insn "*rotrsi3_cnt1"
5943 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5944 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5948 [(set_attr "type" "shift")
5949 (set_attr "predicable" "no")
5950 (set_attr "length" "4")])
5952 (define_insn "*rotrsi3_cnt8"
5953 [(set (match_operand:SI 0 "register_operand" "=r")
5954 (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5956 "TARGET_BARREL_SHIFTER && TARGET_V2"
5958 [(set_attr "type" "shift")
5959 (set_attr "predicable" "no")
5960 (set_attr "length" "4")])
5962 (define_insn "*ashlsi2_cnt1"
5963 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
5964 (ashift:SI (match_operand:SI 1 "register_operand" "q,c")
5968 [(set_attr "type" "shift")
5969 (set_attr "iscompact" "maybe,false")
5970 (set_attr "length" "4")
5971 (set_attr "predicable" "no,no")])
5973 (define_insn "*ashlsi2_cnt8"
5974 [(set (match_operand:SI 0 "register_operand" "=r")
5975 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5977 "TARGET_BARREL_SHIFTER && TARGET_V2"
5979 [(set_attr "type" "shift")
5980 (set_attr "iscompact" "false")
5981 (set_attr "length" "4")
5982 (set_attr "predicable" "no")])
5984 (define_insn "*ashlsi2_cnt16"
5985 [(set (match_operand:SI 0 "register_operand" "=r")
5986 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
5988 "TARGET_BARREL_SHIFTER && TARGET_V2"
5990 [(set_attr "type" "shift")
5991 (set_attr "iscompact" "false")
5992 (set_attr "length" "4")
5993 (set_attr "predicable" "no")])
5995 (define_insn "*lshrsi3_cnt1"
5996 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
5997 (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6001 [(set_attr "type" "shift")
6002 (set_attr "iscompact" "maybe,false")
6003 (set_attr "predicable" "no,no")])
6005 (define_insn "*ashrsi3_cnt1"
6006 [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
6007 (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6011 [(set_attr "type" "shift")
6012 (set_attr "iscompact" "maybe,false")
6013 (set_attr "predicable" "no,no")])
6016 [(set (match_operand:SI 0 "register_operand" "")
6017 (zero_extract:SI (match_dup 0)
6018 (match_operand:SI 1 "const_int_operand" "")
6019 (match_operand:SI 2 "const_int_operand" "")))
6020 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6025 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6026 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6027 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6029 ;; Dummy pattern used as a place holder for automatically saved
6031 (define_insn "stack_irq_dwarf"
6032 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6035 [(set_attr "length" "0")])
6037 ;; MAC and DMPY instructions
6039 ; Use VMAC2H(U) instruction to emulate scalar 16bit mac.
6040 (define_expand "maddhisi4"
6041 [(match_operand:SI 0 "register_operand" "")
6042 (match_operand:HI 1 "register_operand" "")
6043 (match_operand:HI 2 "register_operand" "")
6044 (match_operand:SI 3 "register_operand" "")]
6047 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6049 emit_move_insn (acc_reg, operands[3]);
6050 emit_insn (gen_machi (operands[0], operands[1], operands[2], acc_reg));
6054 (define_insn "machi"
6055 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6057 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6058 (sign_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6059 (match_operand:SI 3 "accl_operand" "")))
6060 (clobber (reg:DI ARCV2_ACC))]
6063 [(set_attr "length" "4")
6064 (set_attr "type" "multi")
6065 (set_attr "predicable" "no")
6066 (set_attr "cond" "nocond")])
6068 ; The same for the unsigned variant, but using VMAC2HU instruction.
6069 (define_expand "umaddhisi4"
6070 [(match_operand:SI 0 "register_operand" "")
6071 (match_operand:HI 1 "register_operand" "")
6072 (match_operand:HI 2 "register_operand" "")
6073 (match_operand:SI 3 "register_operand" "")]
6076 rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6078 emit_move_insn (acc_reg, operands[3]);
6079 emit_insn (gen_umachi (operands[0], operands[1], operands[2], acc_reg));
6083 (define_insn "umachi"
6084 [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6086 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6087 (zero_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6088 (match_operand:SI 3 "accl_operand" "")))
6089 (clobber (reg:DI ARCV2_ACC))]
6092 [(set_attr "length" "4")
6093 (set_attr "type" "multi")
6094 (set_attr "predicable" "no")
6095 (set_attr "cond" "nocond")])
6097 (define_expand "maddsidi4"
6098 [(match_operand:DI 0 "register_operand" "")
6099 (match_operand:SI 1 "register_operand" "")
6100 (match_operand:SI 2 "extend_operand" "")
6101 (match_operand:DI 3 "register_operand" "")]
6104 emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6108 (define_insn_and_split "maddsidi4_split"
6109 [(set (match_operand:DI 0 "register_operand" "=r")
6112 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6113 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6114 (match_operand:DI 3 "register_operand" "r")))
6115 (clobber (reg:DI ARCV2_ACC))]
6118 "TARGET_PLUS_DMPY && reload_completed"
6121 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6122 emit_move_insn (acc_reg, operands[3]);
6123 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6124 && REGNO (operands[0]) != ACC_REG_FIRST)
6125 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6128 emit_insn (gen_mac (operands[1], operands[2]));
6129 if (REGNO (operands[0]) != ACC_REG_FIRST)
6130 emit_move_insn (operands[0], acc_reg);
6134 [(set_attr "type" "multi")
6135 (set_attr "length" "36")])
6138 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6141 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6142 (sign_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,Cal")))
6143 (reg:DI ARCV2_ACC)))
6144 (set (reg:DI ARCV2_ACC)
6146 (mult:DI (sign_extend:DI (match_dup 1))
6147 (sign_extend:DI (match_dup 2)))
6148 (reg:DI ARCV2_ACC)))]
6151 [(set_attr "length" "4,4,8")
6152 (set_attr "type" "multi")
6153 (set_attr "predicable" "yes,no,no")
6154 (set_attr "cond" "canuse,nocond,nocond")])
6157 [(set (reg:DI ARCV2_ACC)
6159 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6160 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6161 (reg:DI ARCV2_ACC)))]
6164 [(set_attr "length" "4,8")
6165 (set_attr "type" "multi")
6166 (set_attr "predicable" "no")
6167 (set_attr "cond" "nocond")])
6170 [(set (reg:DI ARCV2_ACC)
6172 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6173 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6174 (reg:DI ARCV2_ACC)))
6175 (set (match_operand:SI 2 "register_operand" "")
6176 (match_operand:SI 3 "accl_operand" ""))]
6180 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6184 (define_insn "mac_r"
6185 [(set (match_operand:SI 0 "register_operand" "=r,r")
6188 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6189 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6190 (reg:DI ARCV2_ACC))))
6191 (clobber (reg:DI ARCV2_ACC))]
6194 [(set_attr "length" "4,8")
6195 (set_attr "type" "multi")
6196 (set_attr "predicable" "no")
6197 (set_attr "cond" "nocond")])
6199 (define_expand "umaddsidi4"
6200 [(match_operand:DI 0 "register_operand" "")
6201 (match_operand:SI 1 "register_operand" "")
6202 (match_operand:SI 2 "extend_operand" "")
6203 (match_operand:DI 3 "register_operand" "")]
6206 emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6210 (define_insn_and_split "umaddsidi4_split"
6211 [(set (match_operand:DI 0 "register_operand" "=r")
6214 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6215 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6216 (match_operand:DI 3 "register_operand" "r")))
6217 (clobber (reg:DI ARCV2_ACC))]
6220 "TARGET_PLUS_DMPY && reload_completed"
6223 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6224 emit_move_insn (acc_reg, operands[3]);
6225 if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6226 && REGNO (operands[0]) != ACC_REG_FIRST)
6227 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6230 emit_insn (gen_macu (operands[1], operands[2]));
6231 if (REGNO (operands[0]) != ACC_REG_FIRST)
6232 emit_move_insn (operands[0], acc_reg);
6236 [(set_attr "type" "multi")
6237 (set_attr "length" "36")])
6239 (define_insn "macdu"
6240 [(set (match_operand:DI 0 "even_register_operand" "=r,r,r")
6243 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6244 (zero_extend:DI (match_operand:SI 2 "extend_operand" "r,rI,i")))
6245 (reg:DI ARCV2_ACC)))
6246 (set (reg:DI ARCV2_ACC)
6248 (mult:DI (zero_extend:DI (match_dup 1))
6249 (zero_extend:DI (match_dup 2)))
6250 (reg:DI ARCV2_ACC)))]
6253 [(set_attr "length" "4,4,8")
6254 (set_attr "type" "multi")
6255 (set_attr "predicable" "yes,no,no")
6256 (set_attr "cond" "canuse,nocond,nocond")])
6259 [(set (reg:DI ARCV2_ACC)
6261 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6262 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6263 (reg:DI ARCV2_ACC)))]
6266 [(set_attr "length" "4,8")
6267 (set_attr "type" "multi")
6268 (set_attr "predicable" "no")
6269 (set_attr "cond" "nocond")])
6272 [(set (reg:DI ARCV2_ACC)
6274 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6275 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6276 (reg:DI ARCV2_ACC)))
6277 (set (match_operand:SI 2 "register_operand" "")
6278 (match_operand:SI 3 "accl_operand" ""))]
6282 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6286 (define_insn "macu_r"
6287 [(set (match_operand:SI 0 "register_operand" "=r,r")
6290 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6291 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6292 (reg:DI ARCV2_ACC))))
6293 (clobber (reg:DI ARCV2_ACC))]
6296 [(set_attr "length" "4,8")
6297 (set_attr "type" "multi")
6298 (set_attr "predicable" "no")
6299 (set_attr "cond" "nocond")])
6301 (define_insn "mpyd<su_optab>_arcv2hs"
6302 [(set (match_operand:DI 0 "even_register_operand" "=r")
6303 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r"))
6304 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6305 (set (reg:DI ARCV2_ACC)
6307 (SEZ:DI (match_dup 1))
6308 (SEZ:DI (match_dup 2))))]
6310 "mpyd<su_optab>%?\\t%0,%1,%2"
6311 [(set_attr "length" "4")
6312 (set_attr "iscompact" "false")
6313 (set_attr "type" "multi")
6314 (set_attr "predicable" "no")])
6316 (define_insn "*pmpyd<su_optab>_arcv2hs"
6317 [(set (match_operand:DI 0 "even_register_operand" "=r")
6319 (SEZ:DI (match_operand:SI 1 "even_register_operand" "%0"))
6320 (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6321 (set (reg:DI ARCV2_ACC)
6323 (SEZ:DI (match_dup 1))
6324 (SEZ:DI (match_dup 2))))]
6326 "mpyd<su_optab>%?\\t%0,%1,%2"
6327 [(set_attr "length" "4")
6328 (set_attr "iscompact" "false")
6329 (set_attr "type" "multi")
6330 (set_attr "predicable" "yes")])
6332 (define_insn "mpyd<su_optab>_imm_arcv2hs"
6333 [(set (match_operand:DI 0 "even_register_operand" "=r,r, r")
6334 (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r,0, r"))
6335 (match_operand 2 "immediate_operand" "L,I,Cal")))
6336 (set (reg:DI ARCV2_ACC)
6337 (mult:DI (SEZ:DI (match_dup 1))
6340 "mpyd<su_optab>%?\\t%0,%1,%2"
6341 [(set_attr "length" "4,4,8")
6342 (set_attr "iscompact" "false")
6343 (set_attr "type" "multi")
6344 (set_attr "predicable" "no")])
6346 (define_insn "*pmpyd<su_optab>_imm_arcv2hs"
6347 [(set (match_operand:DI 0 "even_register_operand" "=r,r")
6349 (SEZ:DI (match_operand:SI 1 "even_register_operand" "0,0"))
6350 (match_operand 2 "immediate_operand" "L,Cal")))
6351 (set (reg:DI ARCV2_ACC)
6352 (mult:DI (SEZ:DI (match_dup 1))
6355 "mpyd<su_optab>%?\\t%0,%1,%2"
6356 [(set_attr "length" "4,8")
6357 (set_attr "iscompact" "false")
6358 (set_attr "type" "multi")
6359 (set_attr "predicable" "yes")])
6361 (define_insn "*add_shift"
6362 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6363 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
6364 (match_operand:SI 2 "_1_2_3_operand" ""))
6365 (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
6367 "add%2%?\\t%0,%3,%1"
6368 [(set_attr "length" "*,4,8")
6369 (set_attr "predicable" "yes,no,no")
6370 (set_attr "iscompact" "maybe,false,false")
6371 (set_attr "cond" "canuse,nocond,nocond")])
6373 (define_insn "*add_shift2"
6374 [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6375 (plus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6376 (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r")
6377 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6379 "add%3%?\\t%0,%1,%2"
6380 [(set_attr "length" "*,4,8")
6381 (set_attr "predicable" "yes,no,no")
6382 (set_attr "iscompact" "maybe,false,false")
6383 (set_attr "cond" "canuse,nocond,nocond")])
6385 (define_insn "*sub_shift"
6386 [(set (match_operand:SI 0"register_operand" "=r,r,r")
6387 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6388 (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
6389 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6392 [(set_attr "length" "4,4,8")
6393 (set_attr "cond" "canuse,nocond,nocond")
6394 (set_attr "predicable" "yes,no,no")])
6396 (define_insn "*sub_shift_cmp0_noout"
6397 [(set (match_operand 0 "cc_set_register" "")
6399 (minus:SI (match_operand:SI 1 "register_operand" "r")
6400 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6401 (match_operand:SI 3 "_1_2_3_operand" "")))
6405 [(set_attr "length" "4")])
6407 (define_insn "*compare_si_ashiftsi"
6408 [(set (match_operand 0 "cc_set_register" "")
6409 (compare:CC (match_operand:SI 1 "register_operand" "r")
6410 (ashift:SI (match_operand:SI 2 "register_operand" "r")
6411 (match_operand:SI 3 "_1_2_3_operand" ""))))]
6414 [(set_attr "length" "4")])
6416 ;; Convert the sequence
6420 ;; sub{123}.f 0,ra,rn
6422 [(set (match_operand:SI 0 "register_operand" "")
6423 (ashift:SI (match_operand:SI 1 "register_operand" "")
6424 (match_operand:SI 2 "_1_2_3_operand" "")))
6425 (set (reg:CC CC_REG)
6426 (compare:CC (match_operand:SI 3 "register_operand" "")
6428 "peep2_reg_dead_p (2, operands[0])"
6429 [(set (reg:CC CC_REG) (compare:CC (match_dup 3)
6430 (ashift:SI (match_dup 1) (match_dup 2))))])
6432 (define_peephole2 ; std
6433 [(set (match_operand:SI 2 "memory_operand" "")
6434 (match_operand:SI 0 "register_operand" ""))
6435 (set (match_operand:SI 3 "memory_operand" "")
6436 (match_operand:SI 1 "register_operand" ""))]
6440 if (!gen_operands_ldd_std (operands, false, false))
6442 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6443 operands[2] = adjust_address (operands[2], DImode, 0);
6444 emit_insn (gen_rtx_SET (operands[2], operands[0]));
6448 (define_peephole2 ; ldd
6449 [(set (match_operand:SI 0 "register_operand" "")
6450 (match_operand:SI 2 "memory_operand" ""))
6451 (set (match_operand:SI 1 "register_operand" "")
6452 (match_operand:SI 3 "memory_operand" ""))]
6456 if (!gen_operands_ldd_std (operands, true, false))
6458 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6459 operands[2] = adjust_address (operands[2], DImode, 0);
6460 emit_insn (gen_rtx_SET (operands[0], operands[2]));
6464 ;; We require consecutive registers for LDD instruction. Check if we
6465 ;; can reorder them and use an LDD.
6467 (define_peephole2 ; swap the destination registers of two loads
6468 ; before a commutative operation.
6469 [(set (match_operand:SI 0 "register_operand" "")
6470 (match_operand:SI 2 "memory_operand" ""))
6471 (set (match_operand:SI 1 "register_operand" "")
6472 (match_operand:SI 3 "memory_operand" ""))
6473 (set (match_operand:SI 4 "register_operand" "")
6474 (match_operator:SI 5 "commutative_operator"
6475 [(match_operand 6 "register_operand" "")
6476 (match_operand 7 "register_operand" "") ]))]
6478 && (((rtx_equal_p (operands[0], operands[6]))
6479 && (rtx_equal_p (operands[1], operands[7])))
6480 || ((rtx_equal_p (operands[0], operands[7]))
6481 && (rtx_equal_p (operands[1], operands[6]))))
6482 && (peep2_reg_dead_p (3, operands[0])
6483 || rtx_equal_p (operands[0], operands[4]))
6484 && (peep2_reg_dead_p (3, operands[1])
6485 || rtx_equal_p (operands[1], operands[4]))"
6486 [(set (match_dup 0) (match_dup 2))
6487 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]
6489 if (!gen_operands_ldd_std (operands, true, true))
6495 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6496 operands[2] = adjust_address (operands[2], DImode, 0);
6501 (define_insn "*push_multi_fp"
6502 [(match_parallel 0 "push_multi_operand"
6503 [(set (reg:SI SP_REG)
6504 (plus:SI (reg:SI SP_REG)
6505 (match_operand 1 "immediate_operand" "")))
6506 (set (mem:SI (plus:SI (reg:SI SP_REG)
6507 (match_operand 2 "immediate_operand"
6510 "TARGET_CODE_DENSITY"
6512 int len = XVECLEN (operands[0], 0);
6513 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6514 if (MEM_P (XEXP (tmp, 0)))
6516 operands[3] = XEXP (tmp, 1);
6517 return "enter_s\\t{r13-%3} ; sp=sp+(%1)";
6521 tmp = XVECEXP (operands[0], 0, len - 3);
6522 operands[3] = XEXP (tmp, 1);
6523 return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)";
6526 [(set_attr "type" "call_no_delay_slot")
6527 (set_attr "length" "2")])
6529 (define_insn "*push_multi_fp_blink"
6530 [(match_parallel 0 "push_multi_operand"
6531 [(set (reg:SI SP_REG)
6532 (plus:SI (reg:SI SP_REG)
6533 (match_operand 1 "immediate_operand" "")))
6534 (set (mem:SI (plus:SI (reg:SI SP_REG)
6535 (match_operand 2 "immediate_operand"
6537 (reg:SI RETURN_ADDR_REGNUM))])]
6538 "TARGET_CODE_DENSITY"
6540 int len = XVECLEN (operands[0], 0);
6541 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6542 if (MEM_P (XEXP (tmp, 0)))
6544 operands[3] = XEXP (tmp, 1);
6545 return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)";
6549 tmp = XVECEXP (operands[0], 0, len - 3);
6550 operands[3] = XEXP (tmp, 1);
6551 return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)";
6554 [(set_attr "type" "call_no_delay_slot")
6555 (set_attr "length" "2")])
6557 (define_insn "*pop_multi_fp"
6558 [(match_parallel 0 "pop_multi_operand"
6559 [(set (reg:SI SP_REG)
6560 (plus:SI (reg:SI SP_REG)
6561 (match_operand 1 "immediate_operand" "")))
6566 (match_operand 2 "immediate_operand" ""))))])]
6567 "TARGET_CODE_DENSITY"
6569 int len = XVECLEN (operands[0], 0);
6570 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6571 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6573 operands[3] = XEXP (tmp, 0);
6574 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6575 return "leave_s\\t{r13-%3} ; sp=sp+%1";
6579 tmp = XVECEXP (operands[0], 0, len - 2);
6580 operands[3] = XEXP (tmp, 0);
6581 return "leave_s\\t{r13-%3, fp} ; sp=sp+%1";
6584 [(set_attr "type" "call_no_delay_slot")
6585 (set_attr "length" "2")])
6587 (define_insn "*pop_multi_fp_blink"
6588 [(match_parallel 0 "pop_multi_operand"
6589 [(set (reg:SI SP_REG)
6590 (plus:SI (reg:SI SP_REG)
6591 (match_operand 1 "immediate_operand" "")))
6592 (set (reg:SI RETURN_ADDR_REGNUM)
6596 (match_operand 2 "immediate_operand" ""))))])]
6597 "TARGET_CODE_DENSITY"
6599 int len = XVECLEN (operands[0], 0);
6600 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6601 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6603 operands[3] = XEXP (tmp, 0);
6604 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6605 return "leave_s\\t{r13-%3, blink} ; sp=sp+%1";
6609 tmp = XVECEXP (operands[0], 0, len - 2);
6610 operands[3] = XEXP (tmp, 0);
6611 return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1";
6614 [(set_attr "type" "call_no_delay_slot")
6615 (set_attr "length" "2")])
6617 (define_insn "*pop_multi_fp_ret"
6618 [(match_parallel 0 "pop_multi_operand"
6620 (set (reg:SI SP_REG)
6621 (plus:SI (reg:SI SP_REG)
6622 (match_operand 1 "immediate_operand" "")))
6627 (match_operand 2 "immediate_operand" ""))))])]
6628 "TARGET_CODE_DENSITY"
6630 int len = XVECLEN (operands[0], 0);
6631 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6632 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6634 operands[3] = XEXP (tmp, 0);
6635 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6636 return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1";
6640 tmp = XVECEXP (operands[0], 0, len - 2);
6641 operands[3] = XEXP (tmp, 0);
6642 return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1";
6645 [(set_attr "type" "call_no_delay_slot")
6646 (set_attr "length" "2")])
6648 (define_insn "*pop_multi_fp_blink_ret"
6649 [(match_parallel 0 "pop_multi_operand"
6651 (set (reg:SI SP_REG)
6652 (plus:SI (reg:SI SP_REG)
6653 (match_operand 1 "immediate_operand" "")))
6654 (set (reg:SI RETURN_ADDR_REGNUM)
6658 (match_operand 2 "immediate_operand" ""))))])]
6659 "TARGET_CODE_DENSITY"
6661 int len = XVECLEN (operands[0], 0);
6662 rtx tmp = XVECEXP (operands[0], 0, len - 1);
6663 if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6665 operands[3] = XEXP (tmp, 0);
6666 gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6667 return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1";
6671 tmp = XVECEXP (operands[0], 0, len - 2);
6672 operands[3] = XEXP (tmp, 0);
6673 return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1";
6676 [(set_attr "type" "call_no_delay_slot")
6677 (set_attr "length" "2")])
6679 ;; Patterns for exception handling
6680 (define_insn_and_split "eh_return"
6681 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6682 VUNSPEC_ARC_EH_RETURN)]
6689 arc_eh_return_address_location (operands[0]);
6692 [(set_attr "length" "8")]
6695 ;; include the arc-FPX instructions
6698 ;; include the arc-FPU instructions
6701 (include "simdext.md")
6703 ;; include atomic extensions
6704 (include "atomic.md")