1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2017 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 (eq_attr "iscompact" "maybe") (const_string "true")
477 (if_then_else (eq_attr "length" "2,4")
478 (const_string "true")
479 (const_string "false"))))
481 ; must not put an insn inside that refers to blink.
482 (define_attr "in_call_delay_slot" "false,true"
483 (cond [(eq_attr "in_delay_slot" "false")
484 (const_string "false")
485 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
486 (const_string "false")]
487 (const_string "true")))
489 (define_attr "in_sfunc_delay_slot" "false,true"
490 (cond [(eq_attr "in_call_delay_slot" "false")
491 (const_string "false")
492 (match_test "arc_regno_use_in (12, PATTERN (insn))")
493 (const_string "false")]
494 (const_string "true")))
496 ;; Instructions that we can put into a delay slot and conditionalize.
497 (define_attr "cond_delay_insn" "no,yes"
498 (cond [(eq_attr "cond" "!canuse") (const_string "no")
499 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
501 (eq_attr "length" "2,4") (const_string "yes")]
502 (const_string "no")))
504 (define_attr "in_ret_delay_slot" "no,yes"
505 (cond [(eq_attr "in_delay_slot" "false")
507 (match_test "regno_clobbered_p
508 (arc_return_address_register
509 (arc_compute_function_type (cfun)),
512 (const_string "yes")))
514 (define_attr "cond_ret_delay_insn" "no,yes"
515 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
516 (eq_attr "cond_delay_insn" "no") (const_string "no")]
517 (const_string "yes")))
519 (define_attr "annul_ret_delay_insn" "no,yes"
520 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
521 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
522 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
523 (const_string "yes")]
524 (const_string "no")))
527 ;; Delay slot definition for ARCompact ISA
529 ;; When outputting an annul-true insn elegible for cond-exec
530 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
531 ;; for ARC600; we could also use this for ARC700 if the branch can't be
532 ;; unaligned and is at least somewhat likely (add parameter for this).
534 (define_delay (eq_attr "type" "call")
535 [(eq_attr "in_call_delay_slot" "true")
536 (eq_attr "in_call_delay_slot" "true")
539 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
540 (eq_attr "type" "brcc"))
541 [(eq_attr "in_delay_slot" "true")
542 (eq_attr "in_delay_slot" "true")
545 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
546 (eq_attr "type" "brcc"))
547 [(eq_attr "in_delay_slot" "true")
552 (eq_attr "type" "return")
553 [(eq_attr "in_ret_delay_slot" "yes")
554 (eq_attr "annul_ret_delay_insn" "yes")
555 (eq_attr "cond_ret_delay_insn" "yes")])
557 (define_delay (eq_attr "type" "loop_end")
558 [(eq_attr "in_delay_slot" "true")
559 (eq_attr "in_delay_slot" "true")
562 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
563 ;; non-taken case, so the only meaningful way to have an annull-true
564 ;; filled delay slot is to conditionalize the delay slot insn.
565 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
566 (eq_attr "type" "branch,uncond_branch,jump")
567 (match_test "!optimize_size"))
568 [(eq_attr "in_delay_slot" "true")
569 (eq_attr "cond_delay_insn" "yes")
570 (eq_attr "cond_delay_insn" "yes")])
572 ;; For ARC700, anything goes for annulled-true insns, since there is no
573 ;; penalty for the unexposed delay slot when the branch is not taken,
574 ;; however, we must avoid things that have a delay slot themselvese to
575 ;; avoid confusing gcc.
576 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
577 (eq_attr "type" "branch,uncond_branch,jump")
578 (match_test "!optimize_size"))
579 [(eq_attr "in_delay_slot" "true")
580 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
581 (eq_attr "cond_delay_insn" "yes")])
583 ;; -mlongcall -fpic sfuncs use r12 to load the function address
584 (define_delay (eq_attr "type" "sfunc")
585 [(eq_attr "in_sfunc_delay_slot" "true")
586 (eq_attr "in_sfunc_delay_slot" "true")
588 ;; ??? need to use a working strategy for canuse_limm:
589 ;; - either canuse_limm is not eligible for delay slots, and has no
590 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
591 ;; somehow modify them to become inelegible for delay slots if a decision
592 ;; is made that makes conditional execution required.
594 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
596 (cond [(symbol_ref "arc_tune == TUNE_ARC600")
597 (const_string "arc600")
598 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
599 (const_string "arc700_4_2_std")
600 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
601 (const_string "arc700_4_2_xmac")]
602 (const_string "none"))))
604 (define_attr "tune_arc700" "false,true"
605 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
606 (const_string "true")
607 (const_string "false")))
609 ;; Move instructions.
610 (define_expand "movqi"
611 [(set (match_operand:QI 0 "move_dest_operand" "")
612 (match_operand:QI 1 "general_operand" ""))]
614 "if (prepare_move_operands (operands, QImode)) DONE;")
616 ; In order to allow the ccfsm machinery to do its work, the leading compact
617 ; alternatives say 'canuse' - there is another alternative that will match
618 ; when the condition codes are used.
619 ; Rcq won't match if the condition is actually used; to avoid a spurious match
620 ; via q, q is inactivated as constraint there.
621 ; Likewise, the length of an alternative that might be shifted to conditional
622 ; execution must reflect this, lest out-of-range branches are created.
623 ; The iscompact attribute allows the epilogue expander to know for which
624 ; insns it should lengthen the return insn.
625 (define_insn "*movqi_insn"
626 [(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")
627 (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"))]
628 "register_operand (operands[0], QImode)
629 || register_operand (operands[1], QImode)"
651 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
652 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
653 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
654 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
656 (define_expand "movhi"
657 [(set (match_operand:HI 0 "move_dest_operand" "")
658 (match_operand:HI 1 "general_operand" ""))]
660 "if (prepare_move_operands (operands, HImode)) DONE;")
662 (define_insn "*movhi_insn"
663 [(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")
664 (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"))]
665 "register_operand (operands[0], HImode)
666 || register_operand (operands[1], HImode)
667 || (CONSTANT_P (operands[1])
668 /* Don't use a LIMM that we could load with a single insn - we loose
669 delay-slot filling opportunities. */
670 && !satisfies_constraint_I (operands[1])
671 && satisfies_constraint_Usc (operands[0]))"
693 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
694 (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")
695 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
696 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
698 (define_expand "movsi"
699 [(set (match_operand:SI 0 "move_dest_operand" "")
700 (match_operand:SI 1 "general_operand" ""))]
702 "if (prepare_move_operands (operands, SImode)) DONE;")
704 ; In order to allow the ccfsm machinery to do its work, the leading compact
705 ; alternatives say 'canuse' - there is another alternative that will match
706 ; when the condition codes are used.
707 ; Rcq won't match if the condition is actually used; to avoid a spurious match
708 ; via q, q is inactivated as constraint there.
709 ; Likewise, the length of an alternative that might be shifted to conditional
710 ; execution must reflect this, lest out-of-range branches are created.
711 ; the iscompact attribute allows the epilogue expander to know for which
712 ; insns it should lengthen the return insn.
713 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
714 (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
715 [(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")
716 (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"))]
717 "register_operand (operands[0], SImode)
718 || register_operand (operands[1], SImode)
719 || (CONSTANT_P (operands[1])
720 /* Don't use a LIMM that we could load with a single insn - we loose
721 delay-slot filling opportunities. */
722 && !satisfies_constraint_I (operands[1])
723 && satisfies_constraint_Usc (operands[0]))"
732 ror %0,((%1*2+1) & 0x3f) ;7
734 movh.cl %0,%L1>>16 ;9
735 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
738 add %0,pcl,%1@pcl ;13
744 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
745 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
757 ; 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
758 [(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")
759 (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")
760 ; Use default length for iscompact to allow for COND_EXEC. But set length
762 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,*,8")
763 (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")
764 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
766 ;; Sometimes generated by the epilogue code. We don't want to
767 ;; recognize these addresses in general, because the limm is costly,
768 ;; and we can't use them for stores. */
769 (define_insn "*movsi_pre_mod"
770 [(set (match_operand:SI 0 "register_operand" "=w")
773 (plus:SI (reg:SI SP_REG)
774 (match_operand 1 "immediate_operand" "Cal")))))]
777 [(set_attr "type" "load")
778 (set_attr "length" "8")])
780 ;; Store a value to directly to memory. The location might also be cached.
781 ;; Since the cached copy can cause a write-back at unpredictable times,
782 ;; we first write cached, then we write uncached.
783 (define_insn "store_direct"
784 [(set (match_operand:SI 0 "move_dest_operand" "=m")
785 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
788 "st%U0 %1,%0\;st%U0.di %1,%0"
789 [(set_attr "type" "store")])
791 (define_insn_and_split "*movsi_set_cc_insn"
792 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
793 (match_operator:CC_ZN 3 "zn_compare_operator"
794 [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
795 (set (match_operand:SI 0 "register_operand" "=w,w,w")
799 ; splitting to 'tst' allows short insns and combination into brcc.
800 "reload_completed && operands_match_p (operands[0], operands[1])"
801 [(set (match_dup 2) (match_dup 3))]
803 [(set_attr "type" "compare")
804 (set_attr "predicable" "no,yes,yes")
805 (set_attr "cond" "set_zn")
806 (set_attr "length" "4,4,8")])
808 (define_insn "unary_comparison"
809 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
810 (match_operator:CC_ZN 3 "zn_compare_operator"
811 [(match_operator:SI 2 "unary_operator"
812 [(match_operand:SI 1 "register_operand" "c")])
816 [(set_attr "type" "compare")
817 (set_attr "cond" "set_zn")])
820 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
821 (define_insn "*unary_comparison_result_used"
822 [(set (match_operand 2 "cc_register" "")
823 (match_operator 4 "zn_compare_operator"
824 [(match_operator:SI 3 "unary_operator"
825 [(match_operand:SI 1 "register_operand" "c")])
827 (set (match_operand:SI 0 "register_operand" "=w")
831 [(set_attr "type" "compare")
832 (set_attr "cond" "set_zn")
833 (set_attr "length" "4")])
835 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
836 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
837 ; even if we don't need the clobber.
838 (define_insn_and_split "*tst_movb"
840 (match_operand 0 "cc_register" "")
841 (match_operator 4 "zn_compare_operator"
843 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c")
844 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
846 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
848 "movb.f.cl %3,%1,%p2,%p2,%s2"
849 "TARGET_NPS_BITOPS && reload_completed
850 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
851 [(set (match_dup 0) (match_dup 4))])
855 (match_operand 0 "cc_register" "")
856 (match_operator 3 "zn_compare_operator"
858 (match_operand:SI 1 "register_operand"
859 "%Rcq,Rcq, c, c, c, c, c, c")
860 (match_operand:SI 2 "nonmemory_operand"
861 " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
864 || !satisfies_constraint_Cbf (operands[2])
865 || satisfies_constraint_C0p (operands[2])
866 || satisfies_constraint_I (operands[2])
867 || satisfies_constraint_C1p (operands[2])
868 || satisfies_constraint_Chs (operands[2])"
870 switch (which_alternative)
872 case 0: case 2: case 3: case 7:
873 return \"tst%? %1,%2\";
875 return \"btst%? %1,%z2\";
877 return \"bmsk%?.f 0,%1,%Z2%&\";
879 return \"bclr%?.f 0,%1,%M2%&\";
881 return \"asr.f 0,%1,%p2\";
886 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
887 (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
888 (set_attr "length" "*,*,4,4,4,4,4,8")
889 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
890 (set_attr "cond" "set_zn")])
892 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
893 ; combine will do that and not try the AND.
895 ; It would take 66 constraint combinations to describe the zero_extract
896 ; constants that are covered by the 12-bit signed constant for tst
897 ; (excluding the ones that are better done by mov or btst).
898 ; so we rather use an extra pattern for tst;
899 ; since this is about constants, reload shouldn't care.
900 (define_insn "*tst_bitfield_tst"
901 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
902 (match_operator 4 "zn_compare_operator"
904 (match_operand:SI 1 "register_operand" "c")
905 (match_operand:SI 2 "const_int_operand" "n")
906 (match_operand:SI 3 "const_int_operand" "n"))
908 "INTVAL (operands[2]) > 1
909 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
910 || (INTVAL (operands[3]) <= 11
911 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
912 "tst %1,((1<<%2)-1)<<%3"
913 [(set_attr "type" "compare")
914 (set_attr "cond" "set_zn")
915 (set_attr "length" "4")])
917 ; Likewise for asr.f.
918 (define_insn "*tst_bitfield_asr"
919 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
920 (match_operator 4 "zn_compare_operator"
922 (match_operand:SI 1 "register_operand" "c")
923 (match_operand:SI 2 "const_int_operand" "n")
924 (match_operand:SI 3 "const_int_operand" "n"))
926 "INTVAL (operands[2]) > 1
927 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
929 [(set_attr "type" "shift")
930 (set_attr "cond" "set_zn")
931 (set_attr "length" "4")])
933 (define_insn "*tst_bitfield"
934 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
935 (match_operator 5 "zn_compare_operator"
937 (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c")
938 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
939 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
941 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
947 movb.f.cl %4,%1,%3,%3,%2
948 and.f 0,%1,((1<<%2)-1)<<%3"
949 [(set_attr "iscompact" "maybe,false,false,false,false")
950 (set_attr "type" "compare,compare,compare,shift,compare")
951 (set_attr "cond" "set_zn")
952 (set_attr "length" "*,4,4,4,8")])
954 (define_insn "*commutative_binary_comparison"
955 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
956 (match_operator:CC_ZN 5 "zn_compare_operator"
957 [(match_operator:SI 4 "commutative_operator"
958 [(match_operand:SI 1 "register_operand" "%c,c")
959 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
961 (clobber (match_scratch:SI 3 "=X,X"))]
964 [(set_attr "type" "compare")
965 (set_attr "cond" "set_zn")
966 (set_attr "length" "4,8")])
968 ; for flag setting 'add' instructions like if (a+b) { ...}
969 ; the combiner needs this pattern
970 (define_insn "*addsi_compare"
971 [(set (reg:CC_ZN CC_REG)
972 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
973 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
976 [(set_attr "cond" "set")
977 (set_attr "type" "compare")
978 (set_attr "length" "4")])
980 ; for flag setting 'add' instructions like if (a+b < a) { ...}
981 ; the combiner needs this pattern
982 (define_insn "addsi_compare_2"
983 [(set (reg:CC_C CC_REG)
984 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
985 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
989 [(set_attr "cond" "set")
990 (set_attr "type" "compare")
991 (set_attr "length" "4,8")])
993 (define_insn "*addsi_compare_3"
994 [(set (reg:CC_C CC_REG)
995 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
996 (match_operand:SI 1 "register_operand" "c"))
1000 [(set_attr "cond" "set")
1001 (set_attr "type" "compare")
1002 (set_attr "length" "4")])
1004 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1005 (define_insn "*commutative_binary_comparison_result_used"
1006 [(set (match_operand 3 "cc_register" "")
1007 (match_operator 5 "zn_compare_operator"
1008 ; We can accept any commutative operator except mult because
1009 ; our 'w' class below could try to use LP_COUNT.
1010 [(match_operator:SI 4 "commutative_operator_sans_mult"
1011 [(match_operand:SI 1 "register_operand" "c,0,c")
1012 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1014 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1017 "%O4.f %0,%1,%2 ; non-mult commutative"
1018 [(set_attr "type" "compare,compare,compare")
1019 (set_attr "cond" "set_zn,set_zn,set_zn")
1020 (set_attr "length" "4,4,8")])
1022 ; a MULT-specific version of this pattern to avoid touching the
1024 (define_insn "*commutative_binary_mult_comparison_result_used"
1025 [(set (match_operand 3 "cc_register" "")
1026 (match_operator 5 "zn_compare_operator"
1027 [(match_operator:SI 4 "mult_operator"
1028 [(match_operand:SI 1 "register_operand" "c,0,c")
1029 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1031 ; Make sure to use the W class to not touch LP_COUNT.
1032 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1034 "!TARGET_ARC600_FAMILY"
1035 "%O4.f %0,%1,%2 ; mult commutative"
1036 [(set_attr "type" "compare,compare,compare")
1037 (set_attr "cond" "set_zn,set_zn,set_zn")
1038 (set_attr "length" "4,4,8")])
1040 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1041 (define_insn "*noncommutative_binary_comparison_result_used"
1042 [(set (match_operand 3 "cc_register" "")
1043 (match_operator 5 "zn_compare_operator"
1044 [(match_operator:SI 4 "noncommutative_operator"
1045 [(match_operand:SI 1 "register_operand" "c,0,c")
1046 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1048 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1050 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1052 [(set_attr "type" "compare,compare,compare")
1053 (set_attr "cond" "set_zn,set_zn,set_zn")
1054 (set_attr "length" "4,4,8")])
1056 (define_insn "*noncommutative_binary_comparison"
1057 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1058 (match_operator:CC_ZN 5 "zn_compare_operator"
1059 [(match_operator:SI 4 "noncommutative_operator"
1060 [(match_operand:SI 1 "register_operand" "c,c")
1061 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
1063 (clobber (match_scratch:SI 3 "=X,X"))]
1064 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1066 [(set_attr "type" "compare")
1067 (set_attr "cond" "set_zn")
1068 (set_attr "length" "4,8")])
1070 (define_expand "bic_f_zn"
1072 [(set (reg:CC_ZN CC_REG)
1074 (and:SI (match_operand:SI 1 "register_operand" "")
1075 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1077 (set (match_operand:SI 0 "register_operand" "")
1078 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1081 (define_insn "*bic_f"
1082 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1083 (match_operator 4 "zn_compare_operator"
1084 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1086 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1088 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1089 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1092 [(set_attr "type" "compare,compare,compare")
1093 (set_attr "cond" "set_zn,set_zn,set_zn")
1094 (set_attr "length" "4,4,8")])
1096 (define_expand "movdi"
1097 [(set (match_operand:DI 0 "move_dest_operand" "")
1098 (match_operand:DI 1 "general_operand" ""))]
1101 if (prepare_move_operands (operands, DImode))
1105 (define_insn_and_split "*movdi_insn"
1106 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m")
1107 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1108 "register_operand (operands[0], DImode)
1109 || register_operand (operands[1], DImode)"
1112 switch (which_alternative)
1119 && ((even_register_operand (operands[0], DImode)
1120 && memory_operand (operands[1], DImode))
1121 || (memory_operand (operands[0], DImode)
1122 && even_register_operand (operands[1], DImode))))
1123 return \"ldd%U1%V1 %0,%1%&\";
1128 && ((even_register_operand (operands[0], DImode)
1129 && memory_operand (operands[1], DImode))
1130 || (memory_operand (operands[0], DImode)
1131 && even_register_operand (operands[1], DImode))))
1132 return \"std%U0%V0 %1,%0\";
1139 arc_split_move (operands);
1142 [(set_attr "type" "move,move,load,store")
1143 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1144 (set_attr "length" "8,16,*,*")])
1147 ;; Floating point move insns.
1149 (define_expand "movsf"
1150 [(set (match_operand:SF 0 "move_dest_operand" "")
1151 (match_operand:SF 1 "general_operand" ""))]
1153 "if (prepare_move_operands (operands, SFmode)) DONE;")
1155 (define_insn "*movsf_insn"
1156 [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m")
1157 (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))]
1158 "register_operand (operands[0], SFmode)
1159 || register_operand (operands[1], SFmode)"
1166 [(set_attr "type" "move,move,move,load,store")
1167 (set_attr "predicable" "no,yes,yes,no,no")
1168 (set_attr "iscompact" "true,false,false,false,false")])
1170 (define_expand "movdf"
1171 [(set (match_operand:DF 0 "move_dest_operand" "")
1172 (match_operand:DF 1 "general_operand" ""))]
1174 "if (prepare_move_operands (operands, DFmode)) DONE;")
1176 (define_insn_and_split "*movdf_insn"
1177 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
1178 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1179 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1182 switch (which_alternative)
1188 && ((even_register_operand (operands[0], DFmode)
1189 && memory_operand (operands[1], DFmode))
1190 || (memory_operand (operands[0], DFmode)
1191 && even_register_operand (operands[1], DFmode))))
1192 return \"ldd%U1%V1 %0,%1%&\";
1197 && ((even_register_operand (operands[0], DFmode)
1198 && memory_operand (operands[1], DFmode))
1199 || (memory_operand (operands[0], DFmode)
1200 && even_register_operand (operands[1], DFmode))))
1201 return \"std%U0%V0 %1,%0\";
1208 arc_split_move (operands);
1211 [(set_attr "type" "move,move,move,move,load,store")
1212 (set_attr "predicable" "no,no,yes,yes,no,no")
1213 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1214 (set_attr "length" "4,16,8,16,16,16")])
1216 (define_insn_and_split "*movdf_insn_nolrsr"
1217 [(set (match_operand:DF 0 "register_operand" "=r")
1218 (match_operand:DF 1 "arc_double_register_operand" "D"))
1219 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1221 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1226 (set (match_dup 0) (match_dup 3))
1228 ; daddh?? r1, r0, r0
1230 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1233 (use (match_dup 0)) ; used to block can_combine_p
1234 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1237 ; We have to do this twice, once to read the value into R0 and
1238 ; second time to put back the contents which the first DEXCLx
1239 ; will have overwritten
1242 (set (match_dup 4) ; aka r0result
1244 (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1246 (clobber (match_dup 1))
1248 ; Generate the second, which makes sure operand5 and operand4 values
1249 ; are put back in the Dx register properly.
1250 (set (match_dup 1) (unspec_volatile:DF
1251 [(match_dup 5) (match_dup 4)]
1252 VUNSPEC_ARC_DEXCL_NORES))
1254 ; Note: we cannot use a (clobber (match_scratch)) here because
1255 ; the combine pass will end up replacing uses of it with 0
1257 "operands[3] = CONST0_RTX (DFmode);
1258 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1259 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1260 [(set_attr "type" "move")])
1262 ;; Load/Store with update instructions.
1264 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1265 ;; hardware can also do cases where the increment is not the size of the
1268 ;; In all these cases, we use operands 0 and 1 for the register being
1269 ;; incremented because those are the operands that local-alloc will
1270 ;; tie and these are the pair most likely to be tieable (and the ones
1271 ;; that will benefit the most).
1273 ;; We use match_operator here because we need to know whether the memory
1274 ;; object is volatile or not.
1277 ;; Note: loadqi_update has no 16-bit variant
1278 (define_insn "*loadqi_update"
1279 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1280 (match_operator:QI 4 "any_mem_operand"
1281 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1282 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1283 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1284 (plus:SI (match_dup 1) (match_dup 2)))]
1286 "ldb.a%V4 %3,[%0,%S2]"
1287 [(set_attr "type" "load,load")
1288 (set_attr "length" "4,8")])
1290 (define_insn "*load_zeroextendqisi_update"
1291 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1292 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1293 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1294 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1295 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1296 (plus:SI (match_dup 1) (match_dup 2)))]
1298 "ldb.a%V4 %3,[%0,%S2]"
1299 [(set_attr "type" "load,load")
1300 (set_attr "length" "4,8")])
1302 (define_insn "*load_signextendqisi_update"
1303 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1304 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1305 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1306 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1307 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1308 (plus:SI (match_dup 1) (match_dup 2)))]
1310 "ldb.x.a%V4 %3,[%0,%S2]"
1311 [(set_attr "type" "load,load")
1312 (set_attr "length" "4,8")])
1314 (define_insn "*storeqi_update"
1315 [(set (match_operator:QI 4 "any_mem_operand"
1316 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1317 (match_operand:SI 2 "short_immediate_operand" "I"))])
1318 (match_operand:QI 3 "register_operand" "c"))
1319 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1320 (plus:SI (match_dup 1) (match_dup 2)))]
1322 "stb.a%V4 %3,[%0,%2]"
1323 [(set_attr "type" "store")
1324 (set_attr "length" "4")])
1326 ;; ??? pattern may have to be re-written
1327 ;; Note: no 16-bit variant for this pattern
1328 (define_insn "*loadhi_update"
1329 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1330 (match_operator:HI 4 "any_mem_operand"
1331 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1332 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1333 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1334 (plus:SI (match_dup 1) (match_dup 2)))]
1336 "ld%_.a%V4 %3,[%0,%S2]"
1337 [(set_attr "type" "load,load")
1338 (set_attr "length" "4,8")])
1340 (define_insn "*load_zeroextendhisi_update"
1341 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1342 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1343 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1344 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1345 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1346 (plus:SI (match_dup 1) (match_dup 2)))]
1348 "ld%_.a%V4 %3,[%0,%S2]"
1349 [(set_attr "type" "load,load")
1350 (set_attr "length" "4,8")])
1352 ;; Note: no 16-bit variant for this instruction
1353 (define_insn "*load_signextendhisi_update"
1354 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1355 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1356 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1357 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1358 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1359 (plus:SI (match_dup 1) (match_dup 2)))]
1361 "ld%_.x.a%V4 %3,[%0,%S2]"
1362 [(set_attr "type" "load,load")
1363 (set_attr "length" "4,8")])
1365 (define_insn "*storehi_update"
1366 [(set (match_operator:HI 4 "any_mem_operand"
1367 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1368 (match_operand:SI 2 "short_immediate_operand" "I"))])
1369 (match_operand:HI 3 "register_operand" "c"))
1370 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1371 (plus:SI (match_dup 1) (match_dup 2)))]
1373 "st%_.a%V4 %3,[%0,%2]"
1374 [(set_attr "type" "store")
1375 (set_attr "length" "4")])
1377 ;; No 16-bit variant for this instruction pattern
1378 (define_insn "*loadsi_update"
1379 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1380 (match_operator:SI 4 "any_mem_operand"
1381 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1382 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1383 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1384 (plus:SI (match_dup 1) (match_dup 2)))]
1386 "ld.a%V4 %3,[%0,%S2]"
1387 [(set_attr "type" "load,load")
1388 (set_attr "length" "4,8")])
1390 (define_insn "*storesi_update"
1391 [(set (match_operator:SI 4 "any_mem_operand"
1392 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1393 (match_operand:SI 2 "short_immediate_operand" "I"))])
1394 (match_operand:SI 3 "register_operand" "c"))
1395 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1396 (plus:SI (match_dup 1) (match_dup 2)))]
1398 "st.a%V4 %3,[%0,%2]"
1399 [(set_attr "type" "store")
1400 (set_attr "length" "4")])
1402 (define_insn "*loadsf_update"
1403 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1404 (match_operator:SF 4 "any_mem_operand"
1405 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1406 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1407 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1408 (plus:SI (match_dup 1) (match_dup 2)))]
1410 "ld.a%V4 %3,[%0,%S2]"
1411 [(set_attr "type" "load,load")
1412 (set_attr "length" "4,8")])
1414 (define_insn "*storesf_update"
1415 [(set (match_operator:SF 4 "any_mem_operand"
1416 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1417 (match_operand:SI 2 "short_immediate_operand" "I"))])
1418 (match_operand:SF 3 "register_operand" "c"))
1419 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1420 (plus:SI (match_dup 1) (match_dup 2)))]
1422 "st.a%V4 %3,[%0,%2]"
1423 [(set_attr "type" "store")
1424 (set_attr "length" "4")])
1426 ;; Conditional move instructions.
1428 (define_expand "movsicc"
1429 [(set (match_operand:SI 0 "dest_reg_operand" "")
1430 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1431 (match_operand:SI 2 "nonmemory_operand" "")
1432 (match_operand:SI 3 "register_operand" "")))]
1434 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1437 (define_expand "movdicc"
1438 [(set (match_operand:DI 0 "dest_reg_operand" "")
1439 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1440 (match_operand:DI 2 "nonmemory_operand" "")
1441 (match_operand:DI 3 "register_operand" "")))]
1443 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1446 (define_expand "movsfcc"
1447 [(set (match_operand:SF 0 "dest_reg_operand" "")
1448 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1449 (match_operand:SF 2 "nonmemory_operand" "")
1450 (match_operand:SF 3 "register_operand" "")))]
1452 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1454 (define_expand "movdfcc"
1455 [(set (match_operand:DF 0 "dest_reg_operand" "")
1456 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1457 (match_operand:DF 2 "nonmemory_operand" "")
1458 (match_operand:DF 3 "register_operand" "")))]
1460 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1462 (define_insn "*movsicc_insn"
1463 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1464 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1465 [(match_operand 4 "cc_register" "") (const_int 0)])
1466 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1467 (match_operand:SI 2 "register_operand" "0,0")))]
1470 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1471 && satisfies_constraint_Rcq (operands[0]))
1472 return "sub%?.ne %0,%0,%0";
1473 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1474 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1475 && rtx_equal_p (operands[1], constm1_rtx)
1476 && GET_CODE (operands[3]) == LTU)
1477 return "sbc.cs %0,%0,%0";
1478 return "mov.%d3 %0,%S1";
1480 [(set_attr "type" "cmove,cmove")
1481 (set_attr "length" "4,8")])
1483 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1484 ;; if the single bit is the sign bit, then GCC likes to convert this
1485 ;; into a sign extend and a compare less than, or greater to zero.
1486 ;; This is usually fine, except for the NXP400 where we have access to
1487 ;; a bit test instruction, along with a special short load instruction
1488 ;; (from CMEM), that doesn't support sign-extension on load.
1490 ;; This peephole optimisation attempts to restore the use of bit-test
1491 ;; in those cases where it is useful to do so.
1493 [(set (match_operand:SI 0 "register_operand" "")
1495 (match_operand:QI 1 "any_mem_operand" "")))
1496 (set (reg:CC_ZN CC_REG)
1497 (compare:CC_ZN (match_dup 0)
1500 (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1501 [(reg:CC_ZN CC_REG) (const_int 0)])
1502 (match_operand 3 "" "")
1503 (match_operand 4 "" "")))]
1505 && cmem_address (XEXP (operands[1], 0), SImode)
1506 && peep2_reg_dead_p (2, operands[0])
1507 && peep2_regno_dead_p (3, CC_REG)"
1511 (set (reg:CC_ZN CC_REG)
1512 (compare:CC_ZN (zero_extract:SI
1518 (if_then_else (match_dup 2)
1521 "if (GET_CODE (operands[2]) == GE)
1522 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1524 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1526 ; Try to generate more short moves, and/or less limms, by substituting a
1527 ; conditional move with a conditional sub.
1529 [(set (match_operand:SI 0 "compact_register_operand")
1530 (match_operand:SI 1 "const_int_operand"))
1532 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1533 [(match_operand 4 "cc_register" "") (const_int 0)])
1534 (match_operand:SI 2 "const_int_operand" "")
1536 "!satisfies_constraint_P (operands[1])
1537 && satisfies_constraint_P (operands[2])
1538 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1539 [(set (match_dup 0) (match_dup 2))
1543 (plus:SI (match_dup 0) (match_dup 1))))]
1544 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1545 GET_MODE (operands[4])),
1546 VOIDmode, operands[4], const0_rtx);
1547 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1549 (define_insn "*movdicc_insn"
1550 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1551 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1552 [(match_operand 4 "cc_register" "") (const_int 0)])
1553 (match_operand:DI 1 "nonmemory_operand" "c,i")
1554 (match_operand:DI 2 "register_operand" "0,0")))]
1558 switch (which_alternative)
1562 /* We normally copy the low-numbered register first. However, if
1563 the first register operand 0 is the same as the second register of
1564 operand 1, we must copy in the opposite order. */
1565 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1566 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1568 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1570 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1575 [(set_attr "type" "cmove,cmove")
1576 (set_attr "length" "8,16")])
1579 (define_insn "*movsfcc_insn"
1580 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1581 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1582 [(match_operand 4 "cc_register" "") (const_int 0)])
1583 (match_operand:SF 1 "nonmemory_operand" "c,E")
1584 (match_operand:SF 2 "register_operand" "0,0")))]
1588 mov.%d3 %0,%1 ; %A1"
1589 [(set_attr "type" "cmove,cmove")])
1591 (define_insn "*movdfcc_insn"
1592 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1593 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1594 [(match_operand 4 "cc_register" "") (const_int 0)])
1595 (match_operand:DF 2 "nonmemory_operand" "c,E")
1596 (match_operand:DF 3 "register_operand" "0,0")))]
1600 switch (which_alternative)
1604 /* We normally copy the low-numbered register first. However, if
1605 the first register operand 0 is the same as the second register of
1606 operand 1, we must copy in the opposite order. */
1607 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1608 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1610 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1612 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1616 [(set_attr "type" "cmove,cmove")
1617 (set_attr "length" "8,16")])
1620 (define_insn "*zero_extendqihi2_i"
1621 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1622 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1631 [(set_attr "type" "unary,unary,unary,unary,load,load")
1632 (set_attr "iscompact" "maybe,true,false,false,false,false")
1633 (set_attr "predicable" "no,no,yes,no,no,no")])
1635 (define_expand "zero_extendqihi2"
1636 [(set (match_operand:HI 0 "dest_reg_operand" "")
1637 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1639 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1642 (define_insn "*zero_extendqisi2_ac"
1643 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1644 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1655 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1656 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1657 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1659 (define_expand "zero_extendqisi2"
1660 [(set (match_operand:SI 0 "dest_reg_operand" "")
1661 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1663 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1666 (define_insn "*zero_extendhisi2_i"
1667 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1668 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,T,Ucm,m")))]
1677 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1679 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1680 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1681 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1684 (define_expand "zero_extendhisi2"
1685 [(set (match_operand:SI 0 "dest_reg_operand" "")
1686 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1688 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1691 ;; Sign extension instructions.
1693 (define_insn "*extendqihi2_i"
1694 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1695 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1702 [(set_attr "type" "unary,unary,load,load")
1703 (set_attr "iscompact" "true,false,false,false")
1704 (set_attr "length" "*,*,*,8")])
1707 (define_expand "extendqihi2"
1708 [(set (match_operand:HI 0 "dest_reg_operand" "")
1709 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1711 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1714 (define_insn "*extendqisi2_ac"
1715 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1716 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1723 [(set_attr "type" "unary,unary,load,load")
1724 (set_attr "iscompact" "true,false,false,false")
1725 (set_attr "length" "*,*,*,8")])
1727 (define_expand "extendqisi2"
1728 [(set (match_operand:SI 0 "dest_reg_operand" "")
1729 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1731 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1734 (define_insn "*extendhisi2_i"
1735 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcqq,r,r")
1736 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1744 [(set_attr "type" "unary,unary,load,load,load")
1745 (set_attr "iscompact" "true,false,true,false,false")
1746 (set_attr "length" "*,*,*,4,8")])
1748 (define_expand "extendhisi2"
1749 [(set (match_operand:SI 0 "dest_reg_operand" "")
1750 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1752 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1755 ;; Unary arithmetic insns
1757 ;; We allow constant operands to enable late constant propagation, but it is
1758 ;; not worth while to have more than one dedicated alternative to output them -
1759 ;; if we are really worried about getting these the maximum benefit of all
1760 ;; the available alternatives, we should add an extra pass to fold such
1761 ;; operations to movsi.
1763 ;; Absolute instructions
1765 (define_insn "*abssi2_mixed"
1766 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1767 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1770 [(set_attr "type" "two_cycle_core")
1771 (set_attr "iscompact" "true")])
1773 (define_insn "abssi2"
1774 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1775 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1778 [(set_attr "type" "two_cycle_core")
1779 (set_attr "length" "*,4,8")
1780 (set_attr "iscompact" "true,false,false")])
1782 ;; Maximum and minimum insns
1784 (define_insn "smaxsi3"
1785 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1786 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1787 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1790 [(set_attr "type" "two_cycle_core")
1791 (set_attr "length" "4,4,8")
1792 (set_attr "predicable" "yes,no,no")]
1795 (define_insn "sminsi3"
1796 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1797 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1798 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1801 [(set_attr "type" "two_cycle_core")
1802 (set_attr "length" "4,4,8")
1803 (set_attr "predicable" "yes,no,no")]
1806 ;; Arithmetic instructions.
1808 ; We say an insn can be conditionalized if this doesn't introduce a long
1809 ; immediate. We set the type such that we still have good scheduling if the
1810 ; insn is conditionalized.
1811 ; ??? It would make sense to allow introduction of long immediates, but
1812 ; we'd need to communicate to the ccfsm machinery the extra cost.
1813 ; The alternatives in the constraints still serve three purposes:
1814 ; - estimate insn size assuming conditional execution
1815 ; - guide reload to re-order the second and third operand to get a better fit.
1816 ; - give tentative insn type to guide scheduling
1817 ; N.B. "%" for commutativity doesn't help when there is another matching
1818 ; (but longer) alternative.
1819 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1820 ; register class 'W' instead of 'w'.
1821 (define_insn_and_split "*addsi3_mixed"
1822 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12
1823 [(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")
1824 (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")
1825 (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")))]
1828 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1831 "&& reload_completed && get_attr_length (insn) == 8
1832 && satisfies_constraint_I (operands[2])
1833 && GET_CODE (PATTERN (insn)) != COND_EXEC"
1834 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1835 "split_addsi (operands);"
1836 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
1837 (set (attr "iscompact")
1838 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1839 (const_string "false")
1840 (match_operand 2 "long_immediate_operand" "")
1841 (const_string "maybe_limm")]
1842 (const_string "maybe")))
1843 (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
1844 (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
1845 (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1848 ;; ARCv2 MPYW and MPYUW
1849 (define_expand "mulhisi3"
1850 [(set (match_operand:SI 0 "register_operand" "")
1851 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1852 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1855 if (CONSTANT_P (operands[2]))
1857 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1863 (define_insn "mulhisi3_imm"
1864 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
1865 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
1866 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
1869 [(set_attr "length" "4,4,4,8,8")
1870 (set_attr "iscompact" "false")
1871 (set_attr "type" "mul16_em")
1872 (set_attr "predicable" "yes,no,no,yes,no")
1873 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1876 (define_insn "mulhisi3_reg"
1877 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r")
1878 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r"))
1879 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1882 [(set_attr "length" "*,4,4")
1883 (set_attr "iscompact" "maybe,false,false")
1884 (set_attr "type" "mul16_em")
1885 (set_attr "predicable" "yes,yes,no")
1886 (set_attr "cond" "canuse,canuse,nocond")
1889 (define_expand "umulhisi3"
1890 [(set (match_operand:SI 0 "register_operand" "")
1891 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1892 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1895 if (CONSTANT_P (operands[2]))
1897 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1903 (define_insn "umulhisi3_imm"
1904 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
1905 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
1906 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
1909 [(set_attr "length" "4,4,4,8,8")
1910 (set_attr "iscompact" "false")
1911 (set_attr "type" "mul16_em")
1912 (set_attr "predicable" "yes,no,no,yes,no")
1913 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1916 (define_insn "umulhisi3_reg"
1917 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r")
1918 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r"))
1919 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1922 [(set_attr "length" "*,4,4")
1923 (set_attr "iscompact" "maybe,false,false")
1924 (set_attr "type" "mul16_em")
1925 (set_attr "predicable" "yes,yes,no")
1926 (set_attr "cond" "canuse,canuse,nocond")
1929 ;; ARC700/ARC600/V2 multiply
1932 (define_expand "mulsi3"
1933 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1934 (mult:SI (match_operand:SI 1 "register_operand" "")
1935 (match_operand:SI 2 "nonmemory_operand" "")))]
1940 if (!register_operand (operands[0], SImode))
1942 rtx result = gen_reg_rtx (SImode);
1944 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1945 emit_move_insn (operands[0], result);
1949 else if (TARGET_MUL64_SET)
1951 rtx tmp = gen_reg_rtx (SImode);
1952 emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
1953 emit_move_insn (operands[0], tmp);
1956 else if (TARGET_MULMAC_32BY16_SET)
1958 rtx tmp = gen_reg_rtx (SImode);
1959 emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
1960 emit_move_insn (operands[0], tmp);
1965 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1966 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1967 emit_insn (gen_mulsi3_600_lib ());
1968 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1973 (define_insn_and_split "mulsi32x16"
1974 [(set (match_operand:SI 0 "register_operand" "=w")
1975 (mult:SI (match_operand:SI 1 "register_operand" "%c")
1976 (match_operand:SI 2 "nonmemory_operand" "ci")))
1977 (clobber (reg:DI MUL32x16_REG))]
1978 "TARGET_MULMAC_32BY16_SET"
1980 "TARGET_MULMAC_32BY16_SET && reload_completed"
1983 if (immediate_operand (operands[2], SImode)
1984 && INTVAL (operands[2]) >= 0
1985 && INTVAL (operands[2]) <= 65535)
1987 emit_insn (gen_umul_600 (operands[1], operands[2],
1988 gen_acc2 (), gen_acc1 ()));
1989 emit_move_insn (operands[0], gen_acc2 ());
1992 emit_insn (gen_umul_600 (operands[1], operands[2],
1993 gen_acc2 (), gen_acc1 ()));
1994 emit_insn (gen_mac_600 (operands[1], operands[2],
1995 gen_acc2 (), gen_acc1 ()));
1996 emit_move_insn (operands[0], gen_acc2 ());
1999 [(set_attr "type" "multi")
2000 (set_attr "length" "8")])
2002 ; mululw conditional execution without a LIMM clobbers an input register;
2003 ; we'd need a different pattern to describe this.
2004 ; To make the conditional execution valid for the LIMM alternative, we
2005 ; have to emit the LIMM before the register operand.
2006 (define_insn "umul_600"
2007 [(set (match_operand:SI 2 "acc2_operand" "")
2008 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2009 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2013 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2014 "TARGET_MULMAC_32BY16_SET"
2016 [(set_attr "length" "4,4,8")
2017 (set_attr "type" "mulmac_600")
2018 (set_attr "predicable" "no")
2019 (set_attr "cond" "nocond")])
2021 (define_insn "mac_600"
2022 [(set (match_operand:SI 2 "acc2_operand" "")
2024 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2026 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2031 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2032 "TARGET_MULMAC_32BY16_SET"
2033 "machlw%? 0, %0, %1"
2034 [(set_attr "length" "4,4,8")
2035 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2036 (set_attr "predicable" "no, no, yes")
2037 (set_attr "cond" "nocond, canuse_limm, canuse")])
2039 (define_insn_and_split "mulsi64"
2040 [(set (match_operand:SI 0 "register_operand" "=w")
2041 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2042 (match_operand:SI 2 "nonmemory_operand" "ci")))
2043 (clobber (reg:DI MUL64_OUT_REG))]
2046 "TARGET_MUL64_SET && reload_completed"
2049 emit_insn (gen_mulsi_600 (operands[1], operands[2],
2050 gen_mlo (), gen_mhi ()));
2051 emit_move_insn (operands[0], gen_mlo ());
2054 [(set_attr "type" "multi")
2055 (set_attr "length" "8")])
2057 (define_insn "mulsi_600"
2058 [(set (match_operand:SI 2 "mlo_operand" "")
2059 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
2060 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
2061 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2063 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
2064 ; using a machine code pattern that only allows "L" constraint constants.
2065 ; "mul64%? \t0, %0, %1%&"
2067 if (satisfies_constraint_I (operands[1])
2068 && !satisfies_constraint_L (operands[1]))
2070 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */
2071 int n = true_regnum (operands[0]);
2072 int i = INTVAL (operands[1]);
2073 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
2074 asm_fprintf (asm_out_file, "\t.short %d`",
2075 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
2076 return "; mul64%? \t0, %0, %1%&";
2078 return "mul64%? \t0, %0, %1%&";
2080 [(set_attr "length" "*,4,4,8")
2081 (set_attr "iscompact" "maybe,false,false,false")
2082 (set_attr "type" "multi,multi,multi,multi")
2083 (set_attr "predicable" "yes,yes,no,yes")
2084 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2086 ; If we compile without an mul option enabled, but link with libraries
2087 ; for a mul option, we'll see clobbers of multiplier output registers.
2088 ; There is also an implementation using norm that clobbers the loop registers.
2089 (define_insn "mulsi3_600_lib"
2090 [(set (reg:SI R0_REG)
2091 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2092 (clobber (reg:SI RETURN_ADDR_REGNUM))
2093 (clobber (reg:SI R1_REG))
2094 (clobber (reg:SI R2_REG))
2095 (clobber (reg:SI R3_REG))
2096 (clobber (reg:DI MUL64_OUT_REG))
2097 (clobber (reg:SI LP_COUNT))
2098 (clobber (reg:SI LP_START))
2099 (clobber (reg:SI LP_END))
2100 (clobber (reg:CC CC_REG))]
2102 && SFUNC_CHECK_PREDICABLE"
2103 "*return arc_output_libcall (\"__mulsi3\");"
2104 [(set_attr "is_sfunc" "yes")
2105 (set_attr "predicable" "yes")])
2107 (define_insn_and_split "mulsidi_600"
2108 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c")
2109 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c"))
2110 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32"))))
2111 (clobber (reg:DI MUL64_OUT_REG))]
2116 "emit_insn (gen_mul64 (operands[1], operands[2]));
2117 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2119 [(set_attr "type" "multi")
2120 (set_attr "length" "8")])
2122 (define_insn "mul64"
2123 [(set (reg:DI MUL64_OUT_REG)
2125 (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c, c"))
2126 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))]
2128 "mul64%? \t0, %0, %1%&"
2129 [(set_attr "length" "*,4,4,8")
2130 (set_attr "iscompact" "maybe,false,false,false")
2131 (set_attr "type" "multi,multi,multi,multi")
2132 (set_attr "predicable" "yes,yes,no,yes")
2133 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2135 (define_insn_and_split "umulsidi_600"
2136 [(set (match_operand:DI 0 "register_operand" "=c,c, c")
2137 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c,c, c"))
2138 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "cL,L,C32"))))
2139 (clobber (reg:DI MUL64_OUT_REG))]
2144 "emit_insn (gen_mulu64 (operands[1], operands[2]));
2145 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2147 [(set_attr "type" "umulti")
2148 (set_attr "length" "8")])
2150 (define_insn "mulu64"
2151 [(set (reg:DI MUL64_OUT_REG)
2153 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2154 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2156 "mulu64%? \t0, %0, %1%&"
2157 [(set_attr "length" "4,4,8")
2158 (set_attr "iscompact" "false")
2159 (set_attr "type" "umulti")
2160 (set_attr "predicable" "yes,no,yes")
2161 (set_attr "cond" "canuse,canuse_limm,canuse")])
2163 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2164 ; may not be used as destination constraint.
2166 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2167 ; but mpyu is faster for the standard multiplier.
2168 ; Note: we must make sure LP_COUNT is not one of the destination
2169 ; registers, since it cannot be the destination of a multi-cycle insn
2171 (define_insn "mulsi3_700"
2172 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r")
2173 (mult:SI (match_operand:SI 1 "register_operand" "%0,c,0,0,c")
2174 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2177 [(set_attr "length" "4,4,4,8,8")
2178 (set_attr "type" "umulti")
2179 (set_attr "predicable" "yes,no,no,yes,no")
2180 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2182 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2183 ; short variant. LP_COUNT constraints are still valid.
2184 (define_insn "mulsi3_v2"
2185 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r")
2186 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c")
2187 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2190 [(set_attr "length" "*,4,4,4,8,8")
2191 (set_attr "iscompact" "maybe,false,false,false,false,false")
2192 (set_attr "type" "umulti")
2193 (set_attr "predicable" "no,yes,no,no,yes,no")
2194 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2196 (define_expand "mulsidi3"
2197 [(set (match_operand:DI 0 "register_operand" "")
2198 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2199 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2202 if (TARGET_PLUS_MACD)
2204 if (CONST_INT_P (operands[2]))
2206 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2210 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2216 operands[2] = force_reg (SImode, operands[2]);
2217 if (!register_operand (operands[0], DImode))
2219 rtx result = gen_reg_rtx (DImode);
2221 operands[2] = force_reg (SImode, operands[2]);
2222 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2223 emit_move_insn (operands[0], result);
2227 else if (TARGET_MUL64_SET)
2229 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2232 else if (TARGET_MULMAC_32BY16_SET)
2234 operands[2] = force_reg (SImode, operands[2]);
2235 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2238 operands[2] = force_reg (SImode, operands[2]);
2241 (define_insn_and_split "mulsidi64"
2242 [(set (match_operand:DI 0 "register_operand" "=w")
2243 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2244 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2245 (clobber (reg:DI MUL32x16_REG))]
2246 "TARGET_MULMAC_32BY16_SET"
2248 "TARGET_MULMAC_32BY16_SET && reload_completed"
2251 rtx result_hi = gen_highpart (SImode, operands[0]);
2252 rtx result_low = gen_lowpart (SImode, operands[0]);
2254 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2255 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2256 emit_move_insn (result_low, gen_acc2 ());
2259 [(set_attr "type" "multi")
2260 (set_attr "length" "8")])
2263 (define_insn "mul64_600"
2264 [(set (reg:DI MUL32x16_REG)
2265 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2267 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2272 "TARGET_MULMAC_32BY16_SET"
2274 [(set_attr "length" "4,4,8")
2275 (set_attr "type" "mulmac_600")
2276 (set_attr "predicable" "no,no,yes")
2277 (set_attr "cond" "nocond, canuse_limm, canuse")])
2280 ;; ??? check if this is canonical rtl
2281 (define_insn "mac64_600"
2282 [(set (reg:DI MUL32x16_REG)
2284 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2286 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2287 (const_int 16) (const_int 16))
2289 (reg:DI MUL32x16_REG)))
2290 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2293 (mult:DI (sign_extend:DI (match_dup 1))
2295 (sign_extract:DI (match_dup 2)
2296 (const_int 16) (const_int 16))
2298 (reg:DI MUL32x16_REG))
2299 (const_int 32) (const_int 32)))]
2300 "TARGET_MULMAC_32BY16_SET"
2301 "machlw%? %0, %1, %2"
2302 [(set_attr "length" "4,4,8")
2303 (set_attr "type" "mulmac_600")
2304 (set_attr "predicable" "no,no,yes")
2305 (set_attr "cond" "nocond, canuse_limm, canuse")])
2308 ;; DI <- DI(signed SI) * DI(signed SI)
2309 (define_insn_and_split "mulsidi3_700"
2310 [(set (match_operand:DI 0 "register_operand" "=&r")
2311 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2312 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2313 "TARGET_MPY && !TARGET_PLUS_MACD"
2315 "&& reload_completed"
2318 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2319 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2320 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2321 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2322 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2323 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2326 [(set_attr "type" "multi")
2327 (set_attr "length" "8")])
2329 (define_insn "mulsi3_highpart"
2330 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2334 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2335 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2339 [(set_attr "length" "4,4,8,8")
2340 (set_attr "type" "multi")
2341 (set_attr "predicable" "yes,no,yes,no")
2342 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2344 ; Note that mpyhu has the same latency as mpy / mpyh,
2345 ; thus we use the type multi.
2346 (define_insn "*umulsi3_highpart_i"
2347 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2351 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2352 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2356 [(set_attr "length" "4,4,8,8")
2357 (set_attr "type" "multi")
2358 (set_attr "predicable" "yes,no,yes,no")
2359 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2361 ; Implementations include additional labels for umulsidi3, so we got all
2362 ; the same clobbers - plus one for the result low part. */
2363 (define_insn "umulsi3_highpart_600_lib_le"
2364 [(set (reg:SI R1_REG)
2367 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2368 (zero_extend:DI (reg:SI R1_REG)))
2370 (clobber (reg:SI RETURN_ADDR_REGNUM))
2371 (clobber (reg:SI R0_REG))
2372 (clobber (reg:DI R2_REG))
2373 (clobber (reg:SI R12_REG))
2374 (clobber (reg:DI MUL64_OUT_REG))
2375 (clobber (reg:CC CC_REG))]
2378 && SFUNC_CHECK_PREDICABLE"
2379 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2380 [(set_attr "is_sfunc" "yes")
2381 (set_attr "predicable" "yes")])
2383 (define_insn "umulsi3_highpart_600_lib_be"
2384 [(set (reg:SI R0_REG)
2387 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2388 (zero_extend:DI (reg:SI R1_REG)))
2390 (clobber (reg:SI RETURN_ADDR_REGNUM))
2391 (clobber (reg:SI R1_REG))
2392 (clobber (reg:DI R2_REG))
2393 (clobber (reg:SI R12_REG))
2394 (clobber (reg:DI MUL64_OUT_REG))
2395 (clobber (reg:CC CC_REG))]
2398 && SFUNC_CHECK_PREDICABLE"
2399 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2400 [(set_attr "is_sfunc" "yes")
2401 (set_attr "predicable" "yes")])
2403 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2404 ;; need a separate pattern for immediates
2405 ;; ??? This is fine for combine, but not for reload.
2406 (define_insn "umulsi3_highpart_int"
2407 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2411 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2412 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2416 [(set_attr "length" "4,4,4,8,8")
2417 (set_attr "type" "multi")
2418 (set_attr "predicable" "yes,no,no,yes,no")
2419 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2421 (define_expand "umulsi3_highpart"
2422 [(set (match_operand:SI 0 "general_operand" "")
2426 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2427 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2429 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2432 rtx target = operands[0];
2436 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2437 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2438 if (TARGET_BIG_ENDIAN)
2439 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2441 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2442 emit_move_insn (target, gen_rtx_REG (SImode, 0));
2446 if (!register_operand (target, SImode))
2447 target = gen_reg_rtx (SImode);
2449 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2450 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2451 operands[2], SImode);
2452 else if (!immediate_operand (operands[2], SImode))
2453 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2454 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2455 if (target != operands[0])
2456 emit_move_insn (operands[0], target);
2460 (define_expand "umulsidi3"
2461 [(set (match_operand:DI 0 "register_operand" "")
2462 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2463 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2466 if (TARGET_PLUS_MACD)
2468 if (CONST_INT_P (operands[2]))
2470 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2474 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2480 operands[2] = force_reg (SImode, operands[2]);
2481 if (!register_operand (operands[0], DImode))
2483 rtx result = gen_reg_rtx (DImode);
2485 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2486 emit_move_insn (operands[0], result);
2490 else if (TARGET_MUL64_SET)
2492 operands[2] = force_reg (SImode, operands[2]);
2493 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2496 else if (TARGET_MULMAC_32BY16_SET)
2498 operands[2] = force_reg (SImode, operands[2]);
2499 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2504 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2505 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2506 emit_insn (gen_umulsidi3_600_lib ());
2507 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2512 (define_insn_and_split "umulsidi64"
2513 [(set (match_operand:DI 0 "register_operand" "=w")
2514 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2515 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2516 (clobber (reg:DI MUL32x16_REG))]
2517 "TARGET_MULMAC_32BY16_SET"
2519 "TARGET_MULMAC_32BY16_SET && reload_completed"
2525 result_hi = gen_highpart (SImode, operands[0]);
2526 result_low = gen_lowpart (SImode, operands[0]);
2528 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2529 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2530 emit_move_insn (result_low, gen_acc2 ());
2533 [(set_attr "type" "multi")
2534 (set_attr "length" "8")])
2536 (define_insn "umul64_600"
2537 [(set (reg:DI MUL32x16_REG)
2538 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2540 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2545 "TARGET_MULMAC_32BY16_SET"
2547 [(set_attr "length" "4,4,8")
2548 (set_attr "type" "mulmac_600")
2549 (set_attr "predicable" "no")
2550 (set_attr "cond" "nocond")])
2553 (define_insn "umac64_600"
2554 [(set (reg:DI MUL32x16_REG)
2556 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2558 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2559 (const_int 16) (const_int 16))
2561 (reg:DI MUL32x16_REG)))
2562 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2565 (mult:DI (zero_extend:DI (match_dup 1))
2567 (zero_extract:DI (match_dup 2)
2568 (const_int 16) (const_int 16))
2570 (reg:DI MUL32x16_REG))
2571 (const_int 32) (const_int 32)))]
2572 "TARGET_MULMAC_32BY16_SET"
2573 "machulw%? %0, %1, %2"
2574 [(set_attr "length" "4,4,8")
2575 (set_attr "type" "mulmac_600")
2576 (set_attr "predicable" "no,no,yes")
2577 (set_attr "cond" "nocond, canuse_limm, canuse")])
2579 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2580 (define_insn_and_split "umulsidi3_700"
2581 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2582 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2583 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2584 "TARGET_MPY && !TARGET_PLUS_MACD"
2589 int hi = !TARGET_BIG_ENDIAN;
2591 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2592 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2593 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2594 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2597 [(set_attr "type" "umulti")
2598 (set_attr "length" "8")])
2600 (define_insn "umulsidi3_600_lib"
2601 [(set (reg:DI R0_REG)
2602 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2603 (zero_extend:DI (reg:SI R1_REG))))
2604 (clobber (reg:SI RETURN_ADDR_REGNUM))
2605 (clobber (reg:DI R2_REG))
2606 (clobber (reg:SI R12_REG))
2607 (clobber (reg:DI MUL64_OUT_REG))
2608 (clobber (reg:CC CC_REG))]
2610 && SFUNC_CHECK_PREDICABLE"
2611 "*return arc_output_libcall (\"__umulsidi3\");"
2612 [(set_attr "is_sfunc" "yes")
2613 (set_attr "predicable" "yes")])
2617 [(set (reg:DI R0_REG)
2618 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2619 (zero_extend:DI (reg:SI R1_REG))))
2620 (clobber (reg:SI RETURN_ADDR_REGNUM))
2621 (clobber (reg:DI R2_REG))
2622 (clobber (reg:SI R12_REG))
2623 (clobber (reg:DI MUL64_OUT_REG))
2624 (clobber (reg:CC CC_REG))])]
2626 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2629 if (TARGET_BIG_ENDIAN)
2630 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2632 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2636 (define_expand "addsi3"
2637 [(set (match_operand:SI 0 "dest_reg_operand" "")
2638 (plus:SI (match_operand:SI 1 "register_operand" "")
2639 (match_operand:SI 2 "nonmemory_operand" "")))]
2641 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2643 operands[2]=force_reg(SImode, operands[2]);
2645 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2647 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2652 (define_expand "adddi3"
2653 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2654 (plus:DI (match_operand:DI 1 "register_operand" "")
2655 (match_operand:DI 2 "nonmemory_operand" "")))
2656 (clobber (reg:CC CC_REG))])]
2660 ; This assumes that there can be no strictly partial overlap between
2661 ; operands[1] and operands[2].
2662 (define_insn_and_split "*adddi3_i"
2663 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2664 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2665 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2666 (clobber (reg:CC CC_REG))]
2672 int hi = !TARGET_BIG_ENDIAN;
2674 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2675 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2676 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2677 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2678 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2679 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2682 if (l2 == const0_rtx)
2684 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2685 emit_move_insn (l0, l1);
2686 emit_insn (gen_addsi3 (h0, h1, h2));
2687 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2688 emit_move_insn (l0, l1);
2691 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2692 && INTVAL (operands[2]) >= -0x7fffffff)
2694 emit_insn (gen_subdi3_i (operands[0], operands[1],
2695 GEN_INT (-INTVAL (operands[2]))));
2698 if (rtx_equal_p (l0, h1))
2700 if (h2 != const0_rtx)
2701 emit_insn (gen_addsi3 (h0, h1, h2));
2702 else if (!rtx_equal_p (h0, h1))
2703 emit_move_insn (h0, h1);
2704 emit_insn (gen_add_f (l0, l1, l2));
2708 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2709 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2712 emit_insn (gen_add_f (l0, l1, l2));
2713 emit_insn (gen_adc (h0, h1, h2));
2716 [(set_attr "cond" "clob")
2717 (set_attr "type" "binary")
2718 (set_attr "length" "16,16,20")])
2720 (define_insn "add_f"
2721 [(set (reg:CC_C CC_REG)
2723 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2724 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2726 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2727 (plus:SI (match_dup 1) (match_dup 2)))]
2730 [(set_attr "cond" "set")
2731 (set_attr "type" "compare")
2732 (set_attr "length" "4,4,8")])
2734 (define_insn "*add_f_2"
2735 [(set (reg:CC_C CC_REG)
2737 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2738 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2740 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2741 (plus:SI (match_dup 1) (match_dup 2)))]
2744 [(set_attr "cond" "set")
2745 (set_attr "type" "compare")
2746 (set_attr "length" "4,4,8")])
2748 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2749 ; needlessly prioritizing the matching constraint.
2750 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2751 ; execution is used where possible.
2752 (define_insn_and_split "adc"
2753 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2754 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2755 (match_operand:SI 1 "nonmemory_operand"
2757 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2758 "register_operand (operands[1], SImode)
2759 || register_operand (operands[2], SImode)"
2766 ; if we have a bad schedule after sched2, split.
2768 && !optimize_size && (!TARGET_ARC600_FAMILY)
2769 && arc_scheduling_not_expected ()
2770 && arc_sets_cc_p (prev_nonnote_insn (insn))
2771 /* If next comes a return or other insn that needs a delay slot,
2772 expect the adc to get into the delay slot. */
2773 && next_nonnote_insn (insn)
2774 && !arc_need_delay (next_nonnote_insn (insn))
2775 /* Restore operands before emitting. */
2776 && (extract_insn_cached (insn), 1)"
2777 [(set (match_dup 0) (match_dup 3))
2779 (ltu (reg:CC_C CC_REG) (const_int 0))
2780 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2781 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2782 [(set_attr "cond" "use")
2783 (set_attr "type" "cc_arith")
2784 (set_attr "length" "4,4,4,4,8")])
2786 ; combiner-splitter cmp / scc -> cmp / adc
2788 [(set (match_operand:SI 0 "dest_reg_operand" "")
2789 (gtu:SI (match_operand:SI 1 "register_operand" "")
2790 (match_operand:SI 2 "register_operand" "")))
2791 (clobber (reg CC_REG))]
2793 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2794 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2796 ; combine won't work when an intermediate result is used later...
2797 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2799 [(set (match_operand:SI 0 "dest_reg_operand" "")
2800 (plus:SI (match_operand:SI 1 "register_operand" "")
2801 (match_operand:SI 2 "nonmemory_operand" "")))
2802 (set (reg:CC_C CC_REG)
2803 (compare:CC_C (match_dup 0)
2804 (match_operand:SI 3 "nonmemory_operand" "")))]
2805 "rtx_equal_p (operands[1], operands[3])
2806 || rtx_equal_p (operands[2], operands[3])"
2808 [(set (reg:CC_C CC_REG)
2809 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2811 (plus:SI (match_dup 1) (match_dup 2)))])])
2813 ; ??? need to delve into combine to find out why this is not useful.
2814 ; We'd like to be able to grok various C idioms for carry bit usage.
2815 ;(define_insn "*adc_0"
2816 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2817 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2818 ; (match_operand:SI 1 "register_operand" "c")))]
2821 ; [(set_attr "cond" "use")
2822 ; (set_attr "type" "cc_arith")
2823 ; (set_attr "length" "4")])
2826 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2827 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2828 ; (match_operand:SI 2 "register_operand" "c"))
2829 ; (match_operand:SI 3 "register_operand" "c")))
2830 ; (clobber (reg CC_REG))]
2832 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2833 ; (set (match_dup 0)
2834 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2837 (define_expand "subsi3"
2838 [(set (match_operand:SI 0 "dest_reg_operand" "")
2839 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2840 (match_operand:SI 2 "nonmemory_operand" "")))]
2846 if (!register_operand (operands[2], SImode))
2848 operands[1] = force_reg (SImode, operands[1]);
2851 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2852 operands[c] = force_reg (SImode, operands[c]);
2853 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2854 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2857 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2858 ; combine should make such an insn go away.
2859 (define_insn_and_split "subsi3_insn"
2860 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2861 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,Rcqq, 0, cL,c,L,I,Cal,Cal, c")
2862 (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2863 "register_operand (operands[1], SImode)
2864 || register_operand (operands[2], SImode)"
2876 "reload_completed && get_attr_length (insn) == 8
2877 && satisfies_constraint_I (operands[1])
2878 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2879 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2880 "split_subsi (operands);"
2881 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2882 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2883 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2884 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2885 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2888 (define_expand "subdi3"
2889 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2890 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2891 (match_operand:DI 2 "nonmemory_operand" "")))
2892 (clobber (reg:CC CC_REG))])]
2895 if (!register_operand (operands[2], DImode))
2896 operands[1] = force_reg (DImode, operands[1]);
2899 (define_insn_and_split "subdi3_i"
2900 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2901 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2902 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2903 (clobber (reg:CC CC_REG))]
2904 "register_operand (operands[1], DImode)
2905 || register_operand (operands[2], DImode)"
2910 int hi = !TARGET_BIG_ENDIAN;
2912 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2913 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2914 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2915 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2916 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2917 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2919 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2921 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2922 if (!rtx_equal_p (h0, h1))
2923 emit_insn (gen_rtx_SET (h0, h1));
2924 emit_insn (gen_sub_f (l0, l1, l2));
2928 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2929 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2932 emit_insn (gen_sub_f (l0, l1, l2));
2933 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2936 [(set_attr "cond" "clob")
2937 (set_attr "length" "16,16,16,20,20")])
2939 (define_insn "*sbc_0"
2940 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2941 (minus:SI (match_operand:SI 1 "register_operand" "c")
2942 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2946 [(set_attr "cond" "use")
2947 (set_attr "type" "cc_arith")
2948 (set_attr "length" "4")])
2950 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2951 ; needlessly prioritizing the matching constraint.
2952 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2953 ; is used where possible.
2954 (define_insn_and_split "sbc"
2955 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2956 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2958 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2960 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2961 "register_operand (operands[1], SImode)
2962 || register_operand (operands[2], SImode)"
2969 ; if we have a bad schedule after sched2, split.
2971 && !optimize_size && (!TARGET_ARC600_FAMILY)
2972 && arc_scheduling_not_expected ()
2973 && arc_sets_cc_p (prev_nonnote_insn (insn))
2974 /* If next comes a return or other insn that needs a delay slot,
2975 expect the adc to get into the delay slot. */
2976 && next_nonnote_insn (insn)
2977 && !arc_need_delay (next_nonnote_insn (insn))
2978 /* Restore operands before emitting. */
2979 && (extract_insn_cached (insn), 1)"
2980 [(set (match_dup 0) (match_dup 4))
2982 (ltu (reg:CC_C CC_REG) (const_int 0))
2983 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2984 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2985 [(set_attr "cond" "use")
2986 (set_attr "type" "cc_arith")
2987 (set_attr "length" "4,4,4,4,8")])
2989 (define_insn "sub_f"
2990 [(set (reg:CC CC_REG)
2991 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2992 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2993 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2994 (minus:SI (match_dup 1) (match_dup 2)))]
2995 "register_operand (operands[1], SImode)
2996 || register_operand (operands[2], SImode)"
3004 [(set_attr "type" "compare")
3005 (set_attr "length" "4,4,4,4,8,8")])
3007 ; combine won't work when an intermediate result is used later...
3008 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3010 [(set (reg:CC CC_REG)
3011 (compare:CC (match_operand:SI 1 "register_operand" "")
3012 (match_operand:SI 2 "nonmemory_operand" "")))
3013 (set (match_operand:SI 0 "dest_reg_operand" "")
3014 (minus:SI (match_dup 1) (match_dup 2)))]
3017 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3018 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3021 [(set (reg:CC CC_REG)
3022 (compare:CC (match_operand:SI 1 "register_operand" "")
3023 (match_operand:SI 2 "nonmemory_operand" "")))
3024 (set (match_operand 3 "" "") (match_operand 4 "" ""))
3025 (set (match_operand:SI 0 "dest_reg_operand" "")
3026 (minus:SI (match_dup 1) (match_dup 2)))]
3027 "!reg_overlap_mentioned_p (operands[3], operands[1])
3028 && !reg_overlap_mentioned_p (operands[3], operands[2])
3029 && !reg_overlap_mentioned_p (operands[0], operands[4])
3030 && !reg_overlap_mentioned_p (operands[0], operands[3])"
3032 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3033 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3034 (set (match_dup 3) (match_dup 4))])
3036 (define_insn "*add_n"
3037 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3038 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3039 (match_operand:SI 2 "_1_2_3_operand" ""))
3040 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3042 "add%c2%? %0,%3,%1%&"
3043 [(set_attr "type" "shift")
3044 (set_attr "length" "*,4,4,8,4,8")
3045 (set_attr "predicable" "yes,yes,no,no,no,no")
3046 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3047 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3049 (define_insn "*add_n"
3050 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3051 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3052 (match_operand:SI 2 "_2_4_8_operand" ""))
3053 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3055 "add%z2%? %0,%3,%1%&"
3056 [(set_attr "type" "shift")
3057 (set_attr "length" "*,4,4,8,4,8")
3058 (set_attr "predicable" "yes,yes,no,no,no,no")
3059 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3060 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3062 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3063 ;; what synth_mult likes.
3064 (define_insn "*sub_n"
3065 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3066 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3067 (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
3068 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3071 [(set_attr "type" "shift")
3072 (set_attr "length" "4,4,8")
3073 (set_attr "predicable" "yes,no,no")
3074 (set_attr "cond" "canuse,nocond,nocond")
3075 (set_attr "iscompact" "false")])
3077 (define_insn "*sub_n"
3078 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3079 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3080 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
3081 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3084 [(set_attr "type" "shift")
3085 (set_attr "length" "4,4,8")
3086 (set_attr "predicable" "yes,no,no")
3087 (set_attr "cond" "canuse,nocond,nocond")
3088 (set_attr "iscompact" "false")])
3090 ; ??? check if combine matches this.
3091 (define_insn "*bset"
3092 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3093 (ior:SI (ashift:SI (const_int 1)
3094 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3095 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3098 [(set_attr "length" "4,4,8")
3099 (set_attr "predicable" "yes,no,no")
3100 (set_attr "cond" "canuse,nocond,nocond")]
3103 ; ??? check if combine matches this.
3104 (define_insn "*bxor"
3105 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3106 (xor:SI (ashift:SI (const_int 1)
3107 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3108 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3111 [(set_attr "length" "4,4,8")
3112 (set_attr "predicable" "yes,no,no")
3113 (set_attr "cond" "canuse,nocond,nocond")]
3116 ; ??? check if combine matches this.
3117 (define_insn "*bclr"
3118 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3119 (and:SI (not:SI (ashift:SI (const_int 1)
3120 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
3121 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3124 [(set_attr "length" "4,4,8")
3125 (set_attr "predicable" "yes,no,no")
3126 (set_attr "cond" "canuse,nocond,nocond")]
3129 ; ??? FIXME: find combine patterns for bmsk.
3131 ;;Following are the define_insns added for the purpose of peephole2's
3133 ; see also iorsi3 for use with constant bit number.
3134 (define_insn "*bset_insn"
3135 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3136 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3137 (ashift:SI (const_int 1)
3138 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3141 bset%? %0,%1,%2 ;;peep2, constr 1
3142 bset %0,%1,%2 ;;peep2, constr 2
3143 bset %0,%S1,%2 ;;peep2, constr 3"
3144 [(set_attr "length" "4,4,8")
3145 (set_attr "predicable" "yes,no,no")
3146 (set_attr "cond" "canuse,nocond,nocond")]
3149 ; see also xorsi3 for use with constant bit number.
3150 (define_insn "*bxor_insn"
3151 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3152 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3153 (ashift:SI (const_int 1)
3154 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3160 [(set_attr "length" "4,4,8")
3161 (set_attr "predicable" "yes,no,no")
3162 (set_attr "cond" "canuse,nocond,nocond")]
3165 ; see also andsi3 for use with constant bit number.
3166 (define_insn "*bclr_insn"
3167 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3168 (and:SI (not:SI (ashift:SI (const_int 1)
3169 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3170 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3176 [(set_attr "length" "4,4,8")
3177 (set_attr "predicable" "yes,no,no")
3178 (set_attr "cond" "canuse,nocond,nocond")]
3181 ; see also andsi3 for use with constant bit number.
3182 (define_insn "*bmsk_insn"
3183 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3184 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3185 (plus:SI (ashift:SI (const_int 1)
3186 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3194 [(set_attr "length" "4,4,8")
3195 (set_attr "predicable" "yes,no,no")
3196 (set_attr "cond" "canuse,nocond,nocond")]
3199 ;;Instructions added for peephole2s end
3201 ;; Boolean instructions.
3203 (define_expand "andsi3"
3204 [(set (match_operand:SI 0 "dest_reg_operand" "")
3205 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3206 (match_operand:SI 2 "nonmemory_operand" "")))]
3208 "if (!satisfies_constraint_Cux (operands[2]))
3209 operands[1] = force_reg (SImode, operands[1]);
3210 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3211 operands[1] = arc_rewrite_small_data (operands[1]);")
3213 (define_insn "andsi3_i"
3214 [(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")
3215 (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")
3216 (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")))]
3217 "(register_operand (operands[1], SImode)
3218 && nonmemory_operand (operands[2], SImode))
3219 || (memory_operand (operands[1], SImode)
3220 && satisfies_constraint_Cux (operands[2]))"
3222 switch (which_alternative)
3224 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3225 return "and%? %0,%1,%2%&";
3227 return "and%? %0,%2,%1%&";
3229 return "bmsk%? %0,%1,%Z2%&";
3231 if (satisfies_constraint_C2p (operands[2]))
3233 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3234 return "bmskn%? %0,%1,%Z2%&";
3238 return "bmsk%? %0,%1,%Z2%&";
3240 case 3: case 8: case 13:
3241 return "bclr%? %0,%1,%M2%&";
3243 return (INTVAL (operands[2]) == 0xff
3244 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3245 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3247 return "movb.cl %0,%1,%p2,%p2,%s2";
3252 if (satisfies_constraint_Ucm (operands[1]))
3253 tmpl = (INTVAL (operands[2]) == 0xff
3254 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3256 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3258 if (TARGET_BIG_ENDIAN)
3262 xop[0] = operands[0];
3263 xop[1] = adjust_address (operands[1], QImode,
3264 INTVAL (operands[2]) == 0xff ? 3 : 2);
3265 output_asm_insn (tmpl, xop);
3273 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3274 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3275 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3276 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3277 (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")])
3279 ; combiner splitter, pattern found in ldtoa.c .
3280 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3282 [(set (reg:CC_Z CC_REG)
3283 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3284 (match_operand 1 "const_int_operand" ""))
3285 (match_operand 2 "const_int_operand" "")))
3286 (clobber (match_operand:SI 3 "register_operand" ""))]
3287 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3289 (plus:SI (match_dup 0) (match_dup 4)))
3290 (set (reg:CC_Z CC_REG)
3291 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3293 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3295 ;;bic define_insn that allows limm to be the first operand
3296 (define_insn "*bicsi3_insn"
3297 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3298 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3299 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3302 bic%? %0, %2, %1%& ;;constraint 0
3303 bic%? %0,%2,%1 ;;constraint 1
3304 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3305 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3306 bic %0,%2,%1 ;;constraint 4
3307 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3308 bic %0,%S2,%1 ;;constraint 6"
3309 [(set_attr "length" "*,4,4,8,4,8,8")
3310 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3311 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3312 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3314 (define_insn "iorsi3"
3315 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3316 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3317 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3320 switch (which_alternative)
3322 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3323 return \"or%? %0,%1,%2%&\";
3325 return \"or%? %0,%2,%1%&\";
3326 case 2: case 5: case 8:
3327 return \"bset%? %0,%1,%z2%&\";
3331 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3332 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3333 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3334 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3336 (define_insn "xorsi3"
3337 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3338 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3339 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3342 switch (which_alternative)
3344 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3345 return \"xor%? %0,%1,%2%&\";
3347 return \"xor%? %0,%2,%1%&\";
3349 return \"bxor%? %0,%1,%z2\";
3354 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3355 (set_attr "type" "binary")
3356 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3357 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3358 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3360 (define_insn "negsi2"
3361 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3362 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3365 [(set_attr "type" "unary")
3366 (set_attr "iscompact" "maybe,true,false,false")
3367 (set_attr "predicable" "no,no,yes,no")])
3369 (define_insn "one_cmplsi2"
3370 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3371 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3374 [(set_attr "type" "unary,unary")
3375 (set_attr "iscompact" "true,false")])
3377 (define_insn_and_split "one_cmpldi2"
3378 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3379 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3382 "&& reload_completed"
3383 [(set (match_dup 2) (not:SI (match_dup 3)))
3384 (set (match_dup 4) (not:SI (match_dup 5)))]
3386 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3388 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3389 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3390 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3391 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3393 [(set_attr "type" "unary,unary")
3394 (set_attr "cond" "nocond,nocond")
3395 (set_attr "length" "4,8")])
3397 ;; Shift instructions.
3399 (define_expand "ashlsi3"
3400 [(set (match_operand:SI 0 "dest_reg_operand" "")
3401 (ashift:SI (match_operand:SI 1 "register_operand" "")
3402 (match_operand:SI 2 "nonmemory_operand" "")))]
3406 if (!TARGET_BARREL_SHIFTER)
3408 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3413 (define_expand "ashrsi3"
3414 [(set (match_operand:SI 0 "dest_reg_operand" "")
3415 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3416 (match_operand:SI 2 "nonmemory_operand" "")))]
3420 if (!TARGET_BARREL_SHIFTER)
3422 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3427 (define_expand "lshrsi3"
3428 [(set (match_operand:SI 0 "dest_reg_operand" "")
3429 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3430 (match_operand:SI 2 "nonmemory_operand" "")))]
3434 if (!TARGET_BARREL_SHIFTER)
3436 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3441 (define_insn "shift_si3"
3442 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3443 (match_operator:SI 3 "shift4_operator"
3444 [(match_operand:SI 1 "register_operand" "0")
3445 (match_operand:SI 2 "const_int_operand" "n")]))
3446 (clobber (match_scratch:SI 4 "=&r"))
3447 (clobber (reg:CC CC_REG))
3449 "!TARGET_BARREL_SHIFTER"
3450 "* return output_shift (operands);"
3451 [(set_attr "type" "shift")
3452 (set_attr "length" "16")])
3454 (define_insn "shift_si3_loop"
3455 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3456 (match_operator:SI 3 "shift_operator"
3457 [(match_operand:SI 1 "register_operand" "0,0")
3458 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3459 (clobber (match_scratch:SI 4 "=X,X"))
3460 (clobber (reg:SI LP_COUNT))
3461 (clobber (reg:SI LP_START))
3462 (clobber (reg:SI LP_END))
3463 (clobber (reg:CC CC_REG))
3465 "!TARGET_BARREL_SHIFTER"
3466 "* return output_shift (operands);"
3467 [(set_attr "type" "shift")
3468 (set_attr "length" "16,20")])
3470 ; asl, asr, lsr patterns:
3471 ; There is no point in including an 'I' alternative since only the lowest 5
3472 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3473 ; is defined in an external symbol, as we don't have special relocations
3474 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3475 ; provide one alternatice for this, without condexec support.
3476 (define_insn "*ashlsi3_insn"
3477 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3478 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3479 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3480 "TARGET_BARREL_SHIFTER
3481 && (register_operand (operands[1], SImode)
3482 || register_operand (operands[2], SImode))"
3484 [(set_attr "type" "shift")
3485 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3486 (set_attr "predicable" "no,no,no,yes,no,no")
3487 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3489 (define_insn "*ashrsi3_insn"
3490 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3491 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3492 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3493 "TARGET_BARREL_SHIFTER
3494 && (register_operand (operands[1], SImode)
3495 || register_operand (operands[2], SImode))"
3497 [(set_attr "type" "shift")
3498 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3499 (set_attr "predicable" "no,no,no,yes,no,no")
3500 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3502 (define_insn "*lshrsi3_insn"
3503 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3504 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3505 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3506 "TARGET_BARREL_SHIFTER
3507 && (register_operand (operands[1], SImode)
3508 || register_operand (operands[2], SImode))"
3509 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3510 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3511 [(set_attr "type" "shift")
3512 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3513 (set_attr "predicable" "no,no,no,yes,no,no")
3514 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3516 (define_insn "rotrsi3"
3517 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3518 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3519 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3520 "TARGET_BARREL_SHIFTER"
3522 [(set_attr "type" "shift,shift,shift")
3523 (set_attr "predicable" "yes,no,no")
3524 (set_attr "length" "4,4,8")])
3526 ;; Compare / branch instructions.
3528 (define_expand "cbranchsi4"
3529 [(set (reg:CC CC_REG)
3530 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3531 (match_operand:SI 2 "nonmemory_operand" "")))
3534 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3536 (label_ref (match_operand 3 "" ""))
3540 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3541 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3542 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3543 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3547 ;; ??? Could add a peephole to generate compare with swapped operands and
3548 ;; modifed cc user if second, but not first operand is a compact register.
3549 (define_insn "cmpsi_cc_insn_mixed"
3550 [(set (reg:CC CC_REG)
3551 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq, h, c, c,qRcq,c")
3552 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI,cL, Cal,Cal")))]
3555 [(set_attr "type" "compare")
3556 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3557 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3558 (set_attr "cond" "set")
3559 (set_attr "length" "*,*,*,4,4,*,8")
3560 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3562 (define_insn "*cmpsi_cc_zn_insn"
3563 [(set (reg:CC_ZN CC_REG)
3564 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3568 [(set_attr "type" "compare,compare")
3569 (set_attr "iscompact" "true,false")
3570 (set_attr "predicable" "no,yes")
3571 (set_attr "cond" "set_zn")
3572 (set_attr "length" "*,4")])
3574 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3575 (define_insn "*btst"
3576 [(set (reg:CC_ZN CC_REG)
3578 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3580 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3584 [(set_attr "iscompact" "true,false")
3585 (set_attr "predicable" "no,yes")
3586 (set_attr "cond" "set")
3587 (set_attr "type" "compare")
3588 (set_attr "length" "*,4")])
3590 ; combine suffers from 'simplifications' that replace a one-bit zero
3591 ; extract with a shift if it can prove that the upper bits are zero.
3592 ; arc_reorg sees the code after sched2, which can have caused our
3593 ; inputs to be clobbered even if they were not clobbered before.
3594 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3595 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3596 ; bbit (i.e. bad scheduling) and missed conditional execution,
3597 ; so make this an option.
3599 [(set (reg:CC_ZN CC_REG)
3601 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3603 (match_operand:SI 1 "nonmemory_operand" ""))
3606 (if_then_else (match_operator 3 "equality_comparison_operator"
3607 [(reg:CC_ZN CC_REG) (const_int 0)])
3608 (label_ref (match_operand 2 "" ""))
3610 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3611 [(parallel [(set (pc)
3614 [(zero_extract:SI (match_dup 0)
3615 (const_int 1) (match_dup 1))
3617 (label_ref (match_dup 2))
3619 (clobber (reg:CC_ZN CC_REG))])])
3621 (define_insn "*cmpsi_cc_z_insn"
3622 [(set (reg:CC_Z CC_REG)
3623 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3624 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3629 [(set_attr "type" "compare,compare")
3630 (set_attr "iscompact" "true,false")
3631 (set_attr "cond" "set,set_zn")
3632 (set_attr "length" "*,4")])
3634 (define_insn "*cmpsi_cc_c_insn"
3635 [(set (reg:CC_C CC_REG)
3636 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c")
3637 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))]
3640 [(set_attr "type" "compare")
3641 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3642 (set_attr "cond" "set")
3643 (set_attr "length" "*,*,*,4,*,8")
3644 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3646 ;; Next come the scc insns.
3648 (define_expand "cstoresi4"
3649 [(set (match_operand:SI 0 "dest_reg_operand" "")
3650 (match_operator:SI 1 "ordered_comparison_operator"
3651 [(match_operand:SI 2 "nonmemory_operand" "")
3652 (match_operand:SI 3 "nonmemory_operand" "")]))]
3655 if (!TARGET_CODE_DENSITY)
3657 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3658 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3659 operands[1] = gen_compare_reg (operands[1], SImode);
3660 emit_insn (gen_scc_insn (operands[0], operands[1]));
3663 if (!register_operand (operands[2], SImode))
3664 operands[2] = force_reg (SImode, operands[2]);
3668 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3669 (DF "TARGET_OPTFPE")])
3671 (define_expand "cstore<mode>4"
3672 [(set (reg:CC CC_REG)
3673 (compare:CC (match_operand:SDF 2 "register_operand" "")
3674 (match_operand:SDF 3 "register_operand" "")))
3675 (set (match_operand:SI 0 "dest_reg_operand" "")
3676 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3679 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3681 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3682 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3683 operands[1] = gen_compare_reg (operands[1], SImode);
3684 emit_insn (gen_scc_insn (operands[0], operands[1]));
3688 ; We need a separate expander for this lest we loose the mode of CC_REG
3689 ; when match_operator substitutes the literal operand into the comparison.
3690 (define_expand "scc_insn"
3691 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3693 (define_insn_and_split "*scc_insn"
3694 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3695 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3699 [(set (match_dup 0) (const_int 1))
3702 (set (match_dup 0) (const_int 0)))]
3705 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3706 GET_MODE (XEXP (operands[1], 0))),
3708 XEXP (operands[1], 0), XEXP (operands[1], 1));
3710 [(set_attr "type" "unary")])
3712 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3713 ;; that is one lower if the carry flag is set.
3715 ;; ??? Look up negscc insn. See pa.md for example.
3716 (define_insn "*neg_scc_insn"
3717 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3718 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3719 [(reg CC_REG) (const_int 0)])))]
3721 "mov %0,-1\;sub.%D1 %0,%0,%0"
3722 [(set_attr "type" "unary")
3723 (set_attr "length" "8")])
3725 (define_insn "*not_scc_insn"
3726 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3727 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3728 [(reg CC_REG) (const_int 0)])))]
3730 "mov %0,1\;sub.%d1 %0,%0,%0"
3731 [(set_attr "type" "unary")
3732 (set_attr "length" "8")])
3734 ; cond_exec patterns
3735 (define_insn "*movsi_ne"
3737 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0))
3738 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w")
3739 (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))]
3742 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3743 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3744 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3747 [(set_attr "type" "cmove")
3748 (set_attr "iscompact" "true,true,true_limm,false,false")
3749 (set_attr "length" "2,2,6,4,8")
3750 (set_attr "cpu_facility" "*,av2,av2,*,*")])
3752 (define_insn "*movsi_cond_exec"
3754 (match_operator 3 "proper_comparison_operator"
3755 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3756 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3757 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3760 [(set_attr "type" "cmove")
3761 (set_attr "length" "4,8")])
3763 (define_insn "*commutative_cond_exec"
3765 (match_operator 5 "proper_comparison_operator"
3766 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3767 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3768 (match_operator:SI 3 "commutative_operator"
3769 [(match_operand:SI 1 "register_operand" "%0,0")
3770 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3773 arc_output_commutative_cond_exec (operands, true);
3776 [(set_attr "cond" "use")
3777 (set_attr "type" "cmove")
3778 (set_attr_alternative "length"
3781 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3786 (define_insn "*sub_cond_exec"
3788 (match_operator 4 "proper_comparison_operator"
3789 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3790 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3791 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3792 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3798 [(set_attr "cond" "use")
3799 (set_attr "type" "cmove")
3800 (set_attr "length" "4,4,8")])
3802 (define_insn "*noncommutative_cond_exec"
3804 (match_operator 5 "proper_comparison_operator"
3805 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3806 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3807 (match_operator:SI 3 "noncommutative_operator"
3808 [(match_operand:SI 1 "register_operand" "0,0")
3809 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3812 [(set_attr "cond" "use")
3813 (set_attr "type" "cmove")
3814 (set_attr "length" "4,8")])
3816 ;; These control RTL generation for conditional jump insns
3817 ;; Match both normal and inverted jump.
3819 ; We need a separate expander for this lest we loose the mode of CC_REG
3820 ; when match_operator substitutes the literal operand into the comparison.
3821 (define_expand "branch_insn"
3823 (if_then_else (match_operand 1 "" "")
3824 (label_ref (match_operand 0 "" ""))
3827 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3828 ; are three reasons why we need to consider branches to be length 6:
3829 ; - annull-false delay slot insns are implemented using conditional execution,
3830 ; thus preventing short insn formation where used.
3831 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3832 ; using conditional execution, preventing short insn formation where used.
3833 ; - for ARC700: likely or somewhat likely taken branches are made long and
3834 ; unaligned if possible to avoid branch penalty.
3835 (define_insn "*branch_insn"
3837 (if_then_else (match_operator 1 "proper_comparison_operator"
3838 [(reg CC_REG) (const_int 0)])
3839 (label_ref (match_operand 0 "" ""))
3844 if (arc_ccfsm_branch_deleted_p ())
3846 arc_ccfsm_record_branch_deleted ();
3847 return \"; branch deleted, next insns conditionalized\";
3851 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3852 if (get_attr_length (insn) == 2)
3853 return \"b%d1%? %^%l0%&\";
3855 return \"b%d1%# %^%l0\";
3858 [(set_attr "type" "branch")
3862 (eq_attr "delay_slot_filled" "yes")
3867 (match_operand 1 "equality_comparison_operator" "")
3868 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3869 (gt (minus (match_dup 0) (pc))
3870 (minus (const_int 506)
3871 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3872 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3873 (lt (minus (match_dup 0) (pc)) (const_int -64))
3874 (gt (minus (match_dup 0) (pc))
3875 (minus (const_int 58)
3876 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3881 (set (attr "iscompact")
3882 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3883 (const_string "false")))])
3885 (define_insn "*rev_branch_insn"
3887 (if_then_else (match_operator 1 "proper_comparison_operator"
3888 [(reg CC_REG) (const_int 0)])
3890 (label_ref (match_operand 0 "" ""))))]
3891 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3894 if (arc_ccfsm_branch_deleted_p ())
3896 arc_ccfsm_record_branch_deleted ();
3897 return \"; branch deleted, next insns conditionalized\";
3901 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3902 if (get_attr_length (insn) == 2)
3903 return \"b%D1%? %^%l0\";
3905 return \"b%D1%# %^%l0\";
3908 [(set_attr "type" "branch")
3912 (eq_attr "delay_slot_filled" "yes")
3917 (match_operand 1 "equality_comparison_operator" "")
3918 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3919 (gt (minus (match_dup 0) (pc))
3920 (minus (const_int 506)
3921 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3922 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3923 (lt (minus (match_dup 0) (pc)) (const_int -64))
3924 (gt (minus (match_dup 0) (pc))
3925 (minus (const_int 58)
3926 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3931 (set (attr "iscompact")
3932 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3933 (const_string "false")))])
3935 ;; Unconditional and other jump instructions.
3937 (define_expand "jump"
3938 [(set (pc) (label_ref (match_operand 0 "" "")))]
3942 (define_insn "jump_i"
3943 [(set (pc) (label_ref (match_operand 0 "" "")))]
3944 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3946 [(set_attr "type" "uncond_branch")
3947 (set (attr "iscompact")
3948 (if_then_else (match_test "get_attr_length (insn) == 2")
3949 (const_string "true") (const_string "false")))
3950 (set_attr "cond" "canuse")
3951 (set (attr "length")
3953 ; In arc_reorg we just guesstimate; might be more or less than 4.
3954 (match_test "arc_branch_size_unknown_p ()")
3957 (eq_attr "delay_slot_filled" "yes")
3960 (match_test "CROSSING_JUMP_P (insn)")
3963 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3964 (gt (minus (match_dup 0) (pc))
3965 (minus (const_int 506)
3966 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3970 (define_insn "indirect_jump"
3971 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3979 [(set_attr "type" "jump")
3980 (set_attr "iscompact" "false,false,false,maybe,false")
3981 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3983 ;; Implement a switch statement.
3985 (define_expand "casesi"
3987 (minus:SI (match_operand:SI 0 "register_operand" "")
3988 (match_operand:SI 1 "nonmemory_operand" "")))
3989 (set (reg:CC CC_REG)
3990 (compare:CC (match_dup 5)
3991 (match_operand:SI 2 "nonmemory_operand" "")))
3993 (if_then_else (gtu (reg:CC CC_REG)
3995 (label_ref (match_operand 4 "" ""))
3998 (unspec:SI [(match_operand 3 "" "")
3999 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
4000 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4006 operands[5] = gen_reg_rtx (SImode);
4007 operands[6] = gen_reg_rtx (SImode);
4008 operands[7] = operands[3];
4009 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4010 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4011 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4012 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4013 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4014 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
4015 if (TARGET_COMPACT_CASESI)
4017 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4021 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4022 if (flag_pic || !cse_not_expected)
4023 operands[3] = force_reg (Pmode, operands[3]);
4024 emit_insn (gen_casesi_load (operands[6],
4025 operands[3], operands[5], operands[7]));
4026 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4027 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4028 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4033 (define_insn "casesi_load"
4034 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
4035 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4036 (match_operand:SI 2 "register_operand" "Rcq,c,c")
4037 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
4041 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4043 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4045 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4046 gcc_assert (GET_MODE (diff_vec) == SImode);
4047 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4050 switch (GET_MODE (diff_vec))
4053 return \"ld.as %0,[%1,%2]%&\";
4055 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4056 return \"ld%_.as %0,[%1,%2]\";
4057 return \"ld%_.x.as %0,[%1,%2]\";
4059 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4060 return \"ldb%? %0,[%1,%2]%&\";
4061 return \"ldb.x %0,[%1,%2]\";
4066 [(set_attr "type" "load")
4067 (set_attr_alternative "iscompact"
4069 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4070 (as_a<rtx_insn *> (operands[3]))))")
4071 (symbol_ref "QImode"))
4072 (const_string "false")
4073 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4074 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4075 (const_string "false")]
4076 (const_string "true"))
4077 (const_string "false")
4078 (const_string "false")])
4079 (set_attr_alternative "length"
4081 [(eq_attr "iscompact" "false") (const_int 4)
4082 ; We have to mention (match_dup 3) to convince genattrtab.c that this
4083 ; is a varying length insn.
4084 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4085 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4090 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4091 ; even for CASE_VECTOR_PC_RELATIVE.
4092 (define_insn "casesi_jump"
4093 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4094 (use (label_ref (match_operand 1 "" "")))]
4097 [(set_attr "type" "jump")
4098 (set_attr "iscompact" "false,maybe,false")
4099 (set_attr "cond" "canuse")])
4101 (define_insn "casesi_compact_jump"
4103 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4105 (use (label_ref (match_operand 1 "" "")))
4106 (clobber (match_scratch:SI 2 "=q,0"))]
4107 "TARGET_COMPACT_CASESI"
4110 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4111 int unalign = arc_get_unalign ();
4115 xop[0] = operands[0];
4116 xop[2] = operands[2];
4117 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4119 switch (GET_MODE (diff_vec))
4122 /* Max length can be 12 in this case, but this is OK because
4123 2 of these are for alignment, and are anticipated in the length
4124 of the ADDR_DIFF_VEC. */
4125 if (unalign && !satisfies_constraint_Rcq (xop[0]))
4126 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
4128 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4130 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4131 arc_clear_unalign ();
4134 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4136 if (satisfies_constraint_Rcq (xop[0]))
4138 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
4139 xop[1] = GEN_INT ((10 - unalign) / 2U);
4143 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
4144 xop[1] = GEN_INT (10 + unalign);
4149 if (satisfies_constraint_Rcq (xop[0]))
4151 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
4152 xop[1] = GEN_INT ((10 - unalign) / 2U);
4156 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
4157 xop[1] = GEN_INT (10 + unalign);
4160 arc_toggle_unalign ();
4163 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4165 if ((rtx_equal_p (xop[2], xop[0])
4166 || find_reg_note (insn, REG_DEAD, xop[0]))
4167 && satisfies_constraint_Rcq (xop[0]))
4169 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4170 xop[1] = GEN_INT (8 + unalign);
4174 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4175 xop[1] = GEN_INT (10 + unalign);
4176 arc_toggle_unalign ();
4179 else if ((rtx_equal_p (xop[0], xop[2])
4180 || find_reg_note (insn, REG_DEAD, xop[0]))
4181 && satisfies_constraint_Rcq (xop[0]))
4183 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4184 xop[1] = GEN_INT (10 - unalign);
4185 arc_toggle_unalign ();
4189 /* ??? Length is 12. */
4190 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4191 xop[1] = GEN_INT (8 + unalign);
4197 output_asm_insn (s, xop);
4198 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4200 [(set_attr "length" "10")
4201 (set_attr "type" "jump")
4202 (set_attr "iscompact" "true")
4203 (set_attr "cond" "nocond")])
4205 (define_expand "call"
4206 ;; operands[1] is stack_size_rtx
4207 ;; operands[2] is next_arg_register
4208 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4209 (match_operand 1 "" ""))
4210 (clobber (reg:SI 31))])]
4215 gcc_assert (MEM_P (operands[0]));
4216 callee = XEXP (operands[0], 0);
4217 /* This is to decide if we should generate indirect calls by loading the
4218 32 bit address of the callee into a register before performing the
4219 branch and link - this exposes cse opportunities.
4220 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4221 if (GET_CODE (callee) != REG
4222 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4223 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4228 ; Rcq, which is used in alternative 0, checks for conditional execution.
4229 ; At instruction output time, if it doesn't match and we end up with
4230 ; alternative 1 ("q"), that means that we can't use the short form.
4231 (define_insn "*call_i"
4232 [(call (mem:SI (match_operand:SI 0
4233 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4234 (match_operand 1 "" ""))
4235 (clobber (reg:SI 31))]
4246 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4247 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4248 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4249 (set_attr "length" "*,*,4,4,4,4,4,8")])
4251 (define_expand "call_value"
4252 ;; operand 2 is stack_size_rtx
4253 ;; operand 3 is next_arg_register
4254 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4255 (call (match_operand:SI 1 "call_operand" "")
4256 (match_operand 2 "" "")))
4257 (clobber (reg:SI 31))])]
4263 gcc_assert (MEM_P (operands[1]));
4264 callee = XEXP (operands[1], 0);
4265 /* See the comment in define_expand \"call\". */
4266 if (GET_CODE (callee) != REG
4267 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4268 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4272 ; Rcq, which is used in alternative 0, checks for conditional execution.
4273 ; At instruction output time, if it doesn't match and we end up with
4274 ; alternative 1 ("q"), that means that we can't use the short form.
4275 (define_insn "*call_value_i"
4276 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
4277 (call (mem:SI (match_operand:SI 1
4278 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4279 (match_operand 2 "" "")))
4280 (clobber (reg:SI 31))]
4291 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4292 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4293 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4294 (set_attr "length" "*,*,4,4,4,4,4,8")])
4296 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4297 ; use it for lack of inter-procedural branch shortening.
4298 ; Link-time relaxation would help...
4304 [(set_attr "type" "misc")
4305 (set_attr "iscompact" "true")
4306 (set_attr "cond" "canuse")
4307 (set_attr "length" "2")])
4310 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4313 [(set_attr "type" "misc")
4314 (set_attr "iscompact" "true")
4315 (set_attr "length" "2")])
4317 ;; Special pattern to flush the icache.
4318 ;; ??? Not sure what to do here. Some ARC's are known to support this.
4320 (define_insn "flush_icache"
4321 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4324 [(set_attr "type" "misc")])
4326 ;; Split up troublesome insns for better scheduling.
4328 ;; Peepholes go at the end.
4329 ;;asl followed by add can be replaced by an add{1,2,3}
4330 ;; Three define_peepholes have been added for this optimization
4331 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4332 ;; can be generated by combine. Check if these peepholes still provide
4335 ;; -------------------------------------------------------------
4336 ;; Pattern 1 : r0 = r1 << {i}
4337 ;; r3 = r4/INT + r0 ;;and commutative
4340 ;; add{i} r3,r4/INT,r1
4341 ;; -------------------------------------------------------------
4342 ;; ??? This should be covered by combine, alas, at times combine gets
4343 ;; too clever for it's own good: when the shifted input is known to be
4344 ;; either 0 or 1, the operation will be made into an if-then-else, and
4345 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4346 ;; newlib/libc/time/mktm_r.c .
4349 [(set (match_operand:SI 0 "dest_reg_operand" "")
4350 (ashift:SI (match_operand:SI 1 "register_operand" "")
4351 (match_operand:SI 2 "const_int_operand" "")))
4352 (set (match_operand:SI 3 "dest_reg_operand" "")
4353 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4354 (match_operand:SI 5 "nonmemory_operand" "")))]
4355 "(INTVAL (operands[2]) == 1
4356 || INTVAL (operands[2]) == 2
4357 || INTVAL (operands[2]) == 3)
4358 && (true_regnum (operands[4]) == true_regnum (operands[0])
4359 || true_regnum (operands[5]) == true_regnum (operands[0]))
4360 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4361 ;; the preparation statements take care to put proper operand in operands[4]
4362 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4364 (plus:SI (mult:SI (match_dup 1)
4367 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4368 operands[4] = operands[5];
4369 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4372 ;; -------------------------------------------------------------
4373 ;; Pattern 1 : r0 = r1 << {i}
4378 ;; -------------------------------------------------------------
4379 ;; ??? This should be covered by combine, alas, at times combine gets
4380 ;; too clever for it's own good: when the shifted input is known to be
4381 ;; either 0 or 1, the operation will be made into an if-then-else, and
4382 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4383 ;; newlib/libm/math/e_jn.c .
4386 [(set (match_operand:SI 0 "dest_reg_operand" "")
4387 (ashift:SI (match_operand:SI 1 "register_operand" "")
4388 (match_operand:SI 2 "const_int_operand" "")))
4389 (set (match_operand:SI 3 "dest_reg_operand" "")
4390 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4392 "(INTVAL (operands[2]) == 1
4393 || INTVAL (operands[2]) == 2
4394 || INTVAL (operands[2]) == 3)
4395 && (peep2_reg_dead_p (2, operands[0])
4396 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4398 (minus:SI (match_dup 4)
4399 (mult:SI (match_dup 1)
4401 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4406 ; When using the high single bit, the result of a multiply is either
4407 ; the original number or zero. But MPY costs 4 cycles, which we
4408 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4410 [(set (match_operand:SI 0 "dest_reg_operand" "")
4411 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4413 (set (match_operand:SI 4 "register_operand" "")
4414 (mult:SI (match_operand:SI 2 "register_operand")
4415 (match_operand:SI 3 "nonmemory_operand" "")))]
4417 && (rtx_equal_p (operands[0], operands[2])
4418 || rtx_equal_p (operands[0], operands[3]))
4419 && peep2_regno_dead_p (0, CC_REG)
4420 && (rtx_equal_p (operands[0], operands[4])
4421 || (peep2_reg_dead_p (2, operands[0])
4422 && peep2_reg_dead_p (1, operands[4])))"
4423 [(parallel [(set (reg:CC_Z CC_REG)
4424 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4426 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4428 (ne (reg:CC_Z CC_REG) (const_int 0))
4429 (set (match_dup 4) (match_dup 5)))]
4431 if (!rtx_equal_p (operands[0], operands[2]))
4432 operands[5] = operands[2];
4433 else if (!rtx_equal_p (operands[0], operands[3]))
4434 operands[5] = operands[3];
4436 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4440 [(set (match_operand:SI 0 "dest_reg_operand" "")
4441 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4443 (set (match_operand:SI 4 "register_operand" "")
4444 (mult:SI (match_operand:SI 2 "register_operand")
4445 (match_operand:SI 3 "nonmemory_operand" "")))]
4447 && (rtx_equal_p (operands[0], operands[2])
4448 || rtx_equal_p (operands[0], operands[3]))
4449 && peep2_regno_dead_p (2, CC_REG)"
4450 [(parallel [(set (reg:CC_Z CC_REG)
4451 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4453 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4454 (set (match_dup 4) (match_dup 5))
4456 (eq (reg:CC_Z CC_REG) (const_int 0))
4457 (set (match_dup 4) (const_int 0)))]
4458 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4460 ;; Instructions generated through builtins
4462 (define_insn "clrsbsi2"
4463 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4464 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4469 [(set_attr "length" "4,8")
4470 (set_attr "type" "two_cycle_core,two_cycle_core")])
4472 (define_insn "norm_f"
4473 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4474 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4475 (set (reg:CC_ZN CC_REG)
4476 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4481 [(set_attr "length" "4,8")
4482 (set_attr "type" "two_cycle_core,two_cycle_core")])
4484 (define_insn_and_split "clrsbhi2"
4485 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4486 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4490 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4491 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4493 (define_insn "normw"
4494 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4496 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4501 [(set_attr "length" "4,8")
4502 (set_attr "type" "two_cycle_core,two_cycle_core")])
4504 (define_expand "clzsi2"
4506 [(set (match_operand:SI 0 "register_operand" "")
4507 (clz:SI (match_operand:SI 1 "register_operand" "")))
4508 (clobber (match_dup 2))])]
4510 "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);")
4512 (define_insn_and_split "*arc_clzsi2"
4513 [(set (match_operand:SI 0 "register_operand" "=r")
4514 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4515 (clobber (reg:CC_ZN CC_REG))]
4521 emit_insn (gen_norm_f (operands[0], operands[1]));
4525 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4526 gen_rtx_SET (operands[0], const0_rtx)));
4530 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4531 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4534 [(set_attr "type" "unary")
4535 (set_attr "length" "12")])
4537 (define_expand "ctzsi2"
4538 [(match_operand:SI 0 "register_operand" "")
4539 (match_operand:SI 1 "register_operand" "")]
4542 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4546 (define_insn_and_split "arc_ctzsi2"
4547 [(set (match_operand:SI 0 "register_operand" "=r")
4548 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4549 (clobber (reg:CC_ZN CC_REG))
4550 (clobber (match_scratch:SI 2 "=&r"))]
4556 rtx temp = operands[0];
4558 if (reg_overlap_mentioned_p (temp, operands[1])
4559 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4560 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4563 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4564 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4565 emit_insn (gen_clrsbsi2 (operands[0], temp));
4569 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4570 gen_rtx_SET (operands[0], GEN_INT (32))));
4574 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4575 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4579 [(set_attr "type" "unary")
4580 (set_attr "length" "20")])
4583 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4584 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4591 [(set_attr "length" "4,8,4")
4592 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4594 (define_insn "divaw"
4595 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4596 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4597 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4599 "TARGET_ARC700 || TARGET_EA_SET"
4603 divaw \t%0, %1, %S2"
4604 [(set_attr "length" "4,8,8")
4605 (set_attr "type" "divaw,divaw,divaw")])
4608 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4615 [(set_attr "length" "4,4,8")
4616 (set_attr "type" "misc,misc,misc")
4617 (set_attr "predicable" "yes,no,yes")
4618 (set_attr "cond" "clob,clob,clob")])
4621 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4625 [(set_attr "length" "4")
4626 (set_attr "type" "misc")])
4629 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4633 [(set_attr "length" "4")
4634 (set_attr "type" "misc")
4635 (set_attr "cond" "clob")])
4638 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4642 [(set_attr "length" "4")
4643 (set_attr "type" "misc")])
4646 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4656 [(set_attr "length" "4")
4657 (set_attr "type" "misc")])
4660 (define_insn "sleep"
4661 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4663 "check_if_valid_sleep_operand(operands,0)"
4665 [(set_attr "length" "4")
4666 (set_attr "type" "misc")])
4668 (define_insn "core_read"
4669 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4670 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4671 VUNSPEC_ARC_CORE_READ))]
4674 if (check_if_valid_regno_const (operands, 1))
4675 return \"mov \t%0, r%1\";
4676 return \"mov \t%0, r%1\";
4678 [(set_attr "length" "4")
4679 (set_attr "type" "unary")])
4681 (define_insn "core_write"
4682 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4683 (match_operand:SI 1 "general_operand" "Hn,!r")]
4684 VUNSPEC_ARC_CORE_WRITE)]
4687 if (check_if_valid_regno_const (operands, 1))
4688 return \"mov \tr%1, %0\";
4689 return \"mov \tr%1, %0\";
4691 [(set_attr "length" "4")
4692 (set_attr "type" "unary")])
4695 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4696 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4700 [(set_attr "length" "4,8,4,8")
4701 (set_attr "type" "lr,lr,lr,lr")])
4704 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4705 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4709 [(set_attr "length" "8,4,8,4")
4710 (set_attr "type" "sr,sr,sr,sr")])
4712 (define_insn "trap_s"
4713 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4714 VUNSPEC_ARC_TRAP_S)]
4715 "!TARGET_ARC600_FAMILY"
4717 if (which_alternative == 0)
4719 arc_toggle_unalign ();
4720 return \"trap_s %0\";
4723 /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4724 because *.md files do not get scanned by exgettext. */
4725 fatal_error (input_location,
4726 \"operand to trap_s should be an unsigned 6-bit value\");
4728 [(set_attr "length" "2")
4729 (set_attr "type" "misc")])
4731 (define_insn "unimp_s"
4732 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4733 VUNSPEC_ARC_UNIMP_S)]
4734 "!TARGET_ARC600_FAMILY"
4736 [(set_attr "length" "4")
4737 (set_attr "type" "misc")])
4739 ;; End of instructions generated through builtins
4741 ; Since the demise of REG_N_SETS as reliable data readily available to the
4742 ; target, it is no longer possible to find out
4743 ; in the prologue / epilogue expanders how many times blink is set.
4744 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4745 ; any explicit use of blink will cause it to be saved; hence we cannot
4746 ; represent the blink use in return / sibcall instructions themselves, and
4747 ; instead have to show it in EPILOGUE_USES and must explicitly
4748 ; forbid instructions that change blink in the return / sibcall delay slot.
4749 (define_expand "sibcall"
4750 [(parallel [(call (match_operand 0 "memory_operand" "")
4751 (match_operand 1 "general_operand" ""))
4753 (use (match_operand 2 "" ""))])]
4757 rtx callee = XEXP (operands[0], 0);
4759 if (operands[2] == NULL_RTX)
4760 operands[2] = const0_rtx;
4761 if (GET_CODE (callee) != REG
4762 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4763 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4767 (define_expand "sibcall_value"
4768 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4769 (call (match_operand 1 "memory_operand" "")
4770 (match_operand 2 "general_operand" "")))
4772 (use (match_operand 3 "" ""))])]
4776 rtx callee = XEXP (operands[1], 0);
4778 if (operands[3] == NULL_RTX)
4779 operands[3] = const0_rtx;
4780 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4781 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4785 (define_insn "*sibcall_insn"
4786 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4787 "Cbp,Cbr,Rs5,Rsc,Cal"))
4788 (match_operand 1 "" ""))
4790 (use (match_operand 2 "" ""))]
4798 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4799 (set_attr "predicable" "yes,no,no,yes,yes")
4800 (set_attr "iscompact" "false,false,maybe,false,false")
4801 (set_attr "is_SIBCALL" "yes")]
4804 (define_insn "*sibcall_value_insn"
4805 [(set (match_operand 0 "dest_reg_operand" "")
4806 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4807 "Cbp,Cbr,Rs5,Rsc,Cal"))
4808 (match_operand 2 "" "")))
4810 (use (match_operand 3 "" ""))]
4818 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4819 (set_attr "predicable" "yes,no,no,yes,yes")
4820 (set_attr "iscompact" "false,false,maybe,false,false")
4821 (set_attr "is_SIBCALL" "yes")]
4824 (define_expand "prologue"
4828 arc_expand_prologue ();
4832 (define_expand "epilogue"
4836 arc_expand_epilogue (0);
4840 (define_expand "sibcall_epilogue"
4844 arc_expand_epilogue (1);
4848 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4849 ; in the prologue / epilogue expanders how many times blink is set.
4850 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4851 ; any explicit use of blink will cause it to be saved; hence we cannot
4852 ; represent the blink use in return / sibcall instructions themselves, and
4853 ; instead have to show it in EPILOGUE_USES and must explicitly
4854 ; forbid instructions that change blink in the return / sibcall delay slot.
4855 (define_insn "simple_return"
4860 = gen_rtx_REG (Pmode,
4861 arc_return_address_register (arc_compute_function_type
4865 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
4869 if (TARGET_PAD_RETURN)
4871 output_asm_insn (\"j%!%* [%0]%&\", ®);
4875 (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
4876 (match_test "TARGET_V2"))
4877 (const_string "brcc_no_delay_slot")]
4878 (const_string "return")))
4879 ; predicable won't help here since the canonical rtl looks different
4882 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4883 (symbol_ref "ARC_FUNCTION_ILINK1"))
4884 (match_test "TARGET_V2"))
4885 (const_string "nocond")]
4886 (const_string "canuse")))
4887 (set (attr "iscompact")
4888 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4889 (symbol_ref "ARC_FUNCTION_NORMAL"))
4890 (const_string "maybe")]
4891 (const_string "false")))
4892 (set (attr "length")
4893 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4894 (symbol_ref "ARC_FUNCTION_NORMAL"))
4898 (define_insn "p_return_i"
4900 (if_then_else (match_operator 0 "proper_comparison_operator"
4901 [(reg CC_REG) (const_int 0)])
4902 (simple_return) (pc)))]
4905 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
4908 xop[0] = operands[0];
4910 = gen_rtx_REG (Pmode,
4911 arc_return_address_register (arc_compute_function_type
4914 if (TARGET_PAD_RETURN)
4916 output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4917 /* record the condition in case there is a delay insn. */
4918 arc_ccfsm_record_condition (xop[0], false, insn, 0);
4921 [(set_attr "type" "return")
4922 (set_attr "cond" "use")
4923 (set (attr "iscompact")
4924 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4925 (symbol_ref "ARC_FUNCTION_NORMAL"))
4926 (const_string "maybe")]
4927 (const_string "false")))
4928 (set (attr "length")
4929 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4930 (symbol_ref "ARC_FUNCTION_NORMAL"))
4932 (not (match_operand 0 "equality_comparison_operator" ""))
4934 (eq_attr "delay_slot_filled" "yes")
4938 (define_insn_and_split "eh_return"
4940 (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4941 (clobber (match_scratch:SI 1 "=X,r"))
4942 (clobber (match_scratch:SI 2 "=&r,r"))]
4946 [(set (match_dup 2) (match_dup 0))]
4948 int offs = arc_return_slot_offset ();
4951 operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4954 if (!register_operand (operands[0], Pmode)
4955 && !satisfies_constraint_C32 (operands[0]))
4957 emit_move_insn (operands[1], operands[0]);
4958 operands[0] = operands[1];
4960 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4961 if (!strict_memory_address_p (Pmode, addr))
4963 emit_move_insn (operands[2], addr);
4966 operands[2] = gen_frame_mem (Pmode, addr);
4969 [(set_attr "length" "12")])
4971 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4972 ;; non-constant predicate.
4973 (define_expand "return"
4977 ;; Comment in final.c (insn_current_reference_address) says
4978 ;; forward branch addresses are calculated from the next insn after branch
4979 ;; and for backward branches, it is calculated from the branch insn start.
4980 ;; The shortening logic here is tuned to accomodate this behavior
4981 ;; ??? This should be grokked by the ccfsm machinery.
4982 (define_insn "cbranchsi4_scratch"
4984 (if_then_else (match_operator 0 "proper_comparison_operator"
4985 [(match_operand:SI 1 "register_operand" "c,c, c")
4986 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4987 (label_ref (match_operand 3 "" ""))
4989 (clobber (match_operand 4 "cc_register" ""))]
4991 || (TARGET_EARLY_CBRANCHSI
4992 && brcc_nolimm_operator (operands[0], VOIDmode)))
4993 && !CROSSING_JUMP_P (insn)"
4995 switch (get_attr_length (insn))
4997 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4998 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4999 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5000 return \"br%d0%* %1, %B2, %^%l3\";
5003 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
5004 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5007 [(set_attr "cond" "clob, clob, clob")
5010 (match_test "valid_brcc_with_delay_p (operands)")
5011 (const_string "brcc")
5012 (const_string "brcc_no_delay_slot")))
5013 ; For forward branches, we need to account not only for the distance to
5014 ; the target, but also the difference between pcl and pc, the instruction
5015 ; length, and any delay insn, if present.
5018 (cond ; the outer cond does a test independent of branch shortening.
5019 [(match_operand 0 "brcc_nolimm_operator" "")
5021 [(and (match_operand:CC_Z 4 "cc_register")
5022 (eq_attr "delay_slot_filled" "no")
5023 (ge (minus (match_dup 3) (pc)) (const_int -128))
5024 (le (minus (match_dup 3) (pc))
5025 (minus (const_int 122)
5026 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5028 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5029 (le (minus (match_dup 3) (pc))
5030 (minus (const_int 244)
5031 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5033 (and (match_operand:SI 1 "compact_register_operand" "")
5034 (match_operand:SI 2 "compact_hreg_operand" ""))
5037 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5038 (le (minus (match_dup 3) (pc)) (const_int 244)))
5040 (and (match_operand:SI 1 "compact_register_operand" "")
5041 (match_operand:SI 2 "compact_hreg_operand" ""))
5044 (set (attr "iscompact")
5045 (if_then_else (match_test "get_attr_length (insn) & 2")
5046 (const_string "true") (const_string "false")))])
5048 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5049 (define_insn "*bbit"
5052 (match_operator 3 "equality_comparison_operator"
5053 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5055 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5057 (label_ref (match_operand 0 "" ""))
5059 (clobber (reg:CC_ZN CC_REG))]
5060 "!CROSSING_JUMP_P (insn)"
5062 switch (get_attr_length (insn))
5064 case 4: return (GET_CODE (operands[3]) == EQ
5065 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5067 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5068 default: gcc_unreachable ();
5071 [(set_attr "type" "brcc")
5072 (set_attr "cond" "clob")
5073 (set (attr "length")
5074 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5075 (le (minus (match_dup 0) (pc))
5076 (minus (const_int 248)
5077 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5079 (eq (symbol_ref "which_alternative") (const_int 0))
5082 (set (attr "iscompact")
5083 (if_then_else (match_test "get_attr_length (insn) == 6")
5084 (const_string "true") (const_string "false")))])
5086 ; ??? When testing a bit from a DImode register, combine creates a
5087 ; zero_extract in DImode. This goes via an AND with a DImode constant,
5088 ; so can only be observed on 64 bit hosts.
5089 (define_insn_and_split "*bbit_di"
5092 (match_operator 3 "equality_comparison_operator"
5093 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
5095 (match_operand 2 "immediate_operand" "L,L"))
5097 (label_ref (match_operand 0 "" ""))
5099 (clobber (reg:CC_ZN CC_REG))]
5100 "!CROSSING_JUMP_P (insn)"
5104 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
5105 (clobber (reg:CC_ZN CC_REG))])]
5109 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5110 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5114 ;; -------------------------------------------------------------------
5116 ;; -------------------------------------------------------------------
5118 ; operand 0 is the loop count pseudo register
5119 ; operand 1 is the label to jump to at the top of the loop
5120 (define_expand "doloop_end"
5121 [(parallel [(set (pc)
5123 (ne (match_operand 0 "" "")
5125 (label_ref (match_operand 1 "" ""))
5127 (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5128 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5129 (clobber (match_dup 2))])]
5132 if (GET_MODE (operands[0]) != SImode)
5134 operands[2] = gen_rtx_SCRATCH (SImode);
5137 (define_insn "arc_lp"
5138 [(unspec:SI [(match_operand:SI 0 "register_operand" "l")]
5140 (use (label_ref (match_operand 1 "" "")))
5141 (use (label_ref (match_operand 2 "" "")))]
5143 "lp\\t@%l2\\t; %0:@%l1->@%l2"
5144 [(set_attr "type" "loop_setup")
5145 (set_attr "length" "4")])
5147 ;; if by any chance the lp_count is not used, then use an 'r'
5148 ;; register, instead of going to memory.
5149 (define_insn "loop_end"
5151 (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
5153 (label_ref (match_operand 1 "" ""))
5155 (set (match_operand:SI 0 "nonimmediate_operand" "=l!r,m")
5156 (plus (match_dup 2) (const_int -1)))
5157 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5158 (clobber (match_scratch:SI 3 "=X,&r"))]
5161 [(set_attr "length" "0")
5162 (set_attr "predicable" "no")
5163 (set_attr "type" "loop_end")])
5165 ;; split pattern for the very slim chance when the loop register is
5169 (if_then_else (ne (match_operand:SI 0 "memory_operand")
5171 (label_ref (match_operand 1 ""))
5173 (set (match_dup 0) (plus (match_dup 0) (const_int -1)))
5174 (unspec [(const_int 0)] UNSPEC_ARC_LP)
5175 (clobber (match_scratch:SI 2))]
5176 "memory_operand (operands[0], SImode)"
5177 [(set (match_dup 2) (match_dup 0))
5178 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5179 (set (match_dup 0) (match_dup 2))
5180 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5182 (if_then_else (ne (reg:CC CC_REG)
5184 (label_ref (match_dup 1))
5188 (define_insn "loop_fail"
5189 [(set (reg:SI LP_COUNT)
5190 (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5191 (set (reg:CC_ZN CC_REG)
5192 (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5195 "sub.f%?\\tlp_count,lp_count,1"
5196 [(set_attr "iscompact" "false")
5197 (set_attr "type" "compare")
5198 (set_attr "cond" "set_zn")
5199 (set_attr "length" "4")
5200 (set_attr "predicable" "yes")])
5202 (define_insn_and_split "dbnz"
5205 (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+r!l,m")
5208 (label_ref (match_operand 1 "" ""))
5211 (plus:SI (match_dup 0)
5213 (clobber (match_scratch:SI 2 "=X,r"))]
5218 "TARGET_V2 && reload_completed && memory_operand (operands[0], SImode)"
5219 [(set (match_dup 2) (match_dup 0))
5220 (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5221 (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5222 (set (match_dup 0) (match_dup 2))
5223 (set (pc) (if_then_else (ge (reg:CC CC_REG)
5225 (label_ref (match_dup 1))
5228 [(set_attr "iscompact" "false")
5229 (set_attr "type" "loop_end")
5230 (set_attr "length" "4,20")])
5232 (define_expand "movmemsi"
5233 [(match_operand:BLK 0 "" "")
5234 (match_operand:BLK 1 "" "")
5235 (match_operand:SI 2 "nonmemory_operand" "")
5236 (match_operand 3 "immediate_operand" "")]
5238 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5240 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5241 ;; to the point that we can generate cmove instructions.
5242 (define_expand "cbranch<mode>4"
5243 [(set (reg:CC CC_REG)
5244 (compare:CC (match_operand:SDF 1 "register_operand" "")
5245 (match_operand:SDF 2 "register_operand" "")))
5248 (match_operator 0 "comparison_operator" [(reg CC_REG)
5250 (label_ref (match_operand 3 "" ""))
5253 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5255 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5256 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5257 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5258 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5262 (define_expand "cmp_float"
5263 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5264 (clobber (reg:SI RETURN_ADDR_REGNUM))
5265 (clobber (reg:SI R12_REG))])]
5269 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5270 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5271 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5273 (define_insn "*cmpsf_<cmp>"
5274 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5275 (clobber (reg:SI RETURN_ADDR_REGNUM))
5276 (clobber (reg:SI R12_REG))]
5277 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5278 && SFUNC_CHECK_PREDICABLE"
5279 "*return arc_output_libcall (\"__<cmp>sf2\");"
5280 [(set_attr "is_sfunc" "yes")
5281 (set_attr "predicable" "yes")])
5283 ;; N.B. for "*cmpdf_ord":
5284 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5285 ;; for the floating point emulation to recognize the NaN.
5286 (define_insn "*cmpdf_<cmp>"
5287 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5288 (clobber (reg:SI RETURN_ADDR_REGNUM))
5289 (clobber (reg:SI R12_REG))]
5290 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5291 && SFUNC_CHECK_PREDICABLE"
5292 "*return arc_output_libcall (\"__<cmp>df2\");"
5293 [(set_attr "is_sfunc" "yes")
5294 (set_attr "predicable" "yes")])
5296 (define_insn "abssf2"
5297 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5298 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5301 [(set_attr "type" "unary")
5302 (set_attr "iscompact" "maybe,false,false")
5303 (set_attr "length" "2,4,4")
5304 (set_attr "predicable" "no,yes,no")])
5306 (define_insn "negsf2"
5307 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5308 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5311 [(set_attr "type" "unary")
5312 (set_attr "predicable" "yes,no")])
5314 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5315 (define_insn "*millicode_thunk_st"
5316 [(match_parallel 0 "millicode_store_operation"
5317 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5320 output_asm_insn ("bl%* __st_r13_to_%0",
5321 &SET_SRC (XVECEXP (operands[0], 0,
5322 XVECLEN (operands[0], 0) - 2)));
5325 [(set_attr "type" "call")])
5327 (define_insn "*millicode_thunk_ld"
5328 [(match_parallel 0 "millicode_load_clob_operation"
5329 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5332 output_asm_insn ("bl%* __ld_r13_to_%0",
5333 &SET_DEST (XVECEXP (operands[0], 0,
5334 XVECLEN (operands[0], 0) - 2)));
5337 [(set_attr "type" "call")])
5339 ; the sibthunk restores blink, so we use the return rtx.
5340 (define_insn "*millicode_sibthunk_ld"
5341 [(match_parallel 0 "millicode_load_operation"
5343 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5344 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5347 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5348 &SET_DEST (XVECEXP (operands[0], 0,
5349 XVECLEN (operands[0], 0) - 1)));
5352 [(set_attr "type" "call")
5353 (set_attr "is_SIBCALL" "yes")])
5355 (define_insn "tls_load_tp_soft"
5356 [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5357 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5359 "*return arc_output_libcall (\"__read_tp\");"
5360 [(set_attr "is_sfunc" "yes")
5361 (set_attr "predicable" "yes")])
5363 (define_insn "tls_gd_get_addr"
5364 [(set (reg:SI R0_REG)
5365 (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5366 "symbolic_operand" "X,X")]
5369 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5371 ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5372 [(set_attr "type" "call")
5373 ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5374 (set_attr "predicable" "no")])
5376 ;; For thread pointer builtins
5377 (define_expand "get_thread_pointersi"
5378 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5380 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5382 (define_expand "set_thread_pointersi"
5383 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5385 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5387 ;; If hardware floating point is available, don't define a negdf pattern;
5388 ;; it would be something like:
5389 ;;(define_insn "negdf2"
5390 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5391 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5392 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5395 ;; bxor%? %H0,%H1,31
5396 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5397 ;; drsubh%F0%F1 0,0,0
5398 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5399 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5400 ;; (set_attr "iscompact" "false,false,false,false")
5401 ;; (set_attr "length" "4,4,8,12")
5402 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5403 ;; and this suffers from always requiring a long immediate when using
5404 ;; the floating point hardware.
5405 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5406 ;; constant zero efficiently into a register when we want to do the
5407 ;; computation using the floating point hardware. There should be a special
5408 ;; subdf alternative that matches a zero operand 1, which then can allow
5409 ;; to use bxor to flip the high bit of an integer register.
5410 ;; ??? we actually can't use the floating point hardware for neg, because
5411 ;; this would not work right for -0. OTOH optabs.c has already code
5412 ;; to synthesyze negate by flipping the sign bit.
5415 (define_insn "bswapsi2"
5416 [(set (match_operand:SI 0 "register_operand" "= r,r")
5417 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5418 "TARGET_V2 && TARGET_SWAP"
5420 [(set_attr "length" "4,8")
5421 (set_attr "type" "two_cycle_core")])
5423 (define_expand "prefetch"
5424 [(prefetch (match_operand:SI 0 "address_operand" "")
5425 (match_operand:SI 1 "const_int_operand" "")
5426 (match_operand:SI 2 "const_int_operand" ""))]
5430 (define_insn "prefetch_1"
5431 [(prefetch (match_operand:SI 0 "register_operand" "r")
5432 (match_operand:SI 1 "const_int_operand" "n")
5433 (match_operand:SI 2 "const_int_operand" "n"))]
5436 if (INTVAL (operands[1]))
5437 return "prefetchw [%0]";
5439 return "prefetch [%0]";
5441 [(set_attr "type" "load")
5442 (set_attr "length" "4")])
5444 (define_insn "prefetch_2"
5445 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5446 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5447 (match_operand:SI 2 "const_int_operand" "n,n,n")
5448 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5451 if (INTVAL (operands[2]))
5452 return "prefetchw [%0, %1]";
5454 return "prefetch [%0, %1]";
5456 [(set_attr "type" "load")
5457 (set_attr "length" "4,4,8")])
5459 (define_insn "prefetch_3"
5460 [(prefetch (match_operand:SI 0 "address_operand" "p")
5461 (match_operand:SI 1 "const_int_operand" "n")
5462 (match_operand:SI 2 "const_int_operand" "n"))]
5465 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5466 if (INTVAL (operands[1]))
5467 return "prefetchw%U0 %0";
5469 return "prefetch%U0 %0";
5471 [(set_attr "type" "load")
5472 (set_attr "length" "8")])
5474 (define_insn "divsi3"
5475 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5476 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5477 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5480 [(set_attr "length" "4,4,8,4,4,4,8,8")
5481 (set_attr "iscompact" "false")
5482 (set_attr "type" "div_rem")
5483 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5484 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5487 (define_insn "udivsi3"
5488 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5489 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5490 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5493 [(set_attr "length" "4,4,8,4,4,4,8,8")
5494 (set_attr "iscompact" "false")
5495 (set_attr "type" "div_rem")
5496 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5497 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5500 (define_insn "modsi3"
5501 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5502 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5503 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5506 [(set_attr "length" "4,4,8,4,4,4,8,8")
5507 (set_attr "iscompact" "false")
5508 (set_attr "type" "div_rem")
5509 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5510 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5513 (define_insn "umodsi3"
5514 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5515 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5516 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5519 [(set_attr "length" "4,4,8,4,4,4,8,8")
5520 (set_attr "iscompact" "false")
5521 (set_attr "type" "div_rem")
5522 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5523 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5526 ;; SETcc instructions
5527 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5529 (define_insn "arcset<code>"
5530 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5531 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5532 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5533 "TARGET_V2 && TARGET_CODE_DENSITY"
5534 "set<code>%? %0, %1, %2"
5535 [(set_attr "length" "4,4,4,4,4,8,8")
5536 (set_attr "iscompact" "false")
5537 (set_attr "type" "compare")
5538 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5539 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5542 (define_insn "arcsetltu"
5543 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5544 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5545 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5546 "TARGET_V2 && TARGET_CODE_DENSITY"
5547 "setlo%? %0, %1, %2"
5548 [(set_attr "length" "4,4,4,4,4,8,8")
5549 (set_attr "iscompact" "false")
5550 (set_attr "type" "compare")
5551 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5552 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5555 (define_insn "arcsetgeu"
5556 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5557 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5558 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5559 "TARGET_V2 && TARGET_CODE_DENSITY"
5560 "seths%? %0, %1, %2"
5561 [(set_attr "length" "4,4,4,4,4,8,8")
5562 (set_attr "iscompact" "false")
5563 (set_attr "type" "compare")
5564 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5565 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5568 ;; Special cases of SETCC
5569 (define_insn_and_split "arcsethi"
5570 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5571 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5572 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5573 "TARGET_V2 && TARGET_CODE_DENSITY"
5574 "setlo%? %0, %2, %1"
5576 && CONST_INT_P (operands[2])
5577 && satisfies_constraint_C62 (operands[2])"
5580 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5581 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5582 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5585 [(set_attr "length" "4,4,4,8")
5586 (set_attr "iscompact" "false")
5587 (set_attr "type" "compare")
5588 (set_attr "predicable" "yes,no,no,no")
5589 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5592 (define_insn_and_split "arcsetls"
5593 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5594 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5595 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5596 "TARGET_V2 && TARGET_CODE_DENSITY"
5597 "seths%? %0, %2, %1"
5599 && CONST_INT_P (operands[2])
5600 && satisfies_constraint_C62 (operands[2])"
5603 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5604 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5605 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5608 [(set_attr "length" "4,4,4,8")
5609 (set_attr "iscompact" "false")
5610 (set_attr "type" "compare")
5611 (set_attr "predicable" "yes,no,no,no")
5612 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5615 ; Any mode that needs to be solved by secondary reload
5616 (define_mode_iterator SRI [QI HI])
5618 (define_expand "reload_<mode>_load"
5619 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5620 (match_operand:SRI 1 "memory_operand" "m")
5621 (match_operand:SI 2 "register_operand" "=&r")])]
5624 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5628 (define_expand "reload_<mode>_store"
5629 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5630 (match_operand:SRI 1 "register_operand" "r")
5631 (match_operand:SI 2 "register_operand" "=&r")])]
5634 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5639 (define_insn "extzvsi"
5640 [(set (match_operand:SI 0 "register_operand" "=r , r , r, r, r")
5641 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, 0, r")
5642 (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5643 (match_operand:SI 3 "const_int_operand" "i , i , i, i, i")))]
5644 "TARGET_HS && TARGET_BARREL_SHIFTER"
5646 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5647 operands[2] = GEN_INT (assemble_op2);
5648 return "xbfu%? %0,%1,%2";
5650 [(set_attr "type" "shift")
5651 (set_attr "iscompact" "false")
5652 (set_attr "length" "4,4,4,8,8")
5653 (set_attr "predicable" "yes,no,no,yes,no")
5654 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
5656 (define_insn "kflag"
5657 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5664 [(set_attr "length" "4,4,8")
5665 (set_attr "type" "misc,misc,misc")
5666 (set_attr "predicable" "yes,no,yes")
5667 (set_attr "cond" "clob,clob,clob")])
5670 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5671 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5675 [(set_attr "length" "4")
5676 (set_attr "type" "misc")])
5679 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5680 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5682 "TARGET_NORM && TARGET_V2"
5686 [(set_attr "length" "4,8")
5687 (set_attr "type" "two_cycle_core,two_cycle_core")])
5689 (define_insn "ffs_f"
5690 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5691 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5693 (set (reg:CC_ZN CC_REG)
5694 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5695 "TARGET_NORM && TARGET_V2"
5699 [(set_attr "length" "4,8")
5700 (set_attr "type" "two_cycle_core,two_cycle_core")])
5702 (define_expand "ffssi2"
5703 [(parallel [(set (match_dup 2)
5704 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5706 (set (reg:CC_ZN CC_REG)
5707 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5708 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5709 (set (match_operand:SI 0 "dest_reg_operand" "")
5710 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5713 "TARGET_NORM && TARGET_V2"
5715 operands[2] = gen_reg_rtx (SImode);
5719 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5720 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5722 "TARGET_NORM && TARGET_V2"
5726 [(set_attr "length" "4,8")
5727 (set_attr "type" "two_cycle_core,two_cycle_core")])
5730 [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5734 [(set_attr "length" "4")
5735 (set_attr "type" "misc")])
5740 (define_expand "addsf3"
5741 [(set (match_operand:SF 0 "register_operand" "")
5742 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5743 (match_operand:SF 2 "nonmemory_operand" "")))]
5744 "TARGET_FP_SP_BASE || TARGET_SPFP"
5746 if (!register_operand (operands[1], SFmode)
5747 && !register_operand (operands[2], SFmode))
5748 operands[1] = force_reg (SFmode, operands[1]);
5752 (define_expand "subsf3"
5753 [(set (match_operand:SF 0 "register_operand" "")
5754 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5755 (match_operand:SF 2 "nonmemory_operand" "")))]
5756 "TARGET_FP_SP_BASE || TARGET_SPFP"
5758 if (!register_operand (operands[1], SFmode)
5759 && !register_operand (operands[2], SFmode))
5760 operands[1] = force_reg (SFmode, operands[1]);
5764 (define_expand "mulsf3"
5765 [(set (match_operand:SF 0 "register_operand" "")
5766 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5767 (match_operand:SF 2 "nonmemory_operand" "")))]
5768 "TARGET_FP_SP_BASE || TARGET_SPFP"
5770 if (!register_operand (operands[1], SFmode)
5771 && !register_operand (operands[2], SFmode))
5772 operands[1] = force_reg (SFmode, operands[1]);
5776 (define_expand "adddf3"
5777 [(set (match_operand:DF 0 "double_register_operand" "")
5778 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5779 (match_operand:DF 2 "nonmemory_operand" "")))]
5780 "TARGET_FP_DP_BASE || TARGET_DPFP"
5784 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5786 rtx first, second, tmp;
5787 split_double (operands[2], &first, &second);
5788 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5789 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5790 operands[2], tmp, const0_rtx));
5793 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5794 operands[2], const1_rtx, const1_rtx));
5797 else if (TARGET_FP_DP_BASE)
5799 if (!even_register_operand (operands[2], DFmode))
5800 operands[2] = force_reg (DFmode, operands[2]);
5802 if (!even_register_operand (operands[1], DFmode))
5803 operands[1] = force_reg (DFmode, operands[1]);
5810 (define_expand "subdf3"
5811 [(set (match_operand:DF 0 "double_register_operand" "")
5812 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5813 (match_operand:DF 2 "nonmemory_operand" "")))]
5814 "TARGET_FP_DP_BASE || TARGET_DPFP"
5818 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5819 operands[1] = force_reg (DFmode, operands[1]);
5820 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5821 || GET_CODE (operands[2]) == CONST_DOUBLE)
5823 rtx first, second, tmp;
5824 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5825 split_double (operands[const_index], &first, &second);
5826 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5827 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5828 operands[2], tmp, const0_rtx));
5831 emit_insn (gen_subdf3_insn (operands[0], operands[1],
5832 operands[2], const1_rtx, const1_rtx));
5835 else if (TARGET_FP_DP_BASE)
5837 if (!even_register_operand (operands[2], DFmode))
5838 operands[2] = force_reg (DFmode, operands[2]);
5840 if (!even_register_operand (operands[1], DFmode))
5841 operands[1] = force_reg (DFmode, operands[1]);
5848 (define_expand "muldf3"
5849 [(set (match_operand:DF 0 "double_register_operand" "")
5850 (mult:DF (match_operand:DF 1 "double_register_operand" "")
5851 (match_operand:DF 2 "nonmemory_operand" "")))]
5852 "TARGET_FP_DP_BASE || TARGET_DPFP"
5856 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5858 rtx first, second, tmp;
5859 split_double (operands[2], &first, &second);
5860 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5861 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5862 operands[2], tmp, const0_rtx));
5865 emit_insn (gen_muldf3_insn (operands[0], operands[1],
5866 operands[2], const1_rtx, const1_rtx));
5869 else if (TARGET_FP_DP_BASE)
5871 if (!even_register_operand (operands[2], DFmode))
5872 operands[2] = force_reg (DFmode, operands[2]);
5874 if (!even_register_operand (operands[1], DFmode))
5875 operands[1] = force_reg (DFmode, operands[1]);
5882 (define_expand "divsf3"
5883 [(set (match_operand:SF 0 "register_operand" "")
5884 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5885 (match_operand:SF 2 "nonmemory_operand" "")))]
5886 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5888 if (TARGET_FPX_QUARK)
5890 operands[1] = force_reg (SFmode, operands[1]);
5891 operands[2] = force_reg (SFmode, operands[2]);
5895 if (!register_operand (operands[1], SFmode)
5896 && !register_operand (operands[2], SFmode))
5897 operands[1] = force_reg (SFmode, operands[1]);
5902 (define_expand "sqrtsf2"
5903 [(set (match_operand:SF 0 "register_operand" "")
5904 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5905 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5907 if (TARGET_FPX_QUARK)
5909 operands[1] = force_reg (SFmode, operands[1]);
5913 ;; SF->SI (using rounding towards zero)
5914 (define_expand "fix_truncsfsi2"
5915 [(set (match_operand:SI 0 "register_operand" "")
5916 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5917 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5921 (define_expand "floatsisf2"
5922 [(set (match_operand:SF 0 "register_operand" "")
5923 (float:SF (match_operand:SI 1 "register_operand" "")))]
5924 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5927 (define_expand "extzv"
5928 [(set (match_operand:SI 0 "register_operand" "")
5929 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5930 (match_operand:SI 2 "const_int_operand" "")
5931 (match_operand:SI 3 "const_int_operand" "")))]
5932 "TARGET_NPS_BITOPS")
5934 ; We need a sanity check in the instuction predicate because combine
5935 ; will throw any old rubbish at us and see what sticks.
5936 (define_insn "*extzv_i"
5937 [(set (match_operand:SI 0 "register_operand" "=Rrq")
5938 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5939 (match_operand:SI 2 "const_int_operand" "n")
5940 (match_operand:SI 3 "const_int_operand" "n")))]
5941 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5942 "movb.cl %0,%1,0,%3,%2"
5943 [(set_attr "type" "shift")
5944 (set_attr "length" "4")])
5946 (define_expand "insv"
5947 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5948 (match_operand:SI 1 "const_int_operand" "")
5949 (match_operand:SI 2 "const_int_operand" ""))
5950 (match_operand:SI 3 "nonmemory_operand" ""))]
5953 int size = INTVAL (operands[1]);
5955 if (size != 1 && size != 2 && size != 4 && size != 8)
5956 operands[3] = force_reg (SImode, operands[3]);
5959 (define_insn "*insv_i"
5960 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5961 (match_operand:SI 1 "const_int_operand" "C18,n")
5962 (match_operand:SI 2 "const_int_operand" "n,n"))
5963 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5965 && (register_operand (operands[3], SImode)
5966 || satisfies_constraint_C18 (operands[1]))"
5968 movbi %0,%0,%3,%2,%1
5969 movb %0,%0,%3,%2,0,%1"
5970 [(set_attr "type" "shift")
5971 (set_attr "length" "4")])
5973 (define_insn "*movb"
5974 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5975 (match_operand:SI 1 "const_int_operand" "n")
5976 (match_operand:SI 2 "const_int_operand" "n"))
5977 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5979 (match_operand:SI 4 "const_int_operand" "n")))]
5981 "movb %0,%0,%3,%2,%4,%1"
5982 [(set_attr "type" "shift")
5983 (set_attr "length" "4")])
5985 (define_insn "*movb_signed"
5986 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5987 (match_operand:SI 1 "const_int_operand" "n")
5988 (match_operand:SI 2 "const_int_operand" "n"))
5989 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5991 (match_operand:SI 4 "const_int_operand" "n")))]
5993 "movb %0,%0,%3,%2,%4,%1"
5994 [(set_attr "type" "shift")
5995 (set_attr "length" "4")])
5997 (define_insn "*movb_high"
5998 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5999 (match_operand:SI 1 "const_int_operand" "n")
6000 (match_operand:SI 2 "const_int_operand" "n"))
6001 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6002 (match_operand:SI 4 "const_int_operand" "n")))]
6004 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6005 "movb %0,%0,%3,%2,%4,%1"
6006 [(set_attr "type" "shift")
6007 (set_attr "length" "4")])
6009 ; N.B.: when processing signed bitfields that fit in the top half of
6010 ; a word, gcc will use a narrow sign extending load, and in this case
6011 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6012 (define_insn "*movb_high_signed"
6013 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6014 (match_operand:SI 1 "const_int_operand" "n")
6015 (match_operand:SI 2 "const_int_operand" "n"))
6016 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6017 (match_operand:SI 4 "const_int_operand" "n")))]
6019 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6020 "movb %0,%0,%3,%2,%4,%1"
6021 [(set_attr "type" "shift")
6022 (set_attr "length" "4")])
6025 [(set (match_operand:SI 0 "register_operand" "")
6026 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6027 (match_operand:SI 2 "const_int_operand" ""))
6028 (subreg:SI (match_operand 3 "") 0)))]
6030 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6031 && !reg_overlap_mentioned_p (operands[0], operands[1])"
6032 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6033 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6035 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6037 (define_insn "*mrgb"
6038 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6039 (match_operand:SI 1 "const_int_operand" "n")
6040 (match_operand:SI 2 "const_int_operand" "n"))
6041 (zero_extract:SI (match_dup 0) (match_dup 1)
6042 (match_operand:SI 3 "const_int_operand" "n")))
6043 (set (zero_extract:SI (match_dup 0)
6044 (match_operand:SI 4 "const_int_operand" "n")
6045 (match_operand:SI 5 "const_int_operand" "n"))
6046 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6048 (match_operand:SI 7 "const_int_operand" "n")))]
6051 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6052 /* The ;%? updates the known unalignment. */
6053 return arc_short_long (insn, ";%?", "nop_s");
6055 [(set_attr "type" "shift")
6056 (set_attr "length" "6")
6057 (set_attr "iscompact" "true")])
6059 ;; combine fumbles combination of two movb patterns, and then the
6060 ;; combination is rejected by combinable_i3pat.
6061 ;; Thus, we can only use a peephole2 to combine two such insns.
6064 [(set (match_operand:SI 0 "register_operand" "")
6065 (match_operand:SI 1 "register_operand" ""))
6066 (set (zero_extract:SI (match_dup 0)
6067 (match_operand:SI 2 "const_int_operand" "")
6068 (match_operand:SI 3 "const_int_operand" ""))
6069 (zero_extract:SI (match_dup 1)
6071 (match_operand:SI 4 "const_int_operand" "")))
6072 (match_operand 9) ; unrelated insn scheduled here
6073 (set (zero_extract:SI (match_dup 0)
6074 (match_operand:SI 5 "const_int_operand" "")
6075 (match_operand:SI 6 "const_int_operand" ""))
6076 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6078 (match_operand:SI 8 "const_int_operand" "")))]
6080 // Check that the second movb doesn't clobber an input of the extra insn.
6081 && !reg_overlap_mentioned_p (operands[0], operands[9])
6083 && !reg_set_p (operands[0], operands[9])
6084 && !reg_set_p (operands[7], operands[9])"
6085 [(set (match_dup 0) (match_dup 1))
6086 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6087 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6088 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6089 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6093 [(set (match_operand:SI 0 "register_operand" "")
6094 (match_operand:SI 1 "register_operand" ""))
6095 (set (zero_extract:SI (match_dup 0)
6096 (match_operand:SI 2 "const_int_operand" "")
6097 (match_operand:SI 3 "const_int_operand" ""))
6098 (zero_extract:SI (match_dup 1)
6100 (match_operand:SI 4 "const_int_operand" "")))
6101 (set (match_dup 1) (match_operand 8))
6102 (set (zero_extract:SI (match_dup 0)
6103 (match_operand:SI 5 "const_int_operand" "")
6104 (match_operand:SI 6 "const_int_operand" ""))
6105 (zero_extract:SI (match_dup 1) (match_dup 5)
6106 (match_operand:SI 7 "const_int_operand" "")))]
6108 && !reg_overlap_mentioned_p (operands[0], operands[8])"
6109 [(set (match_dup 0) (match_dup 1))
6110 (set (match_dup 1) (match_dup 8))
6111 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6112 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6113 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6114 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6117 (define_insn "*rotrsi3_cnt1"
6118 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
6119 (rotatert:SI (match_operand:SI 1 "register_operand" "c")
6123 [(set_attr "type" "shift")
6124 (set_attr "predicable" "no")
6125 (set_attr "length" "4")])
6127 (define_insn "*ashlsi2_cnt1"
6128 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6129 (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6133 [(set_attr "type" "shift")
6134 (set_attr "iscompact" "maybe,false")
6135 (set_attr "predicable" "no,no")])
6137 (define_insn "*lshrsi3_cnt1"
6138 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6139 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6143 [(set_attr "type" "shift")
6144 (set_attr "iscompact" "maybe,false")
6145 (set_attr "predicable" "no,no")])
6147 (define_insn "*ashrsi3_cnt1"
6148 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6149 (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6153 [(set_attr "type" "shift")
6154 (set_attr "iscompact" "maybe,false")
6155 (set_attr "predicable" "no,no")])
6158 [(set (match_operand:SI 0 "register_operand" "")
6159 (zero_extract:SI (match_dup 0)
6160 (match_operand:SI 1 "const_int_operand" "")
6161 (match_operand:SI 2 "const_int_operand" "")))
6162 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6167 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6168 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6169 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6171 ;; Dummy pattern used as a place holder for automatically saved
6173 (define_insn "stack_irq_dwarf"
6174 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6177 [(set_attr "length" "0")])
6179 ;; MAC and DMPY instructions
6180 (define_insn_and_split "maddsidi4"
6181 [(set (match_operand:DI 0 "register_operand" "=r")
6184 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6185 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6186 (match_operand:DI 3 "register_operand" "r")))]
6189 "TARGET_PLUS_DMPY && reload_completed"
6192 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6193 emit_move_insn (acc_reg, operands[3]);
6194 if (TARGET_PLUS_MACD)
6195 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6198 emit_insn (gen_mac (operands[1], operands[2]));
6199 emit_move_insn (operands[0], acc_reg);
6203 [(set_attr "type" "multi")
6204 (set_attr "length" "36")])
6207 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6210 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6211 (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
6212 (reg:DI ARCV2_ACC)))
6213 (set (reg:DI ARCV2_ACC)
6215 (mult:DI (sign_extend:DI (match_dup 1))
6216 (sign_extend:DI (match_dup 2)))
6217 (reg:DI ARCV2_ACC)))]
6220 [(set_attr "length" "4,4,8")
6221 (set_attr "type" "multi")
6222 (set_attr "predicable" "yes,no,no")
6223 (set_attr "cond" "canuse,nocond,nocond")])
6226 [(set (reg:DI ARCV2_ACC)
6228 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6229 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6230 (reg:DI ARCV2_ACC)))]
6233 [(set_attr "length" "4,8")
6234 (set_attr "type" "multi")
6235 (set_attr "predicable" "no")
6236 (set_attr "cond" "nocond")])
6239 [(set (reg:DI ARCV2_ACC)
6241 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6242 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6243 (reg:DI ARCV2_ACC)))
6244 (set (match_operand:SI 2 "register_operand" "")
6245 (match_operand:SI 3 "accl_operand" ""))]
6249 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6253 (define_insn "mac_r"
6254 [(set (match_operand:SI 0 "register_operand" "=r,r")
6257 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6258 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6259 (reg:DI ARCV2_ACC))))
6260 (clobber (reg:DI ARCV2_ACC))]
6263 [(set_attr "length" "4,8")
6264 (set_attr "type" "multi")
6265 (set_attr "predicable" "no")
6266 (set_attr "cond" "nocond")])
6268 (define_insn_and_split "umaddsidi4"
6269 [(set (match_operand:DI 0 "register_operand" "=r")
6272 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6273 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6274 (match_operand:DI 3 "register_operand" "r")))]
6277 "TARGET_PLUS_DMPY && reload_completed"
6280 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6281 emit_move_insn (acc_reg, operands[3]);
6282 if (TARGET_PLUS_MACD)
6283 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6286 emit_insn (gen_macu (operands[1], operands[2]));
6287 emit_move_insn (operands[0], acc_reg);
6291 [(set_attr "type" "multi")
6292 (set_attr "length" "36")])
6294 (define_insn "macdu"
6295 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6298 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6299 (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
6300 (reg:DI ARCV2_ACC)))
6301 (set (reg:DI ARCV2_ACC)
6303 (mult:DI (zero_extend:DI (match_dup 1))
6304 (zero_extend:DI (match_dup 2)))
6305 (reg:DI ARCV2_ACC)))]
6308 [(set_attr "length" "4,4,8")
6309 (set_attr "type" "multi")
6310 (set_attr "predicable" "yes,no,no")
6311 (set_attr "cond" "canuse,nocond,nocond")])
6314 [(set (reg:DI ARCV2_ACC)
6316 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6317 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6318 (reg:DI ARCV2_ACC)))]
6321 [(set_attr "length" "4,8")
6322 (set_attr "type" "multi")
6323 (set_attr "predicable" "no")
6324 (set_attr "cond" "nocond")])
6327 [(set (reg:DI ARCV2_ACC)
6329 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6330 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6331 (reg:DI ARCV2_ACC)))
6332 (set (match_operand:SI 2 "register_operand" "")
6333 (match_operand:SI 3 "accl_operand" ""))]
6337 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6341 (define_insn "macu_r"
6342 [(set (match_operand:SI 0 "register_operand" "=r,r")
6345 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6346 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6347 (reg:DI ARCV2_ACC))))
6348 (clobber (reg:DI ARCV2_ACC))]
6351 [(set_attr "length" "4,8")
6352 (set_attr "type" "multi")
6353 (set_attr "predicable" "no")
6354 (set_attr "cond" "nocond")])
6356 (define_insn "mpyd_arcv2hs"
6357 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6358 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6359 (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6360 (set (reg:DI ARCV2_ACC)
6362 (sign_extend:DI (match_dup 1))
6363 (sign_extend:DI (match_dup 2))))]
6366 [(set_attr "length" "4,4")
6367 (set_attr "iscompact" "false")
6368 (set_attr "type" "multi")
6369 (set_attr "predicable" "yes,no")
6370 (set_attr "cond" "canuse,nocond")])
6372 (define_insn "mpyd_imm_arcv2hs"
6373 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6374 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6375 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6376 (set (reg:DI ARCV2_ACC)
6377 (mult:DI (sign_extend:DI (match_dup 1))
6381 [(set_attr "length" "4,4,4,8,8")
6382 (set_attr "iscompact" "false")
6383 (set_attr "type" "multi")
6384 (set_attr "predicable" "yes,no,no,yes,no")
6385 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6387 (define_insn "mpydu_arcv2hs"
6388 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6389 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6390 (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6391 (set (reg:DI ARCV2_ACC)
6392 (mult:DI (zero_extend:DI (match_dup 1))
6393 (zero_extend:DI (match_dup 2))))]
6396 [(set_attr "length" "4,4")
6397 (set_attr "iscompact" "false")
6398 (set_attr "type" "multi")
6399 (set_attr "predicable" "yes,no")
6400 (set_attr "cond" "canuse,nocond")])
6402 (define_insn "mpydu_imm_arcv2hs"
6403 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6404 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6405 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6406 (set (reg:DI ARCV2_ACC)
6407 (mult:DI (zero_extend:DI (match_dup 1))
6411 [(set_attr "length" "4,4,4,8,8")
6412 (set_attr "iscompact" "false")
6413 (set_attr "type" "multi")
6414 (set_attr "predicable" "yes,no,no,yes,no")
6415 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6417 (define_insn "stack_tie"
6418 [(set (mem:BLK (scratch))
6419 (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
6420 (match_operand:SI 1 "register_operand" "rb")]
6421 UNSPEC_ARC_STKTIE))]
6424 [(set_attr "length" "0")
6425 (set_attr "iscompact" "false")
6426 (set_attr "type" "block")]
6429 ;; include the arc-FPX instructions
6432 ;; include the arc-FPU instructions
6435 (include "simdext.md")
6437 ;; include atomic extensions
6438 (include "atomic.md")