1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2018 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"))
88 (include ("predicates.md"))
89 (include ("constraints.md"))
90 ;; -----------------------------------------------------------------------------
94 ;; -----------------------------------------------------------------------------
95 ;; Symbolic name Value Desc.
96 ;; -----------------------------------------------------------------------------
97 ;; UNSPEC_PLT 3 symbol to be referenced through the PLT
98 ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT
99 ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the
100 ;; GOTBASE.(Referenced as @GOTOFF)
101 ;; UNSPEC_GOTOFFPC 6 Local symbol. To be referenced pc-relative.
102 ;; ----------------------------------------------------------------------------
104 (define_c_enum "unspec" [
141 (define_c_enum "vunspec" [
148 VUNSPEC_ARC_CORE_READ
149 VUNSPEC_ARC_CORE_WRITE
158 VUNSPEC_ARC_STACK_IRQ
160 VUNSPEC_ARC_DEXCL_NORES
178 (RETURN_ADDR_REGNUM 31)
190 (define_attr "is_sfunc" "no,yes" (const_string "no"))
192 ;; Insn type. Used to default other attribute values.
193 ; While the attribute is_sfunc is set for any call of a special function,
194 ; the instruction type sfunc is used only for the special call sequence
195 ; that loads the (pc-relative) function address into r12 and then calls
199 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
200 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
201 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
202 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
203 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
204 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
205 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
206 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
207 simd_valign, simd_valign_with_acc, simd_vcontrol,
208 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
210 (cond [(eq_attr "is_sfunc" "yes")
211 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
212 (match_test "flag_pic") (const_string "sfunc")]
213 (const_string "call_no_delay_slot"))]
214 (const_string "binary")))
216 ;; The following three attributes are mixed case so that they can be
217 ;; used conveniently with the CALL_ATTR macro.
218 (define_attr "is_CALL" "no,yes"
219 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
220 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
221 (const_string "no")))
223 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
225 (define_attr "is_NON_SIBCALL" "no,yes"
226 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
227 (eq_attr "is_CALL" "yes") (const_string "yes")]
228 (const_string "no")))
230 ;; true for compact instructions (those with _s suffix)
231 ;; "maybe" means compact unless we conditionalize the insn.
232 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
233 (cond [(eq_attr "type" "sfunc")
234 (const_string "maybe")]
235 (const_string "false")))
238 ; Is there an instruction that we are actually putting into the delay slot?
239 (define_attr "delay_slot_filled" "no,yes"
240 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
242 (match_test "!TARGET_AT_DBR_CONDEXEC
244 && INSN_ANNULLED_BRANCH_P (insn)
245 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
247 (const_string "yes")))
249 ; Is a delay slot present for purposes of shorten_branches?
250 ; We have to take the length of this insn into account for forward branches
251 ; even if we don't put the insn actually into a delay slot.
252 (define_attr "delay_slot_present" "no,yes"
253 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
255 (const_string "yes")))
257 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
258 ; length of a different insn with the same uid.
259 (define_attr "delay_slot_length" ""
260 (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
262 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
263 - get_attr_length (insn)")))
265 ; for ARCv2 we need to disable/enable different instruction alternatives
266 (define_attr "cpu_facility" "std,av1,av2,fpx,cd"
267 (const_string "std"))
269 ; We should consider all the instructions enabled until otherwise
270 (define_attr "enabled" "no,yes"
271 (cond [(and (eq_attr "cpu_facility" "av1")
272 (match_test "TARGET_V2"))
275 (and (eq_attr "cpu_facility" "av2")
276 (not (match_test "TARGET_V2")))
279 (and (eq_attr "cpu_facility" "fpx")
280 (match_test "TARGET_FP_DP_AX"))
283 (and (eq_attr "cpu_facility" "cd")
284 (not (and (match_test "TARGET_V2")
285 (match_test "TARGET_CODE_DENSITY"))))
288 (const_string "yes")))
290 (define_attr "predicable" "no,yes" (const_string "no"))
291 ;; if 'predicable' were not so brain-dead, we would specify:
292 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
293 ;; (eq_attr "iscompact" "maybe") (const_string "no")]
294 ;; (const_string "yes"))
295 ;; and then for everything but calls, we could just set the cond attribute.
297 ;; Condition codes: this one is used by final_prescan_insn to speed up
298 ;; conditionalizing instructions. It saves having to scan the rtl to see if
299 ;; it uses or alters the condition codes.
301 ;; USE: This insn uses the condition codes (eg: a conditional branch).
302 ;; CANUSE: This insn can use the condition codes (for conditional execution).
303 ;; SET: All condition codes are set by this insn.
304 ;; SET_ZN: the Z and N flags are set by this insn.
305 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
306 ;; CLOB: The condition codes are set to unknown values by this insn.
307 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
309 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
311 [(and (eq_attr "predicable" "yes")
312 (eq_attr "is_sfunc" "no")
313 (eq_attr "delay_slot_filled" "no"))
314 (const_string "canuse")
316 (eq_attr "type" "call")
317 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
318 (match_test "!flag_pic") (const_string "canuse_limm")]
319 (const_string "nocond"))
321 (eq_attr "iscompact" "maybe,false")
322 (cond [ (and (eq_attr "type" "move")
323 (match_operand 1 "immediate_operand" ""))
325 (ior (match_operand 1 "u6_immediate_operand" "")
326 (match_operand 1 "long_immediate_operand" ""))
327 (const_string "canuse")
328 (const_string "canuse_limm"))
330 (eq_attr "type" "binary")
331 (cond [(ne (symbol_ref "REGNO (operands[0])")
332 (symbol_ref "REGNO (operands[1])"))
333 (const_string "nocond")
334 (match_operand 2 "register_operand" "")
335 (const_string "canuse")
336 (match_operand 2 "u6_immediate_operand" "")
337 (const_string "canuse")
338 (match_operand 2 "long_immediate_operand" "")
339 (const_string "canuse")
340 (match_operand 2 "const_int_operand" "")
341 (const_string "canuse_limm")]
342 (const_string "nocond"))
344 (eq_attr "type" "compare")
347 (eq_attr "type" "cmove,branch")
350 (eq_attr "is_sfunc" "yes")
351 (cond [(match_test "(TARGET_MEDIUM_CALLS
352 && !TARGET_LONG_CALLS_SET
354 (const_string "canuse_limm_add")
355 (match_test "(TARGET_MEDIUM_CALLS
356 && !TARGET_LONG_CALLS_SET)")
357 (const_string "canuse_limm")]
358 (const_string "canuse"))
362 (const_string "nocond"))]
364 (cond [(eq_attr "type" "compare")
367 (eq_attr "type" "cmove,branch")
372 (const_string "nocond"))))
374 /* ??? Having all these patterns gives ifcvt more freedom to generate
375 inefficient code. It seem to operate on the premise that
376 register-register copies and registers are free. I see better code
377 with -fno-if-convert now than without. */
379 [(match_operator 0 "proper_comparison_operator"
380 [(reg CC_REG) (const_int 0)])]
384 ;; Length (in # of bytes, long immediate constants counted too).
385 ;; ??? There's a nasty interaction between the conditional execution fsm
386 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
387 (define_attr "length" ""
389 [(eq_attr "iscompact" "true,maybe")
391 [(eq_attr "type" "sfunc")
392 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
395 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)]
398 (eq_attr "iscompact" "true_limm")
401 (eq_attr "iscompact" "maybe_limm")
402 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
405 (eq_attr "type" "load")
407 (match_operand 1 "long_immediate_loadstore_operand" "")
408 (const_int 8) (const_int 4))
410 (eq_attr "type" "store")
412 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
413 (match_operand 1 "immediate_operand" ""))
414 (const_int 8) (const_int 4))
416 (eq_attr "type" "move,unary")
418 [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
419 (match_operand 1 "register_operand" "") (const_int 4)
420 (match_operand 1 "long_immediate_operand" "") (const_int 8)
421 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
424 (and (eq_attr "type" "shift")
425 (match_operand 1 "immediate_operand"))
427 (eq_attr "type" "binary,shift")
429 (ior (match_operand 2 "long_immediate_operand" "")
430 (and (ne (symbol_ref "REGNO (operands[0])")
431 (symbol_ref "REGNO (operands[1])"))
432 (eq (match_operand 2 "u6_immediate_operand" "")
435 (const_int 8) (const_int 4))
437 (eq_attr "type" "cmove")
438 (if_then_else (match_operand 1 "register_operand" "")
439 (const_int 4) (const_int 8))
441 (eq_attr "type" "call_no_delay_slot") (const_int 8)
447 ;; The length here is the length of a single asm. Unfortunately it might be
448 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
449 ;; lament asm's not being put in delay slots?
451 (define_asm_attributes
452 [(set_attr "length" "8")
453 (set_attr "type" "multi")
454 (set_attr "cond" "clob") ])
457 ;; The first two cond clauses and the default are necessary for correctness;
458 ;; the remaining cond clause is mainly an optimization, as otherwise nops
459 ;; would be inserted; however, if we didn't do this optimization, we would
460 ;; have to be more conservative in our length calculations.
462 (define_attr "in_delay_slot" "false,true"
463 (cond [(eq_attr "type" "uncond_branch,jump,branch,
464 call,sfunc,call_no_delay_slot,
465 brcc, brcc_no_delay_slot,loop_setup,loop_end")
466 (const_string "false")
467 (match_test "arc_write_ext_corereg (insn)")
468 (const_string "false")
469 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
470 next_active_insn (insn))")
471 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
472 + arc_hazard (insn, next_active_insn (insn)))"))
473 (const_string "false")
474 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
475 (const_string "false")
476 (eq_attr "iscompact" "maybe") (const_string "true")
479 (if_then_else (eq_attr "length" "2,4")
480 (const_string "true")
481 (const_string "false"))))
483 ; must not put an insn inside that refers to blink.
484 (define_attr "in_call_delay_slot" "false,true"
485 (cond [(eq_attr "in_delay_slot" "false")
486 (const_string "false")
487 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
488 (const_string "false")]
489 (const_string "true")))
491 (define_attr "in_sfunc_delay_slot" "false,true"
492 (cond [(eq_attr "in_call_delay_slot" "false")
493 (const_string "false")
494 (match_test "arc_regno_use_in (12, PATTERN (insn))")
495 (const_string "false")]
496 (const_string "true")))
498 ;; Instructions that we can put into a delay slot and conditionalize.
499 (define_attr "cond_delay_insn" "no,yes"
500 (cond [(eq_attr "cond" "!canuse") (const_string "no")
501 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
503 (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
505 (eq_attr "length" "2,4") (const_string "yes")]
506 (const_string "no")))
508 (define_attr "in_ret_delay_slot" "no,yes"
509 (cond [(eq_attr "in_delay_slot" "false")
511 (match_test "regno_clobbered_p
512 (arc_return_address_register
513 (arc_compute_function_type (cfun)),
516 (const_string "yes")))
518 (define_attr "cond_ret_delay_insn" "no,yes"
519 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
520 (eq_attr "cond_delay_insn" "no") (const_string "no")]
521 (const_string "yes")))
523 (define_attr "annul_ret_delay_insn" "no,yes"
524 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
525 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
526 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
527 (const_string "yes")]
528 (const_string "no")))
531 ;; Delay slot definition for ARCompact ISA
533 ;; When outputting an annul-true insn elegible for cond-exec
534 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
535 ;; for ARC600; we could also use this for ARC700 if the branch can't be
536 ;; unaligned and is at least somewhat likely (add parameter for this).
538 (define_delay (eq_attr "type" "call")
539 [(eq_attr "in_call_delay_slot" "true")
540 (eq_attr "in_call_delay_slot" "true")
543 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
544 (eq_attr "type" "brcc"))
545 [(eq_attr "in_delay_slot" "true")
546 (eq_attr "in_delay_slot" "true")
549 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
550 (eq_attr "type" "brcc"))
551 [(eq_attr "in_delay_slot" "true")
556 (eq_attr "type" "return")
557 [(eq_attr "in_ret_delay_slot" "yes")
558 (eq_attr "annul_ret_delay_insn" "yes")
559 (eq_attr "cond_ret_delay_insn" "yes")])
561 (define_delay (eq_attr "type" "loop_end")
562 [(eq_attr "in_delay_slot" "true")
563 (eq_attr "in_delay_slot" "true")
566 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
567 ;; non-taken case, so the only meaningful way to have an annull-true
568 ;; filled delay slot is to conditionalize the delay slot insn.
569 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
570 (eq_attr "type" "branch,uncond_branch,jump")
571 (match_test "!optimize_size"))
572 [(eq_attr "in_delay_slot" "true")
573 (eq_attr "cond_delay_insn" "yes")
574 (eq_attr "cond_delay_insn" "yes")])
576 ;; For ARC700, anything goes for annulled-true insns, since there is no
577 ;; penalty for the unexposed delay slot when the branch is not taken,
578 ;; however, we must avoid things that have a delay slot themselvese to
579 ;; avoid confusing gcc.
580 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
581 (eq_attr "type" "branch,uncond_branch,jump")
582 (match_test "!optimize_size"))
583 [(eq_attr "in_delay_slot" "true")
584 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
585 (eq_attr "cond_delay_insn" "yes")])
587 ;; -mlongcall -fpic sfuncs use r12 to load the function address
588 (define_delay (eq_attr "type" "sfunc")
589 [(eq_attr "in_sfunc_delay_slot" "true")
590 (eq_attr "in_sfunc_delay_slot" "true")
592 ;; ??? need to use a working strategy for canuse_limm:
593 ;; - either canuse_limm is not eligible for delay slots, and has no
594 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
595 ;; somehow modify them to become inelegible for delay slots if a decision
596 ;; is made that makes conditional execution required.
598 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
600 (cond [(symbol_ref "arc_tune == TUNE_ARC600")
601 (const_string "arc600")
602 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
603 (const_string "arc700_4_2_std")
604 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
605 (const_string "arc700_4_2_xmac")]
606 (const_string "none"))))
608 (define_attr "tune_arc700" "false,true"
609 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
610 (const_string "true")
611 (const_string "false")))
613 ;; Move instructions.
614 (define_expand "movqi"
615 [(set (match_operand:QI 0 "move_dest_operand" "")
616 (match_operand:QI 1 "general_operand" ""))]
618 "if (prepare_move_operands (operands, QImode)) DONE;")
620 ; In order to allow the ccfsm machinery to do its work, the leading compact
621 ; alternatives say 'canuse' - there is another alternative that will match
622 ; when the condition codes are used.
623 ; Rcq won't match if the condition is actually used; to avoid a spurious match
624 ; via q, q is inactivated as constraint there.
625 ; Likewise, the length of an alternative that might be shifted to conditional
626 ; execution must reflect this, lest out-of-range branches are created.
627 ; The iscompact attribute allows the epilogue expander to know for which
628 ; insns it should lengthen the return insn.
629 (define_insn "*movqi_insn"
630 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l,???w,h,w*l,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc")
631 (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,?Rac,i, ?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
632 "register_operand (operands[0], QImode)
633 || register_operand (operands[1], QImode)"
655 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
656 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
657 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
658 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
660 (define_expand "movhi"
661 [(set (match_operand:HI 0 "move_dest_operand" "")
662 (match_operand:HI 1 "general_operand" ""))]
664 "if (prepare_move_operands (operands, HImode)) DONE;")
666 (define_insn "*movhi_insn"
667 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l,???w,Rcq#q,h,w*l,Rcq, S, r,r, Ucm,m,???m, m,VUsc")
668 (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,?Rac, i,i, ?i, T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
669 "register_operand (operands[0], HImode)
670 || register_operand (operands[1], HImode)
671 || (CONSTANT_P (operands[1])
672 /* Don't use a LIMM that we could load with a single insn - we loose
673 delay-slot filling opportunities. */
674 && !satisfies_constraint_I (operands[1])
675 && satisfies_constraint_Usc (operands[0]))"
697 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
698 (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")
699 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
700 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
702 (define_expand "movsi"
703 [(set (match_operand:SI 0 "move_dest_operand" "")
704 (match_operand:SI 1 "general_operand" ""))]
706 "if (prepare_move_operands (operands, SImode)) DONE;")
708 ; In order to allow the ccfsm machinery to do its work, the leading compact
709 ; alternatives say 'canuse' - there is another alternative that will match
710 ; when the condition codes are used.
711 ; Rcq won't match if the condition is actually used; to avoid a spurious match
712 ; via q, q is inactivated as constraint there.
713 ; Likewise, the length of an alternative that might be shifted to conditional
714 ; execution must reflect this, lest out-of-range branches are created.
715 ; the iscompact attribute allows the epilogue expander to know for which
716 ; insns it should lengthen the return insn.
717 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
718 (define_insn "*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 29 30 31
719 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h,w*l,w*l, w, w, w, w, ???w, ?w, w,Rcq#q, h, w*l,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m, m,VUsc")
720 (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1, cL, I,Crr,Clo,Chi,Cbi,?Rac*l,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac,Cm3, C32"))]
721 "register_operand (operands[0], SImode)
722 || register_operand (operands[1], SImode)
723 || (CONSTANT_P (operands[1])
724 /* Don't use a LIMM that we could load with a single insn - we loose
725 delay-slot filling opportunities. */
726 && !satisfies_constraint_I (operands[1])
727 && satisfies_constraint_Usc (operands[0]))"
736 ror %0,((%1*2+1) & 0x3f) ;7
738 movh.cl %0,%L1>>16 ;9
739 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
742 add %0,pcl,%1@pcl ;13
748 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
749 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
761 ; 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 29 30 31
762 [(set_attr "type" "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary, move, move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store")
763 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false, false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false,false")
764 ; Use default length for iscompact to allow for COND_EXEC. But set length
766 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8")
767 (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
768 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
770 ;; Sometimes generated by the epilogue code. We don't want to
771 ;; recognize these addresses in general, because the limm is costly,
772 ;; and we can't use them for stores. */
773 (define_insn "*movsi_pre_mod"
774 [(set (match_operand:SI 0 "register_operand" "=w")
777 (plus:SI (reg:SI SP_REG)
778 (match_operand 1 "immediate_operand" "Cal")))))]
781 [(set_attr "type" "load")
782 (set_attr "length" "8")])
784 ;; Store a value to directly to memory. The location might also be cached.
785 ;; Since the cached copy can cause a write-back at unpredictable times,
786 ;; we first write cached, then we write uncached.
787 (define_insn "store_direct"
788 [(set (match_operand:SI 0 "move_dest_operand" "=m")
789 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
792 "st%U0 %1,%0\;st%U0.di %1,%0"
793 [(set_attr "type" "store")])
795 (define_insn_and_split "*movsi_set_cc_insn"
796 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
797 (match_operator:CC_ZN 3 "zn_compare_operator"
798 [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
799 (set (match_operand:SI 0 "register_operand" "=w,w,w")
803 ; splitting to 'tst' allows short insns and combination into brcc.
804 "reload_completed && operands_match_p (operands[0], operands[1])"
805 [(set (match_dup 2) (match_dup 3))]
807 [(set_attr "type" "compare")
808 (set_attr "predicable" "no,yes,yes")
809 (set_attr "cond" "set_zn")
810 (set_attr "length" "4,4,8")])
812 (define_insn "unary_comparison"
813 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
814 (match_operator:CC_ZN 3 "zn_compare_operator"
815 [(match_operator:SI 2 "unary_operator"
816 [(match_operand:SI 1 "register_operand" "c")])
820 [(set_attr "type" "compare")
821 (set_attr "cond" "set_zn")])
824 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
825 (define_insn "*unary_comparison_result_used"
826 [(set (match_operand 2 "cc_register" "")
827 (match_operator 4 "zn_compare_operator"
828 [(match_operator:SI 3 "unary_operator"
829 [(match_operand:SI 1 "register_operand" "c")])
831 (set (match_operand:SI 0 "register_operand" "=w")
835 [(set_attr "type" "compare")
836 (set_attr "cond" "set_zn")
837 (set_attr "length" "4")])
839 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
840 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
841 ; even if we don't need the clobber.
842 (define_insn_and_split "*tst_movb"
844 (match_operand 0 "cc_register" "")
845 (match_operator 4 "zn_compare_operator"
847 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c")
848 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
850 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
852 "movb.f.cl %3,%1,%p2,%p2,%s2"
853 "TARGET_NPS_BITOPS && reload_completed
854 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
855 [(set (match_dup 0) (match_dup 4))])
859 (match_operand 0 "cc_register" "")
860 (match_operator 3 "zn_compare_operator"
862 (match_operand:SI 1 "register_operand"
863 "%Rcq,Rcq, c, c, c, c, c, c")
864 (match_operand:SI 2 "nonmemory_operand"
865 " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
868 || !satisfies_constraint_Cbf (operands[2])
869 || satisfies_constraint_C0p (operands[2])
870 || satisfies_constraint_I (operands[2])
871 || satisfies_constraint_C1p (operands[2])
872 || satisfies_constraint_Chs (operands[2])"
874 switch (which_alternative)
876 case 0: case 2: case 3: case 7:
877 return \"tst%? %1,%2\";
879 return \"btst%? %1,%z2\";
881 return \"bmsk%?.f 0,%1,%Z2%&\";
883 return \"bclr%?.f 0,%1,%M2%&\";
885 return \"asr.f 0,%1,%p2\";
890 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
891 (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
892 (set_attr "length" "*,*,4,4,4,4,4,8")
893 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
894 (set_attr "cond" "set_zn")])
896 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
897 ; combine will do that and not try the AND.
899 ; It would take 66 constraint combinations to describe the zero_extract
900 ; constants that are covered by the 12-bit signed constant for tst
901 ; (excluding the ones that are better done by mov or btst).
902 ; so we rather use an extra pattern for tst;
903 ; since this is about constants, reload shouldn't care.
904 (define_insn "*tst_bitfield_tst"
905 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
906 (match_operator 4 "zn_compare_operator"
908 (match_operand:SI 1 "register_operand" "c")
909 (match_operand:SI 2 "const_int_operand" "n")
910 (match_operand:SI 3 "const_int_operand" "n"))
912 "INTVAL (operands[2]) > 1
913 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
914 || (INTVAL (operands[3]) <= 11
915 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
916 "tst %1,((1<<%2)-1)<<%3"
917 [(set_attr "type" "compare")
918 (set_attr "cond" "set_zn")
919 (set_attr "length" "4")])
921 ; Likewise for asr.f.
922 (define_insn "*tst_bitfield_asr"
923 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
924 (match_operator 4 "zn_compare_operator"
926 (match_operand:SI 1 "register_operand" "c")
927 (match_operand:SI 2 "const_int_operand" "n")
928 (match_operand:SI 3 "const_int_operand" "n"))
930 "INTVAL (operands[2]) > 1
931 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
933 [(set_attr "type" "shift")
934 (set_attr "cond" "set_zn")
935 (set_attr "length" "4")])
937 (define_insn "*tst_bitfield"
938 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
939 (match_operator 5 "zn_compare_operator"
941 (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c")
942 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
943 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
945 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
951 movb.f.cl %4,%1,%3,%3,%2
952 and.f 0,%1,((1<<%2)-1)<<%3"
953 [(set_attr "iscompact" "maybe,false,false,false,false")
954 (set_attr "type" "compare,compare,compare,shift,compare")
955 (set_attr "cond" "set_zn")
956 (set_attr "length" "*,4,4,4,8")])
958 (define_insn "*commutative_binary_comparison"
959 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
960 (match_operator:CC_ZN 5 "zn_compare_operator"
961 [(match_operator:SI 4 "commutative_operator"
962 [(match_operand:SI 1 "register_operand" "%c,c")
963 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
965 (clobber (match_scratch:SI 3 "=X,X"))]
968 [(set_attr "type" "compare")
969 (set_attr "cond" "set_zn")
970 (set_attr "length" "4,8")])
972 ; for flag setting 'add' instructions like if (a+b) { ...}
973 ; the combiner needs this pattern
974 (define_insn "*addsi_compare"
975 [(set (reg:CC_ZN CC_REG)
976 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
977 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
980 [(set_attr "cond" "set")
981 (set_attr "type" "compare")
982 (set_attr "length" "4")])
984 ; for flag setting 'add' instructions like if (a+b < a) { ...}
985 ; the combiner needs this pattern
986 (define_insn "addsi_compare_2"
987 [(set (reg:CC_C CC_REG)
988 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
989 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
993 [(set_attr "cond" "set")
994 (set_attr "type" "compare")
995 (set_attr "length" "4,8")])
997 (define_insn "*addsi_compare_3"
998 [(set (reg:CC_C CC_REG)
999 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
1000 (match_operand:SI 1 "register_operand" "c"))
1004 [(set_attr "cond" "set")
1005 (set_attr "type" "compare")
1006 (set_attr "length" "4")])
1008 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1009 (define_insn "*commutative_binary_comparison_result_used"
1010 [(set (match_operand 3 "cc_register" "")
1011 (match_operator 5 "zn_compare_operator"
1012 ; We can accept any commutative operator except mult because
1013 ; our 'w' class below could try to use LP_COUNT.
1014 [(match_operator:SI 4 "commutative_operator_sans_mult"
1015 [(match_operand:SI 1 "register_operand" "c,0,c")
1016 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1018 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1021 "%O4.f %0,%1,%2 ; non-mult commutative"
1022 [(set_attr "type" "compare,compare,compare")
1023 (set_attr "cond" "set_zn,set_zn,set_zn")
1024 (set_attr "length" "4,4,8")])
1026 ; a MULT-specific version of this pattern to avoid touching the
1028 (define_insn "*commutative_binary_mult_comparison_result_used"
1029 [(set (match_operand 3 "cc_register" "")
1030 (match_operator 5 "zn_compare_operator"
1031 [(match_operator:SI 4 "mult_operator"
1032 [(match_operand:SI 1 "register_operand" "c,0,c")
1033 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1035 ; Make sure to use the W class to not touch LP_COUNT.
1036 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1038 "!TARGET_ARC600_FAMILY"
1039 "%O4.f %0,%1,%2 ; mult commutative"
1040 [(set_attr "type" "compare,compare,compare")
1041 (set_attr "cond" "set_zn,set_zn,set_zn")
1042 (set_attr "length" "4,4,8")])
1044 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1045 (define_insn "*noncommutative_binary_comparison_result_used"
1046 [(set (match_operand 3 "cc_register" "")
1047 (match_operator 5 "zn_compare_operator"
1048 [(match_operator:SI 4 "noncommutative_operator"
1049 [(match_operand:SI 1 "register_operand" "c,0,c")
1050 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1052 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1054 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1056 [(set_attr "type" "compare,compare,compare")
1057 (set_attr "cond" "set_zn,set_zn,set_zn")
1058 (set_attr "length" "4,4,8")])
1060 (define_insn "*noncommutative_binary_comparison"
1061 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1062 (match_operator:CC_ZN 5 "zn_compare_operator"
1063 [(match_operator:SI 4 "noncommutative_operator"
1064 [(match_operand:SI 1 "register_operand" "c,c")
1065 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
1067 (clobber (match_scratch:SI 3 "=X,X"))]
1068 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1070 [(set_attr "type" "compare")
1071 (set_attr "cond" "set_zn")
1072 (set_attr "length" "4,8")])
1074 (define_expand "bic_f_zn"
1076 [(set (reg:CC_ZN CC_REG)
1078 (and:SI (match_operand:SI 1 "register_operand" "")
1079 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1081 (set (match_operand:SI 0 "register_operand" "")
1082 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1085 (define_insn "*bic_f"
1086 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1087 (match_operator 4 "zn_compare_operator"
1088 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1090 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1092 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1093 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1096 [(set_attr "type" "compare,compare,compare")
1097 (set_attr "cond" "set_zn,set_zn,set_zn")
1098 (set_attr "length" "4,4,8")])
1100 (define_expand "movdi"
1101 [(set (match_operand:DI 0 "move_dest_operand" "")
1102 (match_operand:DI 1 "general_operand" ""))]
1105 if (prepare_move_operands (operands, DImode))
1109 (define_insn_and_split "*movdi_insn"
1110 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m")
1111 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1112 "register_operand (operands[0], DImode)
1113 || register_operand (operands[1], DImode)"
1116 switch (which_alternative)
1123 && ((even_register_operand (operands[0], DImode)
1124 && memory_operand (operands[1], DImode))
1125 || (memory_operand (operands[0], DImode)
1126 && even_register_operand (operands[1], DImode))))
1127 return \"ldd%U1%V1 %0,%1%&\";
1132 && ((even_register_operand (operands[0], DImode)
1133 && memory_operand (operands[1], DImode))
1134 || (memory_operand (operands[0], DImode)
1135 && even_register_operand (operands[1], DImode))))
1136 return \"std%U0%V0 %1,%0\";
1143 arc_split_move (operands);
1146 [(set_attr "type" "move,move,load,store")
1147 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1148 (set_attr "length" "8,16,*,*")])
1151 ;; Floating point move insns.
1153 (define_expand "movsf"
1154 [(set (match_operand:SF 0 "move_dest_operand" "")
1155 (match_operand:SF 1 "general_operand" ""))]
1157 "if (prepare_move_operands (operands, SFmode)) DONE;")
1159 (define_insn "*movsf_insn"
1160 [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m")
1161 (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))]
1162 "register_operand (operands[0], SFmode)
1163 || register_operand (operands[1], SFmode)"
1170 [(set_attr "type" "move,move,move,load,store")
1171 (set_attr "predicable" "no,yes,yes,no,no")
1172 (set_attr "iscompact" "true,false,false,false,false")])
1174 (define_expand "movdf"
1175 [(set (match_operand:DF 0 "move_dest_operand" "")
1176 (match_operand:DF 1 "general_operand" ""))]
1178 "if (prepare_move_operands (operands, DFmode)) DONE;")
1180 (define_insn_and_split "*movdf_insn"
1181 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
1182 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1183 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1186 switch (which_alternative)
1192 && ((even_register_operand (operands[0], DFmode)
1193 && memory_operand (operands[1], DFmode))
1194 || (memory_operand (operands[0], DFmode)
1195 && even_register_operand (operands[1], DFmode))))
1196 return \"ldd%U1%V1 %0,%1%&\";
1201 && ((even_register_operand (operands[0], DFmode)
1202 && memory_operand (operands[1], DFmode))
1203 || (memory_operand (operands[0], DFmode)
1204 && even_register_operand (operands[1], DFmode))))
1205 return \"std%U0%V0 %1,%0\";
1212 arc_split_move (operands);
1215 [(set_attr "type" "move,move,move,move,load,store")
1216 (set_attr "predicable" "no,no,yes,yes,no,no")
1217 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1218 (set_attr "length" "4,16,8,16,16,16")])
1220 (define_insn_and_split "*movdf_insn_nolrsr"
1221 [(set (match_operand:DF 0 "register_operand" "=r")
1222 (match_operand:DF 1 "arc_double_register_operand" "D"))
1223 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1225 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1230 (set (match_dup 0) (match_dup 3))
1232 ; daddh?? r1, r0, r0
1234 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1237 (use (match_dup 0)) ; used to block can_combine_p
1238 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1241 ; We have to do this twice, once to read the value into R0 and
1242 ; second time to put back the contents which the first DEXCLx
1243 ; will have overwritten
1246 (set (match_dup 4) ; aka r0result
1248 (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1250 (clobber (match_dup 1))
1252 ; Generate the second, which makes sure operand5 and operand4 values
1253 ; are put back in the Dx register properly.
1254 (set (match_dup 1) (unspec_volatile:DF
1255 [(match_dup 5) (match_dup 4)]
1256 VUNSPEC_ARC_DEXCL_NORES))
1258 ; Note: we cannot use a (clobber (match_scratch)) here because
1259 ; the combine pass will end up replacing uses of it with 0
1261 "operands[3] = CONST0_RTX (DFmode);
1262 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1263 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1264 [(set_attr "type" "move")])
1266 ;; Load/Store with update instructions.
1268 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1269 ;; hardware can also do cases where the increment is not the size of the
1272 ;; In all these cases, we use operands 0 and 1 for the register being
1273 ;; incremented because those are the operands that local-alloc will
1274 ;; tie and these are the pair most likely to be tieable (and the ones
1275 ;; that will benefit the most).
1277 ;; We use match_operator here because we need to know whether the memory
1278 ;; object is volatile or not.
1281 ;; Note: loadqi_update has no 16-bit variant
1282 (define_insn "*loadqi_update"
1283 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1284 (match_operator:QI 4 "any_mem_operand"
1285 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1286 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1287 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1288 (plus:SI (match_dup 1) (match_dup 2)))]
1290 "ldb.a%V4 %3,[%0,%S2]"
1291 [(set_attr "type" "load,load")
1292 (set_attr "length" "4,8")])
1294 (define_insn "*load_zeroextendqisi_update"
1295 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1296 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1297 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1298 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1299 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1300 (plus:SI (match_dup 1) (match_dup 2)))]
1302 "ldb.a%V4 %3,[%0,%S2]"
1303 [(set_attr "type" "load,load")
1304 (set_attr "length" "4,8")])
1306 (define_insn "*load_signextendqisi_update"
1307 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1308 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1309 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1310 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1311 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1312 (plus:SI (match_dup 1) (match_dup 2)))]
1314 "ldb.x.a%V4 %3,[%0,%S2]"
1315 [(set_attr "type" "load,load")
1316 (set_attr "length" "4,8")])
1318 (define_insn "*storeqi_update"
1319 [(set (match_operator:QI 4 "any_mem_operand"
1320 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1321 (match_operand:SI 2 "short_immediate_operand" "I"))])
1322 (match_operand:QI 3 "register_operand" "c"))
1323 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1324 (plus:SI (match_dup 1) (match_dup 2)))]
1326 "stb.a%V4 %3,[%0,%2]"
1327 [(set_attr "type" "store")
1328 (set_attr "length" "4")])
1330 ;; ??? pattern may have to be re-written
1331 ;; Note: no 16-bit variant for this pattern
1332 (define_insn "*loadhi_update"
1333 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1334 (match_operator:HI 4 "any_mem_operand"
1335 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1336 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1337 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1338 (plus:SI (match_dup 1) (match_dup 2)))]
1340 "ld%_.a%V4 %3,[%0,%S2]"
1341 [(set_attr "type" "load,load")
1342 (set_attr "length" "4,8")])
1344 (define_insn "*load_zeroextendhisi_update"
1345 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1346 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1347 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1348 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1349 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1350 (plus:SI (match_dup 1) (match_dup 2)))]
1352 "ld%_.a%V4 %3,[%0,%S2]"
1353 [(set_attr "type" "load,load")
1354 (set_attr "length" "4,8")])
1356 ;; Note: no 16-bit variant for this instruction
1357 (define_insn "*load_signextendhisi_update"
1358 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1359 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1360 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1361 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1362 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1363 (plus:SI (match_dup 1) (match_dup 2)))]
1365 "ld%_.x.a%V4 %3,[%0,%S2]"
1366 [(set_attr "type" "load,load")
1367 (set_attr "length" "4,8")])
1369 (define_insn "*storehi_update"
1370 [(set (match_operator:HI 4 "any_mem_operand"
1371 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1372 (match_operand:SI 2 "short_immediate_operand" "I"))])
1373 (match_operand:HI 3 "register_operand" "c"))
1374 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1375 (plus:SI (match_dup 1) (match_dup 2)))]
1377 "st%_.a%V4 %3,[%0,%2]"
1378 [(set_attr "type" "store")
1379 (set_attr "length" "4")])
1381 ;; No 16-bit variant for this instruction pattern
1382 (define_insn "*loadsi_update"
1383 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1384 (match_operator:SI 4 "any_mem_operand"
1385 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1386 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1387 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1388 (plus:SI (match_dup 1) (match_dup 2)))]
1390 "ld.a%V4 %3,[%0,%S2]"
1391 [(set_attr "type" "load,load")
1392 (set_attr "length" "4,8")])
1394 (define_insn "*storesi_update"
1395 [(set (match_operator:SI 4 "any_mem_operand"
1396 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1397 (match_operand:SI 2 "short_immediate_operand" "I"))])
1398 (match_operand:SI 3 "register_operand" "c"))
1399 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1400 (plus:SI (match_dup 1) (match_dup 2)))]
1402 "st.a%V4 %3,[%0,%2]"
1403 [(set_attr "type" "store")
1404 (set_attr "length" "4")])
1406 (define_insn "*loadsf_update"
1407 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1408 (match_operator:SF 4 "any_mem_operand"
1409 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1410 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1411 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1412 (plus:SI (match_dup 1) (match_dup 2)))]
1414 "ld.a%V4 %3,[%0,%S2]"
1415 [(set_attr "type" "load,load")
1416 (set_attr "length" "4,8")])
1418 (define_insn "*storesf_update"
1419 [(set (match_operator:SF 4 "any_mem_operand"
1420 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1421 (match_operand:SI 2 "short_immediate_operand" "I"))])
1422 (match_operand:SF 3 "register_operand" "c"))
1423 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1424 (plus:SI (match_dup 1) (match_dup 2)))]
1426 "st.a%V4 %3,[%0,%2]"
1427 [(set_attr "type" "store")
1428 (set_attr "length" "4")])
1430 ;; Conditional move instructions.
1432 (define_expand "movsicc"
1433 [(set (match_operand:SI 0 "dest_reg_operand" "")
1434 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1435 (match_operand:SI 2 "nonmemory_operand" "")
1436 (match_operand:SI 3 "register_operand" "")))]
1438 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1441 (define_expand "movdicc"
1442 [(set (match_operand:DI 0 "dest_reg_operand" "")
1443 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1444 (match_operand:DI 2 "nonmemory_operand" "")
1445 (match_operand:DI 3 "register_operand" "")))]
1447 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1450 (define_expand "movsfcc"
1451 [(set (match_operand:SF 0 "dest_reg_operand" "")
1452 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1453 (match_operand:SF 2 "nonmemory_operand" "")
1454 (match_operand:SF 3 "register_operand" "")))]
1456 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1458 (define_expand "movdfcc"
1459 [(set (match_operand:DF 0 "dest_reg_operand" "")
1460 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1461 (match_operand:DF 2 "nonmemory_operand" "")
1462 (match_operand:DF 3 "register_operand" "")))]
1464 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1466 (define_insn "*movsicc_insn"
1467 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1468 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1469 [(match_operand 4 "cc_register" "") (const_int 0)])
1470 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1471 (match_operand:SI 2 "register_operand" "0,0")))]
1474 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1475 && satisfies_constraint_Rcq (operands[0]))
1476 return "sub%?.ne %0,%0,%0";
1477 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1478 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1479 && rtx_equal_p (operands[1], constm1_rtx)
1480 && GET_CODE (operands[3]) == LTU)
1481 return "sbc.cs %0,%0,%0";
1482 return "mov.%d3 %0,%S1";
1484 [(set_attr "type" "cmove,cmove")
1485 (set_attr "length" "4,8")])
1487 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1488 ;; if the single bit is the sign bit, then GCC likes to convert this
1489 ;; into a sign extend and a compare less than, or greater to zero.
1490 ;; This is usually fine, except for the NXP400 where we have access to
1491 ;; a bit test instruction, along with a special short load instruction
1492 ;; (from CMEM), that doesn't support sign-extension on load.
1494 ;; This peephole optimisation attempts to restore the use of bit-test
1495 ;; in those cases where it is useful to do so.
1497 [(set (match_operand:SI 0 "register_operand" "")
1499 (match_operand:QI 1 "any_mem_operand" "")))
1500 (set (reg:CC_ZN CC_REG)
1501 (compare:CC_ZN (match_dup 0)
1504 (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1505 [(reg:CC_ZN CC_REG) (const_int 0)])
1506 (match_operand 3 "" "")
1507 (match_operand 4 "" "")))]
1509 && cmem_address (XEXP (operands[1], 0), SImode)
1510 && peep2_reg_dead_p (2, operands[0])
1511 && peep2_regno_dead_p (3, CC_REG)"
1515 (set (reg:CC_ZN CC_REG)
1516 (compare:CC_ZN (zero_extract:SI
1522 (if_then_else (match_dup 2)
1525 "if (GET_CODE (operands[2]) == GE)
1526 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1528 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1530 ; Try to generate more short moves, and/or less limms, by substituting a
1531 ; conditional move with a conditional sub.
1533 [(set (match_operand:SI 0 "compact_register_operand")
1534 (match_operand:SI 1 "const_int_operand"))
1536 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1537 [(match_operand 4 "cc_register" "") (const_int 0)])
1538 (match_operand:SI 2 "const_int_operand" "")
1540 "!satisfies_constraint_P (operands[1])
1541 && satisfies_constraint_P (operands[2])
1542 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1543 [(set (match_dup 0) (match_dup 2))
1547 (plus:SI (match_dup 0) (match_dup 1))))]
1548 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1549 GET_MODE (operands[4])),
1550 VOIDmode, operands[4], const0_rtx);
1551 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1553 (define_insn "*movdicc_insn"
1554 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1555 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1556 [(match_operand 4 "cc_register" "") (const_int 0)])
1557 (match_operand:DI 1 "nonmemory_operand" "c,i")
1558 (match_operand:DI 2 "register_operand" "0,0")))]
1562 switch (which_alternative)
1566 /* We normally copy the low-numbered register first. However, if
1567 the first register operand 0 is the same as the second register of
1568 operand 1, we must copy in the opposite order. */
1569 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1570 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1572 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1574 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1579 [(set_attr "type" "cmove,cmove")
1580 (set_attr "length" "8,16")])
1583 (define_insn "*movsfcc_insn"
1584 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1585 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1586 [(match_operand 4 "cc_register" "") (const_int 0)])
1587 (match_operand:SF 1 "nonmemory_operand" "c,E")
1588 (match_operand:SF 2 "register_operand" "0,0")))]
1592 mov.%d3 %0,%1 ; %A1"
1593 [(set_attr "type" "cmove,cmove")])
1595 (define_insn "*movdfcc_insn"
1596 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1597 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1598 [(match_operand 4 "cc_register" "") (const_int 0)])
1599 (match_operand:DF 2 "nonmemory_operand" "c,E")
1600 (match_operand:DF 3 "register_operand" "0,0")))]
1604 switch (which_alternative)
1608 /* We normally copy the low-numbered register first. However, if
1609 the first register operand 0 is the same as the second register of
1610 operand 1, we must copy in the opposite order. */
1611 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1612 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1614 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1616 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1620 [(set_attr "type" "cmove,cmove")
1621 (set_attr "length" "8,16")])
1624 (define_insn "*zero_extendqihi2_i"
1625 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1626 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1635 [(set_attr "type" "unary,unary,unary,unary,load,load")
1636 (set_attr "iscompact" "maybe,true,false,false,false,false")
1637 (set_attr "predicable" "no,no,yes,no,no,no")])
1639 (define_expand "zero_extendqihi2"
1640 [(set (match_operand:HI 0 "dest_reg_operand" "")
1641 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1643 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1646 (define_insn "*zero_extendqisi2_ac"
1647 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1648 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1659 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1660 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1661 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1663 (define_expand "zero_extendqisi2"
1664 [(set (match_operand:SI 0 "dest_reg_operand" "")
1665 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1667 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1670 (define_insn "*zero_extendhisi2_i"
1671 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1672 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))]
1681 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1683 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1684 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1685 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1688 (define_expand "zero_extendhisi2"
1689 [(set (match_operand:SI 0 "dest_reg_operand" "")
1690 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1692 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1695 ;; Sign extension instructions.
1697 (define_insn "*extendqihi2_i"
1698 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1699 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1706 [(set_attr "type" "unary,unary,load,load")
1707 (set_attr "iscompact" "true,false,false,false")
1708 (set_attr "length" "*,*,*,8")])
1711 (define_expand "extendqihi2"
1712 [(set (match_operand:HI 0 "dest_reg_operand" "")
1713 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1715 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1718 (define_insn "*extendqisi2_ac"
1719 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1720 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1727 [(set_attr "type" "unary,unary,load,load")
1728 (set_attr "iscompact" "true,false,false,false")
1729 (set_attr "length" "*,*,*,8")])
1731 (define_expand "extendqisi2"
1732 [(set (match_operand:SI 0 "dest_reg_operand" "")
1733 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1735 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1738 (define_insn "*extendhisi2_i"
1739 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r")
1740 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1748 [(set_attr "type" "unary,unary,load,load,load")
1749 (set_attr "iscompact" "true,false,true,false,false")
1750 (set_attr "length" "*,*,*,4,8")])
1752 (define_expand "extendhisi2"
1753 [(set (match_operand:SI 0 "dest_reg_operand" "")
1754 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1756 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1759 ;; Unary arithmetic insns
1761 ;; We allow constant operands to enable late constant propagation, but it is
1762 ;; not worth while to have more than one dedicated alternative to output them -
1763 ;; if we are really worried about getting these the maximum benefit of all
1764 ;; the available alternatives, we should add an extra pass to fold such
1765 ;; operations to movsi.
1767 ;; Absolute instructions
1769 (define_insn "*abssi2_mixed"
1770 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1771 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1774 [(set_attr "type" "two_cycle_core")
1775 (set_attr "iscompact" "true")])
1777 (define_insn "abssi2"
1778 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1779 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1782 [(set_attr "type" "two_cycle_core")
1783 (set_attr "length" "*,4,8")
1784 (set_attr "iscompact" "true,false,false")])
1786 ;; Maximum and minimum insns
1788 (define_insn "smaxsi3"
1789 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1790 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1791 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1794 [(set_attr "type" "two_cycle_core")
1795 (set_attr "length" "4,4,8")
1796 (set_attr "predicable" "yes,no,no")]
1799 (define_insn "sminsi3"
1800 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1801 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1802 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1805 [(set_attr "type" "two_cycle_core")
1806 (set_attr "length" "4,4,8")
1807 (set_attr "predicable" "yes,no,no")]
1810 ;; Arithmetic instructions.
1812 ; We say an insn can be conditionalized if this doesn't introduce a long
1813 ; immediate. We set the type such that we still have good scheduling if the
1814 ; insn is conditionalized.
1815 ; ??? It would make sense to allow introduction of long immediates, but
1816 ; we'd need to communicate to the ccfsm machinery the extra cost.
1817 ; The alternatives in the constraints still serve three purposes:
1818 ; - estimate insn size assuming conditional execution
1819 ; - guide reload to re-order the second and third operand to get a better fit.
1820 ; - give tentative insn type to guide scheduling
1821 ; N.B. "%" for commutativity doesn't help when there is another matching
1822 ; (but longer) alternative.
1823 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1824 ; register class 'W' instead of 'w'.
1825 (define_insn_and_split "*addsi3_mixed"
1826 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12
1827 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq, h,!*Rsd,Rcq,Rcb,Rcq, Rcqq,Rcqq,Rcw,Rcw, Rcw, W, W,W, W,Rcqq,Rcw, W")
1828 (plus:SI (match_operand:SI 1 "register_operand" "%0, c, 0, Rcqq, 0, 0,Rcb, Rcqq, 0, 0, c, 0, c, c,0, 0, 0, 0, c")
1829 (match_operand:SI 2 "nonmemory_operand" "cL, 0, Cm1, L,CL2,Csp,CM4,RcqqK, cO, cL, 0,cCca,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1832 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1835 "&& reload_completed && get_attr_length (insn) == 8
1836 && satisfies_constraint_I (operands[2])
1837 && GET_CODE (PATTERN (insn)) != COND_EXEC"
1838 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1839 "split_addsi (operands);"
1840 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
1841 (set (attr "iscompact")
1842 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1843 (const_string "false")
1844 (match_operand 2 "long_immediate_operand" "")
1845 (const_string "maybe_limm")]
1846 (const_string "maybe")))
1847 (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
1848 (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
1849 (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1852 ;; ARCv2 MPYW and MPYUW
1853 (define_expand "mulhisi3"
1854 [(set (match_operand:SI 0 "register_operand" "")
1855 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1856 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1859 if (CONSTANT_P (operands[2]))
1861 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1867 (define_insn "mulhisi3_imm"
1868 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
1869 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
1870 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
1873 [(set_attr "length" "4,4,4,8,8")
1874 (set_attr "iscompact" "false")
1875 (set_attr "type" "mul16_em")
1876 (set_attr "predicable" "yes,no,no,yes,no")
1877 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1880 (define_insn "mulhisi3_reg"
1881 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r")
1882 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r"))
1883 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1886 [(set_attr "length" "*,4,4")
1887 (set_attr "iscompact" "maybe,false,false")
1888 (set_attr "type" "mul16_em")
1889 (set_attr "predicable" "yes,yes,no")
1890 (set_attr "cond" "canuse,canuse,nocond")
1893 (define_expand "umulhisi3"
1894 [(set (match_operand:SI 0 "register_operand" "")
1895 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1896 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1899 if (CONSTANT_P (operands[2]))
1901 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1907 (define_insn "umulhisi3_imm"
1908 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
1909 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
1910 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
1913 [(set_attr "length" "4,4,4,8,8")
1914 (set_attr "iscompact" "false")
1915 (set_attr "type" "mul16_em")
1916 (set_attr "predicable" "yes,no,no,yes,no")
1917 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1920 (define_insn "umulhisi3_reg"
1921 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r")
1922 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r"))
1923 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1926 [(set_attr "length" "*,4,4")
1927 (set_attr "iscompact" "maybe,false,false")
1928 (set_attr "type" "mul16_em")
1929 (set_attr "predicable" "yes,yes,no")
1930 (set_attr "cond" "canuse,canuse,nocond")
1933 ;; ARC700/ARC600/V2 multiply
1936 (define_expand "mulsi3"
1937 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1938 (mult:SI (match_operand:SI 1 "register_operand" "")
1939 (match_operand:SI 2 "nonmemory_operand" "")))]
1944 if (!register_operand (operands[0], SImode))
1946 rtx result = gen_reg_rtx (SImode);
1948 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1949 emit_move_insn (operands[0], result);
1953 else if (TARGET_MUL64_SET)
1955 rtx tmp = gen_reg_rtx (SImode);
1956 emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
1957 emit_move_insn (operands[0], tmp);
1960 else if (TARGET_MULMAC_32BY16_SET)
1962 rtx tmp = gen_reg_rtx (SImode);
1963 emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
1964 emit_move_insn (operands[0], tmp);
1969 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1970 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1971 emit_insn (gen_mulsi3_600_lib ());
1972 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1977 (define_insn_and_split "mulsi32x16"
1978 [(set (match_operand:SI 0 "register_operand" "=w")
1979 (mult:SI (match_operand:SI 1 "register_operand" "%c")
1980 (match_operand:SI 2 "nonmemory_operand" "ci")))
1981 (clobber (reg:DI MUL32x16_REG))]
1982 "TARGET_MULMAC_32BY16_SET"
1984 "TARGET_MULMAC_32BY16_SET && reload_completed"
1987 if (immediate_operand (operands[2], SImode)
1988 && INTVAL (operands[2]) >= 0
1989 && INTVAL (operands[2]) <= 65535)
1991 emit_insn (gen_umul_600 (operands[1], operands[2],
1992 gen_acc2 (), gen_acc1 ()));
1993 emit_move_insn (operands[0], gen_acc2 ());
1996 emit_insn (gen_umul_600 (operands[1], operands[2],
1997 gen_acc2 (), gen_acc1 ()));
1998 emit_insn (gen_mac_600 (operands[1], operands[2],
1999 gen_acc2 (), gen_acc1 ()));
2000 emit_move_insn (operands[0], gen_acc2 ());
2003 [(set_attr "type" "multi")
2004 (set_attr "length" "8")])
2006 ; mululw conditional execution without a LIMM clobbers an input register;
2007 ; we'd need a different pattern to describe this.
2008 ; To make the conditional execution valid for the LIMM alternative, we
2009 ; have to emit the LIMM before the register operand.
2010 (define_insn "umul_600"
2011 [(set (match_operand:SI 2 "acc2_operand" "")
2012 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2013 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2017 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2018 "TARGET_MULMAC_32BY16_SET"
2020 [(set_attr "length" "4,4,8")
2021 (set_attr "type" "mulmac_600")
2022 (set_attr "predicable" "no")
2023 (set_attr "cond" "nocond")])
2025 (define_insn "mac_600"
2026 [(set (match_operand:SI 2 "acc2_operand" "")
2028 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2030 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2035 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2036 "TARGET_MULMAC_32BY16_SET"
2037 "machlw%? 0, %0, %1"
2038 [(set_attr "length" "4,4,8")
2039 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2040 (set_attr "predicable" "no, no, yes")
2041 (set_attr "cond" "nocond, canuse_limm, canuse")])
2043 (define_insn_and_split "mulsi64"
2044 [(set (match_operand:SI 0 "register_operand" "=w")
2045 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2046 (match_operand:SI 2 "nonmemory_operand" "ci")))
2047 (clobber (reg:DI MUL64_OUT_REG))]
2050 "TARGET_MUL64_SET && reload_completed"
2053 emit_insn (gen_mulsi_600 (operands[1], operands[2],
2054 gen_mlo (), gen_mhi ()));
2055 emit_move_insn (operands[0], gen_mlo ());
2058 [(set_attr "type" "multi")
2059 (set_attr "length" "8")])
2061 (define_insn "mulsi_600"
2062 [(set (match_operand:SI 2 "mlo_operand" "")
2063 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
2064 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
2065 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2067 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
2068 ; using a machine code pattern that only allows "L" constraint constants.
2069 ; "mul64%? \t0, %0, %1%&"
2071 if (satisfies_constraint_I (operands[1])
2072 && !satisfies_constraint_L (operands[1]))
2074 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */
2075 int n = true_regnum (operands[0]);
2076 int i = INTVAL (operands[1]);
2077 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
2078 asm_fprintf (asm_out_file, "\t.short %d`",
2079 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
2080 return "; mul64%? \t0, %0, %1%&";
2082 return "mul64%? \t0, %0, %1%&";
2084 [(set_attr "length" "*,4,4,8")
2085 (set_attr "iscompact" "maybe,false,false,false")
2086 (set_attr "type" "multi,multi,multi,multi")
2087 (set_attr "predicable" "yes,yes,no,yes")
2088 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2090 ; If we compile without an mul option enabled, but link with libraries
2091 ; for a mul option, we'll see clobbers of multiplier output registers.
2092 ; There is also an implementation using norm that clobbers the loop registers.
2093 (define_insn "mulsi3_600_lib"
2094 [(set (reg:SI R0_REG)
2095 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2096 (clobber (reg:SI RETURN_ADDR_REGNUM))
2097 (clobber (reg:SI R1_REG))
2098 (clobber (reg:SI R2_REG))
2099 (clobber (reg:SI R3_REG))
2100 (clobber (reg:DI MUL64_OUT_REG))
2101 (clobber (reg:SI LP_COUNT))
2102 (clobber (reg:SI LP_START))
2103 (clobber (reg:SI LP_END))
2104 (clobber (reg:CC CC_REG))]
2106 && SFUNC_CHECK_PREDICABLE"
2107 "*return arc_output_libcall (\"__mulsi3\");"
2108 [(set_attr "is_sfunc" "yes")
2109 (set_attr "predicable" "yes")])
2111 (define_insn_and_split "mulsidi_600"
2112 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c")
2113 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c"))
2114 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32"))))
2115 (clobber (reg:DI MUL64_OUT_REG))]
2120 "emit_insn (gen_mul64 (operands[1], operands[2]));
2121 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2123 [(set_attr "type" "multi")
2124 (set_attr "length" "8")])
2126 (define_insn "mul64"
2127 [(set (reg:DI MUL64_OUT_REG)
2129 (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c, c"))
2130 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))]
2132 "mul64%? \t0, %0, %1%&"
2133 [(set_attr "length" "*,4,4,8")
2134 (set_attr "iscompact" "maybe,false,false,false")
2135 (set_attr "type" "multi,multi,multi,multi")
2136 (set_attr "predicable" "yes,yes,no,yes")
2137 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2139 (define_insn_and_split "umulsidi_600"
2140 [(set (match_operand:DI 0 "register_operand" "=c,c, c")
2141 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c,c, c"))
2142 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "cL,L,C32"))))
2143 (clobber (reg:DI MUL64_OUT_REG))]
2148 "emit_insn (gen_mulu64 (operands[1], operands[2]));
2149 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2151 [(set_attr "type" "umulti")
2152 (set_attr "length" "8")])
2154 (define_insn "mulu64"
2155 [(set (reg:DI MUL64_OUT_REG)
2157 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2158 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2160 "mulu64%? \t0, %0, %1%&"
2161 [(set_attr "length" "4,4,8")
2162 (set_attr "iscompact" "false")
2163 (set_attr "type" "umulti")
2164 (set_attr "predicable" "yes,no,yes")
2165 (set_attr "cond" "canuse,canuse_limm,canuse")])
2167 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2168 ; may not be used as destination constraint.
2170 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2171 ; but mpyu is faster for the standard multiplier.
2172 ; Note: we must make sure LP_COUNT is not one of the destination
2173 ; registers, since it cannot be the destination of a multi-cycle insn
2175 (define_insn "mulsi3_700"
2176 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r")
2177 (mult:SI (match_operand:SI 1 "register_operand" "%0,c,0,0,c")
2178 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2181 [(set_attr "length" "4,4,4,8,8")
2182 (set_attr "type" "umulti")
2183 (set_attr "predicable" "yes,no,no,yes,no")
2184 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2186 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2187 ; short variant. LP_COUNT constraints are still valid.
2188 (define_insn "mulsi3_v2"
2189 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r")
2190 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c")
2191 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2194 [(set_attr "length" "*,4,4,4,8,8")
2195 (set_attr "iscompact" "maybe,false,false,false,false,false")
2196 (set_attr "type" "umulti")
2197 (set_attr "predicable" "no,yes,no,no,yes,no")
2198 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2200 (define_expand "mulsidi3"
2201 [(set (match_operand:DI 0 "register_operand" "")
2202 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2203 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2206 if (TARGET_PLUS_MACD)
2208 if (CONST_INT_P (operands[2]))
2210 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2214 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2220 operands[2] = force_reg (SImode, operands[2]);
2221 if (!register_operand (operands[0], DImode))
2223 rtx result = gen_reg_rtx (DImode);
2225 operands[2] = force_reg (SImode, operands[2]);
2226 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2227 emit_move_insn (operands[0], result);
2231 else if (TARGET_MUL64_SET)
2233 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2236 else if (TARGET_MULMAC_32BY16_SET)
2238 operands[2] = force_reg (SImode, operands[2]);
2239 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2242 operands[2] = force_reg (SImode, operands[2]);
2245 (define_insn_and_split "mulsidi64"
2246 [(set (match_operand:DI 0 "register_operand" "=w")
2247 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2248 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2249 (clobber (reg:DI MUL32x16_REG))]
2250 "TARGET_MULMAC_32BY16_SET"
2252 "TARGET_MULMAC_32BY16_SET && reload_completed"
2255 rtx result_hi = gen_highpart (SImode, operands[0]);
2256 rtx result_low = gen_lowpart (SImode, operands[0]);
2258 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2259 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2260 emit_move_insn (result_low, gen_acc2 ());
2263 [(set_attr "type" "multi")
2264 (set_attr "length" "8")])
2267 (define_insn "mul64_600"
2268 [(set (reg:DI MUL32x16_REG)
2269 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2271 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2276 "TARGET_MULMAC_32BY16_SET"
2278 [(set_attr "length" "4,4,8")
2279 (set_attr "type" "mulmac_600")
2280 (set_attr "predicable" "no,no,yes")
2281 (set_attr "cond" "nocond, canuse_limm, canuse")])
2284 ;; ??? check if this is canonical rtl
2285 (define_insn "mac64_600"
2286 [(set (reg:DI MUL32x16_REG)
2288 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2290 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2291 (const_int 16) (const_int 16))
2293 (reg:DI MUL32x16_REG)))
2294 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2297 (mult:DI (sign_extend:DI (match_dup 1))
2299 (sign_extract:DI (match_dup 2)
2300 (const_int 16) (const_int 16))
2302 (reg:DI MUL32x16_REG))
2303 (const_int 32) (const_int 32)))]
2304 "TARGET_MULMAC_32BY16_SET"
2305 "machlw%? %0, %1, %2"
2306 [(set_attr "length" "4,4,8")
2307 (set_attr "type" "mulmac_600")
2308 (set_attr "predicable" "no,no,yes")
2309 (set_attr "cond" "nocond, canuse_limm, canuse")])
2312 ;; DI <- DI(signed SI) * DI(signed SI)
2313 (define_insn_and_split "mulsidi3_700"
2314 [(set (match_operand:DI 0 "register_operand" "=&r")
2315 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2316 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2317 "TARGET_MPY && !TARGET_PLUS_MACD"
2319 "&& reload_completed"
2322 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2323 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2324 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2325 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2326 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2327 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2330 [(set_attr "type" "multi")
2331 (set_attr "length" "8")])
2333 (define_insn "mulsi3_highpart"
2334 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2338 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2339 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2343 [(set_attr "length" "4,4,8,8")
2344 (set_attr "type" "multi")
2345 (set_attr "predicable" "yes,no,yes,no")
2346 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2348 ; Note that mpyhu has the same latency as mpy / mpyh,
2349 ; thus we use the type multi.
2350 (define_insn "*umulsi3_highpart_i"
2351 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2355 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2356 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2360 [(set_attr "length" "4,4,8,8")
2361 (set_attr "type" "multi")
2362 (set_attr "predicable" "yes,no,yes,no")
2363 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2365 ; Implementations include additional labels for umulsidi3, so we got all
2366 ; the same clobbers - plus one for the result low part. */
2367 (define_insn "umulsi3_highpart_600_lib_le"
2368 [(set (reg:SI R1_REG)
2371 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2372 (zero_extend:DI (reg:SI R1_REG)))
2374 (clobber (reg:SI RETURN_ADDR_REGNUM))
2375 (clobber (reg:SI R0_REG))
2376 (clobber (reg:DI R2_REG))
2377 (clobber (reg:SI R12_REG))
2378 (clobber (reg:DI MUL64_OUT_REG))
2379 (clobber (reg:CC CC_REG))]
2382 && SFUNC_CHECK_PREDICABLE"
2383 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2384 [(set_attr "is_sfunc" "yes")
2385 (set_attr "predicable" "yes")])
2387 (define_insn "umulsi3_highpart_600_lib_be"
2388 [(set (reg:SI R0_REG)
2391 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2392 (zero_extend:DI (reg:SI R1_REG)))
2394 (clobber (reg:SI RETURN_ADDR_REGNUM))
2395 (clobber (reg:SI R1_REG))
2396 (clobber (reg:DI R2_REG))
2397 (clobber (reg:SI R12_REG))
2398 (clobber (reg:DI MUL64_OUT_REG))
2399 (clobber (reg:CC CC_REG))]
2402 && SFUNC_CHECK_PREDICABLE"
2403 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2404 [(set_attr "is_sfunc" "yes")
2405 (set_attr "predicable" "yes")])
2407 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2408 ;; need a separate pattern for immediates
2409 ;; ??? This is fine for combine, but not for reload.
2410 (define_insn "umulsi3_highpart_int"
2411 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2415 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2416 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2420 [(set_attr "length" "4,4,4,8,8")
2421 (set_attr "type" "multi")
2422 (set_attr "predicable" "yes,no,no,yes,no")
2423 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2425 (define_expand "umulsi3_highpart"
2426 [(set (match_operand:SI 0 "general_operand" "")
2430 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2431 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2433 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2436 rtx target = operands[0];
2440 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2441 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2442 if (TARGET_BIG_ENDIAN)
2443 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2445 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2446 emit_move_insn (target, gen_rtx_REG (SImode, 0));
2450 if (!register_operand (target, SImode))
2451 target = gen_reg_rtx (SImode);
2453 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2454 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2455 operands[2], SImode);
2456 else if (!immediate_operand (operands[2], SImode))
2457 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2458 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2459 if (target != operands[0])
2460 emit_move_insn (operands[0], target);
2464 (define_expand "umulsidi3"
2465 [(set (match_operand:DI 0 "register_operand" "")
2466 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2467 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2470 if (TARGET_PLUS_MACD)
2472 if (CONST_INT_P (operands[2]))
2474 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2478 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2484 operands[2] = force_reg (SImode, operands[2]);
2485 if (!register_operand (operands[0], DImode))
2487 rtx result = gen_reg_rtx (DImode);
2489 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2490 emit_move_insn (operands[0], result);
2494 else if (TARGET_MUL64_SET)
2496 operands[2] = force_reg (SImode, operands[2]);
2497 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2500 else if (TARGET_MULMAC_32BY16_SET)
2502 operands[2] = force_reg (SImode, operands[2]);
2503 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2508 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2509 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2510 emit_insn (gen_umulsidi3_600_lib ());
2511 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2516 (define_insn_and_split "umulsidi64"
2517 [(set (match_operand:DI 0 "register_operand" "=w")
2518 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2519 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2520 (clobber (reg:DI MUL32x16_REG))]
2521 "TARGET_MULMAC_32BY16_SET"
2523 "TARGET_MULMAC_32BY16_SET && reload_completed"
2529 result_hi = gen_highpart (SImode, operands[0]);
2530 result_low = gen_lowpart (SImode, operands[0]);
2532 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2533 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2534 emit_move_insn (result_low, gen_acc2 ());
2537 [(set_attr "type" "multi")
2538 (set_attr "length" "8")])
2540 (define_insn "umul64_600"
2541 [(set (reg:DI MUL32x16_REG)
2542 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2544 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2549 "TARGET_MULMAC_32BY16_SET"
2551 [(set_attr "length" "4,4,8")
2552 (set_attr "type" "mulmac_600")
2553 (set_attr "predicable" "no")
2554 (set_attr "cond" "nocond")])
2557 (define_insn "umac64_600"
2558 [(set (reg:DI MUL32x16_REG)
2560 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2562 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2563 (const_int 16) (const_int 16))
2565 (reg:DI MUL32x16_REG)))
2566 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2569 (mult:DI (zero_extend:DI (match_dup 1))
2571 (zero_extract:DI (match_dup 2)
2572 (const_int 16) (const_int 16))
2574 (reg:DI MUL32x16_REG))
2575 (const_int 32) (const_int 32)))]
2576 "TARGET_MULMAC_32BY16_SET"
2577 "machulw%? %0, %1, %2"
2578 [(set_attr "length" "4,4,8")
2579 (set_attr "type" "mulmac_600")
2580 (set_attr "predicable" "no,no,yes")
2581 (set_attr "cond" "nocond, canuse_limm, canuse")])
2583 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2584 (define_insn_and_split "umulsidi3_700"
2585 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2586 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2587 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2588 "TARGET_MPY && !TARGET_PLUS_MACD"
2593 int hi = !TARGET_BIG_ENDIAN;
2595 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2596 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2597 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2598 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2601 [(set_attr "type" "umulti")
2602 (set_attr "length" "8")])
2604 (define_insn "umulsidi3_600_lib"
2605 [(set (reg:DI R0_REG)
2606 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2607 (zero_extend:DI (reg:SI R1_REG))))
2608 (clobber (reg:SI RETURN_ADDR_REGNUM))
2609 (clobber (reg:DI R2_REG))
2610 (clobber (reg:SI R12_REG))
2611 (clobber (reg:DI MUL64_OUT_REG))
2612 (clobber (reg:CC CC_REG))]
2614 && SFUNC_CHECK_PREDICABLE"
2615 "*return arc_output_libcall (\"__umulsidi3\");"
2616 [(set_attr "is_sfunc" "yes")
2617 (set_attr "predicable" "yes")])
2621 [(set (reg:DI R0_REG)
2622 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2623 (zero_extend:DI (reg:SI R1_REG))))
2624 (clobber (reg:SI RETURN_ADDR_REGNUM))
2625 (clobber (reg:DI R2_REG))
2626 (clobber (reg:SI R12_REG))
2627 (clobber (reg:DI MUL64_OUT_REG))
2628 (clobber (reg:CC CC_REG))])]
2630 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2633 if (TARGET_BIG_ENDIAN)
2634 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2636 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2640 (define_expand "addsi3"
2641 [(set (match_operand:SI 0 "dest_reg_operand" "")
2642 (plus:SI (match_operand:SI 1 "register_operand" "")
2643 (match_operand:SI 2 "nonmemory_operand" "")))]
2645 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2647 operands[2]=force_reg(SImode, operands[2]);
2649 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2651 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2656 (define_expand "adddi3"
2657 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2658 (plus:DI (match_operand:DI 1 "register_operand" "")
2659 (match_operand:DI 2 "nonmemory_operand" "")))
2660 (clobber (reg:CC CC_REG))])]
2664 ; This assumes that there can be no strictly partial overlap between
2665 ; operands[1] and operands[2].
2666 (define_insn_and_split "*adddi3_i"
2667 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2668 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2669 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2670 (clobber (reg:CC CC_REG))]
2676 int hi = !TARGET_BIG_ENDIAN;
2678 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2679 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2680 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2681 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2682 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2683 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2686 if (l2 == const0_rtx)
2688 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2689 emit_move_insn (l0, l1);
2690 emit_insn (gen_addsi3 (h0, h1, h2));
2691 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2692 emit_move_insn (l0, l1);
2695 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2696 && INTVAL (operands[2]) >= -0x7fffffff)
2698 emit_insn (gen_subdi3_i (operands[0], operands[1],
2699 GEN_INT (-INTVAL (operands[2]))));
2702 if (rtx_equal_p (l0, h1))
2704 if (h2 != const0_rtx)
2705 emit_insn (gen_addsi3 (h0, h1, h2));
2706 else if (!rtx_equal_p (h0, h1))
2707 emit_move_insn (h0, h1);
2708 emit_insn (gen_add_f (l0, l1, l2));
2712 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2713 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2716 emit_insn (gen_add_f (l0, l1, l2));
2717 emit_insn (gen_adc (h0, h1, h2));
2720 [(set_attr "cond" "clob")
2721 (set_attr "type" "binary")
2722 (set_attr "length" "16,16,20")])
2724 (define_insn "add_f"
2725 [(set (reg:CC_C CC_REG)
2727 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2728 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2730 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2731 (plus:SI (match_dup 1) (match_dup 2)))]
2734 [(set_attr "cond" "set")
2735 (set_attr "type" "compare")
2736 (set_attr "length" "4,4,8")])
2738 (define_insn "*add_f_2"
2739 [(set (reg:CC_C CC_REG)
2741 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2742 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2744 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2745 (plus:SI (match_dup 1) (match_dup 2)))]
2748 [(set_attr "cond" "set")
2749 (set_attr "type" "compare")
2750 (set_attr "length" "4,4,8")])
2752 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2753 ; needlessly prioritizing the matching constraint.
2754 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2755 ; execution is used where possible.
2756 (define_insn_and_split "adc"
2757 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2758 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2759 (match_operand:SI 1 "nonmemory_operand"
2761 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2762 "register_operand (operands[1], SImode)
2763 || register_operand (operands[2], SImode)"
2770 ; if we have a bad schedule after sched2, split.
2772 && !optimize_size && (!TARGET_ARC600_FAMILY)
2773 && arc_scheduling_not_expected ()
2774 && arc_sets_cc_p (prev_nonnote_insn (insn))
2775 /* If next comes a return or other insn that needs a delay slot,
2776 expect the adc to get into the delay slot. */
2777 && next_nonnote_insn (insn)
2778 && !arc_need_delay (next_nonnote_insn (insn))
2779 /* Restore operands before emitting. */
2780 && (extract_insn_cached (insn), 1)"
2781 [(set (match_dup 0) (match_dup 3))
2783 (ltu (reg:CC_C CC_REG) (const_int 0))
2784 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2785 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2786 [(set_attr "cond" "use")
2787 (set_attr "type" "cc_arith")
2788 (set_attr "length" "4,4,4,4,8")])
2790 ; combiner-splitter cmp / scc -> cmp / adc
2792 [(set (match_operand:SI 0 "dest_reg_operand" "")
2793 (gtu:SI (match_operand:SI 1 "register_operand" "")
2794 (match_operand:SI 2 "register_operand" "")))
2795 (clobber (reg CC_REG))]
2797 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2798 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2800 ; combine won't work when an intermediate result is used later...
2801 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2803 [(set (match_operand:SI 0 "dest_reg_operand" "")
2804 (plus:SI (match_operand:SI 1 "register_operand" "")
2805 (match_operand:SI 2 "nonmemory_operand" "")))
2806 (set (reg:CC_C CC_REG)
2807 (compare:CC_C (match_dup 0)
2808 (match_operand:SI 3 "nonmemory_operand" "")))]
2809 "rtx_equal_p (operands[1], operands[3])
2810 || rtx_equal_p (operands[2], operands[3])"
2812 [(set (reg:CC_C CC_REG)
2813 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2815 (plus:SI (match_dup 1) (match_dup 2)))])])
2817 ; ??? need to delve into combine to find out why this is not useful.
2818 ; We'd like to be able to grok various C idioms for carry bit usage.
2819 ;(define_insn "*adc_0"
2820 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2821 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2822 ; (match_operand:SI 1 "register_operand" "c")))]
2825 ; [(set_attr "cond" "use")
2826 ; (set_attr "type" "cc_arith")
2827 ; (set_attr "length" "4")])
2830 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2831 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2832 ; (match_operand:SI 2 "register_operand" "c"))
2833 ; (match_operand:SI 3 "register_operand" "c")))
2834 ; (clobber (reg CC_REG))]
2836 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2837 ; (set (match_dup 0)
2838 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2841 (define_expand "subsi3"
2842 [(set (match_operand:SI 0 "dest_reg_operand" "")
2843 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2844 (match_operand:SI 2 "nonmemory_operand" "")))]
2850 if (!register_operand (operands[2], SImode))
2852 operands[1] = force_reg (SImode, operands[1]);
2855 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2856 operands[c] = force_reg (SImode, operands[c]);
2857 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2858 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2861 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2862 ; combine should make such an insn go away.
2863 (define_insn_and_split "subsi3_insn"
2864 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2865 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,Rcqq, 0, cL,c,L,I,Cal,Cal, c")
2866 (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2867 "register_operand (operands[1], SImode)
2868 || register_operand (operands[2], SImode)"
2880 "reload_completed && get_attr_length (insn) == 8
2881 && satisfies_constraint_I (operands[1])
2882 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2883 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2884 "split_subsi (operands);"
2885 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2886 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2887 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2888 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2889 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2892 (define_expand "subdi3"
2893 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2894 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2895 (match_operand:DI 2 "nonmemory_operand" "")))
2896 (clobber (reg:CC CC_REG))])]
2899 if (!register_operand (operands[2], DImode))
2900 operands[1] = force_reg (DImode, operands[1]);
2903 (define_insn_and_split "subdi3_i"
2904 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2905 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2906 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2907 (clobber (reg:CC CC_REG))]
2908 "register_operand (operands[1], DImode)
2909 || register_operand (operands[2], DImode)"
2914 int hi = !TARGET_BIG_ENDIAN;
2916 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2917 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2918 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2919 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2920 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2921 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2923 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2925 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2926 if (!rtx_equal_p (h0, h1))
2927 emit_insn (gen_rtx_SET (h0, h1));
2928 emit_insn (gen_sub_f (l0, l1, l2));
2932 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2933 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2936 emit_insn (gen_sub_f (l0, l1, l2));
2937 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2940 [(set_attr "cond" "clob")
2941 (set_attr "length" "16,16,16,20,20")])
2943 (define_insn "*sbc_0"
2944 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2945 (minus:SI (match_operand:SI 1 "register_operand" "c")
2946 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2950 [(set_attr "cond" "use")
2951 (set_attr "type" "cc_arith")
2952 (set_attr "length" "4")])
2954 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2955 ; needlessly prioritizing the matching constraint.
2956 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2957 ; is used where possible.
2958 (define_insn_and_split "sbc"
2959 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2960 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2962 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2964 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2965 "register_operand (operands[1], SImode)
2966 || register_operand (operands[2], SImode)"
2973 ; if we have a bad schedule after sched2, split.
2975 && !optimize_size && (!TARGET_ARC600_FAMILY)
2976 && arc_scheduling_not_expected ()
2977 && arc_sets_cc_p (prev_nonnote_insn (insn))
2978 /* If next comes a return or other insn that needs a delay slot,
2979 expect the adc to get into the delay slot. */
2980 && next_nonnote_insn (insn)
2981 && !arc_need_delay (next_nonnote_insn (insn))
2982 /* Restore operands before emitting. */
2983 && (extract_insn_cached (insn), 1)"
2984 [(set (match_dup 0) (match_dup 4))
2986 (ltu (reg:CC_C CC_REG) (const_int 0))
2987 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2988 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2989 [(set_attr "cond" "use")
2990 (set_attr "type" "cc_arith")
2991 (set_attr "length" "4,4,4,4,8")])
2993 (define_insn "sub_f"
2994 [(set (reg:CC CC_REG)
2995 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2996 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2997 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2998 (minus:SI (match_dup 1) (match_dup 2)))]
2999 "register_operand (operands[1], SImode)
3000 || register_operand (operands[2], SImode)"
3008 [(set_attr "type" "compare")
3009 (set_attr "length" "4,4,4,4,8,8")])
3011 ; combine won't work when an intermediate result is used later...
3012 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3014 [(set (reg:CC CC_REG)
3015 (compare:CC (match_operand:SI 1 "register_operand" "")
3016 (match_operand:SI 2 "nonmemory_operand" "")))
3017 (set (match_operand:SI 0 "dest_reg_operand" "")
3018 (minus:SI (match_dup 1) (match_dup 2)))]
3021 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3022 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3025 [(set (reg:CC CC_REG)
3026 (compare:CC (match_operand:SI 1 "register_operand" "")
3027 (match_operand:SI 2 "nonmemory_operand" "")))
3028 (set (match_operand 3 "" "") (match_operand 4 "" ""))
3029 (set (match_operand:SI 0 "dest_reg_operand" "")
3030 (minus:SI (match_dup 1) (match_dup 2)))]
3031 "!reg_overlap_mentioned_p (operands[3], operands[1])
3032 && !reg_overlap_mentioned_p (operands[3], operands[2])
3033 && !reg_overlap_mentioned_p (operands[0], operands[4])
3034 && !reg_overlap_mentioned_p (operands[0], operands[3])"
3036 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3037 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3038 (set (match_dup 3) (match_dup 4))])
3040 (define_insn "*add_n"
3041 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3042 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3043 (match_operand:SI 2 "_1_2_3_operand" ""))
3044 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3046 "add%c2%? %0,%3,%1%&"
3047 [(set_attr "type" "shift")
3048 (set_attr "length" "*,4,4,8,4,8")
3049 (set_attr "predicable" "yes,yes,no,no,no,no")
3050 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3051 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3053 (define_insn "*add_n"
3054 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3055 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3056 (match_operand:SI 2 "_2_4_8_operand" ""))
3057 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3059 "add%z2%? %0,%3,%1%&"
3060 [(set_attr "type" "shift")
3061 (set_attr "length" "*,4,4,8,4,8")
3062 (set_attr "predicable" "yes,yes,no,no,no,no")
3063 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3064 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3066 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3067 ;; what synth_mult likes.
3068 (define_insn "*sub_n"
3069 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3070 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3071 (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
3072 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3075 [(set_attr "type" "shift")
3076 (set_attr "length" "4,4,8")
3077 (set_attr "predicable" "yes,no,no")
3078 (set_attr "cond" "canuse,nocond,nocond")
3079 (set_attr "iscompact" "false")])
3081 (define_insn "*sub_n"
3082 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3083 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3084 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
3085 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3088 [(set_attr "type" "shift")
3089 (set_attr "length" "4,4,8")
3090 (set_attr "predicable" "yes,no,no")
3091 (set_attr "cond" "canuse,nocond,nocond")
3092 (set_attr "iscompact" "false")])
3094 ; ??? check if combine matches this.
3095 (define_insn "*bset"
3096 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3097 (ior:SI (ashift:SI (const_int 1)
3098 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3099 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3102 [(set_attr "length" "4,4,8")
3103 (set_attr "predicable" "yes,no,no")
3104 (set_attr "cond" "canuse,nocond,nocond")]
3107 ; ??? check if combine matches this.
3108 (define_insn "*bxor"
3109 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3110 (xor:SI (ashift:SI (const_int 1)
3111 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3112 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3115 [(set_attr "length" "4,4,8")
3116 (set_attr "predicable" "yes,no,no")
3117 (set_attr "cond" "canuse,nocond,nocond")]
3120 ; ??? check if combine matches this.
3121 (define_insn "*bclr"
3122 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3123 (and:SI (not:SI (ashift:SI (const_int 1)
3124 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
3125 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3128 [(set_attr "length" "4,4,8")
3129 (set_attr "predicable" "yes,no,no")
3130 (set_attr "cond" "canuse,nocond,nocond")]
3133 ; ??? FIXME: find combine patterns for bmsk.
3135 ;;Following are the define_insns added for the purpose of peephole2's
3137 ; see also iorsi3 for use with constant bit number.
3138 (define_insn "*bset_insn"
3139 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3140 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3141 (ashift:SI (const_int 1)
3142 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3145 bset%? %0,%1,%2 ;;peep2, constr 1
3146 bset %0,%1,%2 ;;peep2, constr 2
3147 bset %0,%S1,%2 ;;peep2, constr 3"
3148 [(set_attr "length" "4,4,8")
3149 (set_attr "predicable" "yes,no,no")
3150 (set_attr "cond" "canuse,nocond,nocond")]
3153 ; see also xorsi3 for use with constant bit number.
3154 (define_insn "*bxor_insn"
3155 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3156 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3157 (ashift:SI (const_int 1)
3158 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3164 [(set_attr "length" "4,4,8")
3165 (set_attr "predicable" "yes,no,no")
3166 (set_attr "cond" "canuse,nocond,nocond")]
3169 ; see also andsi3 for use with constant bit number.
3170 (define_insn "*bclr_insn"
3171 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3172 (and:SI (not:SI (ashift:SI (const_int 1)
3173 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3174 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3180 [(set_attr "length" "4,4,8")
3181 (set_attr "predicable" "yes,no,no")
3182 (set_attr "cond" "canuse,nocond,nocond")]
3185 ; see also andsi3 for use with constant bit number.
3186 (define_insn "*bmsk_insn"
3187 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3188 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3189 (plus:SI (ashift:SI (const_int 1)
3190 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3198 [(set_attr "length" "4,4,8")
3199 (set_attr "predicable" "yes,no,no")
3200 (set_attr "cond" "canuse,nocond,nocond")]
3203 ;;Instructions added for peephole2s end
3205 ;; Boolean instructions.
3207 (define_expand "andsi3"
3208 [(set (match_operand:SI 0 "dest_reg_operand" "")
3209 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3210 (match_operand:SI 2 "nonmemory_operand" "")))]
3212 "if (!satisfies_constraint_Cux (operands[2]))
3213 operands[1] = force_reg (SImode, operands[1]);
3214 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3215 operands[1] = arc_rewrite_small_data (operands[1]);")
3217 (define_insn "andsi3_i"
3218 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W")
3219 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o")
3220 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
3221 "(register_operand (operands[1], SImode)
3222 && nonmemory_operand (operands[2], SImode))
3223 || (memory_operand (operands[1], SImode)
3224 && satisfies_constraint_Cux (operands[2]))"
3226 switch (which_alternative)
3228 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3229 return "and%? %0,%1,%2%&";
3231 return "and%? %0,%2,%1%&";
3233 return "bmsk%? %0,%1,%Z2%&";
3235 if (satisfies_constraint_C2p (operands[2]))
3237 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3238 return "bmskn%? %0,%1,%Z2%&";
3242 return "bmsk%? %0,%1,%Z2%&";
3244 case 3: case 8: case 13:
3245 return "bclr%? %0,%1,%M2%&";
3247 return (INTVAL (operands[2]) == 0xff
3248 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3249 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3251 return "movb.cl %0,%1,%p2,%p2,%s2";
3256 if (satisfies_constraint_Ucm (operands[1]))
3257 tmpl = (INTVAL (operands[2]) == 0xff
3258 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3260 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3262 if (TARGET_BIG_ENDIAN)
3266 xop[0] = operands[0];
3267 xop[1] = adjust_address (operands[1], QImode,
3268 INTVAL (operands[2]) == 0xff ? 3 : 2);
3269 output_asm_insn (tmpl, xop);
3277 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3278 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3279 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3280 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3281 (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")])
3283 ; combiner splitter, pattern found in ldtoa.c .
3284 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3286 [(set (reg:CC_Z CC_REG)
3287 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3288 (match_operand 1 "const_int_operand" ""))
3289 (match_operand 2 "const_int_operand" "")))
3290 (clobber (match_operand:SI 3 "register_operand" ""))]
3291 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3293 (plus:SI (match_dup 0) (match_dup 4)))
3294 (set (reg:CC_Z CC_REG)
3295 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3297 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3299 ;;bic define_insn that allows limm to be the first operand
3300 (define_insn "*bicsi3_insn"
3301 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3302 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3303 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3306 bic%? %0, %2, %1%& ;;constraint 0
3307 bic%? %0,%2,%1 ;;constraint 1
3308 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3309 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3310 bic %0,%2,%1 ;;constraint 4
3311 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3312 bic %0,%S2,%1 ;;constraint 6"
3313 [(set_attr "length" "*,4,4,8,4,8,8")
3314 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3315 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3316 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3318 (define_insn "iorsi3"
3319 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3320 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3321 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3324 switch (which_alternative)
3326 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3327 return \"or%? %0,%1,%2%&\";
3329 return \"or%? %0,%2,%1%&\";
3330 case 2: case 5: case 8:
3331 return \"bset%? %0,%1,%z2%&\";
3335 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3336 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3337 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3338 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3340 (define_insn "xorsi3"
3341 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3342 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3343 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3346 switch (which_alternative)
3348 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3349 return \"xor%? %0,%1,%2%&\";
3351 return \"xor%? %0,%2,%1%&\";
3353 return \"bxor%? %0,%1,%z2\";
3358 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3359 (set_attr "type" "binary")
3360 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3361 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3362 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3364 (define_insn "negsi2"
3365 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3366 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3369 [(set_attr "type" "unary")
3370 (set_attr "iscompact" "maybe,true,false,false")
3371 (set_attr "predicable" "no,no,yes,no")])
3373 (define_insn "one_cmplsi2"
3374 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3375 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3378 [(set_attr "type" "unary,unary")
3379 (set_attr "iscompact" "true,false")])
3381 (define_insn_and_split "one_cmpldi2"
3382 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3383 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3386 "&& reload_completed"
3387 [(set (match_dup 2) (not:SI (match_dup 3)))
3388 (set (match_dup 4) (not:SI (match_dup 5)))]
3390 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3392 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3393 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3394 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3395 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3397 [(set_attr "type" "unary,unary")
3398 (set_attr "cond" "nocond,nocond")
3399 (set_attr "length" "4,8")])
3401 ;; Shift instructions.
3403 (define_expand "ashlsi3"
3404 [(set (match_operand:SI 0 "dest_reg_operand" "")
3405 (ashift:SI (match_operand:SI 1 "register_operand" "")
3406 (match_operand:SI 2 "nonmemory_operand" "")))]
3410 if (!TARGET_BARREL_SHIFTER)
3412 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3417 (define_expand "ashrsi3"
3418 [(set (match_operand:SI 0 "dest_reg_operand" "")
3419 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3420 (match_operand:SI 2 "nonmemory_operand" "")))]
3424 if (!TARGET_BARREL_SHIFTER)
3426 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3431 (define_expand "lshrsi3"
3432 [(set (match_operand:SI 0 "dest_reg_operand" "")
3433 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3434 (match_operand:SI 2 "nonmemory_operand" "")))]
3438 if (!TARGET_BARREL_SHIFTER)
3440 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3445 (define_insn "shift_si3"
3446 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3447 (match_operator:SI 3 "shift4_operator"
3448 [(match_operand:SI 1 "register_operand" "0")
3449 (match_operand:SI 2 "const_int_operand" "n")]))
3450 (clobber (match_scratch:SI 4 "=&r"))
3451 (clobber (reg:CC CC_REG))
3453 "!TARGET_BARREL_SHIFTER"
3454 "* return output_shift (operands);"
3455 [(set_attr "type" "shift")
3456 (set_attr "length" "16")])
3458 (define_insn "shift_si3_loop"
3459 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3460 (match_operator:SI 3 "shift_operator"
3461 [(match_operand:SI 1 "register_operand" "0,0")
3462 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3463 (clobber (match_scratch:SI 4 "=X,X"))
3464 (clobber (reg:SI LP_COUNT))
3465 (clobber (reg:SI LP_START))
3466 (clobber (reg:SI LP_END))
3467 (clobber (reg:CC CC_REG))
3469 "!TARGET_BARREL_SHIFTER"
3470 "* return output_shift (operands);"
3471 [(set_attr "type" "shift")
3472 (set_attr "length" "16,20")])
3474 ; asl, asr, lsr patterns:
3475 ; There is no point in including an 'I' alternative since only the lowest 5
3476 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3477 ; is defined in an external symbol, as we don't have special relocations
3478 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3479 ; provide one alternatice for this, without condexec support.
3480 (define_insn "*ashlsi3_insn"
3481 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3482 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3483 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3484 "TARGET_BARREL_SHIFTER
3485 && (register_operand (operands[1], SImode)
3486 || register_operand (operands[2], SImode))"
3488 [(set_attr "type" "shift")
3489 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3490 (set_attr "predicable" "no,no,no,yes,no,no")
3491 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3493 (define_insn "*ashrsi3_insn"
3494 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3495 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3496 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3497 "TARGET_BARREL_SHIFTER
3498 && (register_operand (operands[1], SImode)
3499 || register_operand (operands[2], SImode))"
3501 [(set_attr "type" "shift")
3502 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3503 (set_attr "predicable" "no,no,no,yes,no,no")
3504 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3506 (define_insn "*lshrsi3_insn"
3507 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3508 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3509 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3510 "TARGET_BARREL_SHIFTER
3511 && (register_operand (operands[1], SImode)
3512 || register_operand (operands[2], SImode))"
3513 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3514 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3515 [(set_attr "type" "shift")
3516 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3517 (set_attr "predicable" "no,no,no,yes,no,no")
3518 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3520 (define_insn "rotrsi3"
3521 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3522 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3523 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3524 "TARGET_BARREL_SHIFTER"
3526 [(set_attr "type" "shift,shift,shift")
3527 (set_attr "predicable" "yes,no,no")
3528 (set_attr "length" "4,4,8")])
3530 ;; Compare / branch instructions.
3532 (define_expand "cbranchsi4"
3533 [(set (reg:CC CC_REG)
3534 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3535 (match_operand:SI 2 "nonmemory_operand" "")))
3538 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3540 (label_ref (match_operand 3 "" ""))
3544 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3545 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3546 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3547 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3551 ;; ??? Could add a peephole to generate compare with swapped operands and
3552 ;; modifed cc user if second, but not first operand is a compact register.
3553 (define_insn "cmpsi_cc_insn_mixed"
3554 [(set (reg:CC CC_REG)
3555 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq, h, c, c,qRcq,c")
3556 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI,cL, Cal,Cal")))]
3559 [(set_attr "type" "compare")
3560 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3561 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3562 (set_attr "cond" "set")
3563 (set_attr "length" "*,*,*,4,4,*,8")
3564 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3566 (define_insn "*cmpsi_cc_zn_insn"
3567 [(set (reg:CC_ZN CC_REG)
3568 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3572 [(set_attr "type" "compare,compare")
3573 (set_attr "iscompact" "true,false")
3574 (set_attr "predicable" "no,yes")
3575 (set_attr "cond" "set_zn")
3576 (set_attr "length" "*,4")])
3578 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3579 (define_insn "*btst"
3580 [(set (reg:CC_ZN CC_REG)
3582 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3584 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3588 [(set_attr "iscompact" "true,false")
3589 (set_attr "predicable" "no,yes")
3590 (set_attr "cond" "set")
3591 (set_attr "type" "compare")
3592 (set_attr "length" "*,4")])
3594 ; combine suffers from 'simplifications' that replace a one-bit zero
3595 ; extract with a shift if it can prove that the upper bits are zero.
3596 ; arc_reorg sees the code after sched2, which can have caused our
3597 ; inputs to be clobbered even if they were not clobbered before.
3598 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3599 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3600 ; bbit (i.e. bad scheduling) and missed conditional execution,
3601 ; so make this an option.
3603 [(set (reg:CC_ZN CC_REG)
3605 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3607 (match_operand:SI 1 "nonmemory_operand" ""))
3610 (if_then_else (match_operator 3 "equality_comparison_operator"
3611 [(reg:CC_ZN CC_REG) (const_int 0)])
3612 (label_ref (match_operand 2 "" ""))
3614 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3615 [(parallel [(set (pc)
3618 [(zero_extract:SI (match_dup 0)
3619 (const_int 1) (match_dup 1))
3621 (label_ref (match_dup 2))
3623 (clobber (reg:CC_ZN CC_REG))])])
3625 (define_insn "*cmpsi_cc_z_insn"
3626 [(set (reg:CC_Z CC_REG)
3627 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3628 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3633 [(set_attr "type" "compare,compare")
3634 (set_attr "iscompact" "true,false")
3635 (set_attr "cond" "set,set_zn")
3636 (set_attr "length" "*,4")])
3638 (define_insn "*cmpsi_cc_c_insn"
3639 [(set (reg:CC_C CC_REG)
3640 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c")
3641 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))]
3644 [(set_attr "type" "compare")
3645 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3646 (set_attr "cond" "set")
3647 (set_attr "length" "*,*,*,4,*,8")
3648 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3650 ;; Next come the scc insns.
3652 (define_expand "cstoresi4"
3653 [(set (match_operand:SI 0 "dest_reg_operand" "")
3654 (match_operator:SI 1 "ordered_comparison_operator"
3655 [(match_operand:SI 2 "nonmemory_operand" "")
3656 (match_operand:SI 3 "nonmemory_operand" "")]))]
3659 if (!TARGET_CODE_DENSITY)
3661 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3662 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3663 operands[1] = gen_compare_reg (operands[1], SImode);
3664 emit_insn (gen_scc_insn (operands[0], operands[1]));
3667 if (!register_operand (operands[2], SImode))
3668 operands[2] = force_reg (SImode, operands[2]);
3672 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3673 (DF "TARGET_OPTFPE")])
3675 (define_expand "cstore<mode>4"
3676 [(set (reg:CC CC_REG)
3677 (compare:CC (match_operand:SDF 2 "register_operand" "")
3678 (match_operand:SDF 3 "register_operand" "")))
3679 (set (match_operand:SI 0 "dest_reg_operand" "")
3680 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3683 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3685 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3686 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3687 operands[1] = gen_compare_reg (operands[1], SImode);
3688 emit_insn (gen_scc_insn (operands[0], operands[1]));
3692 ; We need a separate expander for this lest we loose the mode of CC_REG
3693 ; when match_operator substitutes the literal operand into the comparison.
3694 (define_expand "scc_insn"
3695 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3697 (define_insn_and_split "*scc_insn"
3698 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3699 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3703 [(set (match_dup 0) (const_int 1))
3706 (set (match_dup 0) (const_int 0)))]
3709 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3710 GET_MODE (XEXP (operands[1], 0))),
3712 XEXP (operands[1], 0), XEXP (operands[1], 1));
3714 [(set_attr "type" "unary")])
3716 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3717 ;; that is one lower if the carry flag is set.
3719 ;; ??? Look up negscc insn. See pa.md for example.
3720 (define_insn "*neg_scc_insn"
3721 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3722 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3723 [(reg CC_REG) (const_int 0)])))]
3725 "mov %0,-1\;sub.%D1 %0,%0,%0"
3726 [(set_attr "type" "unary")
3727 (set_attr "length" "8")])
3729 (define_insn "*not_scc_insn"
3730 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3731 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3732 [(reg CC_REG) (const_int 0)])))]
3734 "mov %0,1\;sub.%d1 %0,%0,%0"
3735 [(set_attr "type" "unary")
3736 (set_attr "length" "8")])
3738 ; cond_exec patterns
3739 (define_insn "*movsi_ne"
3741 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0))
3742 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w")
3743 (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))]
3746 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3747 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3748 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3751 [(set_attr "type" "cmove")
3752 (set_attr "iscompact" "true,true,true_limm,false,false")
3753 (set_attr "length" "2,2,6,4,8")
3754 (set_attr "cpu_facility" "*,av2,av2,*,*")])
3756 (define_insn "*movsi_cond_exec"
3758 (match_operator 3 "proper_comparison_operator"
3759 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3760 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3761 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3764 [(set_attr "type" "cmove")
3765 (set_attr "length" "4,8")])
3767 (define_insn "*commutative_cond_exec"
3769 (match_operator 5 "proper_comparison_operator"
3770 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3771 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3772 (match_operator:SI 3 "commutative_operator"
3773 [(match_operand:SI 1 "register_operand" "%0,0")
3774 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3777 arc_output_commutative_cond_exec (operands, true);
3780 [(set_attr "cond" "use")
3781 (set_attr "type" "cmove")
3782 (set_attr_alternative "length"
3785 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3790 (define_insn "*sub_cond_exec"
3792 (match_operator 4 "proper_comparison_operator"
3793 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3794 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3795 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3796 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3802 [(set_attr "cond" "use")
3803 (set_attr "type" "cmove")
3804 (set_attr "length" "4,4,8")])
3806 (define_insn "*noncommutative_cond_exec"
3808 (match_operator 5 "proper_comparison_operator"
3809 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3810 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3811 (match_operator:SI 3 "noncommutative_operator"
3812 [(match_operand:SI 1 "register_operand" "0,0")
3813 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3816 [(set_attr "cond" "use")
3817 (set_attr "type" "cmove")
3818 (set_attr "length" "4,8")])
3820 ;; These control RTL generation for conditional jump insns
3821 ;; Match both normal and inverted jump.
3823 ; We need a separate expander for this lest we loose the mode of CC_REG
3824 ; when match_operator substitutes the literal operand into the comparison.
3825 (define_expand "branch_insn"
3827 (if_then_else (match_operand 1 "" "")
3828 (label_ref (match_operand 0 "" ""))
3831 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3832 ; are three reasons why we need to consider branches to be length 6:
3833 ; - annull-false delay slot insns are implemented using conditional execution,
3834 ; thus preventing short insn formation where used.
3835 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3836 ; using conditional execution, preventing short insn formation where used.
3837 ; - for ARC700: likely or somewhat likely taken branches are made long and
3838 ; unaligned if possible to avoid branch penalty.
3839 (define_insn "*branch_insn"
3841 (if_then_else (match_operator 1 "proper_comparison_operator"
3842 [(reg CC_REG) (const_int 0)])
3843 (label_ref (match_operand 0 "" ""))
3848 if (arc_ccfsm_branch_deleted_p ())
3850 arc_ccfsm_record_branch_deleted ();
3851 return \"; branch deleted, next insns conditionalized\";
3855 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3856 if (get_attr_length (insn) == 2)
3857 return \"b%d1%? %^%l0%&\";
3859 return \"b%d1%# %^%l0\";
3862 [(set_attr "type" "branch")
3866 (eq_attr "delay_slot_filled" "yes")
3871 (match_operand 1 "equality_comparison_operator" "")
3872 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3873 (gt (minus (match_dup 0) (pc))
3874 (minus (const_int 506)
3875 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3876 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3877 (lt (minus (match_dup 0) (pc)) (const_int -64))
3878 (gt (minus (match_dup 0) (pc))
3879 (minus (const_int 58)
3880 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3885 (set (attr "iscompact")
3886 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3887 (const_string "false")))])
3889 (define_insn "*rev_branch_insn"
3891 (if_then_else (match_operator 1 "proper_comparison_operator"
3892 [(reg CC_REG) (const_int 0)])
3894 (label_ref (match_operand 0 "" ""))))]
3895 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3898 if (arc_ccfsm_branch_deleted_p ())
3900 arc_ccfsm_record_branch_deleted ();
3901 return \"; branch deleted, next insns conditionalized\";
3905 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3906 if (get_attr_length (insn) == 2)
3907 return \"b%D1%? %^%l0\";
3909 return \"b%D1%# %^%l0\";
3912 [(set_attr "type" "branch")
3916 (eq_attr "delay_slot_filled" "yes")
3921 (match_operand 1 "equality_comparison_operator" "")
3922 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3923 (gt (minus (match_dup 0) (pc))
3924 (minus (const_int 506)
3925 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3926 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3927 (lt (minus (match_dup 0) (pc)) (const_int -64))
3928 (gt (minus (match_dup 0) (pc))
3929 (minus (const_int 58)
3930 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3935 (set (attr "iscompact")
3936 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3937 (const_string "false")))])
3939 ;; Unconditional and other jump instructions.
3941 (define_expand "jump"
3942 [(set (pc) (label_ref (match_operand 0 "" "")))]
3946 (define_insn "jump_i"
3947 [(set (pc) (label_ref (match_operand 0 "" "")))]
3948 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3950 [(set_attr "type" "uncond_branch")
3951 (set (attr "iscompact")
3952 (if_then_else (match_test "get_attr_length (insn) == 2")
3953 (const_string "true") (const_string "false")))
3954 (set_attr "cond" "canuse")
3955 (set (attr "length")
3957 ; In arc_reorg we just guesstimate; might be more or less than 4.
3958 (match_test "arc_branch_size_unknown_p ()")
3961 (eq_attr "delay_slot_filled" "yes")
3964 (match_test "CROSSING_JUMP_P (insn)")
3967 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3968 (gt (minus (match_dup 0) (pc))
3969 (minus (const_int 506)
3970 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3974 (define_insn "indirect_jump"
3975 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3983 [(set_attr "type" "jump")
3984 (set_attr "iscompact" "false,false,false,maybe,false")
3985 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3987 ;; Implement a switch statement.
3989 (define_expand "casesi"
3991 (minus:SI (match_operand:SI 0 "register_operand" "")
3992 (match_operand:SI 1 "nonmemory_operand" "")))
3993 (set (reg:CC CC_REG)
3994 (compare:CC (match_dup 5)
3995 (match_operand:SI 2 "nonmemory_operand" "")))
3997 (if_then_else (gtu (reg:CC CC_REG)
3999 (label_ref (match_operand 4 "" ""))
4002 (unspec:SI [(match_operand 3 "" "")
4003 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
4004 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4010 operands[5] = gen_reg_rtx (SImode);
4011 operands[6] = gen_reg_rtx (SImode);
4012 operands[7] = operands[3];
4013 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4014 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4015 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4016 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4017 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4018 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
4019 if (TARGET_COMPACT_CASESI)
4021 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4025 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4026 if (flag_pic || !cse_not_expected)
4027 operands[3] = force_reg (Pmode, operands[3]);
4028 emit_insn (gen_casesi_load (operands[6],
4029 operands[3], operands[5], operands[7]));
4030 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4031 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4032 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4037 (define_insn "casesi_load"
4038 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
4039 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4040 (match_operand:SI 2 "register_operand" "Rcq,c,c")
4041 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
4045 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4047 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4049 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4050 gcc_assert (GET_MODE (diff_vec) == SImode);
4051 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4054 switch (GET_MODE (diff_vec))
4057 return \"ld.as %0,[%1,%2]%&\";
4059 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4060 return \"ld%_.as %0,[%1,%2]\";
4061 return \"ld%_.x.as %0,[%1,%2]\";
4063 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4064 return \"ldb%? %0,[%1,%2]%&\";
4065 return \"ldb.x %0,[%1,%2]\";
4070 [(set_attr "type" "load")
4071 (set_attr_alternative "iscompact"
4073 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4074 (as_a<rtx_insn *> (operands[3]))))")
4075 (symbol_ref "QImode"))
4076 (const_string "false")
4077 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4078 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4079 (const_string "false")]
4080 (const_string "true"))
4081 (const_string "false")
4082 (const_string "false")])
4083 (set_attr_alternative "length"
4085 [(eq_attr "iscompact" "false") (const_int 4)
4086 ; We have to mention (match_dup 3) to convince genattrtab.c that this
4087 ; is a varying length insn.
4088 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4089 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4094 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4095 ; even for CASE_VECTOR_PC_RELATIVE.
4096 (define_insn "casesi_jump"
4097 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4098 (use (label_ref (match_operand 1 "" "")))]
4101 [(set_attr "type" "jump")
4102 (set_attr "iscompact" "false,maybe,false")
4103 (set_attr "cond" "canuse")])
4105 (define_insn "casesi_compact_jump"
4107 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4109 (use (label_ref (match_operand 1 "" "")))
4110 (clobber (match_scratch:SI 2 "=q,0"))]
4111 "TARGET_COMPACT_CASESI"
4114 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4115 int unalign = arc_get_unalign ();
4119 xop[0] = operands[0];
4120 xop[2] = operands[2];
4121 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4123 switch (GET_MODE (diff_vec))
4126 /* Max length can be 12 in this case, but this is OK because
4127 2 of these are for alignment, and are anticipated in the length
4128 of the ADDR_DIFF_VEC. */
4129 if (unalign && !satisfies_constraint_Rcq (xop[0]))
4130 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
4132 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4134 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4135 arc_clear_unalign ();
4138 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4140 if (satisfies_constraint_Rcq (xop[0]))
4142 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
4143 xop[1] = GEN_INT ((10 - unalign) / 2U);
4147 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
4148 xop[1] = GEN_INT (10 + unalign);
4153 if (satisfies_constraint_Rcq (xop[0]))
4155 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
4156 xop[1] = GEN_INT ((10 - unalign) / 2U);
4160 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
4161 xop[1] = GEN_INT (10 + unalign);
4164 arc_toggle_unalign ();
4167 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4169 if ((rtx_equal_p (xop[2], xop[0])
4170 || find_reg_note (insn, REG_DEAD, xop[0]))
4171 && satisfies_constraint_Rcq (xop[0]))
4173 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4174 xop[1] = GEN_INT (8 + unalign);
4178 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4179 xop[1] = GEN_INT (10 + unalign);
4180 arc_toggle_unalign ();
4183 else if ((rtx_equal_p (xop[0], xop[2])
4184 || find_reg_note (insn, REG_DEAD, xop[0]))
4185 && satisfies_constraint_Rcq (xop[0]))
4187 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4188 xop[1] = GEN_INT (10 - unalign);
4189 arc_toggle_unalign ();
4193 /* ??? Length is 12. */
4194 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4195 xop[1] = GEN_INT (8 + unalign);
4201 output_asm_insn (s, xop);
4202 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4204 [(set_attr "length" "10")
4205 (set_attr "type" "jump")
4206 (set_attr "iscompact" "true")
4207 (set_attr "cond" "nocond")])
4209 (define_expand "call"
4210 ;; operands[1] is stack_size_rtx
4211 ;; operands[2] is next_arg_register
4212 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4213 (match_operand 1 "" ""))
4214 (clobber (reg:SI 31))])]
4219 gcc_assert (MEM_P (operands[0]));
4220 callee = XEXP (operands[0], 0);
4221 /* This is to decide if we should generate indirect calls by loading the
4222 32 bit address of the callee into a register before performing the
4223 branch and link - this exposes cse opportunities.
4224 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4225 if (GET_CODE (callee) != REG
4226 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4227 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4232 ; Rcq, which is used in alternative 0, checks for conditional execution.
4233 ; At instruction output time, if it doesn't match and we end up with
4234 ; alternative 1 ("q"), that means that we can't use the short form.
4235 (define_insn "*call_i"
4236 [(call (mem:SI (match_operand:SI 0
4237 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4238 (match_operand 1 "" ""))
4239 (clobber (reg:SI 31))]
4250 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4251 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4252 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4253 (set_attr "length" "*,*,4,4,4,4,4,8")])
4255 (define_expand "call_value"
4256 ;; operand 2 is stack_size_rtx
4257 ;; operand 3 is next_arg_register
4258 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4259 (call (match_operand:SI 1 "call_operand" "")
4260 (match_operand 2 "" "")))
4261 (clobber (reg:SI 31))])]
4267 gcc_assert (MEM_P (operands[1]));
4268 callee = XEXP (operands[1], 0);
4269 /* See the comment in define_expand \"call\". */
4270 if (GET_CODE (callee) != REG
4271 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4272 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4276 ; Rcq, which is used in alternative 0, checks for conditional execution.
4277 ; At instruction output time, if it doesn't match and we end up with
4278 ; alternative 1 ("q"), that means that we can't use the short form.
4279 (define_insn "*call_value_i"
4280 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
4281 (call (mem:SI (match_operand:SI 1
4282 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4283 (match_operand 2 "" "")))
4284 (clobber (reg:SI 31))]
4295 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4296 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4297 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4298 (set_attr "length" "*,*,4,4,4,4,4,8")])
4300 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4301 ; use it for lack of inter-procedural branch shortening.
4302 ; Link-time relaxation would help...
4305 [(trap_if (const_int 1) (const_int 0))]
4306 "!TARGET_ARC600_FAMILY"
4308 [(set_attr "type" "misc")
4309 (set_attr "length" "2")])
4315 [(set_attr "type" "misc")
4316 (set_attr "iscompact" "true")
4317 (set_attr "cond" "canuse")
4318 (set_attr "length" "2")])
4321 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4324 [(set_attr "type" "misc")
4325 (set_attr "iscompact" "true")
4326 (set_attr "length" "2")])
4328 ;; Split up troublesome insns for better scheduling.
4330 ;; Peepholes go at the end.
4331 ;;asl followed by add can be replaced by an add{1,2,3}
4332 ;; Three define_peepholes have been added for this optimization
4333 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4334 ;; can be generated by combine. Check if these peepholes still provide
4337 ;; -------------------------------------------------------------
4338 ;; Pattern 1 : r0 = r1 << {i}
4339 ;; r3 = r4/INT + r0 ;;and commutative
4342 ;; add{i} r3,r4/INT,r1
4343 ;; -------------------------------------------------------------
4344 ;; ??? This should be covered by combine, alas, at times combine gets
4345 ;; too clever for it's own good: when the shifted input is known to be
4346 ;; either 0 or 1, the operation will be made into an if-then-else, and
4347 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4348 ;; newlib/libc/time/mktm_r.c .
4351 [(set (match_operand:SI 0 "dest_reg_operand" "")
4352 (ashift:SI (match_operand:SI 1 "register_operand" "")
4353 (match_operand:SI 2 "const_int_operand" "")))
4354 (set (match_operand:SI 3 "dest_reg_operand" "")
4355 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4356 (match_operand:SI 5 "nonmemory_operand" "")))]
4357 "(INTVAL (operands[2]) == 1
4358 || INTVAL (operands[2]) == 2
4359 || INTVAL (operands[2]) == 3)
4360 && (true_regnum (operands[4]) == true_regnum (operands[0])
4361 || true_regnum (operands[5]) == true_regnum (operands[0]))
4362 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4363 ;; the preparation statements take care to put proper operand in operands[4]
4364 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4366 (plus:SI (mult:SI (match_dup 1)
4369 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4370 operands[4] = operands[5];
4371 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4374 ;; -------------------------------------------------------------
4375 ;; Pattern 1 : r0 = r1 << {i}
4380 ;; -------------------------------------------------------------
4381 ;; ??? This should be covered by combine, alas, at times combine gets
4382 ;; too clever for it's own good: when the shifted input is known to be
4383 ;; either 0 or 1, the operation will be made into an if-then-else, and
4384 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4385 ;; newlib/libm/math/e_jn.c .
4388 [(set (match_operand:SI 0 "dest_reg_operand" "")
4389 (ashift:SI (match_operand:SI 1 "register_operand" "")
4390 (match_operand:SI 2 "const_int_operand" "")))
4391 (set (match_operand:SI 3 "dest_reg_operand" "")
4392 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4394 "(INTVAL (operands[2]) == 1
4395 || INTVAL (operands[2]) == 2
4396 || INTVAL (operands[2]) == 3)
4397 && (peep2_reg_dead_p (2, operands[0])
4398 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4400 (minus:SI (match_dup 4)
4401 (mult:SI (match_dup 1)
4403 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4408 ; When using the high single bit, the result of a multiply is either
4409 ; the original number or zero. But MPY costs 4 cycles, which we
4410 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4412 [(set (match_operand:SI 0 "dest_reg_operand" "")
4413 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4415 (set (match_operand:SI 4 "register_operand" "")
4416 (mult:SI (match_operand:SI 2 "register_operand")
4417 (match_operand:SI 3 "nonmemory_operand" "")))]
4419 && (rtx_equal_p (operands[0], operands[2])
4420 || rtx_equal_p (operands[0], operands[3]))
4421 && peep2_regno_dead_p (0, CC_REG)
4422 && (rtx_equal_p (operands[0], operands[4])
4423 || (peep2_reg_dead_p (2, operands[0])
4424 && peep2_reg_dead_p (1, operands[4])))"
4425 [(parallel [(set (reg:CC_Z CC_REG)
4426 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4428 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4430 (ne (reg:CC_Z CC_REG) (const_int 0))
4431 (set (match_dup 4) (match_dup 5)))]
4433 if (!rtx_equal_p (operands[0], operands[2]))
4434 operands[5] = operands[2];
4435 else if (!rtx_equal_p (operands[0], operands[3]))
4436 operands[5] = operands[3];
4438 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4442 [(set (match_operand:SI 0 "dest_reg_operand" "")
4443 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4445 (set (match_operand:SI 4 "register_operand" "")
4446 (mult:SI (match_operand:SI 2 "register_operand")
4447 (match_operand:SI 3 "nonmemory_operand" "")))]
4449 && (rtx_equal_p (operands[0], operands[2])
4450 || rtx_equal_p (operands[0], operands[3]))
4451 && peep2_regno_dead_p (2, CC_REG)"
4452 [(parallel [(set (reg:CC_Z CC_REG)
4453 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4455 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4456 (set (match_dup 4) (match_dup 5))
4458 (eq (reg:CC_Z CC_REG) (const_int 0))
4459 (set (match_dup 4) (const_int 0)))]
4460 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4462 ;; Instructions generated through builtins
4464 (define_insn "clrsbsi2"
4465 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4466 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4471 [(set_attr "length" "4,8")
4472 (set_attr "type" "two_cycle_core,two_cycle_core")])
4474 (define_insn "norm_f"
4475 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4476 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4477 (set (reg:CC_ZN CC_REG)
4478 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4483 [(set_attr "length" "4,8")
4484 (set_attr "type" "two_cycle_core,two_cycle_core")])
4486 (define_insn_and_split "clrsbhi2"
4487 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4488 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4492 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4493 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4495 (define_insn "normw"
4496 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4498 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4503 [(set_attr "length" "4,8")
4504 (set_attr "type" "two_cycle_core,two_cycle_core")])
4506 (define_expand "clzsi2"
4508 [(set (match_operand:SI 0 "register_operand" "")
4509 (clz:SI (match_operand:SI 1 "register_operand" "")))
4510 (clobber (match_dup 2))])]
4512 "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);")
4514 (define_insn_and_split "*arc_clzsi2"
4515 [(set (match_operand:SI 0 "register_operand" "=r")
4516 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4517 (clobber (reg:CC_ZN CC_REG))]
4523 emit_insn (gen_norm_f (operands[0], operands[1]));
4527 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4528 gen_rtx_SET (operands[0], const0_rtx)));
4532 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4533 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4536 [(set_attr "type" "unary")
4537 (set_attr "length" "12")])
4539 (define_expand "ctzsi2"
4540 [(match_operand:SI 0 "register_operand" "")
4541 (match_operand:SI 1 "register_operand" "")]
4544 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4548 (define_insn_and_split "arc_ctzsi2"
4549 [(set (match_operand:SI 0 "register_operand" "=r")
4550 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4551 (clobber (reg:CC_ZN CC_REG))
4552 (clobber (match_scratch:SI 2 "=&r"))]
4558 rtx temp = operands[0];
4560 if (reg_overlap_mentioned_p (temp, operands[1])
4561 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4562 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4565 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4566 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4567 emit_insn (gen_clrsbsi2 (operands[0], temp));
4571 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4572 gen_rtx_SET (operands[0], GEN_INT (32))));
4576 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4577 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4581 [(set_attr "type" "unary")
4582 (set_attr "length" "20")])
4585 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4586 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4593 [(set_attr "length" "4,8,4")
4594 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4596 (define_insn "divaw"
4597 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4598 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4599 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4601 "TARGET_ARC700 || TARGET_EA_SET"
4605 divaw \t%0, %1, %S2"
4606 [(set_attr "length" "4,8,8")
4607 (set_attr "type" "divaw,divaw,divaw")])
4610 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4617 [(set_attr "length" "4,4,8")
4618 (set_attr "type" "misc,misc,misc")
4619 (set_attr "predicable" "yes,no,yes")
4620 (set_attr "cond" "clob,clob,clob")])
4623 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4627 [(set_attr "length" "4")
4628 (set_attr "type" "misc")])
4631 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4635 [(set_attr "length" "4")
4636 (set_attr "type" "misc")
4637 (set_attr "cond" "clob")])
4640 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4644 [(set_attr "length" "4")
4645 (set_attr "type" "misc")])
4648 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4658 [(set_attr "length" "4")
4659 (set_attr "type" "misc")])
4662 (define_insn "sleep"
4663 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4665 "check_if_valid_sleep_operand(operands,0)"
4667 [(set_attr "length" "4")
4668 (set_attr "type" "misc")])
4670 (define_insn "core_read"
4671 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4672 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4673 VUNSPEC_ARC_CORE_READ))]
4676 if (check_if_valid_regno_const (operands, 1))
4677 return \"mov \t%0, r%1\";
4678 return \"mov \t%0, r%1\";
4680 [(set_attr "length" "4")
4681 (set_attr "type" "unary")])
4683 (define_insn "core_write"
4684 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4685 (match_operand:SI 1 "general_operand" "Hn,!r")]
4686 VUNSPEC_ARC_CORE_WRITE)]
4689 if (check_if_valid_regno_const (operands, 1))
4690 return \"mov \tr%1, %0\";
4691 return \"mov \tr%1, %0\";
4693 [(set_attr "length" "4")
4694 (set_attr "type" "unary")])
4697 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4698 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4702 [(set_attr "length" "4,8,4,8")
4703 (set_attr "type" "lr,lr,lr,lr")])
4706 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4707 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4711 [(set_attr "length" "8,4,8,4")
4712 (set_attr "type" "sr,sr,sr,sr")])
4714 (define_insn "trap_s"
4715 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4716 VUNSPEC_ARC_TRAP_S)]
4717 "!TARGET_ARC600_FAMILY"
4719 if (which_alternative == 0)
4721 arc_toggle_unalign ();
4722 return \"trap_s %0\";
4725 /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4726 because *.md files do not get scanned by exgettext. */
4727 fatal_error (input_location,
4728 \"operand to trap_s should be an unsigned 6-bit value\");
4730 [(set_attr "length" "2")
4731 (set_attr "type" "misc")])
4733 (define_insn "unimp_s"
4734 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4735 VUNSPEC_ARC_UNIMP_S)]
4736 "!TARGET_ARC600_FAMILY"
4738 [(set_attr "length" "4")
4739 (set_attr "type" "misc")])
4741 ;; End of instructions generated through builtins
4743 ; Since the demise of REG_N_SETS as reliable data readily available to the
4744 ; target, it is no longer possible to find out
4745 ; in the prologue / epilogue expanders how many times blink is set.
4746 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4747 ; any explicit use of blink will cause it to be saved; hence we cannot
4748 ; represent the blink use in return / sibcall instructions themselves, and
4749 ; instead have to show it in EPILOGUE_USES and must explicitly
4750 ; forbid instructions that change blink in the return / sibcall delay slot.
4751 (define_expand "sibcall"
4752 [(parallel [(call (match_operand 0 "memory_operand" "")
4753 (match_operand 1 "general_operand" ""))
4755 (use (match_operand 2 "" ""))])]
4759 rtx callee = XEXP (operands[0], 0);
4761 if (operands[2] == NULL_RTX)
4762 operands[2] = const0_rtx;
4763 if (GET_CODE (callee) != REG
4764 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4765 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4769 (define_expand "sibcall_value"
4770 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4771 (call (match_operand 1 "memory_operand" "")
4772 (match_operand 2 "general_operand" "")))
4774 (use (match_operand 3 "" ""))])]
4778 rtx callee = XEXP (operands[1], 0);
4780 if (operands[3] == NULL_RTX)
4781 operands[3] = const0_rtx;
4782 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4783 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4787 (define_insn "*sibcall_insn"
4788 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4789 "Cbp,Cbr,Rs5,Rsc,Cal"))
4790 (match_operand 1 "" ""))
4792 (use (match_operand 2 "" ""))]
4800 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4801 (set_attr "predicable" "yes,no,no,yes,yes")
4802 (set_attr "iscompact" "false,false,maybe,false,false")
4803 (set_attr "is_SIBCALL" "yes")]
4806 (define_insn "*sibcall_value_insn"
4807 [(set (match_operand 0 "dest_reg_operand" "")
4808 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4809 "Cbp,Cbr,Rs5,Rsc,Cal"))
4810 (match_operand 2 "" "")))
4812 (use (match_operand 3 "" ""))]
4820 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4821 (set_attr "predicable" "yes,no,no,yes,yes")
4822 (set_attr "iscompact" "false,false,maybe,false,false")
4823 (set_attr "is_SIBCALL" "yes")]
4826 (define_expand "prologue"
4830 arc_expand_prologue ();
4834 (define_expand "epilogue"
4838 arc_expand_epilogue (0);
4842 (define_expand "sibcall_epilogue"
4846 arc_expand_epilogue (1);
4850 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4851 ; in the prologue / epilogue expanders how many times blink is set.
4852 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4853 ; any explicit use of blink will cause it to be saved; hence we cannot
4854 ; represent the blink use in return / sibcall instructions themselves, and
4855 ; instead have to show it in EPILOGUE_USES and must explicitly
4856 ; forbid instructions that change blink in the return / sibcall delay slot.
4857 (define_insn "simple_return"
4862 = gen_rtx_REG (Pmode,
4863 arc_return_address_register (arc_compute_function_type
4867 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
4871 if (TARGET_PAD_RETURN)
4873 output_asm_insn (\"j%!%* [%0]%&\", ®);
4877 (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
4878 (match_test "TARGET_V2"))
4879 (const_string "brcc_no_delay_slot")]
4880 (const_string "return")))
4881 ; predicable won't help here since the canonical rtl looks different
4884 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4885 (symbol_ref "ARC_FUNCTION_ILINK1"))
4886 (match_test "TARGET_V2"))
4887 (const_string "nocond")]
4888 (const_string "canuse")))
4889 (set (attr "iscompact")
4890 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4891 (symbol_ref "ARC_FUNCTION_NORMAL"))
4892 (const_string "maybe")]
4893 (const_string "false")))
4894 (set (attr "length")
4895 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4896 (symbol_ref "ARC_FUNCTION_NORMAL"))
4900 (define_insn "p_return_i"
4902 (if_then_else (match_operator 0 "proper_comparison_operator"
4903 [(reg CC_REG) (const_int 0)])
4904 (simple_return) (pc)))]
4907 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
4910 xop[0] = operands[0];
4912 = gen_rtx_REG (Pmode,
4913 arc_return_address_register (arc_compute_function_type
4916 if (TARGET_PAD_RETURN)
4918 output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4919 /* record the condition in case there is a delay insn. */
4920 arc_ccfsm_record_condition (xop[0], false, insn, 0);
4923 [(set_attr "type" "return")
4924 (set_attr "cond" "use")
4925 (set (attr "iscompact")
4926 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4927 (symbol_ref "ARC_FUNCTION_NORMAL"))
4928 (const_string "maybe")]
4929 (const_string "false")))
4930 (set (attr "length")
4931 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4932 (symbol_ref "ARC_FUNCTION_NORMAL"))
4934 (not (match_operand 0 "equality_comparison_operator" ""))
4936 (eq_attr "delay_slot_filled" "yes")
4940 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4941 ;; non-constant predicate.
4942 (define_expand "return"
4946 ;; Comment in final.c (insn_current_reference_address) says
4947 ;; forward branch addresses are calculated from the next insn after branch
4948 ;; and for backward branches, it is calculated from the branch insn start.
4949 ;; The shortening logic here is tuned to accomodate this behavior
4950 ;; ??? This should be grokked by the ccfsm machinery.
4951 (define_insn "cbranchsi4_scratch"
4953 (if_then_else (match_operator 0 "proper_comparison_operator"
4954 [(match_operand:SI 1 "register_operand" "c,c, c")
4955 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4956 (label_ref (match_operand 3 "" ""))
4958 (clobber (match_operand 4 "cc_register" ""))]
4960 || (TARGET_EARLY_CBRANCHSI
4961 && brcc_nolimm_operator (operands[0], VOIDmode)))
4962 && !CROSSING_JUMP_P (insn)"
4964 switch (get_attr_length (insn))
4966 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4967 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4968 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4969 return \"br%d0%* %1, %B2, %^%l3\";
4972 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
4973 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4976 [(set_attr "cond" "clob, clob, clob")
4979 (match_test "valid_brcc_with_delay_p (operands)")
4980 (const_string "brcc")
4981 (const_string "brcc_no_delay_slot")))
4982 ; For forward branches, we need to account not only for the distance to
4983 ; the target, but also the difference between pcl and pc, the instruction
4984 ; length, and any delay insn, if present.
4987 (cond ; the outer cond does a test independent of branch shortening.
4988 [(match_operand 0 "brcc_nolimm_operator" "")
4990 [(and (match_operand:CC_Z 4 "cc_register")
4991 (eq_attr "delay_slot_filled" "no")
4992 (ge (minus (match_dup 3) (pc)) (const_int -128))
4993 (le (minus (match_dup 3) (pc))
4994 (minus (const_int 122)
4995 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4997 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4998 (le (minus (match_dup 3) (pc))
4999 (minus (const_int 244)
5000 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5002 (and (match_operand:SI 1 "compact_register_operand" "")
5003 (match_operand:SI 2 "compact_hreg_operand" ""))
5006 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5007 (le (minus (match_dup 3) (pc)) (const_int 244)))
5009 (and (match_operand:SI 1 "compact_register_operand" "")
5010 (match_operand:SI 2 "compact_hreg_operand" ""))
5013 (set (attr "iscompact")
5014 (if_then_else (match_test "get_attr_length (insn) & 2")
5015 (const_string "true") (const_string "false")))])
5017 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5018 (define_insn "*bbit"
5021 (match_operator 3 "equality_comparison_operator"
5022 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5024 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5026 (label_ref (match_operand 0 "" ""))
5028 (clobber (reg:CC_ZN CC_REG))]
5029 "!CROSSING_JUMP_P (insn)"
5031 switch (get_attr_length (insn))
5033 case 4: return (GET_CODE (operands[3]) == EQ
5034 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5036 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5037 default: gcc_unreachable ();
5040 [(set_attr "type" "brcc")
5041 (set_attr "cond" "clob")
5042 (set (attr "length")
5043 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5044 (le (minus (match_dup 0) (pc))
5045 (minus (const_int 248)
5046 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5048 (eq (symbol_ref "which_alternative") (const_int 0))
5051 (set (attr "iscompact")
5052 (if_then_else (match_test "get_attr_length (insn) == 6")
5053 (const_string "true") (const_string "false")))])
5055 ; ??? When testing a bit from a DImode register, combine creates a
5056 ; zero_extract in DImode. This goes via an AND with a DImode constant,
5057 ; so can only be observed on 64 bit hosts.
5058 (define_insn_and_split "*bbit_di"
5061 (match_operator 3 "equality_comparison_operator"
5062 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
5064 (match_operand 2 "immediate_operand" "L,L"))
5066 (label_ref (match_operand 0 "" ""))
5068 (clobber (reg:CC_ZN CC_REG))]
5069 "!CROSSING_JUMP_P (insn)"
5073 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
5074 (clobber (reg:CC_ZN CC_REG))])]
5078 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5079 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5083 ;; -------------------------------------------------------------------
5085 ;; -------------------------------------------------------------------
5087 ; operand 0 is the loop count pseudo register
5088 ; operand 1 is the label to jump to at the top of the loop
5089 (define_expand "doloop_end"
5090 [(parallel [(set (pc)
5092 (ne (match_operand 0 "" "")
5094 (label_ref (match_operand 1 "" ""))
5096 (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5097 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5098 (clobber (match_dup 2))])]
5101 if (GET_MODE (operands[0]) != SImode)
5103 operands[2] = gen_rtx_SCRATCH (SImode);
5106 (define_insn "arc_lp"
5107 [(unspec:SI [(match_operand:SI 0 "register_operand" "l")]
5109 (use (label_ref (match_operand 1 "" "")))
5110 (use (label_ref (match_operand 2 "" "")))]
5112 "lp\\t@%l2\\t; %0:@%l1->@%l2"
5113 [(set_attr "type" "loop_setup")
5114 (set_attr "length" "4")])
5116 ;; if by any chance the lp_count is not used, then use an 'r'
5117 ;; register, instead of going to memory.
5118 (define_insn "loop_end"
5120 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
5122 (label_ref (match_operand 1 "" ""))
5124 (set (match_operand:SI 0 "nonimmediate_operand" "=l!r,m")
5125 (plus (match_dup 2) (const_int -1)))
5126 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5127 (clobber (match_scratch:SI 3 "=X,&r"))]
5130 [(set_attr "length" "0")
5131 (set_attr "predicable" "no")
5132 (set_attr "type" "loop_end")])
5134 ;; split pattern for the very slim chance when the loop register is
5138 (if_then_else (ne (match_operand:SI 0 "memory_operand")
5140 (label_ref (match_operand 1 ""))
5142 (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5143 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5144 (clobber (match_scratch:SI 2))]
5145 "memory_operand (operands[0], SImode)"
5146 [(set (match_dup 2) (match_dup 0))
5147 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5148 (set (match_dup 0) (match_dup 2))
5149 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5151 (if_then_else (ne (reg:CC CC_REG)
5153 (label_ref (match_dup 1))
5157 (define_insn "loop_fail"
5158 [(set (reg:SI LP_COUNT)
5159 (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5160 (set (reg:CC_ZN CC_REG)
5161 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5164 "sub.f%?\\tlp_count,lp_count,1"
5165 [(set_attr "iscompact" "false")
5166 (set_attr "type" "compare")
5167 (set_attr "cond" "set_zn")
5168 (set_attr "length" "4")
5169 (set_attr "predicable" "yes")])
5171 (define_insn_and_split "dbnz"
5174 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+r!l,m")
5177 (label_ref (match_operand 1 "" ""))
5180 (plus:SI (match_dup 0)
5182 (clobber (match_scratch:SI 2 "=X,r"))]
5187 "TARGET_V2 && reload_completed && memory_operand (operands[0], SImode)"
5188 [(set (match_dup 2) (match_dup 0))
5189 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5190 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5191 (set (match_dup 0) (match_dup 2))
5192 (set (pc) (if_then_else (ge (reg:CC CC_REG)
5194 (label_ref (match_dup 1))
5197 [(set_attr "iscompact" "false")
5198 (set_attr "type" "loop_end")
5199 (set_attr "length" "4,20")])
5201 (define_expand "movmemsi"
5202 [(match_operand:BLK 0 "" "")
5203 (match_operand:BLK 1 "" "")
5204 (match_operand:SI 2 "nonmemory_operand" "")
5205 (match_operand 3 "immediate_operand" "")]
5207 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5209 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5210 ;; to the point that we can generate cmove instructions.
5211 (define_expand "cbranch<mode>4"
5212 [(set (reg:CC CC_REG)
5213 (compare:CC (match_operand:SDF 1 "register_operand" "")
5214 (match_operand:SDF 2 "register_operand" "")))
5217 (match_operator 0 "comparison_operator" [(reg CC_REG)
5219 (label_ref (match_operand 3 "" ""))
5222 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5224 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5225 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5226 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5227 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5231 (define_expand "cmp_float"
5232 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5233 (clobber (reg:SI RETURN_ADDR_REGNUM))
5234 (clobber (reg:SI R12_REG))])]
5238 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5239 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5240 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5242 (define_insn "*cmpsf_<cmp>"
5243 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5244 (clobber (reg:SI RETURN_ADDR_REGNUM))
5245 (clobber (reg:SI R12_REG))]
5246 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5247 && SFUNC_CHECK_PREDICABLE"
5248 "*return arc_output_libcall (\"__<cmp>sf2\");"
5249 [(set_attr "is_sfunc" "yes")
5250 (set_attr "predicable" "yes")])
5252 ;; N.B. for "*cmpdf_ord":
5253 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5254 ;; for the floating point emulation to recognize the NaN.
5255 (define_insn "*cmpdf_<cmp>"
5256 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5257 (clobber (reg:SI RETURN_ADDR_REGNUM))
5258 (clobber (reg:SI R12_REG))]
5259 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5260 && SFUNC_CHECK_PREDICABLE"
5261 "*return arc_output_libcall (\"__<cmp>df2\");"
5262 [(set_attr "is_sfunc" "yes")
5263 (set_attr "predicable" "yes")])
5265 (define_insn "abssf2"
5266 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5267 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5270 [(set_attr "type" "unary")
5271 (set_attr "iscompact" "maybe,false,false")
5272 (set_attr "length" "2,4,4")
5273 (set_attr "predicable" "no,yes,no")])
5275 (define_insn "negsf2"
5276 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5277 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5280 [(set_attr "type" "unary")
5281 (set_attr "predicable" "yes,no")])
5283 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5284 (define_insn "*millicode_thunk_st"
5285 [(match_parallel 0 "millicode_store_operation"
5286 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5289 output_asm_insn ("bl%* __st_r13_to_%0",
5290 &SET_SRC (XVECEXP (operands[0], 0,
5291 XVECLEN (operands[0], 0) - 2)));
5294 [(set_attr "type" "call")])
5296 (define_insn "*millicode_thunk_ld"
5297 [(match_parallel 0 "millicode_load_clob_operation"
5298 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5301 output_asm_insn ("bl%* __ld_r13_to_%0",
5302 &SET_DEST (XVECEXP (operands[0], 0,
5303 XVECLEN (operands[0], 0) - 2)));
5306 [(set_attr "type" "call")])
5308 ; the sibthunk restores blink, so we use the return rtx.
5309 (define_insn "*millicode_sibthunk_ld"
5310 [(match_parallel 0 "millicode_load_operation"
5312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5313 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5316 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5317 &SET_DEST (XVECEXP (operands[0], 0,
5318 XVECLEN (operands[0], 0) - 1)));
5321 [(set_attr "type" "call")
5322 (set_attr "is_SIBCALL" "yes")])
5324 (define_insn "tls_load_tp_soft"
5325 [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5326 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5328 "*return arc_output_libcall (\"__read_tp\");"
5329 [(set_attr "is_sfunc" "yes")
5330 (set_attr "predicable" "yes")])
5332 (define_insn "tls_gd_get_addr"
5333 [(set (reg:SI R0_REG)
5334 (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5335 "symbolic_operand" "X,X")]
5338 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5340 ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5341 [(set_attr "type" "call")
5342 ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5343 (set_attr "predicable" "no")])
5345 ;; For thread pointer builtins
5346 (define_expand "get_thread_pointersi"
5347 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5349 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5351 (define_expand "set_thread_pointersi"
5352 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5354 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5356 ;; If hardware floating point is available, don't define a negdf pattern;
5357 ;; it would be something like:
5358 ;;(define_insn "negdf2"
5359 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5360 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5361 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5364 ;; bxor%? %H0,%H1,31
5365 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5366 ;; drsubh%F0%F1 0,0,0
5367 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5368 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5369 ;; (set_attr "iscompact" "false,false,false,false")
5370 ;; (set_attr "length" "4,4,8,12")
5371 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5372 ;; and this suffers from always requiring a long immediate when using
5373 ;; the floating point hardware.
5374 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5375 ;; constant zero efficiently into a register when we want to do the
5376 ;; computation using the floating point hardware. There should be a special
5377 ;; subdf alternative that matches a zero operand 1, which then can allow
5378 ;; to use bxor to flip the high bit of an integer register.
5379 ;; ??? we actually can't use the floating point hardware for neg, because
5380 ;; this would not work right for -0. OTOH optabs.c has already code
5381 ;; to synthesyze negate by flipping the sign bit.
5384 (define_insn "bswapsi2"
5385 [(set (match_operand:SI 0 "register_operand" "= r,r")
5386 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5387 "TARGET_V2 && TARGET_SWAP"
5389 [(set_attr "length" "4,8")
5390 (set_attr "type" "two_cycle_core")])
5392 (define_expand "prefetch"
5393 [(prefetch (match_operand:SI 0 "address_operand" "")
5394 (match_operand:SI 1 "const_int_operand" "")
5395 (match_operand:SI 2 "const_int_operand" ""))]
5399 (define_insn "prefetch_1"
5400 [(prefetch (match_operand:SI 0 "register_operand" "r")
5401 (match_operand:SI 1 "const_int_operand" "n")
5402 (match_operand:SI 2 "const_int_operand" "n"))]
5405 if (INTVAL (operands[1]))
5406 return "prefetchw [%0]";
5408 return "prefetch [%0]";
5410 [(set_attr "type" "load")
5411 (set_attr "length" "4")])
5413 (define_insn "prefetch_2"
5414 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5415 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5416 (match_operand:SI 2 "const_int_operand" "n,n,n")
5417 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5420 if (INTVAL (operands[2]))
5421 return "prefetchw [%0, %1]";
5423 return "prefetch [%0, %1]";
5425 [(set_attr "type" "load")
5426 (set_attr "length" "4,4,8")])
5428 (define_insn "prefetch_3"
5429 [(prefetch (match_operand:SI 0 "address_operand" "p")
5430 (match_operand:SI 1 "const_int_operand" "n")
5431 (match_operand:SI 2 "const_int_operand" "n"))]
5434 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5435 if (INTVAL (operands[1]))
5436 return "prefetchw%U0 %0";
5438 return "prefetch%U0 %0";
5440 [(set_attr "type" "load")
5441 (set_attr "length" "8")])
5443 (define_insn "divsi3"
5444 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5445 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5446 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5449 [(set_attr "length" "4,4,8,4,4,4,8,8")
5450 (set_attr "iscompact" "false")
5451 (set_attr "type" "div_rem")
5452 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5453 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5456 (define_insn "udivsi3"
5457 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5458 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5459 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5462 [(set_attr "length" "4,4,8,4,4,4,8,8")
5463 (set_attr "iscompact" "false")
5464 (set_attr "type" "div_rem")
5465 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5466 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5469 (define_insn "modsi3"
5470 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5471 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5472 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5475 [(set_attr "length" "4,4,8,4,4,4,8,8")
5476 (set_attr "iscompact" "false")
5477 (set_attr "type" "div_rem")
5478 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5479 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5482 (define_insn "umodsi3"
5483 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5484 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5485 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5488 [(set_attr "length" "4,4,8,4,4,4,8,8")
5489 (set_attr "iscompact" "false")
5490 (set_attr "type" "div_rem")
5491 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5492 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5495 ;; SETcc instructions
5496 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5498 (define_insn "arcset<code>"
5499 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5500 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5501 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5502 "TARGET_V2 && TARGET_CODE_DENSITY"
5503 "set<code>%? %0, %1, %2"
5504 [(set_attr "length" "4,4,4,4,4,8,8")
5505 (set_attr "iscompact" "false")
5506 (set_attr "type" "compare")
5507 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5508 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5511 (define_insn "arcsetltu"
5512 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5513 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5514 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5515 "TARGET_V2 && TARGET_CODE_DENSITY"
5516 "setlo%? %0, %1, %2"
5517 [(set_attr "length" "4,4,4,4,4,8,8")
5518 (set_attr "iscompact" "false")
5519 (set_attr "type" "compare")
5520 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5521 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5524 (define_insn "arcsetgeu"
5525 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5526 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5527 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5528 "TARGET_V2 && TARGET_CODE_DENSITY"
5529 "seths%? %0, %1, %2"
5530 [(set_attr "length" "4,4,4,4,4,8,8")
5531 (set_attr "iscompact" "false")
5532 (set_attr "type" "compare")
5533 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5534 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5537 ;; Special cases of SETCC
5538 (define_insn_and_split "arcsethi"
5539 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5540 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5541 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5542 "TARGET_V2 && TARGET_CODE_DENSITY"
5543 "setlo%? %0, %2, %1"
5545 && CONST_INT_P (operands[2])
5546 && satisfies_constraint_C62 (operands[2])"
5549 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5550 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5551 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5554 [(set_attr "length" "4,4,4,8")
5555 (set_attr "iscompact" "false")
5556 (set_attr "type" "compare")
5557 (set_attr "predicable" "yes,no,no,no")
5558 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5561 (define_insn_and_split "arcsetls"
5562 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5563 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5564 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5565 "TARGET_V2 && TARGET_CODE_DENSITY"
5566 "seths%? %0, %2, %1"
5568 && CONST_INT_P (operands[2])
5569 && satisfies_constraint_C62 (operands[2])"
5572 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5573 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5574 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5577 [(set_attr "length" "4,4,4,8")
5578 (set_attr "iscompact" "false")
5579 (set_attr "type" "compare")
5580 (set_attr "predicable" "yes,no,no,no")
5581 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5584 ; Any mode that needs to be solved by secondary reload
5585 (define_mode_iterator SRI [QI HI])
5587 (define_expand "reload_<mode>_load"
5588 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5589 (match_operand:SRI 1 "memory_operand" "m")
5590 (match_operand:SI 2 "register_operand" "=&r")])]
5593 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5597 (define_expand "reload_<mode>_store"
5598 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5599 (match_operand:SRI 1 "register_operand" "r")
5600 (match_operand:SI 2 "register_operand" "=&r")])]
5603 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5608 (define_insn "extzvsi"
5609 [(set (match_operand:SI 0 "register_operand" "=r , r , r, r, r")
5610 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, 0, r")
5611 (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5612 (match_operand:SI 3 "const_int_operand" "i , i , i, i, i")))]
5613 "TARGET_HS && TARGET_BARREL_SHIFTER"
5615 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5616 operands[2] = GEN_INT (assemble_op2);
5617 return "xbfu%? %0,%1,%2";
5619 [(set_attr "type" "shift")
5620 (set_attr "iscompact" "false")
5621 (set_attr "length" "4,4,4,8,8")
5622 (set_attr "predicable" "yes,no,no,yes,no")
5623 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
5625 (define_insn "kflag"
5626 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5633 [(set_attr "length" "4,4,8")
5634 (set_attr "type" "misc,misc,misc")
5635 (set_attr "predicable" "yes,no,yes")
5636 (set_attr "cond" "clob,clob,clob")])
5639 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5640 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5644 [(set_attr "length" "4")
5645 (set_attr "type" "misc")])
5648 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5649 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5651 "TARGET_NORM && TARGET_V2"
5655 [(set_attr "length" "4,8")
5656 (set_attr "type" "two_cycle_core,two_cycle_core")])
5658 (define_insn "ffs_f"
5659 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5660 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5662 (set (reg:CC_ZN CC_REG)
5663 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5664 "TARGET_NORM && TARGET_V2"
5668 [(set_attr "length" "4,8")
5669 (set_attr "type" "two_cycle_core,two_cycle_core")])
5671 (define_expand "ffssi2"
5672 [(parallel [(set (match_dup 2)
5673 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5675 (set (reg:CC_ZN CC_REG)
5676 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5677 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5678 (set (match_operand:SI 0 "dest_reg_operand" "")
5679 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5682 "TARGET_NORM && TARGET_V2"
5684 operands[2] = gen_reg_rtx (SImode);
5688 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5689 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5691 "TARGET_NORM && TARGET_V2"
5695 [(set_attr "length" "4,8")
5696 (set_attr "type" "two_cycle_core,two_cycle_core")])
5699 [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5703 [(set_attr "length" "4")
5704 (set_attr "type" "misc")])
5709 (define_expand "addsf3"
5710 [(set (match_operand:SF 0 "register_operand" "")
5711 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5712 (match_operand:SF 2 "nonmemory_operand" "")))]
5713 "TARGET_FP_SP_BASE || TARGET_SPFP"
5715 if (!register_operand (operands[1], SFmode)
5716 && !register_operand (operands[2], SFmode))
5717 operands[1] = force_reg (SFmode, operands[1]);
5721 (define_expand "subsf3"
5722 [(set (match_operand:SF 0 "register_operand" "")
5723 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5724 (match_operand:SF 2 "nonmemory_operand" "")))]
5725 "TARGET_FP_SP_BASE || TARGET_SPFP"
5727 if (!register_operand (operands[1], SFmode)
5728 && !register_operand (operands[2], SFmode))
5729 operands[1] = force_reg (SFmode, operands[1]);
5733 (define_expand "mulsf3"
5734 [(set (match_operand:SF 0 "register_operand" "")
5735 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5736 (match_operand:SF 2 "nonmemory_operand" "")))]
5737 "TARGET_FP_SP_BASE || TARGET_SPFP"
5739 if (!register_operand (operands[1], SFmode)
5740 && !register_operand (operands[2], SFmode))
5741 operands[1] = force_reg (SFmode, operands[1]);
5745 (define_expand "adddf3"
5746 [(set (match_operand:DF 0 "double_register_operand" "")
5747 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5748 (match_operand:DF 2 "nonmemory_operand" "")))]
5749 "TARGET_FP_DP_BASE || TARGET_DPFP"
5753 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5755 rtx first, second, tmp;
5756 split_double (operands[2], &first, &second);
5757 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5758 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5759 operands[2], tmp, const0_rtx));
5762 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5763 operands[2], const1_rtx, const1_rtx));
5766 else if (TARGET_FP_DP_BASE)
5768 if (!even_register_operand (operands[2], DFmode))
5769 operands[2] = force_reg (DFmode, operands[2]);
5771 if (!even_register_operand (operands[1], DFmode))
5772 operands[1] = force_reg (DFmode, operands[1]);
5779 (define_expand "subdf3"
5780 [(set (match_operand:DF 0 "double_register_operand" "")
5781 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5782 (match_operand:DF 2 "nonmemory_operand" "")))]
5783 "TARGET_FP_DP_BASE || TARGET_DPFP"
5787 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5788 operands[1] = force_reg (DFmode, operands[1]);
5789 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5790 || GET_CODE (operands[2]) == CONST_DOUBLE)
5792 rtx first, second, tmp;
5793 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5794 split_double (operands[const_index], &first, &second);
5795 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5796 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5797 operands[2], tmp, const0_rtx));
5800 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5801 operands[2], const1_rtx, const1_rtx));
5804 else if (TARGET_FP_DP_BASE)
5806 if (!even_register_operand (operands[2], DFmode))
5807 operands[2] = force_reg (DFmode, operands[2]);
5809 if (!even_register_operand (operands[1], DFmode))
5810 operands[1] = force_reg (DFmode, operands[1]);
5817 (define_expand "muldf3"
5818 [(set (match_operand:DF 0 "double_register_operand" "")
5819 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5820 (match_operand:DF 2 "nonmemory_operand" "")))]
5821 "TARGET_FP_DP_BASE || TARGET_DPFP"
5825 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5827 rtx first, second, tmp;
5828 split_double (operands[2], &first, &second);
5829 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5830 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5831 operands[2], tmp, const0_rtx));
5834 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5835 operands[2], const1_rtx, const1_rtx));
5838 else if (TARGET_FP_DP_BASE)
5840 if (!even_register_operand (operands[2], DFmode))
5841 operands[2] = force_reg (DFmode, operands[2]);
5843 if (!even_register_operand (operands[1], DFmode))
5844 operands[1] = force_reg (DFmode, operands[1]);
5851 (define_expand "divsf3"
5852 [(set (match_operand:SF 0 "register_operand" "")
5853 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5854 (match_operand:SF 2 "nonmemory_operand" "")))]
5855 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5857 if (TARGET_FPX_QUARK)
5859 operands[1] = force_reg (SFmode, operands[1]);
5860 operands[2] = force_reg (SFmode, operands[2]);
5864 if (!register_operand (operands[1], SFmode)
5865 && !register_operand (operands[2], SFmode))
5866 operands[1] = force_reg (SFmode, operands[1]);
5871 (define_expand "sqrtsf2"
5872 [(set (match_operand:SF 0 "register_operand" "")
5873 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5874 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5876 if (TARGET_FPX_QUARK)
5878 operands[1] = force_reg (SFmode, operands[1]);
5882 ;; SF->SI (using rounding towards zero)
5883 (define_expand "fix_truncsfsi2"
5884 [(set (match_operand:SI 0 "register_operand" "")
5885 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5886 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5890 (define_expand "floatsisf2"
5891 [(set (match_operand:SF 0 "register_operand" "")
5892 (float:SF (match_operand:SI 1 "register_operand" "")))]
5893 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5896 (define_expand "extzv"
5897 [(set (match_operand:SI 0 "register_operand" "")
5898 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5899 (match_operand:SI 2 "const_int_operand" "")
5900 (match_operand:SI 3 "const_int_operand" "")))]
5901 "TARGET_NPS_BITOPS")
5903 ; We need a sanity check in the instuction predicate because combine
5904 ; will throw any old rubbish at us and see what sticks.
5905 (define_insn "*extzv_i"
5906 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5907 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5908 (match_operand:SI 2 "const_int_operand" "n")
5909 (match_operand:SI 3 "const_int_operand" "n")))]
5910 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5911 "movb.cl %0,%1,0,%3,%2"
5912 [(set_attr "type" "shift")
5913 (set_attr "length" "4")])
5915 (define_expand "insv"
5916 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5917 (match_operand:SI 1 "const_int_operand" "")
5918 (match_operand:SI 2 "const_int_operand" ""))
5919 (match_operand:SI 3 "nonmemory_operand" ""))]
5922 int size = INTVAL (operands[1]);
5924 if (size != 1 && size != 2 && size != 4 && size != 8)
5925 operands[3] = force_reg (SImode, operands[3]);
5928 (define_insn "*insv_i"
5929 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5930 (match_operand:SI 1 "const_int_operand" "C18,n")
5931 (match_operand:SI 2 "const_int_operand" "n,n"))
5932 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5934 && (register_operand (operands[3], SImode)
5935 || satisfies_constraint_C18 (operands[1]))"
5937 movbi %0,%0,%3,%2,%1
5938 movb %0,%0,%3,%2,0,%1"
5939 [(set_attr "type" "shift")
5940 (set_attr "length" "4")])
5942 (define_insn "*movb"
5943 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5944 (match_operand:SI 1 "const_int_operand" "n")
5945 (match_operand:SI 2 "const_int_operand" "n"))
5946 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5948 (match_operand:SI 4 "const_int_operand" "n")))]
5950 "movb %0,%0,%3,%2,%4,%1"
5951 [(set_attr "type" "shift")
5952 (set_attr "length" "4")])
5954 (define_insn "*movb_signed"
5955 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5956 (match_operand:SI 1 "const_int_operand" "n")
5957 (match_operand:SI 2 "const_int_operand" "n"))
5958 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5960 (match_operand:SI 4 "const_int_operand" "n")))]
5962 "movb %0,%0,%3,%2,%4,%1"
5963 [(set_attr "type" "shift")
5964 (set_attr "length" "4")])
5966 (define_insn "*movb_high"
5967 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5968 (match_operand:SI 1 "const_int_operand" "n")
5969 (match_operand:SI 2 "const_int_operand" "n"))
5970 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5971 (match_operand:SI 4 "const_int_operand" "n")))]
5973 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5974 "movb %0,%0,%3,%2,%4,%1"
5975 [(set_attr "type" "shift")
5976 (set_attr "length" "4")])
5978 ; N.B.: when processing signed bitfields that fit in the top half of
5979 ; a word, gcc will use a narrow sign extending load, and in this case
5980 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
5981 (define_insn "*movb_high_signed"
5982 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5983 (match_operand:SI 1 "const_int_operand" "n")
5984 (match_operand:SI 2 "const_int_operand" "n"))
5985 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
5986 (match_operand:SI 4 "const_int_operand" "n")))]
5988 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
5989 "movb %0,%0,%3,%2,%4,%1"
5990 [(set_attr "type" "shift")
5991 (set_attr "length" "4")])
5994 [(set (match_operand:SI 0 "register_operand" "")
5995 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
5996 (match_operand:SI 2 "const_int_operand" ""))
5997 (subreg:SI (match_operand 3 "") 0)))]
5999 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6000 && !reg_overlap_mentioned_p (operands[0], operands[1])"
6001 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6002 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6004 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6006 (define_insn "*mrgb"
6007 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6008 (match_operand:SI 1 "const_int_operand" "n")
6009 (match_operand:SI 2 "const_int_operand" "n"))
6010 (zero_extract:SI (match_dup 0) (match_dup 1)
6011 (match_operand:SI 3 "const_int_operand" "n")))
6012 (set (zero_extract:SI (match_dup 0)
6013 (match_operand:SI 4 "const_int_operand" "n")
6014 (match_operand:SI 5 "const_int_operand" "n"))
6015 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6017 (match_operand:SI 7 "const_int_operand" "n")))]
6020 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6021 /* The ;%? updates the known unalignment. */
6022 return arc_short_long (insn, ";%?", "nop_s");
6024 [(set_attr "type" "shift")
6025 (set_attr "length" "6")
6026 (set_attr "iscompact" "true")])
6028 ;; combine fumbles combination of two movb patterns, and then the
6029 ;; combination is rejected by combinable_i3pat.
6030 ;; Thus, we can only use a peephole2 to combine two such insns.
6033 [(set (match_operand:SI 0 "register_operand" "")
6034 (match_operand:SI 1 "register_operand" ""))
6035 (set (zero_extract:SI (match_dup 0)
6036 (match_operand:SI 2 "const_int_operand" "")
6037 (match_operand:SI 3 "const_int_operand" ""))
6038 (zero_extract:SI (match_dup 1)
6040 (match_operand:SI 4 "const_int_operand" "")))
6041 (match_operand 9) ; unrelated insn scheduled here
6042 (set (zero_extract:SI (match_dup 0)
6043 (match_operand:SI 5 "const_int_operand" "")
6044 (match_operand:SI 6 "const_int_operand" ""))
6045 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6047 (match_operand:SI 8 "const_int_operand" "")))]
6049 // Check that the second movb doesn't clobber an input of the extra insn.
6050 && !reg_overlap_mentioned_p (operands[0], operands[9])
6052 && !reg_set_p (operands[0], operands[9])
6053 && !reg_set_p (operands[7], operands[9])"
6054 [(set (match_dup 0) (match_dup 1))
6055 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6056 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6057 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6058 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6062 [(set (match_operand:SI 0 "register_operand" "")
6063 (match_operand:SI 1 "register_operand" ""))
6064 (set (zero_extract:SI (match_dup 0)
6065 (match_operand:SI 2 "const_int_operand" "")
6066 (match_operand:SI 3 "const_int_operand" ""))
6067 (zero_extract:SI (match_dup 1)
6069 (match_operand:SI 4 "const_int_operand" "")))
6070 (set (match_dup 1) (match_operand 8))
6071 (set (zero_extract:SI (match_dup 0)
6072 (match_operand:SI 5 "const_int_operand" "")
6073 (match_operand:SI 6 "const_int_operand" ""))
6074 (zero_extract:SI (match_dup 1) (match_dup 5)
6075 (match_operand:SI 7 "const_int_operand" "")))]
6077 && !reg_overlap_mentioned_p (operands[0], operands[8])"
6078 [(set (match_dup 0) (match_dup 1))
6079 (set (match_dup 1) (match_dup 8))
6080 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6081 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6082 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6083 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6086 (define_insn "*rotrsi3_cnt1"
6087 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
6088 (rotatert:SI (match_operand:SI 1 "register_operand" "c")
6092 [(set_attr "type" "shift")
6093 (set_attr "predicable" "no")
6094 (set_attr "length" "4")])
6096 (define_insn "*ashlsi2_cnt1"
6097 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6098 (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6102 [(set_attr "type" "shift")
6103 (set_attr "iscompact" "maybe,false")
6104 (set_attr "predicable" "no,no")])
6106 (define_insn "*lshrsi3_cnt1"
6107 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6108 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6112 [(set_attr "type" "shift")
6113 (set_attr "iscompact" "maybe,false")
6114 (set_attr "predicable" "no,no")])
6116 (define_insn "*ashrsi3_cnt1"
6117 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6118 (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6122 [(set_attr "type" "shift")
6123 (set_attr "iscompact" "maybe,false")
6124 (set_attr "predicable" "no,no")])
6127 [(set (match_operand:SI 0 "register_operand" "")
6128 (zero_extract:SI (match_dup 0)
6129 (match_operand:SI 1 "const_int_operand" "")
6130 (match_operand:SI 2 "const_int_operand" "")))
6131 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6136 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6137 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6138 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6140 ;; Dummy pattern used as a place holder for automatically saved
6142 (define_insn "stack_irq_dwarf"
6143 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6146 [(set_attr "length" "0")])
6148 ;; MAC and DMPY instructions
6149 (define_expand "maddsidi4"
6150 [(match_operand:DI 0 "register_operand" "")
6151 (match_operand:SI 1 "register_operand" "")
6152 (match_operand:SI 2 "extend_operand" "")
6153 (match_operand:DI 3 "register_operand" "")]
6156 emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6160 (define_insn_and_split "maddsidi4_split"
6161 [(set (match_operand:DI 0 "register_operand" "=r")
6164 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6165 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6166 (match_operand:DI 3 "register_operand" "r")))
6167 (clobber (reg:DI ARCV2_ACC))]
6170 "TARGET_PLUS_DMPY && reload_completed"
6173 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6174 emit_move_insn (acc_reg, operands[3]);
6175 if (TARGET_PLUS_MACD)
6176 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6179 emit_insn (gen_mac (operands[1], operands[2]));
6180 emit_move_insn (operands[0], acc_reg);
6184 [(set_attr "type" "multi")
6185 (set_attr "length" "36")])
6188 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6191 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6192 (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
6193 (reg:DI ARCV2_ACC)))
6194 (set (reg:DI ARCV2_ACC)
6196 (mult:DI (sign_extend:DI (match_dup 1))
6197 (sign_extend:DI (match_dup 2)))
6198 (reg:DI ARCV2_ACC)))]
6201 [(set_attr "length" "4,4,8")
6202 (set_attr "type" "multi")
6203 (set_attr "predicable" "yes,no,no")
6204 (set_attr "cond" "canuse,nocond,nocond")])
6207 [(set (reg:DI ARCV2_ACC)
6209 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6210 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6211 (reg:DI ARCV2_ACC)))]
6214 [(set_attr "length" "4,8")
6215 (set_attr "type" "multi")
6216 (set_attr "predicable" "no")
6217 (set_attr "cond" "nocond")])
6220 [(set (reg:DI ARCV2_ACC)
6222 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6223 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6224 (reg:DI ARCV2_ACC)))
6225 (set (match_operand:SI 2 "register_operand" "")
6226 (match_operand:SI 3 "accl_operand" ""))]
6230 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6234 (define_insn "mac_r"
6235 [(set (match_operand:SI 0 "register_operand" "=r,r")
6238 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6239 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6240 (reg:DI ARCV2_ACC))))
6241 (clobber (reg:DI ARCV2_ACC))]
6244 [(set_attr "length" "4,8")
6245 (set_attr "type" "multi")
6246 (set_attr "predicable" "no")
6247 (set_attr "cond" "nocond")])
6249 (define_expand "umaddsidi4"
6250 [(match_operand:DI 0 "register_operand" "")
6251 (match_operand:SI 1 "register_operand" "")
6252 (match_operand:SI 2 "extend_operand" "")
6253 (match_operand:DI 3 "register_operand" "")]
6256 emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6260 (define_insn_and_split "umaddsidi4_split"
6261 [(set (match_operand:DI 0 "register_operand" "=r")
6264 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6265 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6266 (match_operand:DI 3 "register_operand" "r")))
6267 (clobber (reg:DI ARCV2_ACC))]
6270 "TARGET_PLUS_DMPY && reload_completed"
6273 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6274 emit_move_insn (acc_reg, operands[3]);
6275 if (TARGET_PLUS_MACD)
6276 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6279 emit_insn (gen_macu (operands[1], operands[2]));
6280 emit_move_insn (operands[0], acc_reg);
6284 [(set_attr "type" "multi")
6285 (set_attr "length" "36")])
6287 (define_insn "macdu"
6288 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6291 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6292 (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
6293 (reg:DI ARCV2_ACC)))
6294 (set (reg:DI ARCV2_ACC)
6296 (mult:DI (zero_extend:DI (match_dup 1))
6297 (zero_extend:DI (match_dup 2)))
6298 (reg:DI ARCV2_ACC)))]
6301 [(set_attr "length" "4,4,8")
6302 (set_attr "type" "multi")
6303 (set_attr "predicable" "yes,no,no")
6304 (set_attr "cond" "canuse,nocond,nocond")])
6307 [(set (reg:DI ARCV2_ACC)
6309 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6310 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6311 (reg:DI ARCV2_ACC)))]
6314 [(set_attr "length" "4,8")
6315 (set_attr "type" "multi")
6316 (set_attr "predicable" "no")
6317 (set_attr "cond" "nocond")])
6320 [(set (reg:DI ARCV2_ACC)
6322 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6323 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6324 (reg:DI ARCV2_ACC)))
6325 (set (match_operand:SI 2 "register_operand" "")
6326 (match_operand:SI 3 "accl_operand" ""))]
6330 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6334 (define_insn "macu_r"
6335 [(set (match_operand:SI 0 "register_operand" "=r,r")
6338 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6339 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6340 (reg:DI ARCV2_ACC))))
6341 (clobber (reg:DI ARCV2_ACC))]
6344 [(set_attr "length" "4,8")
6345 (set_attr "type" "multi")
6346 (set_attr "predicable" "no")
6347 (set_attr "cond" "nocond")])
6349 (define_insn "mpyd_arcv2hs"
6350 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6351 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6352 (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6353 (set (reg:DI ARCV2_ACC)
6355 (sign_extend:DI (match_dup 1))
6356 (sign_extend:DI (match_dup 2))))]
6359 [(set_attr "length" "4,4")
6360 (set_attr "iscompact" "false")
6361 (set_attr "type" "multi")
6362 (set_attr "predicable" "yes,no")
6363 (set_attr "cond" "canuse,nocond")])
6365 (define_insn "mpyd_imm_arcv2hs"
6366 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6367 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6368 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6369 (set (reg:DI ARCV2_ACC)
6370 (mult:DI (sign_extend:DI (match_dup 1))
6374 [(set_attr "length" "4,4,4,8,8")
6375 (set_attr "iscompact" "false")
6376 (set_attr "type" "multi")
6377 (set_attr "predicable" "yes,no,no,yes,no")
6378 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6380 (define_insn "mpydu_arcv2hs"
6381 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6382 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6383 (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6384 (set (reg:DI ARCV2_ACC)
6385 (mult:DI (zero_extend:DI (match_dup 1))
6386 (zero_extend:DI (match_dup 2))))]
6389 [(set_attr "length" "4,4")
6390 (set_attr "iscompact" "false")
6391 (set_attr "type" "multi")
6392 (set_attr "predicable" "yes,no")
6393 (set_attr "cond" "canuse,nocond")])
6395 (define_insn "mpydu_imm_arcv2hs"
6396 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6397 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6398 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6399 (set (reg:DI ARCV2_ACC)
6400 (mult:DI (zero_extend:DI (match_dup 1))
6404 [(set_attr "length" "4,4,4,8,8")
6405 (set_attr "iscompact" "false")
6406 (set_attr "type" "multi")
6407 (set_attr "predicable" "yes,no,no,yes,no")
6408 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6410 (define_insn "stack_tie"
6411 [(set (mem:BLK (scratch))
6412 (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
6413 (match_operand:SI 1 "register_operand" "rb")]
6414 UNSPEC_ARC_STKTIE))]
6417 [(set_attr "length" "0")
6418 (set_attr "iscompact" "false")
6419 (set_attr "type" "block")]
6422 ;; include the arc-FPX instructions
6425 ;; include the arc-FPU instructions
6428 (include "simdext.md")
6430 ;; include atomic extensions
6431 (include "atomic.md")