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 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
558 ;; non-taken case, so the only meaningful way to have an annull-true
559 ;; filled delay slot is to conditionalize the delay slot insn.
560 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
561 (eq_attr "type" "branch,uncond_branch,jump")
562 (match_test "!optimize_size"))
563 [(eq_attr "in_delay_slot" "true")
564 (eq_attr "cond_delay_insn" "yes")
565 (eq_attr "cond_delay_insn" "yes")])
567 ;; For ARC700, anything goes for annulled-true insns, since there is no
568 ;; penalty for the unexposed delay slot when the branch is not taken,
569 ;; however, we must avoid things that have a delay slot themselvese to
570 ;; avoid confusing gcc.
571 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
572 (eq_attr "type" "branch,uncond_branch,jump")
573 (match_test "!optimize_size"))
574 [(eq_attr "in_delay_slot" "true")
575 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
576 (eq_attr "cond_delay_insn" "yes")])
578 ;; -mlongcall -fpic sfuncs use r12 to load the function address
579 (define_delay (eq_attr "type" "sfunc")
580 [(eq_attr "in_sfunc_delay_slot" "true")
581 (eq_attr "in_sfunc_delay_slot" "true")
583 ;; ??? need to use a working strategy for canuse_limm:
584 ;; - either canuse_limm is not eligible for delay slots, and has no
585 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
586 ;; somehow modify them to become inelegible for delay slots if a decision
587 ;; is made that makes conditional execution required.
589 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
591 (cond [(symbol_ref "arc_tune == TUNE_ARC600")
592 (const_string "arc600")
593 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
594 (const_string "arc700_4_2_std")
595 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
596 (const_string "arc700_4_2_xmac")]
597 (const_string "none"))))
599 (define_attr "tune_arc700" "false,true"
600 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
601 (const_string "true")
602 (const_string "false")))
604 ;; Move instructions.
605 (define_expand "movqi"
606 [(set (match_operand:QI 0 "move_dest_operand" "")
607 (match_operand:QI 1 "general_operand" ""))]
609 "if (prepare_move_operands (operands, QImode)) DONE;")
611 ; In order to allow the ccfsm machinery to do its work, the leading compact
612 ; alternatives say 'canuse' - there is another alternative that will match
613 ; when the condition codes are used.
614 ; Rcq won't match if the condition is actually used; to avoid a spurious match
615 ; via q, q is inactivated as constraint there.
616 ; Likewise, the length of an alternative that might be shifted to conditional
617 ; execution must reflect this, lest out-of-range branches are created.
618 ; The iscompact attribute allows the epilogue expander to know for which
619 ; insns it should lengthen the return insn.
620 (define_insn "*movqi_insn"
621 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m,Usc")
622 (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"))]
623 "register_operand (operands[0], QImode)
624 || register_operand (operands[1], QImode)"
645 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store")
646 (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false")
647 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
648 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
650 (define_expand "movhi"
651 [(set (match_operand:HI 0 "move_dest_operand" "")
652 (match_operand:HI 1 "general_operand" ""))]
654 "if (prepare_move_operands (operands, HImode)) DONE;")
656 (define_insn "*movhi_insn"
657 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w,???w,Rcq#q,h, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc")
658 (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"))]
659 "register_operand (operands[0], HImode)
660 || register_operand (operands[1], HImode)
661 || (CONSTANT_P (operands[1])
662 /* Don't use a LIMM that we could load with a single insn - we loose
663 delay-slot filling opportunities. */
664 && !satisfies_constraint_I (operands[1])
665 && satisfies_constraint_Usc (operands[0]))"
687 [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
688 (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")
689 (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
690 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
692 (define_expand "movsi"
693 [(set (match_operand:SI 0 "move_dest_operand" "")
694 (match_operand:SI 1 "general_operand" ""))]
696 "if (prepare_move_operands (operands, SImode)) DONE;")
698 ; In order to allow the ccfsm machinery to do its work, the leading compact
699 ; alternatives say 'canuse' - there is another alternative that will match
700 ; when the condition codes are used.
701 ; Rcq won't match if the condition is actually used; to avoid a spurious match
702 ; via q, q is inactivated as constraint there.
703 ; Likewise, the length of an alternative that might be shifted to conditional
704 ; execution must reflect this, lest out-of-range branches are created.
705 ; the iscompact attribute allows the epilogue expander to know for which
706 ; insns it should lengthen the return insn.
707 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
708 (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
709 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, h, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc")
710 (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))]
711 "register_operand (operands[0], SImode)
712 || register_operand (operands[1], SImode)
713 || (CONSTANT_P (operands[1])
714 /* Don't use a LIMM that we could load with a single insn - we loose
715 delay-slot filling opportunities. */
716 && !satisfies_constraint_I (operands[1])
717 && satisfies_constraint_Usc (operands[0]))"
726 ror %0,((%1*2+1) & 0x3f) ;7
728 movh.cl %0,%L1>>16 ;9
729 * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
732 add %0,pcl,%1@pcl ;13
738 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
739 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
751 ; 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
752 [(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")
753 (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")
754 ; Use default length for iscompact to allow for COND_EXEC. But set length
756 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
757 (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")
758 (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
760 ;; Sometimes generated by the epilogue code. We don't want to
761 ;; recognize these addresses in general, because the limm is costly,
762 ;; and we can't use them for stores. */
763 (define_insn "*movsi_pre_mod"
764 [(set (match_operand:SI 0 "register_operand" "=w")
767 (plus:SI (reg:SI SP_REG)
768 (match_operand 1 "immediate_operand" "Cal")))))]
771 [(set_attr "type" "load")
772 (set_attr "length" "8")])
774 ;; Store a value to directly to memory. The location might also be cached.
775 ;; Since the cached copy can cause a write-back at unpredictable times,
776 ;; we first write cached, then we write uncached.
777 (define_insn "store_direct"
778 [(set (match_operand:SI 0 "move_dest_operand" "=m")
779 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
782 "st%U0 %1,%0\;st%U0.di %1,%0"
783 [(set_attr "type" "store")])
785 (define_insn_and_split "*movsi_set_cc_insn"
786 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
787 (match_operator:CC_ZN 3 "zn_compare_operator"
788 [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
789 (set (match_operand:SI 0 "register_operand" "=w,w,w")
793 ; splitting to 'tst' allows short insns and combination into brcc.
794 "reload_completed && operands_match_p (operands[0], operands[1])"
795 [(set (match_dup 2) (match_dup 3))]
797 [(set_attr "type" "compare")
798 (set_attr "predicable" "no,yes,yes")
799 (set_attr "cond" "set_zn")
800 (set_attr "length" "4,4,8")])
802 (define_insn "unary_comparison"
803 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
804 (match_operator:CC_ZN 3 "zn_compare_operator"
805 [(match_operator:SI 2 "unary_operator"
806 [(match_operand:SI 1 "register_operand" "c")])
810 [(set_attr "type" "compare")
811 (set_attr "cond" "set_zn")])
814 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
815 (define_insn "*unary_comparison_result_used"
816 [(set (match_operand 2 "cc_register" "")
817 (match_operator 4 "zn_compare_operator"
818 [(match_operator:SI 3 "unary_operator"
819 [(match_operand:SI 1 "register_operand" "c")])
821 (set (match_operand:SI 0 "register_operand" "=w")
825 [(set_attr "type" "compare")
826 (set_attr "cond" "set_zn")
827 (set_attr "length" "4")])
829 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
830 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
831 ; even if we don't need the clobber.
832 (define_insn_and_split "*tst_movb"
834 (match_operand 0 "cc_register" "")
835 (match_operator 4 "zn_compare_operator"
837 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c")
838 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
840 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
842 "movb.f.cl %3,%1,%p2,%p2,%s2"
843 "TARGET_NPS_BITOPS && reload_completed
844 && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
845 [(set (match_dup 0) (match_dup 4))])
849 (match_operand 0 "cc_register" "")
850 (match_operator 3 "zn_compare_operator"
852 (match_operand:SI 1 "register_operand"
853 "%Rcq,Rcq, c, c, c, c, c, c")
854 (match_operand:SI 2 "nonmemory_operand"
855 " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
858 || !satisfies_constraint_Cbf (operands[2])
859 || satisfies_constraint_C0p (operands[2])
860 || satisfies_constraint_I (operands[2])
861 || satisfies_constraint_C1p (operands[2])
862 || satisfies_constraint_Chs (operands[2])"
864 switch (which_alternative)
866 case 0: case 2: case 3: case 7:
867 return \"tst%? %1,%2\";
869 return \"btst%? %1,%z2\";
871 return \"bmsk%?.f 0,%1,%Z2%&\";
873 return \"bclr%?.f 0,%1,%M2%&\";
875 return \"asr.f 0,%1,%p2\";
880 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
881 (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
882 (set_attr "length" "*,*,4,4,4,4,4,8")
883 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
884 (set_attr "cond" "set_zn")])
886 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
887 ; combine will do that and not try the AND.
889 ; It would take 66 constraint combinations to describe the zero_extract
890 ; constants that are covered by the 12-bit signed constant for tst
891 ; (excluding the ones that are better done by mov or btst).
892 ; so we rather use an extra pattern for tst;
893 ; since this is about constants, reload shouldn't care.
894 (define_insn "*tst_bitfield_tst"
895 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
896 (match_operator 4 "zn_compare_operator"
898 (match_operand:SI 1 "register_operand" "c")
899 (match_operand:SI 2 "const_int_operand" "n")
900 (match_operand:SI 3 "const_int_operand" "n"))
902 "INTVAL (operands[2]) > 1
903 && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
904 || (INTVAL (operands[3]) <= 11
905 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
906 "tst %1,((1<<%2)-1)<<%3"
907 [(set_attr "type" "compare")
908 (set_attr "cond" "set_zn")
909 (set_attr "length" "4")])
911 ; Likewise for asr.f.
912 (define_insn "*tst_bitfield_asr"
913 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
914 (match_operator 4 "zn_compare_operator"
916 (match_operand:SI 1 "register_operand" "c")
917 (match_operand:SI 2 "const_int_operand" "n")
918 (match_operand:SI 3 "const_int_operand" "n"))
920 "INTVAL (operands[2]) > 1
921 && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
923 [(set_attr "type" "shift")
924 (set_attr "cond" "set_zn")
925 (set_attr "length" "4")])
927 (define_insn "*tst_bitfield"
928 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
929 (match_operator 5 "zn_compare_operator"
931 (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c")
932 (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n")
933 (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
935 (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
941 movb.f.cl %4,%1,%3,%3,%2
942 and.f 0,%1,((1<<%2)-1)<<%3"
943 [(set_attr "iscompact" "maybe,false,false,false,false")
944 (set_attr "type" "compare,compare,compare,shift,compare")
945 (set_attr "cond" "set_zn")
946 (set_attr "length" "*,4,4,4,8")])
948 (define_insn "*commutative_binary_comparison"
949 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
950 (match_operator:CC_ZN 5 "zn_compare_operator"
951 [(match_operator:SI 4 "commutative_operator"
952 [(match_operand:SI 1 "register_operand" "%c,c")
953 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
955 (clobber (match_scratch:SI 3 "=X,X"))]
958 [(set_attr "type" "compare")
959 (set_attr "cond" "set_zn")
960 (set_attr "length" "4,8")])
962 ; for flag setting 'add' instructions like if (a+b) { ...}
963 ; the combiner needs this pattern
964 (define_insn "*addsi_compare"
965 [(set (reg:CC_ZN CC_REG)
966 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
967 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
970 [(set_attr "cond" "set")
971 (set_attr "type" "compare")
972 (set_attr "length" "4")])
974 ; for flag setting 'add' instructions like if (a+b < a) { ...}
975 ; the combiner needs this pattern
976 (define_insn "addsi_compare_2"
977 [(set (reg:CC_C CC_REG)
978 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
979 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
983 [(set_attr "cond" "set")
984 (set_attr "type" "compare")
985 (set_attr "length" "4,8")])
987 (define_insn "*addsi_compare_3"
988 [(set (reg:CC_C CC_REG)
989 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
990 (match_operand:SI 1 "register_operand" "c"))
994 [(set_attr "cond" "set")
995 (set_attr "type" "compare")
996 (set_attr "length" "4")])
998 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
999 (define_insn "*commutative_binary_comparison_result_used"
1000 [(set (match_operand 3 "cc_register" "")
1001 (match_operator 5 "zn_compare_operator"
1002 ; We can accept any commutative operator except mult because
1003 ; our 'w' class below could try to use LP_COUNT.
1004 [(match_operator:SI 4 "commutative_operator_sans_mult"
1005 [(match_operand:SI 1 "register_operand" "c,0,c")
1006 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1008 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1011 "%O4.f %0,%1,%2 ; non-mult commutative"
1012 [(set_attr "type" "compare,compare,compare")
1013 (set_attr "cond" "set_zn,set_zn,set_zn")
1014 (set_attr "length" "4,4,8")])
1016 ; a MULT-specific version of this pattern to avoid touching the
1018 (define_insn "*commutative_binary_mult_comparison_result_used"
1019 [(set (match_operand 3 "cc_register" "")
1020 (match_operator 5 "zn_compare_operator"
1021 [(match_operator:SI 4 "mult_operator"
1022 [(match_operand:SI 1 "register_operand" "c,0,c")
1023 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1025 ; Make sure to use the W class to not touch LP_COUNT.
1026 (set (match_operand:SI 0 "register_operand" "=W,W,W")
1028 "!TARGET_ARC600_FAMILY"
1029 "%O4.f %0,%1,%2 ; mult commutative"
1030 [(set_attr "type" "compare,compare,compare")
1031 (set_attr "cond" "set_zn,set_zn,set_zn")
1032 (set_attr "length" "4,4,8")])
1034 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1035 (define_insn "*noncommutative_binary_comparison_result_used"
1036 [(set (match_operand 3 "cc_register" "")
1037 (match_operator 5 "zn_compare_operator"
1038 [(match_operator:SI 4 "noncommutative_operator"
1039 [(match_operand:SI 1 "register_operand" "c,0,c")
1040 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1042 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1044 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1046 [(set_attr "type" "compare,compare,compare")
1047 (set_attr "cond" "set_zn,set_zn,set_zn")
1048 (set_attr "length" "4,4,8")])
1050 (define_insn "*noncommutative_binary_comparison"
1051 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1052 (match_operator:CC_ZN 5 "zn_compare_operator"
1053 [(match_operator:SI 4 "noncommutative_operator"
1054 [(match_operand:SI 1 "register_operand" "c,c")
1055 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
1057 (clobber (match_scratch:SI 3 "=X,X"))]
1058 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1060 [(set_attr "type" "compare")
1061 (set_attr "cond" "set_zn")
1062 (set_attr "length" "4,8")])
1064 (define_expand "bic_f_zn"
1066 [(set (reg:CC_ZN CC_REG)
1068 (and:SI (match_operand:SI 1 "register_operand" "")
1069 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1071 (set (match_operand:SI 0 "register_operand" "")
1072 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1075 (define_insn "*bic_f"
1076 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1077 (match_operator 4 "zn_compare_operator"
1078 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1080 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1082 (set (match_operand:SI 0 "register_operand" "=w,w,w")
1083 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1086 [(set_attr "type" "compare,compare,compare")
1087 (set_attr "cond" "set_zn,set_zn,set_zn")
1088 (set_attr "length" "4,4,8")])
1090 (define_expand "movdi"
1091 [(set (match_operand:DI 0 "move_dest_operand" "")
1092 (match_operand:DI 1 "general_operand" ""))]
1095 if (prepare_move_operands (operands, DImode))
1099 (define_insn_and_split "*movdi_insn"
1100 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m")
1101 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1102 "register_operand (operands[0], DImode)
1103 || register_operand (operands[1], DImode)"
1106 switch (which_alternative)
1113 && ((even_register_operand (operands[0], DImode)
1114 && memory_operand (operands[1], DImode))
1115 || (memory_operand (operands[0], DImode)
1116 && even_register_operand (operands[1], DImode))))
1117 return \"ldd%U1%V1 %0,%1%&\";
1122 && ((even_register_operand (operands[0], DImode)
1123 && memory_operand (operands[1], DImode))
1124 || (memory_operand (operands[0], DImode)
1125 && even_register_operand (operands[1], DImode))))
1126 return \"std%U0%V0 %1,%0\";
1133 arc_split_move (operands);
1136 [(set_attr "type" "move,move,load,store")
1137 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1138 (set_attr "length" "8,16,*,*")])
1141 ;; Floating point move insns.
1143 (define_expand "movsf"
1144 [(set (match_operand:SF 0 "move_dest_operand" "")
1145 (match_operand:SF 1 "general_operand" ""))]
1147 "if (prepare_move_operands (operands, SFmode)) DONE;")
1149 (define_insn "*movsf_insn"
1150 [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m")
1151 (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))]
1152 "register_operand (operands[0], SFmode)
1153 || register_operand (operands[1], SFmode)"
1160 [(set_attr "type" "move,move,move,load,store")
1161 (set_attr "predicable" "no,yes,yes,no,no")
1162 (set_attr "iscompact" "true,false,false,false,false")])
1164 (define_expand "movdf"
1165 [(set (match_operand:DF 0 "move_dest_operand" "")
1166 (match_operand:DF 1 "general_operand" ""))]
1168 "if (prepare_move_operands (operands, DFmode)) DONE;")
1170 (define_insn_and_split "*movdf_insn"
1171 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
1172 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1173 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1176 switch (which_alternative)
1182 && ((even_register_operand (operands[0], DFmode)
1183 && memory_operand (operands[1], DFmode))
1184 || (memory_operand (operands[0], DFmode)
1185 && even_register_operand (operands[1], DFmode))))
1186 return \"ldd%U1%V1 %0,%1%&\";
1191 && ((even_register_operand (operands[0], DFmode)
1192 && memory_operand (operands[1], DFmode))
1193 || (memory_operand (operands[0], DFmode)
1194 && even_register_operand (operands[1], DFmode))))
1195 return \"std%U0%V0 %1,%0\";
1202 arc_split_move (operands);
1205 [(set_attr "type" "move,move,move,move,load,store")
1206 (set_attr "predicable" "no,no,yes,yes,no,no")
1207 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1208 (set_attr "length" "4,16,8,16,16,16")])
1210 (define_insn_and_split "*movdf_insn_nolrsr"
1211 [(set (match_operand:DF 0 "register_operand" "=r")
1212 (match_operand:DF 1 "arc_double_register_operand" "D"))
1213 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1215 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1220 (set (match_dup 0) (match_dup 3))
1222 ; daddh?? r1, r0, r0
1224 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1227 (use (match_dup 0)) ; used to block can_combine_p
1228 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1231 ; We have to do this twice, once to read the value into R0 and
1232 ; second time to put back the contents which the first DEXCLx
1233 ; will have overwritten
1236 (set (match_dup 4) ; aka r0result
1238 (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1240 (clobber (match_dup 1))
1242 ; Generate the second, which makes sure operand5 and operand4 values
1243 ; are put back in the Dx register properly.
1244 (set (match_dup 1) (unspec_volatile:DF
1245 [(match_dup 5) (match_dup 4)]
1246 VUNSPEC_ARC_DEXCL_NORES))
1248 ; Note: we cannot use a (clobber (match_scratch)) here because
1249 ; the combine pass will end up replacing uses of it with 0
1251 "operands[3] = CONST0_RTX (DFmode);
1252 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1253 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1254 [(set_attr "type" "move")])
1256 ;; Load/Store with update instructions.
1258 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1259 ;; hardware can also do cases where the increment is not the size of the
1262 ;; In all these cases, we use operands 0 and 1 for the register being
1263 ;; incremented because those are the operands that local-alloc will
1264 ;; tie and these are the pair most likely to be tieable (and the ones
1265 ;; that will benefit the most).
1267 ;; We use match_operator here because we need to know whether the memory
1268 ;; object is volatile or not.
1271 ;; Note: loadqi_update has no 16-bit variant
1272 (define_insn "*loadqi_update"
1273 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1274 (match_operator:QI 4 "any_mem_operand"
1275 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1276 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1277 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1278 (plus:SI (match_dup 1) (match_dup 2)))]
1280 "ldb.a%V4 %3,[%0,%S2]"
1281 [(set_attr "type" "load,load")
1282 (set_attr "length" "4,8")])
1284 (define_insn "*load_zeroextendqisi_update"
1285 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1286 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1287 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1288 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1289 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1290 (plus:SI (match_dup 1) (match_dup 2)))]
1292 "ldb.a%V4 %3,[%0,%S2]"
1293 [(set_attr "type" "load,load")
1294 (set_attr "length" "4,8")])
1296 (define_insn "*load_signextendqisi_update"
1297 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1298 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1299 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1300 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1301 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1302 (plus:SI (match_dup 1) (match_dup 2)))]
1304 "ldb.x.a%V4 %3,[%0,%S2]"
1305 [(set_attr "type" "load,load")
1306 (set_attr "length" "4,8")])
1308 (define_insn "*storeqi_update"
1309 [(set (match_operator:QI 4 "any_mem_operand"
1310 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1311 (match_operand:SI 2 "short_immediate_operand" "I"))])
1312 (match_operand:QI 3 "register_operand" "c"))
1313 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1314 (plus:SI (match_dup 1) (match_dup 2)))]
1316 "stb.a%V4 %3,[%0,%2]"
1317 [(set_attr "type" "store")
1318 (set_attr "length" "4")])
1320 ;; ??? pattern may have to be re-written
1321 ;; Note: no 16-bit variant for this pattern
1322 (define_insn "*loadhi_update"
1323 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1324 (match_operator:HI 4 "any_mem_operand"
1325 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1326 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1327 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1328 (plus:SI (match_dup 1) (match_dup 2)))]
1330 "ld%_.a%V4 %3,[%0,%S2]"
1331 [(set_attr "type" "load,load")
1332 (set_attr "length" "4,8")])
1334 (define_insn "*load_zeroextendhisi_update"
1335 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1336 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1337 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1338 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1339 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1340 (plus:SI (match_dup 1) (match_dup 2)))]
1342 "ld%_.a%V4 %3,[%0,%S2]"
1343 [(set_attr "type" "load,load")
1344 (set_attr "length" "4,8")])
1346 ;; Note: no 16-bit variant for this instruction
1347 (define_insn "*load_signextendhisi_update"
1348 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1349 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1350 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1351 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1352 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1353 (plus:SI (match_dup 1) (match_dup 2)))]
1355 "ld%_.x.a%V4 %3,[%0,%S2]"
1356 [(set_attr "type" "load,load")
1357 (set_attr "length" "4,8")])
1359 (define_insn "*storehi_update"
1360 [(set (match_operator:HI 4 "any_mem_operand"
1361 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1362 (match_operand:SI 2 "short_immediate_operand" "I"))])
1363 (match_operand:HI 3 "register_operand" "c"))
1364 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1365 (plus:SI (match_dup 1) (match_dup 2)))]
1367 "st%_.a%V4 %3,[%0,%2]"
1368 [(set_attr "type" "store")
1369 (set_attr "length" "4")])
1371 ;; No 16-bit variant for this instruction pattern
1372 (define_insn "*loadsi_update"
1373 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1374 (match_operator:SI 4 "any_mem_operand"
1375 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1376 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1377 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1378 (plus:SI (match_dup 1) (match_dup 2)))]
1380 "ld.a%V4 %3,[%0,%S2]"
1381 [(set_attr "type" "load,load")
1382 (set_attr "length" "4,8")])
1384 (define_insn "*storesi_update"
1385 [(set (match_operator:SI 4 "any_mem_operand"
1386 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1387 (match_operand:SI 2 "short_immediate_operand" "I"))])
1388 (match_operand:SI 3 "register_operand" "c"))
1389 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1390 (plus:SI (match_dup 1) (match_dup 2)))]
1392 "st.a%V4 %3,[%0,%2]"
1393 [(set_attr "type" "store")
1394 (set_attr "length" "4")])
1396 (define_insn "*loadsf_update"
1397 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1398 (match_operator:SF 4 "any_mem_operand"
1399 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1400 (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1401 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1402 (plus:SI (match_dup 1) (match_dup 2)))]
1404 "ld.a%V4 %3,[%0,%S2]"
1405 [(set_attr "type" "load,load")
1406 (set_attr "length" "4,8")])
1408 (define_insn "*storesf_update"
1409 [(set (match_operator:SF 4 "any_mem_operand"
1410 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1411 (match_operand:SI 2 "short_immediate_operand" "I"))])
1412 (match_operand:SF 3 "register_operand" "c"))
1413 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1414 (plus:SI (match_dup 1) (match_dup 2)))]
1416 "st.a%V4 %3,[%0,%2]"
1417 [(set_attr "type" "store")
1418 (set_attr "length" "4")])
1420 ;; Conditional move instructions.
1422 (define_expand "movsicc"
1423 [(set (match_operand:SI 0 "dest_reg_operand" "")
1424 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1425 (match_operand:SI 2 "nonmemory_operand" "")
1426 (match_operand:SI 3 "register_operand" "")))]
1428 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1431 (define_expand "movdicc"
1432 [(set (match_operand:DI 0 "dest_reg_operand" "")
1433 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1434 (match_operand:DI 2 "nonmemory_operand" "")
1435 (match_operand:DI 3 "register_operand" "")))]
1437 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1440 (define_expand "movsfcc"
1441 [(set (match_operand:SF 0 "dest_reg_operand" "")
1442 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1443 (match_operand:SF 2 "nonmemory_operand" "")
1444 (match_operand:SF 3 "register_operand" "")))]
1446 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1448 (define_expand "movdfcc"
1449 [(set (match_operand:DF 0 "dest_reg_operand" "")
1450 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1451 (match_operand:DF 2 "nonmemory_operand" "")
1452 (match_operand:DF 3 "register_operand" "")))]
1454 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1456 (define_insn "*movsicc_insn"
1457 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1458 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1459 [(match_operand 4 "cc_register" "") (const_int 0)])
1460 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1461 (match_operand:SI 2 "register_operand" "0,0")))]
1464 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1465 && satisfies_constraint_Rcq (operands[0]))
1466 return "sub%?.ne %0,%0,%0";
1467 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1468 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1469 && rtx_equal_p (operands[1], constm1_rtx)
1470 && GET_CODE (operands[3]) == LTU)
1471 return "sbc.cs %0,%0,%0";
1472 return "mov.%d3 %0,%S1";
1474 [(set_attr "type" "cmove,cmove")
1475 (set_attr "length" "4,8")])
1477 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1478 ;; if the single bit is the sign bit, then GCC likes to convert this
1479 ;; into a sign extend and a compare less than, or greater to zero.
1480 ;; This is usually fine, except for the NXP400 where we have access to
1481 ;; a bit test instruction, along with a special short load instruction
1482 ;; (from CMEM), that doesn't support sign-extension on load.
1484 ;; This peephole optimisation attempts to restore the use of bit-test
1485 ;; in those cases where it is useful to do so.
1487 [(set (match_operand:SI 0 "register_operand" "")
1489 (match_operand:QI 1 "any_mem_operand" "")))
1490 (set (reg:CC_ZN CC_REG)
1491 (compare:CC_ZN (match_dup 0)
1494 (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1495 [(reg:CC_ZN CC_REG) (const_int 0)])
1496 (match_operand 3 "" "")
1497 (match_operand 4 "" "")))]
1499 && cmem_address (XEXP (operands[1], 0), SImode)
1500 && peep2_reg_dead_p (2, operands[0])
1501 && peep2_regno_dead_p (3, CC_REG)"
1505 (set (reg:CC_ZN CC_REG)
1506 (compare:CC_ZN (zero_extract:SI
1512 (if_then_else (match_dup 2)
1515 "if (GET_CODE (operands[2]) == GE)
1516 operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1518 operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1520 ; Try to generate more short moves, and/or less limms, by substituting a
1521 ; conditional move with a conditional sub.
1523 [(set (match_operand:SI 0 "compact_register_operand")
1524 (match_operand:SI 1 "const_int_operand"))
1526 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1527 [(match_operand 4 "cc_register" "") (const_int 0)])
1528 (match_operand:SI 2 "const_int_operand" "")
1530 "!satisfies_constraint_P (operands[1])
1531 && satisfies_constraint_P (operands[2])
1532 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1533 [(set (match_dup 0) (match_dup 2))
1537 (plus:SI (match_dup 0) (match_dup 1))))]
1538 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1539 GET_MODE (operands[4])),
1540 VOIDmode, operands[4], const0_rtx);
1541 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1543 (define_insn "*movdicc_insn"
1544 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1545 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1546 [(match_operand 4 "cc_register" "") (const_int 0)])
1547 (match_operand:DI 1 "nonmemory_operand" "c,i")
1548 (match_operand:DI 2 "register_operand" "0,0")))]
1552 switch (which_alternative)
1556 /* We normally copy the low-numbered register first. However, if
1557 the first register operand 0 is the same as the second register of
1558 operand 1, we must copy in the opposite order. */
1559 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1560 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1562 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1564 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1569 [(set_attr "type" "cmove,cmove")
1570 (set_attr "length" "8,16")])
1573 (define_insn "*movsfcc_insn"
1574 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1575 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1576 [(match_operand 4 "cc_register" "") (const_int 0)])
1577 (match_operand:SF 1 "nonmemory_operand" "c,E")
1578 (match_operand:SF 2 "register_operand" "0,0")))]
1582 mov.%d3 %0,%1 ; %A1"
1583 [(set_attr "type" "cmove,cmove")])
1585 (define_insn "*movdfcc_insn"
1586 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1587 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1588 [(match_operand 4 "cc_register" "") (const_int 0)])
1589 (match_operand:DF 2 "nonmemory_operand" "c,E")
1590 (match_operand:DF 3 "register_operand" "0,0")))]
1594 switch (which_alternative)
1598 /* We normally copy the low-numbered register first. However, if
1599 the first register operand 0 is the same as the second register of
1600 operand 1, we must copy in the opposite order. */
1601 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1602 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1604 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1606 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1610 [(set_attr "type" "cmove,cmove")
1611 (set_attr "length" "8,16")])
1614 (define_insn "*zero_extendqihi2_i"
1615 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1616 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1625 [(set_attr "type" "unary,unary,unary,unary,load,load")
1626 (set_attr "iscompact" "maybe,true,false,false,false,false")
1627 (set_attr "predicable" "no,no,yes,no,no,no")])
1629 (define_expand "zero_extendqihi2"
1630 [(set (match_operand:HI 0 "dest_reg_operand" "")
1631 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1633 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1636 (define_insn "*zero_extendqisi2_ac"
1637 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1638 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1649 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1650 (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1651 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1653 (define_expand "zero_extendqisi2"
1654 [(set (match_operand:SI 0 "dest_reg_operand" "")
1655 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1657 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1660 (define_insn "*zero_extendhisi2_i"
1661 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1662 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
1671 * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1673 [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1674 (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
1675 (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1678 (define_expand "zero_extendhisi2"
1679 [(set (match_operand:SI 0 "dest_reg_operand" "")
1680 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1682 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1685 ;; Sign extension instructions.
1687 (define_insn "*extendqihi2_i"
1688 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1689 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1696 [(set_attr "type" "unary,unary,load,load")
1697 (set_attr "iscompact" "true,false,false,false")
1698 (set_attr "length" "*,*,*,8")])
1701 (define_expand "extendqihi2"
1702 [(set (match_operand:HI 0 "dest_reg_operand" "")
1703 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1705 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1708 (define_insn "*extendqisi2_ac"
1709 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1710 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1717 [(set_attr "type" "unary,unary,load,load")
1718 (set_attr "iscompact" "true,false,false,false")
1719 (set_attr "length" "*,*,*,8")])
1721 (define_expand "extendqisi2"
1722 [(set (match_operand:SI 0 "dest_reg_operand" "")
1723 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1725 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1728 (define_insn "*extendhisi2_i"
1729 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
1730 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1738 [(set_attr "type" "unary,unary,load,load,load")
1739 (set_attr "iscompact" "true,false,true,false,false")
1740 (set_attr "length" "*,*,*,4,8")])
1742 (define_expand "extendhisi2"
1743 [(set (match_operand:SI 0 "dest_reg_operand" "")
1744 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1746 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1749 ;; Unary arithmetic insns
1751 ;; We allow constant operands to enable late constant propagation, but it is
1752 ;; not worth while to have more than one dedicated alternative to output them -
1753 ;; if we are really worried about getting these the maximum benefit of all
1754 ;; the available alternatives, we should add an extra pass to fold such
1755 ;; operations to movsi.
1757 ;; Absolute instructions
1759 (define_insn "*abssi2_mixed"
1760 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1761 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1764 [(set_attr "type" "two_cycle_core")
1765 (set_attr "iscompact" "true")])
1767 (define_insn "abssi2"
1768 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1769 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1772 [(set_attr "type" "two_cycle_core")
1773 (set_attr "length" "*,4,8")
1774 (set_attr "iscompact" "true,false,false")])
1776 ;; Maximum and minimum insns
1778 (define_insn "smaxsi3"
1779 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1780 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1781 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1784 [(set_attr "type" "two_cycle_core")
1785 (set_attr "length" "4,4,8")
1786 (set_attr "predicable" "yes,no,no")]
1789 (define_insn "sminsi3"
1790 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1791 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1792 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1795 [(set_attr "type" "two_cycle_core")
1796 (set_attr "length" "4,4,8")
1797 (set_attr "predicable" "yes,no,no")]
1800 ;; Arithmetic instructions.
1802 ; We say an insn can be conditionalized if this doesn't introduce a long
1803 ; immediate. We set the type such that we still have good scheduling if the
1804 ; insn is conditionalized.
1805 ; ??? It would make sense to allow introduction of long immediates, but
1806 ; we'd need to communicate to the ccfsm machinery the extra cost.
1807 ; The alternatives in the constraints still serve three purposes:
1808 ; - estimate insn size assuming conditional execution
1809 ; - guide reload to re-order the second and third operand to get a better fit.
1810 ; - give tentative insn type to guide scheduling
1811 ; N.B. "%" for commutativity doesn't help when there is another matching
1812 ; (but longer) alternative.
1813 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1814 ; register class 'W' instead of 'w'.
1815 (define_insn_and_split "*addsi3_mixed"
1816 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12
1817 [(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")
1818 (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")
1819 (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")))]
1822 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1825 "&& reload_completed && get_attr_length (insn) == 8
1826 && satisfies_constraint_I (operands[2])
1827 && GET_CODE (PATTERN (insn)) != COND_EXEC"
1828 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1829 "split_addsi (operands);"
1830 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
1831 (set (attr "iscompact")
1832 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1833 (const_string "false")
1834 (match_operand 2 "long_immediate_operand" "")
1835 (const_string "maybe_limm")]
1836 (const_string "maybe")))
1837 (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
1838 (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
1839 (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1842 ;; ARCv2 MPYW and MPYUW
1843 (define_expand "mulhisi3"
1844 [(set (match_operand:SI 0 "register_operand" "")
1845 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1846 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1849 if (CONSTANT_P (operands[2]))
1851 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1857 (define_insn "mulhisi3_imm"
1858 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
1859 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
1860 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
1863 [(set_attr "length" "4,4,4,8,8")
1864 (set_attr "iscompact" "false")
1865 (set_attr "type" "mul16_em")
1866 (set_attr "predicable" "yes,no,no,yes,no")
1867 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1870 (define_insn "mulhisi3_reg"
1871 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r")
1872 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r"))
1873 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1876 [(set_attr "length" "*,4,4")
1877 (set_attr "iscompact" "maybe,false,false")
1878 (set_attr "type" "mul16_em")
1879 (set_attr "predicable" "yes,yes,no")
1880 (set_attr "cond" "canuse,canuse,nocond")
1883 (define_expand "umulhisi3"
1884 [(set (match_operand:SI 0 "register_operand" "")
1885 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1886 (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1889 if (CONSTANT_P (operands[2]))
1891 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1897 (define_insn "umulhisi3_imm"
1898 [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r")
1899 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r"))
1900 (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))]
1903 [(set_attr "length" "4,4,4,8,8")
1904 (set_attr "iscompact" "false")
1905 (set_attr "type" "mul16_em")
1906 (set_attr "predicable" "yes,no,no,yes,no")
1907 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1910 (define_insn "umulhisi3_reg"
1911 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r")
1912 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r"))
1913 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1916 [(set_attr "length" "*,4,4")
1917 (set_attr "iscompact" "maybe,false,false")
1918 (set_attr "type" "mul16_em")
1919 (set_attr "predicable" "yes,yes,no")
1920 (set_attr "cond" "canuse,canuse,nocond")
1923 ;; ARC700/ARC600/V2 multiply
1926 (define_expand "mulsi3"
1927 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1928 (mult:SI (match_operand:SI 1 "register_operand" "")
1929 (match_operand:SI 2 "nonmemory_operand" "")))]
1934 if (!register_operand (operands[0], SImode))
1936 rtx result = gen_reg_rtx (SImode);
1938 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1939 emit_move_insn (operands[0], result);
1943 else if (TARGET_MUL64_SET)
1945 rtx tmp = gen_reg_rtx (SImode);
1946 emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
1947 emit_move_insn (operands[0], tmp);
1950 else if (TARGET_MULMAC_32BY16_SET)
1952 rtx tmp = gen_reg_rtx (SImode);
1953 emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
1954 emit_move_insn (operands[0], tmp);
1959 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1960 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1961 emit_insn (gen_mulsi3_600_lib ());
1962 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1967 (define_insn_and_split "mulsi32x16"
1968 [(set (match_operand:SI 0 "register_operand" "=w")
1969 (mult:SI (match_operand:SI 1 "register_operand" "%c")
1970 (match_operand:SI 2 "nonmemory_operand" "ci")))
1971 (clobber (reg:DI MUL32x16_REG))]
1972 "TARGET_MULMAC_32BY16_SET"
1974 "TARGET_MULMAC_32BY16_SET && reload_completed"
1977 if (immediate_operand (operands[2], SImode)
1978 && INTVAL (operands[2]) >= 0
1979 && INTVAL (operands[2]) <= 65535)
1981 emit_insn (gen_umul_600 (operands[1], operands[2],
1982 gen_acc2 (), gen_acc1 ()));
1983 emit_move_insn (operands[0], gen_acc2 ());
1986 emit_insn (gen_umul_600 (operands[1], operands[2],
1987 gen_acc2 (), gen_acc1 ()));
1988 emit_insn (gen_mac_600 (operands[1], operands[2],
1989 gen_acc2 (), gen_acc1 ()));
1990 emit_move_insn (operands[0], gen_acc2 ());
1993 [(set_attr "type" "multi")
1994 (set_attr "length" "8")])
1996 ; mululw conditional execution without a LIMM clobbers an input register;
1997 ; we'd need a different pattern to describe this.
1998 ; To make the conditional execution valid for the LIMM alternative, we
1999 ; have to emit the LIMM before the register operand.
2000 (define_insn "umul_600"
2001 [(set (match_operand:SI 2 "acc2_operand" "")
2002 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2003 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2007 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2008 "TARGET_MULMAC_32BY16_SET"
2010 [(set_attr "length" "4,4,8")
2011 (set_attr "type" "mulmac_600")
2012 (set_attr "predicable" "no")
2013 (set_attr "cond" "nocond")])
2015 (define_insn "mac_600"
2016 [(set (match_operand:SI 2 "acc2_operand" "")
2018 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2020 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2025 (clobber (match_operand:SI 3 "acc1_operand" ""))]
2026 "TARGET_MULMAC_32BY16_SET"
2027 "machlw%? 0, %0, %1"
2028 [(set_attr "length" "4,4,8")
2029 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2030 (set_attr "predicable" "no, no, yes")
2031 (set_attr "cond" "nocond, canuse_limm, canuse")])
2033 (define_insn_and_split "mulsi64"
2034 [(set (match_operand:SI 0 "register_operand" "=w")
2035 (mult:SI (match_operand:SI 1 "register_operand" "%c")
2036 (match_operand:SI 2 "nonmemory_operand" "ci")))
2037 (clobber (reg:DI MUL64_OUT_REG))]
2040 "TARGET_MUL64_SET && reload_completed"
2043 emit_insn (gen_mulsi_600 (operands[1], operands[2],
2044 gen_mlo (), gen_mhi ()));
2045 emit_move_insn (operands[0], gen_mlo ());
2048 [(set_attr "type" "multi")
2049 (set_attr "length" "8")])
2051 (define_insn "mulsi_600"
2052 [(set (match_operand:SI 2 "mlo_operand" "")
2053 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
2054 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
2055 (clobber (match_operand:SI 3 "mhi_operand" ""))]
2057 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
2058 ; using a machine code pattern that only allows "L" constraint constants.
2059 ; "mul64%? \t0, %0, %1%&"
2061 if (satisfies_constraint_I (operands[1])
2062 && !satisfies_constraint_L (operands[1]))
2064 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */
2065 int n = true_regnum (operands[0]);
2066 int i = INTVAL (operands[1]);
2067 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
2068 asm_fprintf (asm_out_file, "\t.short %d`",
2069 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
2070 return "; mul64%? \t0, %0, %1%&";
2072 return "mul64%? \t0, %0, %1%&";
2074 [(set_attr "length" "*,4,4,8")
2075 (set_attr "iscompact" "maybe,false,false,false")
2076 (set_attr "type" "multi,multi,multi,multi")
2077 (set_attr "predicable" "yes,yes,no,yes")
2078 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2080 ; If we compile without an mul option enabled, but link with libraries
2081 ; for a mul option, we'll see clobbers of multiplier output registers.
2082 ; There is also an implementation using norm that clobbers the loop registers.
2083 (define_insn "mulsi3_600_lib"
2084 [(set (reg:SI R0_REG)
2085 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2086 (clobber (reg:SI RETURN_ADDR_REGNUM))
2087 (clobber (reg:SI R1_REG))
2088 (clobber (reg:SI R2_REG))
2089 (clobber (reg:SI R3_REG))
2090 (clobber (reg:DI MUL64_OUT_REG))
2091 (clobber (reg:SI LP_COUNT))
2092 (clobber (reg:SI LP_START))
2093 (clobber (reg:SI LP_END))
2094 (clobber (reg:CC CC_REG))]
2096 && SFUNC_CHECK_PREDICABLE"
2097 "*return arc_output_libcall (\"__mulsi3\");"
2098 [(set_attr "is_sfunc" "yes")
2099 (set_attr "predicable" "yes")])
2101 (define_insn_and_split "mulsidi_600"
2102 [(set (match_operand:DI 0 "register_operand" "=c, c,c, c")
2103 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c"))
2104 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32"))))
2105 (clobber (reg:DI MUL64_OUT_REG))]
2110 "emit_insn (gen_mul64 (operands[1], operands[2]));
2111 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2113 [(set_attr "type" "multi")
2114 (set_attr "length" "8")])
2116 (define_insn "mul64"
2117 [(set (reg:DI MUL64_OUT_REG)
2119 (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c, c"))
2120 (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))]
2122 "mul64%? \t0, %0, %1%&"
2123 [(set_attr "length" "*,4,4,8")
2124 (set_attr "iscompact" "maybe,false,false,false")
2125 (set_attr "type" "multi,multi,multi,multi")
2126 (set_attr "predicable" "yes,yes,no,yes")
2127 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2129 (define_insn_and_split "umulsidi_600"
2130 [(set (match_operand:DI 0 "register_operand" "=c,c, c")
2131 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c,c, c"))
2132 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "cL,L,C32"))))
2133 (clobber (reg:DI MUL64_OUT_REG))]
2138 "emit_insn (gen_mulu64 (operands[1], operands[2]));
2139 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2141 [(set_attr "type" "umulti")
2142 (set_attr "length" "8")])
2144 (define_insn "mulu64"
2145 [(set (reg:DI MUL64_OUT_REG)
2147 (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c"))
2148 (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2150 "mulu64%? \t0, %0, %1%&"
2151 [(set_attr "length" "4,4,8")
2152 (set_attr "iscompact" "false")
2153 (set_attr "type" "umulti")
2154 (set_attr "predicable" "yes,no,yes")
2155 (set_attr "cond" "canuse,canuse_limm,canuse")])
2157 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2158 ; may not be used as destination constraint.
2160 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2161 ; but mpyu is faster for the standard multiplier.
2162 ; Note: we must make sure LP_COUNT is not one of the destination
2163 ; registers, since it cannot be the destination of a multi-cycle insn
2165 (define_insn "mulsi3_700"
2166 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r")
2167 (mult:SI (match_operand:SI 1 "register_operand" "%0,c,0,0,c")
2168 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2171 [(set_attr "length" "4,4,4,8,8")
2172 (set_attr "type" "umulti")
2173 (set_attr "predicable" "yes,no,no,yes,no")
2174 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2176 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2177 ; short variant. LP_COUNT constraints are still valid.
2178 (define_insn "mulsi3_v2"
2179 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r")
2180 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c")
2181 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2184 [(set_attr "length" "*,4,4,4,8,8")
2185 (set_attr "iscompact" "maybe,false,false,false,false,false")
2186 (set_attr "type" "umulti")
2187 (set_attr "predicable" "no,yes,no,no,yes,no")
2188 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2190 (define_expand "mulsidi3"
2191 [(set (match_operand:DI 0 "register_operand" "")
2192 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2193 (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2196 if (TARGET_PLUS_MACD)
2198 if (CONST_INT_P (operands[2]))
2200 emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2204 emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2210 operands[2] = force_reg (SImode, operands[2]);
2211 if (!register_operand (operands[0], DImode))
2213 rtx result = gen_reg_rtx (DImode);
2215 operands[2] = force_reg (SImode, operands[2]);
2216 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2217 emit_move_insn (operands[0], result);
2221 else if (TARGET_MUL64_SET)
2223 emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2226 else if (TARGET_MULMAC_32BY16_SET)
2228 operands[2] = force_reg (SImode, operands[2]);
2229 emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2232 operands[2] = force_reg (SImode, operands[2]);
2235 (define_insn_and_split "mulsidi64"
2236 [(set (match_operand:DI 0 "register_operand" "=w")
2237 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2238 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2239 (clobber (reg:DI MUL32x16_REG))]
2240 "TARGET_MULMAC_32BY16_SET"
2242 "TARGET_MULMAC_32BY16_SET && reload_completed"
2245 rtx result_hi = gen_highpart (SImode, operands[0]);
2246 rtx result_low = gen_lowpart (SImode, operands[0]);
2248 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2249 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2250 emit_move_insn (result_low, gen_acc2 ());
2253 [(set_attr "type" "multi")
2254 (set_attr "length" "8")])
2257 (define_insn "mul64_600"
2258 [(set (reg:DI MUL32x16_REG)
2259 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2261 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2266 "TARGET_MULMAC_32BY16_SET"
2268 [(set_attr "length" "4,4,8")
2269 (set_attr "type" "mulmac_600")
2270 (set_attr "predicable" "no,no,yes")
2271 (set_attr "cond" "nocond, canuse_limm, canuse")])
2274 ;; ??? check if this is canonical rtl
2275 (define_insn "mac64_600"
2276 [(set (reg:DI MUL32x16_REG)
2278 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2280 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2281 (const_int 16) (const_int 16))
2283 (reg:DI MUL32x16_REG)))
2284 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2287 (mult:DI (sign_extend:DI (match_dup 1))
2289 (sign_extract:DI (match_dup 2)
2290 (const_int 16) (const_int 16))
2292 (reg:DI MUL32x16_REG))
2293 (const_int 32) (const_int 32)))]
2294 "TARGET_MULMAC_32BY16_SET"
2295 "machlw%? %0, %1, %2"
2296 [(set_attr "length" "4,4,8")
2297 (set_attr "type" "mulmac_600")
2298 (set_attr "predicable" "no,no,yes")
2299 (set_attr "cond" "nocond, canuse_limm, canuse")])
2302 ;; DI <- DI(signed SI) * DI(signed SI)
2303 (define_insn_and_split "mulsidi3_700"
2304 [(set (match_operand:DI 0 "register_operand" "=&r")
2305 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2306 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2307 "TARGET_MPY && !TARGET_PLUS_MACD"
2309 "&& reload_completed"
2312 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2313 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2314 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2315 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2316 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2317 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2320 [(set_attr "type" "multi")
2321 (set_attr "length" "8")])
2323 (define_insn "mulsi3_highpart"
2324 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2328 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2329 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2333 [(set_attr "length" "4,4,8,8")
2334 (set_attr "type" "multi")
2335 (set_attr "predicable" "yes,no,yes,no")
2336 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2338 ; Note that mpyhu has the same latency as mpy / mpyh,
2339 ; thus we use the type multi.
2340 (define_insn "*umulsi3_highpart_i"
2341 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2345 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2346 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2350 [(set_attr "length" "4,4,8,8")
2351 (set_attr "type" "multi")
2352 (set_attr "predicable" "yes,no,yes,no")
2353 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2355 ; Implementations include additional labels for umulsidi3, so we got all
2356 ; the same clobbers - plus one for the result low part. */
2357 (define_insn "umulsi3_highpart_600_lib_le"
2358 [(set (reg:SI R1_REG)
2361 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2362 (zero_extend:DI (reg:SI R1_REG)))
2364 (clobber (reg:SI RETURN_ADDR_REGNUM))
2365 (clobber (reg:SI R0_REG))
2366 (clobber (reg:DI R2_REG))
2367 (clobber (reg:SI R12_REG))
2368 (clobber (reg:DI MUL64_OUT_REG))
2369 (clobber (reg:CC CC_REG))]
2372 && SFUNC_CHECK_PREDICABLE"
2373 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2374 [(set_attr "is_sfunc" "yes")
2375 (set_attr "predicable" "yes")])
2377 (define_insn "umulsi3_highpart_600_lib_be"
2378 [(set (reg:SI R0_REG)
2381 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2382 (zero_extend:DI (reg:SI R1_REG)))
2384 (clobber (reg:SI RETURN_ADDR_REGNUM))
2385 (clobber (reg:SI R1_REG))
2386 (clobber (reg:DI R2_REG))
2387 (clobber (reg:SI R12_REG))
2388 (clobber (reg:DI MUL64_OUT_REG))
2389 (clobber (reg:CC CC_REG))]
2392 && SFUNC_CHECK_PREDICABLE"
2393 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2394 [(set_attr "is_sfunc" "yes")
2395 (set_attr "predicable" "yes")])
2397 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2398 ;; need a separate pattern for immediates
2399 ;; ??? This is fine for combine, but not for reload.
2400 (define_insn "umulsi3_highpart_int"
2401 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2405 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2406 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2410 [(set_attr "length" "4,4,4,8,8")
2411 (set_attr "type" "multi")
2412 (set_attr "predicable" "yes,no,no,yes,no")
2413 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2415 (define_expand "umulsi3_highpart"
2416 [(set (match_operand:SI 0 "general_operand" "")
2420 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2421 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2423 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2426 rtx target = operands[0];
2430 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2431 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2432 if (TARGET_BIG_ENDIAN)
2433 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2435 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2436 emit_move_insn (target, gen_rtx_REG (SImode, 0));
2440 if (!register_operand (target, SImode))
2441 target = gen_reg_rtx (SImode);
2443 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2444 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2445 operands[2], SImode);
2446 else if (!immediate_operand (operands[2], SImode))
2447 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2448 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2449 if (target != operands[0])
2450 emit_move_insn (operands[0], target);
2454 (define_expand "umulsidi3"
2455 [(set (match_operand:DI 0 "register_operand" "")
2456 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2457 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2460 if (TARGET_PLUS_MACD)
2462 if (CONST_INT_P (operands[2]))
2464 emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2468 emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2474 operands[2] = force_reg (SImode, operands[2]);
2475 if (!register_operand (operands[0], DImode))
2477 rtx result = gen_reg_rtx (DImode);
2479 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2480 emit_move_insn (operands[0], result);
2484 else if (TARGET_MUL64_SET)
2486 operands[2] = force_reg (SImode, operands[2]);
2487 emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2490 else if (TARGET_MULMAC_32BY16_SET)
2492 operands[2] = force_reg (SImode, operands[2]);
2493 emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2498 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2499 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2500 emit_insn (gen_umulsidi3_600_lib ());
2501 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2506 (define_insn_and_split "umulsidi64"
2507 [(set (match_operand:DI 0 "register_operand" "=w")
2508 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2509 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2510 (clobber (reg:DI MUL32x16_REG))]
2511 "TARGET_MULMAC_32BY16_SET"
2513 "TARGET_MULMAC_32BY16_SET && reload_completed"
2519 result_hi = gen_highpart (SImode, operands[0]);
2520 result_low = gen_lowpart (SImode, operands[0]);
2522 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2523 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2524 emit_move_insn (result_low, gen_acc2 ());
2527 [(set_attr "type" "multi")
2528 (set_attr "length" "8")])
2530 (define_insn "umul64_600"
2531 [(set (reg:DI MUL32x16_REG)
2532 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2534 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2539 "TARGET_MULMAC_32BY16_SET"
2541 [(set_attr "length" "4,4,8")
2542 (set_attr "type" "mulmac_600")
2543 (set_attr "predicable" "no")
2544 (set_attr "cond" "nocond")])
2547 (define_insn "umac64_600"
2548 [(set (reg:DI MUL32x16_REG)
2550 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2552 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2553 (const_int 16) (const_int 16))
2555 (reg:DI MUL32x16_REG)))
2556 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2559 (mult:DI (zero_extend:DI (match_dup 1))
2561 (zero_extract:DI (match_dup 2)
2562 (const_int 16) (const_int 16))
2564 (reg:DI MUL32x16_REG))
2565 (const_int 32) (const_int 32)))]
2566 "TARGET_MULMAC_32BY16_SET"
2567 "machulw%? %0, %1, %2"
2568 [(set_attr "length" "4,4,8")
2569 (set_attr "type" "mulmac_600")
2570 (set_attr "predicable" "no,no,yes")
2571 (set_attr "cond" "nocond, canuse_limm, canuse")])
2573 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2574 (define_insn_and_split "umulsidi3_700"
2575 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2576 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2577 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2578 "TARGET_MPY && !TARGET_PLUS_MACD"
2583 int hi = !TARGET_BIG_ENDIAN;
2585 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2586 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2587 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2588 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2591 [(set_attr "type" "umulti")
2592 (set_attr "length" "8")])
2594 (define_insn "umulsidi3_600_lib"
2595 [(set (reg:DI R0_REG)
2596 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2597 (zero_extend:DI (reg:SI R1_REG))))
2598 (clobber (reg:SI RETURN_ADDR_REGNUM))
2599 (clobber (reg:DI R2_REG))
2600 (clobber (reg:SI R12_REG))
2601 (clobber (reg:DI MUL64_OUT_REG))
2602 (clobber (reg:CC CC_REG))]
2604 && SFUNC_CHECK_PREDICABLE"
2605 "*return arc_output_libcall (\"__umulsidi3\");"
2606 [(set_attr "is_sfunc" "yes")
2607 (set_attr "predicable" "yes")])
2611 [(set (reg:DI R0_REG)
2612 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2613 (zero_extend:DI (reg:SI R1_REG))))
2614 (clobber (reg:SI RETURN_ADDR_REGNUM))
2615 (clobber (reg:DI R2_REG))
2616 (clobber (reg:SI R12_REG))
2617 (clobber (reg:DI MUL64_OUT_REG))
2618 (clobber (reg:CC CC_REG))])]
2620 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2623 if (TARGET_BIG_ENDIAN)
2624 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2626 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2630 (define_expand "addsi3"
2631 [(set (match_operand:SI 0 "dest_reg_operand" "")
2632 (plus:SI (match_operand:SI 1 "register_operand" "")
2633 (match_operand:SI 2 "nonmemory_operand" "")))]
2635 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2637 operands[2]=force_reg(SImode, operands[2]);
2639 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2641 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2646 (define_expand "adddi3"
2647 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2648 (plus:DI (match_operand:DI 1 "register_operand" "")
2649 (match_operand:DI 2 "nonmemory_operand" "")))
2650 (clobber (reg:CC CC_REG))])]
2654 ; This assumes that there can be no strictly partial overlap between
2655 ; operands[1] and operands[2].
2656 (define_insn_and_split "*adddi3_i"
2657 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2658 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2659 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2660 (clobber (reg:CC CC_REG))]
2666 int hi = !TARGET_BIG_ENDIAN;
2668 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2669 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2670 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2671 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2672 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2673 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2676 if (l2 == const0_rtx)
2678 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2679 emit_move_insn (l0, l1);
2680 emit_insn (gen_addsi3 (h0, h1, h2));
2681 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2682 emit_move_insn (l0, l1);
2685 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2686 && INTVAL (operands[2]) >= -0x7fffffff)
2688 emit_insn (gen_subdi3_i (operands[0], operands[1],
2689 GEN_INT (-INTVAL (operands[2]))));
2692 if (rtx_equal_p (l0, h1))
2694 if (h2 != const0_rtx)
2695 emit_insn (gen_addsi3 (h0, h1, h2));
2696 else if (!rtx_equal_p (h0, h1))
2697 emit_move_insn (h0, h1);
2698 emit_insn (gen_add_f (l0, l1, l2));
2702 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2703 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2706 emit_insn (gen_add_f (l0, l1, l2));
2707 emit_insn (gen_adc (h0, h1, h2));
2710 [(set_attr "cond" "clob")
2711 (set_attr "type" "binary")
2712 (set_attr "length" "16,16,20")])
2714 (define_insn "add_f"
2715 [(set (reg:CC_C CC_REG)
2717 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2718 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2720 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2721 (plus:SI (match_dup 1) (match_dup 2)))]
2724 [(set_attr "cond" "set")
2725 (set_attr "type" "compare")
2726 (set_attr "length" "4,4,8")])
2728 (define_insn "*add_f_2"
2729 [(set (reg:CC_C CC_REG)
2731 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2732 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2734 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2735 (plus:SI (match_dup 1) (match_dup 2)))]
2738 [(set_attr "cond" "set")
2739 (set_attr "type" "compare")
2740 (set_attr "length" "4,4,8")])
2742 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2743 ; needlessly prioritizing the matching constraint.
2744 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2745 ; execution is used where possible.
2746 (define_insn_and_split "adc"
2747 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2748 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2749 (match_operand:SI 1 "nonmemory_operand"
2751 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2752 "register_operand (operands[1], SImode)
2753 || register_operand (operands[2], SImode)"
2760 ; if we have a bad schedule after sched2, split.
2762 && !optimize_size && (!TARGET_ARC600_FAMILY)
2763 && arc_scheduling_not_expected ()
2764 && arc_sets_cc_p (prev_nonnote_insn (insn))
2765 /* If next comes a return or other insn that needs a delay slot,
2766 expect the adc to get into the delay slot. */
2767 && next_nonnote_insn (insn)
2768 && !arc_need_delay (next_nonnote_insn (insn))
2769 /* Restore operands before emitting. */
2770 && (extract_insn_cached (insn), 1)"
2771 [(set (match_dup 0) (match_dup 3))
2773 (ltu (reg:CC_C CC_REG) (const_int 0))
2774 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2775 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2776 [(set_attr "cond" "use")
2777 (set_attr "type" "cc_arith")
2778 (set_attr "length" "4,4,4,4,8")])
2780 ; combiner-splitter cmp / scc -> cmp / adc
2782 [(set (match_operand:SI 0 "dest_reg_operand" "")
2783 (gtu:SI (match_operand:SI 1 "register_operand" "")
2784 (match_operand:SI 2 "register_operand" "")))
2785 (clobber (reg CC_REG))]
2787 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2788 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2790 ; combine won't work when an intermediate result is used later...
2791 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2793 [(set (match_operand:SI 0 "dest_reg_operand" "")
2794 (plus:SI (match_operand:SI 1 "register_operand" "")
2795 (match_operand:SI 2 "nonmemory_operand" "")))
2796 (set (reg:CC_C CC_REG)
2797 (compare:CC_C (match_dup 0)
2798 (match_operand:SI 3 "nonmemory_operand" "")))]
2799 "rtx_equal_p (operands[1], operands[3])
2800 || rtx_equal_p (operands[2], operands[3])"
2802 [(set (reg:CC_C CC_REG)
2803 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2805 (plus:SI (match_dup 1) (match_dup 2)))])])
2807 ; ??? need to delve into combine to find out why this is not useful.
2808 ; We'd like to be able to grok various C idioms for carry bit usage.
2809 ;(define_insn "*adc_0"
2810 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2811 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2812 ; (match_operand:SI 1 "register_operand" "c")))]
2815 ; [(set_attr "cond" "use")
2816 ; (set_attr "type" "cc_arith")
2817 ; (set_attr "length" "4")])
2820 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2821 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2822 ; (match_operand:SI 2 "register_operand" "c"))
2823 ; (match_operand:SI 3 "register_operand" "c")))
2824 ; (clobber (reg CC_REG))]
2826 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2827 ; (set (match_dup 0)
2828 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2831 (define_expand "subsi3"
2832 [(set (match_operand:SI 0 "dest_reg_operand" "")
2833 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2834 (match_operand:SI 2 "nonmemory_operand" "")))]
2840 if (!register_operand (operands[2], SImode))
2842 operands[1] = force_reg (SImode, operands[1]);
2845 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2846 operands[c] = force_reg (SImode, operands[c]);
2847 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2848 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2851 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2852 ; combine should make such an insn go away.
2853 (define_insn_and_split "subsi3_insn"
2854 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2855 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,Rcqq, 0, cL,c,L,I,Cal,Cal, c")
2856 (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2857 "register_operand (operands[1], SImode)
2858 || register_operand (operands[2], SImode)"
2870 "reload_completed && get_attr_length (insn) == 8
2871 && satisfies_constraint_I (operands[1])
2872 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2873 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2874 "split_subsi (operands);"
2875 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2876 (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2877 (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2878 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2879 (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2882 (define_expand "subdi3"
2883 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2884 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2885 (match_operand:DI 2 "nonmemory_operand" "")))
2886 (clobber (reg:CC CC_REG))])]
2889 if (!register_operand (operands[2], DImode))
2890 operands[1] = force_reg (DImode, operands[1]);
2893 (define_insn_and_split "subdi3_i"
2894 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2895 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2896 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2897 (clobber (reg:CC CC_REG))]
2898 "register_operand (operands[1], DImode)
2899 || register_operand (operands[2], DImode)"
2904 int hi = !TARGET_BIG_ENDIAN;
2906 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2907 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2908 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2909 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2910 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2911 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2913 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2915 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2916 if (!rtx_equal_p (h0, h1))
2917 emit_insn (gen_rtx_SET (h0, h1));
2918 emit_insn (gen_sub_f (l0, l1, l2));
2922 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2923 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2926 emit_insn (gen_sub_f (l0, l1, l2));
2927 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2930 [(set_attr "cond" "clob")
2931 (set_attr "length" "16,16,16,20,20")])
2933 (define_insn "*sbc_0"
2934 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2935 (minus:SI (match_operand:SI 1 "register_operand" "c")
2936 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2940 [(set_attr "cond" "use")
2941 (set_attr "type" "cc_arith")
2942 (set_attr "length" "4")])
2944 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2945 ; needlessly prioritizing the matching constraint.
2946 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2947 ; is used where possible.
2948 (define_insn_and_split "sbc"
2949 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2950 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2952 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2954 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2955 "register_operand (operands[1], SImode)
2956 || register_operand (operands[2], SImode)"
2963 ; if we have a bad schedule after sched2, split.
2965 && !optimize_size && (!TARGET_ARC600_FAMILY)
2966 && arc_scheduling_not_expected ()
2967 && arc_sets_cc_p (prev_nonnote_insn (insn))
2968 /* If next comes a return or other insn that needs a delay slot,
2969 expect the adc to get into the delay slot. */
2970 && next_nonnote_insn (insn)
2971 && !arc_need_delay (next_nonnote_insn (insn))
2972 /* Restore operands before emitting. */
2973 && (extract_insn_cached (insn), 1)"
2974 [(set (match_dup 0) (match_dup 4))
2976 (ltu (reg:CC_C CC_REG) (const_int 0))
2977 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2978 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2979 [(set_attr "cond" "use")
2980 (set_attr "type" "cc_arith")
2981 (set_attr "length" "4,4,4,4,8")])
2983 (define_insn "sub_f"
2984 [(set (reg:CC CC_REG)
2985 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2986 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2987 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2988 (minus:SI (match_dup 1) (match_dup 2)))]
2989 "register_operand (operands[1], SImode)
2990 || register_operand (operands[2], SImode)"
2998 [(set_attr "type" "compare")
2999 (set_attr "length" "4,4,4,4,8,8")])
3001 ; combine won't work when an intermediate result is used later...
3002 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3004 [(set (reg:CC CC_REG)
3005 (compare:CC (match_operand:SI 1 "register_operand" "")
3006 (match_operand:SI 2 "nonmemory_operand" "")))
3007 (set (match_operand:SI 0 "dest_reg_operand" "")
3008 (minus:SI (match_dup 1) (match_dup 2)))]
3011 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3012 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3015 [(set (reg:CC CC_REG)
3016 (compare:CC (match_operand:SI 1 "register_operand" "")
3017 (match_operand:SI 2 "nonmemory_operand" "")))
3018 (set (match_operand 3 "" "") (match_operand 4 "" ""))
3019 (set (match_operand:SI 0 "dest_reg_operand" "")
3020 (minus:SI (match_dup 1) (match_dup 2)))]
3021 "!reg_overlap_mentioned_p (operands[3], operands[1])
3022 && !reg_overlap_mentioned_p (operands[3], operands[2])
3023 && !reg_overlap_mentioned_p (operands[0], operands[4])
3024 && !reg_overlap_mentioned_p (operands[0], operands[3])"
3026 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3027 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3028 (set (match_dup 3) (match_dup 4))])
3030 (define_insn "*add_n"
3031 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3032 (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3033 (match_operand:SI 2 "_1_2_3_operand" ""))
3034 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3036 "add%c2%? %0,%3,%1%&"
3037 [(set_attr "type" "shift")
3038 (set_attr "length" "*,4,4,8,4,8")
3039 (set_attr "predicable" "yes,yes,no,no,no,no")
3040 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3041 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3043 (define_insn "*add_n"
3044 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3045 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3046 (match_operand:SI 2 "_2_4_8_operand" ""))
3047 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3049 "add%z2%? %0,%3,%1%&"
3050 [(set_attr "type" "shift")
3051 (set_attr "length" "*,4,4,8,4,8")
3052 (set_attr "predicable" "yes,yes,no,no,no,no")
3053 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3054 (set_attr "iscompact" "maybe,false,false,false,false,false")])
3056 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3057 ;; what synth_mult likes.
3058 (define_insn "*sub_n"
3059 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3060 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3061 (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
3062 (match_operand:SI 3 "_1_2_3_operand" ""))))]
3065 [(set_attr "type" "shift")
3066 (set_attr "length" "4,4,8")
3067 (set_attr "predicable" "yes,no,no")
3068 (set_attr "cond" "canuse,nocond,nocond")
3069 (set_attr "iscompact" "false")])
3071 (define_insn "*sub_n"
3072 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3073 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3074 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
3075 (match_operand:SI 3 "_2_4_8_operand" ""))))]
3078 [(set_attr "type" "shift")
3079 (set_attr "length" "4,4,8")
3080 (set_attr "predicable" "yes,no,no")
3081 (set_attr "cond" "canuse,nocond,nocond")
3082 (set_attr "iscompact" "false")])
3084 ; ??? check if combine matches this.
3085 (define_insn "*bset"
3086 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3087 (ior:SI (ashift:SI (const_int 1)
3088 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3089 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3092 [(set_attr "length" "4,4,8")
3093 (set_attr "predicable" "yes,no,no")
3094 (set_attr "cond" "canuse,nocond,nocond")]
3097 ; ??? check if combine matches this.
3098 (define_insn "*bxor"
3099 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3100 (xor:SI (ashift:SI (const_int 1)
3101 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3102 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3105 [(set_attr "length" "4,4,8")
3106 (set_attr "predicable" "yes,no,no")
3107 (set_attr "cond" "canuse,nocond,nocond")]
3110 ; ??? check if combine matches this.
3111 (define_insn "*bclr"
3112 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3113 (and:SI (not:SI (ashift:SI (const_int 1)
3114 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
3115 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3118 [(set_attr "length" "4,4,8")
3119 (set_attr "predicable" "yes,no,no")
3120 (set_attr "cond" "canuse,nocond,nocond")]
3123 ; ??? FIXME: find combine patterns for bmsk.
3125 ;;Following are the define_insns added for the purpose of peephole2's
3127 ; see also iorsi3 for use with constant bit number.
3128 (define_insn "*bset_insn"
3129 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3130 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3131 (ashift:SI (const_int 1)
3132 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3135 bset%? %0,%1,%2 ;;peep2, constr 1
3136 bset %0,%1,%2 ;;peep2, constr 2
3137 bset %0,%S1,%2 ;;peep2, constr 3"
3138 [(set_attr "length" "4,4,8")
3139 (set_attr "predicable" "yes,no,no")
3140 (set_attr "cond" "canuse,nocond,nocond")]
3143 ; see also xorsi3 for use with constant bit number.
3144 (define_insn "*bxor_insn"
3145 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3146 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3147 (ashift:SI (const_int 1)
3148 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3154 [(set_attr "length" "4,4,8")
3155 (set_attr "predicable" "yes,no,no")
3156 (set_attr "cond" "canuse,nocond,nocond")]
3159 ; see also andsi3 for use with constant bit number.
3160 (define_insn "*bclr_insn"
3161 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3162 (and:SI (not:SI (ashift:SI (const_int 1)
3163 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3164 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3170 [(set_attr "length" "4,4,8")
3171 (set_attr "predicable" "yes,no,no")
3172 (set_attr "cond" "canuse,nocond,nocond")]
3175 ; see also andsi3 for use with constant bit number.
3176 (define_insn "*bmsk_insn"
3177 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3178 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3179 (plus:SI (ashift:SI (const_int 1)
3180 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3188 [(set_attr "length" "4,4,8")
3189 (set_attr "predicable" "yes,no,no")
3190 (set_attr "cond" "canuse,nocond,nocond")]
3193 ;;Instructions added for peephole2s end
3195 ;; Boolean instructions.
3197 (define_expand "andsi3"
3198 [(set (match_operand:SI 0 "dest_reg_operand" "")
3199 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3200 (match_operand:SI 2 "nonmemory_operand" "")))]
3202 "if (!satisfies_constraint_Cux (operands[2]))
3203 operands[1] = force_reg (SImode, operands[1]);
3204 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3205 operands[1] = arc_rewrite_small_data (operands[1]);")
3207 (define_insn "andsi3_i"
3208 [(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")
3209 (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")
3210 (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")))]
3211 "(register_operand (operands[1], SImode)
3212 && nonmemory_operand (operands[2], SImode))
3213 || (memory_operand (operands[1], SImode)
3214 && satisfies_constraint_Cux (operands[2]))"
3216 switch (which_alternative)
3218 case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3219 return "and%? %0,%1,%2%&";
3221 return "and%? %0,%2,%1%&";
3223 return "bmsk%? %0,%1,%Z2%&";
3225 if (satisfies_constraint_C2p (operands[2]))
3227 operands[2] = GEN_INT ((~INTVAL (operands[2])));
3228 return "bmskn%? %0,%1,%Z2%&";
3232 return "bmsk%? %0,%1,%Z2%&";
3234 case 3: case 8: case 13:
3235 return "bclr%? %0,%1,%M2%&";
3237 return (INTVAL (operands[2]) == 0xff
3238 ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3239 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3241 return "movb.cl %0,%1,%p2,%p2,%s2";
3246 if (satisfies_constraint_Ucm (operands[1]))
3247 tmpl = (INTVAL (operands[2]) == 0xff
3248 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3250 tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3252 if (TARGET_BIG_ENDIAN)
3256 xop[0] = operands[0];
3257 xop[1] = adjust_address (operands[1], QImode,
3258 INTVAL (operands[2]) == 0xff ? 3 : 2);
3259 output_asm_insn (tmpl, xop);
3267 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3268 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3269 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3270 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3271 (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")])
3273 ; combiner splitter, pattern found in ldtoa.c .
3274 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3276 [(set (reg:CC_Z CC_REG)
3277 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3278 (match_operand 1 "const_int_operand" ""))
3279 (match_operand 2 "const_int_operand" "")))
3280 (clobber (match_operand:SI 3 "register_operand" ""))]
3281 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3283 (plus:SI (match_dup 0) (match_dup 4)))
3284 (set (reg:CC_Z CC_REG)
3285 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3287 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3289 ;;bic define_insn that allows limm to be the first operand
3290 (define_insn "*bicsi3_insn"
3291 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3292 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3293 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3296 bic%? %0, %2, %1%& ;;constraint 0
3297 bic%? %0,%2,%1 ;;constraint 1
3298 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3299 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3300 bic %0,%2,%1 ;;constraint 4
3301 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3302 bic %0,%S2,%1 ;;constraint 6"
3303 [(set_attr "length" "*,4,4,8,4,8,8")
3304 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3305 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3306 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3308 (define_insn "iorsi3"
3309 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3310 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3311 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3314 switch (which_alternative)
3316 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3317 return \"or%? %0,%1,%2%&\";
3319 return \"or%? %0,%2,%1%&\";
3320 case 2: case 5: case 8:
3321 return \"bset%? %0,%1,%z2%&\";
3325 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3326 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3327 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3328 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3330 (define_insn "xorsi3"
3331 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3332 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3333 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3336 switch (which_alternative)
3338 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3339 return \"xor%? %0,%1,%2%&\";
3341 return \"xor%? %0,%2,%1%&\";
3343 return \"bxor%? %0,%1,%z2\";
3348 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3349 (set_attr "type" "binary")
3350 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3351 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3352 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3354 (define_insn "negsi2"
3355 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3356 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3359 [(set_attr "type" "unary")
3360 (set_attr "iscompact" "maybe,true,false,false")
3361 (set_attr "predicable" "no,no,yes,no")])
3363 (define_insn "one_cmplsi2"
3364 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3365 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3368 [(set_attr "type" "unary,unary")
3369 (set_attr "iscompact" "true,false")])
3371 (define_insn_and_split "one_cmpldi2"
3372 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3373 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3376 "&& reload_completed"
3377 [(set (match_dup 2) (not:SI (match_dup 3)))
3378 (set (match_dup 4) (not:SI (match_dup 5)))]
3380 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3382 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3383 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3384 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3385 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3387 [(set_attr "type" "unary,unary")
3388 (set_attr "cond" "nocond,nocond")
3389 (set_attr "length" "4,8")])
3391 ;; Shift instructions.
3393 (define_expand "ashlsi3"
3394 [(set (match_operand:SI 0 "dest_reg_operand" "")
3395 (ashift:SI (match_operand:SI 1 "register_operand" "")
3396 (match_operand:SI 2 "nonmemory_operand" "")))]
3400 if (!TARGET_BARREL_SHIFTER)
3402 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3407 (define_expand "ashrsi3"
3408 [(set (match_operand:SI 0 "dest_reg_operand" "")
3409 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3410 (match_operand:SI 2 "nonmemory_operand" "")))]
3414 if (!TARGET_BARREL_SHIFTER)
3416 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3421 (define_expand "lshrsi3"
3422 [(set (match_operand:SI 0 "dest_reg_operand" "")
3423 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3424 (match_operand:SI 2 "nonmemory_operand" "")))]
3428 if (!TARGET_BARREL_SHIFTER)
3430 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3435 (define_insn "shift_si3"
3436 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3437 (match_operator:SI 3 "shift4_operator"
3438 [(match_operand:SI 1 "register_operand" "0")
3439 (match_operand:SI 2 "const_int_operand" "n")]))
3440 (clobber (match_scratch:SI 4 "=&r"))
3441 (clobber (reg:CC CC_REG))
3443 "!TARGET_BARREL_SHIFTER"
3444 "* return output_shift (operands);"
3445 [(set_attr "type" "shift")
3446 (set_attr "length" "16")])
3448 (define_insn "shift_si3_loop"
3449 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3450 (match_operator:SI 3 "shift_operator"
3451 [(match_operand:SI 1 "register_operand" "0,0")
3452 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3453 (clobber (match_scratch:SI 4 "=X,X"))
3454 (clobber (reg:SI LP_COUNT))
3455 (clobber (reg:SI LP_START))
3456 (clobber (reg:SI LP_END))
3457 (clobber (reg:CC CC_REG))
3459 "!TARGET_BARREL_SHIFTER"
3460 "* return output_shift (operands);"
3461 [(set_attr "type" "shift")
3462 (set_attr "length" "16,20")])
3464 ; asl, asr, lsr patterns:
3465 ; There is no point in including an 'I' alternative since only the lowest 5
3466 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3467 ; is defined in an external symbol, as we don't have special relocations
3468 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3469 ; provide one alternatice for this, without condexec support.
3470 (define_insn "*ashlsi3_insn"
3471 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3472 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3473 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3474 "TARGET_BARREL_SHIFTER
3475 && (register_operand (operands[1], SImode)
3476 || register_operand (operands[2], SImode))"
3478 [(set_attr "type" "shift")
3479 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3480 (set_attr "predicable" "no,no,no,yes,no,no")
3481 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3483 (define_insn "*ashrsi3_insn"
3484 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3485 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3486 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3487 "TARGET_BARREL_SHIFTER
3488 && (register_operand (operands[1], SImode)
3489 || register_operand (operands[2], SImode))"
3491 [(set_attr "type" "shift")
3492 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3493 (set_attr "predicable" "no,no,no,yes,no,no")
3494 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3496 (define_insn "*lshrsi3_insn"
3497 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3498 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3499 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3500 "TARGET_BARREL_SHIFTER
3501 && (register_operand (operands[1], SImode)
3502 || register_operand (operands[2], SImode))"
3503 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3504 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3505 [(set_attr "type" "shift")
3506 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3507 (set_attr "predicable" "no,no,no,yes,no,no")
3508 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3510 (define_insn "rotrsi3"
3511 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3512 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3513 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3514 "TARGET_BARREL_SHIFTER"
3516 [(set_attr "type" "shift,shift,shift")
3517 (set_attr "predicable" "yes,no,no")
3518 (set_attr "length" "4,4,8")])
3520 ;; Compare / branch instructions.
3522 (define_expand "cbranchsi4"
3523 [(set (reg:CC CC_REG)
3524 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3525 (match_operand:SI 2 "nonmemory_operand" "")))
3528 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3530 (label_ref (match_operand 3 "" ""))
3534 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3535 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3536 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3537 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3541 ;; ??? Could add a peephole to generate compare with swapped operands and
3542 ;; modifed cc user if second, but not first operand is a compact register.
3543 (define_insn "cmpsi_cc_insn_mixed"
3544 [(set (reg:CC CC_REG)
3545 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq, h, c, c,qRcq,c")
3546 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI,cL, Cal,Cal")))]
3549 [(set_attr "type" "compare")
3550 (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3551 (set_attr "predicable" "no,no,no,no,yes,no,yes")
3552 (set_attr "cond" "set")
3553 (set_attr "length" "*,*,*,4,4,*,8")
3554 (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3556 (define_insn "*cmpsi_cc_zn_insn"
3557 [(set (reg:CC_ZN CC_REG)
3558 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3562 [(set_attr "type" "compare,compare")
3563 (set_attr "iscompact" "true,false")
3564 (set_attr "predicable" "no,yes")
3565 (set_attr "cond" "set_zn")
3566 (set_attr "length" "*,4")])
3568 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3569 (define_insn "*btst"
3570 [(set (reg:CC_ZN CC_REG)
3572 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3574 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3578 [(set_attr "iscompact" "true,false")
3579 (set_attr "predicable" "no,yes")
3580 (set_attr "cond" "set")
3581 (set_attr "type" "compare")
3582 (set_attr "length" "*,4")])
3584 ; combine suffers from 'simplifications' that replace a one-bit zero
3585 ; extract with a shift if it can prove that the upper bits are zero.
3586 ; arc_reorg sees the code after sched2, which can have caused our
3587 ; inputs to be clobbered even if they were not clobbered before.
3588 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3589 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3590 ; bbit (i.e. bad scheduling) and missed conditional execution,
3591 ; so make this an option.
3593 [(set (reg:CC_ZN CC_REG)
3595 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3597 (match_operand:SI 1 "nonmemory_operand" ""))
3600 (if_then_else (match_operator 3 "equality_comparison_operator"
3601 [(reg:CC_ZN CC_REG) (const_int 0)])
3602 (label_ref (match_operand 2 "" ""))
3604 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3605 [(parallel [(set (pc)
3608 [(zero_extract:SI (match_dup 0)
3609 (const_int 1) (match_dup 1))
3611 (label_ref (match_dup 2))
3613 (clobber (reg:CC_ZN CC_REG))])])
3615 (define_insn "*cmpsi_cc_z_insn"
3616 [(set (reg:CC_Z CC_REG)
3617 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3618 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3623 [(set_attr "type" "compare,compare")
3624 (set_attr "iscompact" "true,false")
3625 (set_attr "cond" "set,set_zn")
3626 (set_attr "length" "*,4")])
3628 (define_insn "*cmpsi_cc_c_insn"
3629 [(set (reg:CC_C CC_REG)
3630 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c")
3631 (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))]
3634 [(set_attr "type" "compare")
3635 (set_attr "iscompact" "true,true,true,false,true_limm,false")
3636 (set_attr "cond" "set")
3637 (set_attr "length" "*,*,*,4,*,8")
3638 (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3640 ;; Next come the scc insns.
3642 (define_expand "cstoresi4"
3643 [(set (match_operand:SI 0 "dest_reg_operand" "")
3644 (match_operator:SI 1 "ordered_comparison_operator"
3645 [(match_operand:SI 2 "nonmemory_operand" "")
3646 (match_operand:SI 3 "nonmemory_operand" "")]))]
3649 if (!TARGET_CODE_DENSITY)
3651 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3652 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3653 operands[1] = gen_compare_reg (operands[1], SImode);
3654 emit_insn (gen_scc_insn (operands[0], operands[1]));
3657 if (!register_operand (operands[2], SImode))
3658 operands[2] = force_reg (SImode, operands[2]);
3662 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3663 (DF "TARGET_OPTFPE")])
3665 (define_expand "cstore<mode>4"
3666 [(set (reg:CC CC_REG)
3667 (compare:CC (match_operand:SDF 2 "register_operand" "")
3668 (match_operand:SDF 3 "register_operand" "")))
3669 (set (match_operand:SI 0 "dest_reg_operand" "")
3670 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3673 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3675 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3676 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3677 operands[1] = gen_compare_reg (operands[1], SImode);
3678 emit_insn (gen_scc_insn (operands[0], operands[1]));
3682 ; We need a separate expander for this lest we loose the mode of CC_REG
3683 ; when match_operator substitutes the literal operand into the comparison.
3684 (define_expand "scc_insn"
3685 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3687 (define_insn_and_split "*scc_insn"
3688 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3689 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3693 [(set (match_dup 0) (const_int 1))
3696 (set (match_dup 0) (const_int 0)))]
3699 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3700 GET_MODE (XEXP (operands[1], 0))),
3702 XEXP (operands[1], 0), XEXP (operands[1], 1));
3704 [(set_attr "type" "unary")])
3706 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3707 ;; that is one lower if the carry flag is set.
3709 ;; ??? Look up negscc insn. See pa.md for example.
3710 (define_insn "*neg_scc_insn"
3711 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3712 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3713 [(reg CC_REG) (const_int 0)])))]
3715 "mov %0,-1\;sub.%D1 %0,%0,%0"
3716 [(set_attr "type" "unary")
3717 (set_attr "length" "8")])
3719 (define_insn "*not_scc_insn"
3720 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3721 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3722 [(reg CC_REG) (const_int 0)])))]
3724 "mov %0,1\;sub.%d1 %0,%0,%0"
3725 [(set_attr "type" "unary")
3726 (set_attr "length" "8")])
3728 ; cond_exec patterns
3729 (define_insn "*movsi_ne"
3731 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0))
3732 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w")
3733 (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))]
3736 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3737 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3738 * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3741 [(set_attr "type" "cmove")
3742 (set_attr "iscompact" "true,true,true_limm,false,false")
3743 (set_attr "length" "2,2,6,4,8")
3744 (set_attr "cpu_facility" "*,av2,av2,*,*")])
3746 (define_insn "*movsi_cond_exec"
3748 (match_operator 3 "proper_comparison_operator"
3749 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3750 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3751 (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3754 [(set_attr "type" "cmove")
3755 (set_attr "length" "4,8")])
3757 (define_insn "*commutative_cond_exec"
3759 (match_operator 5 "proper_comparison_operator"
3760 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3761 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3762 (match_operator:SI 3 "commutative_operator"
3763 [(match_operand:SI 1 "register_operand" "%0,0")
3764 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3767 arc_output_commutative_cond_exec (operands, true);
3770 [(set_attr "cond" "use")
3771 (set_attr "type" "cmove")
3772 (set_attr_alternative "length"
3775 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3780 (define_insn "*sub_cond_exec"
3782 (match_operator 4 "proper_comparison_operator"
3783 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3784 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3785 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3786 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3792 [(set_attr "cond" "use")
3793 (set_attr "type" "cmove")
3794 (set_attr "length" "4,4,8")])
3796 (define_insn "*noncommutative_cond_exec"
3798 (match_operator 5 "proper_comparison_operator"
3799 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3800 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3801 (match_operator:SI 3 "noncommutative_operator"
3802 [(match_operand:SI 1 "register_operand" "0,0")
3803 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3806 [(set_attr "cond" "use")
3807 (set_attr "type" "cmove")
3808 (set_attr "length" "4,8")])
3810 ;; These control RTL generation for conditional jump insns
3811 ;; Match both normal and inverted jump.
3813 ; We need a separate expander for this lest we loose the mode of CC_REG
3814 ; when match_operator substitutes the literal operand into the comparison.
3815 (define_expand "branch_insn"
3817 (if_then_else (match_operand 1 "" "")
3818 (label_ref (match_operand 0 "" ""))
3821 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3822 ; are three reasons why we need to consider branches to be length 6:
3823 ; - annull-false delay slot insns are implemented using conditional execution,
3824 ; thus preventing short insn formation where used.
3825 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3826 ; using conditional execution, preventing short insn formation where used.
3827 ; - for ARC700: likely or somewhat likely taken branches are made long and
3828 ; unaligned if possible to avoid branch penalty.
3829 (define_insn "*branch_insn"
3831 (if_then_else (match_operator 1 "proper_comparison_operator"
3832 [(reg CC_REG) (const_int 0)])
3833 (label_ref (match_operand 0 "" ""))
3838 if (arc_ccfsm_branch_deleted_p ())
3840 arc_ccfsm_record_branch_deleted ();
3841 return \"; branch deleted, next insns conditionalized\";
3845 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3846 if (get_attr_length (insn) == 2)
3847 return \"b%d1%? %^%l0%&\";
3849 return \"b%d1%# %^%l0\";
3852 [(set_attr "type" "branch")
3856 (eq_attr "delay_slot_filled" "yes")
3861 (match_operand 1 "equality_comparison_operator" "")
3862 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3863 (gt (minus (match_dup 0) (pc))
3864 (minus (const_int 506)
3865 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3866 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3867 (lt (minus (match_dup 0) (pc)) (const_int -64))
3868 (gt (minus (match_dup 0) (pc))
3869 (minus (const_int 58)
3870 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3875 (set (attr "iscompact")
3876 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3877 (const_string "false")))])
3879 (define_insn "*rev_branch_insn"
3881 (if_then_else (match_operator 1 "proper_comparison_operator"
3882 [(reg CC_REG) (const_int 0)])
3884 (label_ref (match_operand 0 "" ""))))]
3885 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3888 if (arc_ccfsm_branch_deleted_p ())
3890 arc_ccfsm_record_branch_deleted ();
3891 return \"; branch deleted, next insns conditionalized\";
3895 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3896 if (get_attr_length (insn) == 2)
3897 return \"b%D1%? %^%l0\";
3899 return \"b%D1%# %^%l0\";
3902 [(set_attr "type" "branch")
3906 (eq_attr "delay_slot_filled" "yes")
3911 (match_operand 1 "equality_comparison_operator" "")
3912 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3913 (gt (minus (match_dup 0) (pc))
3914 (minus (const_int 506)
3915 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3916 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3917 (lt (minus (match_dup 0) (pc)) (const_int -64))
3918 (gt (minus (match_dup 0) (pc))
3919 (minus (const_int 58)
3920 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3925 (set (attr "iscompact")
3926 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3927 (const_string "false")))])
3929 ;; Unconditional and other jump instructions.
3931 (define_expand "jump"
3932 [(set (pc) (label_ref (match_operand 0 "" "")))]
3936 (define_insn "jump_i"
3937 [(set (pc) (label_ref (match_operand 0 "" "")))]
3938 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3940 [(set_attr "type" "uncond_branch")
3941 (set (attr "iscompact")
3942 (if_then_else (match_test "get_attr_length (insn) == 2")
3943 (const_string "true") (const_string "false")))
3944 (set_attr "cond" "canuse")
3945 (set (attr "length")
3947 ; In arc_reorg we just guesstimate; might be more or less than 4.
3948 (match_test "arc_branch_size_unknown_p ()")
3951 (eq_attr "delay_slot_filled" "yes")
3954 (match_test "CROSSING_JUMP_P (insn)")
3957 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3958 (gt (minus (match_dup 0) (pc))
3959 (minus (const_int 506)
3960 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3964 (define_insn "indirect_jump"
3965 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3973 [(set_attr "type" "jump")
3974 (set_attr "iscompact" "false,false,false,maybe,false")
3975 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3977 ;; Implement a switch statement.
3979 (define_expand "casesi"
3981 (minus:SI (match_operand:SI 0 "register_operand" "")
3982 (match_operand:SI 1 "nonmemory_operand" "")))
3983 (set (reg:CC CC_REG)
3984 (compare:CC (match_dup 5)
3985 (match_operand:SI 2 "nonmemory_operand" "")))
3987 (if_then_else (gtu (reg:CC CC_REG)
3989 (label_ref (match_operand 4 "" ""))
3992 (unspec:SI [(match_operand 3 "" "")
3993 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
3994 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4000 operands[5] = gen_reg_rtx (SImode);
4001 operands[6] = gen_reg_rtx (SImode);
4002 operands[7] = operands[3];
4003 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4004 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4005 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4006 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4007 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4008 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
4009 if (TARGET_COMPACT_CASESI)
4011 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4015 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4016 if (flag_pic || !cse_not_expected)
4017 operands[3] = force_reg (Pmode, operands[3]);
4018 emit_insn (gen_casesi_load (operands[6],
4019 operands[3], operands[5], operands[7]));
4020 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4021 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4022 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4027 (define_insn "casesi_load"
4028 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
4029 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4030 (match_operand:SI 2 "register_operand" "Rcq,c,c")
4031 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
4035 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4037 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4039 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4040 gcc_assert (GET_MODE (diff_vec) == SImode);
4041 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4044 switch (GET_MODE (diff_vec))
4047 return \"ld.as %0,[%1,%2]%&\";
4049 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4050 return \"ld%_.as %0,[%1,%2]\";
4051 return \"ld%_.x.as %0,[%1,%2]\";
4053 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4054 return \"ldb%? %0,[%1,%2]%&\";
4055 return \"ldb.x %0,[%1,%2]\";
4060 [(set_attr "type" "load")
4061 (set_attr_alternative "iscompact"
4063 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4064 (as_a<rtx_insn *> (operands[3]))))")
4065 (symbol_ref "QImode"))
4066 (const_string "false")
4067 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4068 (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4069 (const_string "false")]
4070 (const_string "true"))
4071 (const_string "false")
4072 (const_string "false")])
4073 (set_attr_alternative "length"
4075 [(eq_attr "iscompact" "false") (const_int 4)
4076 ; We have to mention (match_dup 3) to convince genattrtab.c that this
4077 ; is a varying length insn.
4078 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4079 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4084 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4085 ; even for CASE_VECTOR_PC_RELATIVE.
4086 (define_insn "casesi_jump"
4087 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4088 (use (label_ref (match_operand 1 "" "")))]
4091 [(set_attr "type" "jump")
4092 (set_attr "iscompact" "false,maybe,false")
4093 (set_attr "cond" "canuse")])
4095 (define_insn "casesi_compact_jump"
4097 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4099 (use (label_ref (match_operand 1 "" "")))
4100 (clobber (match_scratch:SI 2 "=q,0"))]
4101 "TARGET_COMPACT_CASESI"
4104 rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4105 int unalign = arc_get_unalign ();
4109 xop[0] = operands[0];
4110 xop[2] = operands[2];
4111 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4113 switch (GET_MODE (diff_vec))
4116 /* Max length can be 12 in this case, but this is OK because
4117 2 of these are for alignment, and are anticipated in the length
4118 of the ADDR_DIFF_VEC. */
4119 if (unalign && !satisfies_constraint_Rcq (xop[0]))
4120 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
4122 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4124 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4125 arc_clear_unalign ();
4128 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4130 if (satisfies_constraint_Rcq (xop[0]))
4132 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
4133 xop[1] = GEN_INT ((10 - unalign) / 2U);
4137 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
4138 xop[1] = GEN_INT (10 + unalign);
4143 if (satisfies_constraint_Rcq (xop[0]))
4145 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
4146 xop[1] = GEN_INT ((10 - unalign) / 2U);
4150 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
4151 xop[1] = GEN_INT (10 + unalign);
4154 arc_toggle_unalign ();
4157 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4159 if ((rtx_equal_p (xop[2], xop[0])
4160 || find_reg_note (insn, REG_DEAD, xop[0]))
4161 && satisfies_constraint_Rcq (xop[0]))
4163 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4164 xop[1] = GEN_INT (8 + unalign);
4168 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4169 xop[1] = GEN_INT (10 + unalign);
4170 arc_toggle_unalign ();
4173 else if ((rtx_equal_p (xop[0], xop[2])
4174 || find_reg_note (insn, REG_DEAD, xop[0]))
4175 && satisfies_constraint_Rcq (xop[0]))
4177 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4178 xop[1] = GEN_INT (10 - unalign);
4179 arc_toggle_unalign ();
4183 /* ??? Length is 12. */
4184 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4185 xop[1] = GEN_INT (8 + unalign);
4191 output_asm_insn (s, xop);
4192 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4194 [(set_attr "length" "10")
4195 (set_attr "type" "jump")
4196 (set_attr "iscompact" "true")
4197 (set_attr "cond" "nocond")])
4199 (define_expand "call"
4200 ;; operands[1] is stack_size_rtx
4201 ;; operands[2] is next_arg_register
4202 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4203 (match_operand 1 "" ""))
4204 (clobber (reg:SI 31))])]
4209 gcc_assert (MEM_P (operands[0]));
4210 callee = XEXP (operands[0], 0);
4211 /* This is to decide if we should generate indirect calls by loading the
4212 32 bit address of the callee into a register before performing the
4213 branch and link - this exposes cse opportunities.
4214 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4215 if (GET_CODE (callee) != REG
4216 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4217 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4222 ; Rcq, which is used in alternative 0, checks for conditional execution.
4223 ; At instruction output time, if it doesn't match and we end up with
4224 ; alternative 1 ("q"), that means that we can't use the short form.
4225 (define_insn "*call_i"
4226 [(call (mem:SI (match_operand:SI 0
4227 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4228 (match_operand 1 "" ""))
4229 (clobber (reg:SI 31))]
4240 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4241 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4242 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4243 (set_attr "length" "*,*,4,4,4,4,4,8")])
4245 (define_expand "call_value"
4246 ;; operand 2 is stack_size_rtx
4247 ;; operand 3 is next_arg_register
4248 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4249 (call (match_operand:SI 1 "call_operand" "")
4250 (match_operand 2 "" "")))
4251 (clobber (reg:SI 31))])]
4257 gcc_assert (MEM_P (operands[1]));
4258 callee = XEXP (operands[1], 0);
4259 /* See the comment in define_expand \"call\". */
4260 if (GET_CODE (callee) != REG
4261 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4262 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4266 ; Rcq, which is used in alternative 0, checks for conditional execution.
4267 ; At instruction output time, if it doesn't match and we end up with
4268 ; alternative 1 ("q"), that means that we can't use the short form.
4269 (define_insn "*call_value_i"
4270 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
4271 (call (mem:SI (match_operand:SI 1
4272 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4273 (match_operand 2 "" "")))
4274 (clobber (reg:SI 31))]
4285 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4286 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4287 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4288 (set_attr "length" "*,*,4,4,4,4,4,8")])
4290 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4291 ; use it for lack of inter-procedural branch shortening.
4292 ; Link-time relaxation would help...
4298 [(set_attr "type" "misc")
4299 (set_attr "iscompact" "true")
4300 (set_attr "cond" "canuse")
4301 (set_attr "length" "2")])
4304 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4307 [(set_attr "type" "misc")
4308 (set_attr "iscompact" "true")
4309 (set_attr "length" "2")])
4311 ;; Special pattern to flush the icache.
4312 ;; ??? Not sure what to do here. Some ARC's are known to support this.
4314 (define_insn "flush_icache"
4315 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4318 [(set_attr "type" "misc")])
4320 ;; Split up troublesome insns for better scheduling.
4322 ;; Peepholes go at the end.
4323 ;;asl followed by add can be replaced by an add{1,2,3}
4324 ;; Three define_peepholes have been added for this optimization
4325 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4326 ;; can be generated by combine. Check if these peepholes still provide
4329 ;; -------------------------------------------------------------
4330 ;; Pattern 1 : r0 = r1 << {i}
4331 ;; r3 = r4/INT + r0 ;;and commutative
4334 ;; add{i} r3,r4/INT,r1
4335 ;; -------------------------------------------------------------
4336 ;; ??? This should be covered by combine, alas, at times combine gets
4337 ;; too clever for it's own good: when the shifted input is known to be
4338 ;; either 0 or 1, the operation will be made into an if-then-else, and
4339 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4340 ;; newlib/libc/time/mktm_r.c .
4343 [(set (match_operand:SI 0 "dest_reg_operand" "")
4344 (ashift:SI (match_operand:SI 1 "register_operand" "")
4345 (match_operand:SI 2 "const_int_operand" "")))
4346 (set (match_operand:SI 3 "dest_reg_operand" "")
4347 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4348 (match_operand:SI 5 "nonmemory_operand" "")))]
4349 "(INTVAL (operands[2]) == 1
4350 || INTVAL (operands[2]) == 2
4351 || INTVAL (operands[2]) == 3)
4352 && (true_regnum (operands[4]) == true_regnum (operands[0])
4353 || true_regnum (operands[5]) == true_regnum (operands[0]))
4354 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4355 ;; the preparation statements take care to put proper operand in operands[4]
4356 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4358 (plus:SI (mult:SI (match_dup 1)
4361 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4362 operands[4] = operands[5];
4363 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4366 ;; -------------------------------------------------------------
4367 ;; Pattern 1 : r0 = r1 << {i}
4372 ;; -------------------------------------------------------------
4373 ;; ??? This should be covered by combine, alas, at times combine gets
4374 ;; too clever for it's own good: when the shifted input is known to be
4375 ;; either 0 or 1, the operation will be made into an if-then-else, and
4376 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4377 ;; newlib/libm/math/e_jn.c .
4380 [(set (match_operand:SI 0 "dest_reg_operand" "")
4381 (ashift:SI (match_operand:SI 1 "register_operand" "")
4382 (match_operand:SI 2 "const_int_operand" "")))
4383 (set (match_operand:SI 3 "dest_reg_operand" "")
4384 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4386 "(INTVAL (operands[2]) == 1
4387 || INTVAL (operands[2]) == 2
4388 || INTVAL (operands[2]) == 3)
4389 && (peep2_reg_dead_p (2, operands[0])
4390 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4392 (minus:SI (match_dup 4)
4393 (mult:SI (match_dup 1)
4395 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4400 ; When using the high single bit, the result of a multiply is either
4401 ; the original number or zero. But MPY costs 4 cycles, which we
4402 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4404 [(set (match_operand:SI 0 "dest_reg_operand" "")
4405 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4407 (set (match_operand:SI 4 "register_operand" "")
4408 (mult:SI (match_operand:SI 2 "register_operand")
4409 (match_operand:SI 3 "nonmemory_operand" "")))]
4411 && (rtx_equal_p (operands[0], operands[2])
4412 || rtx_equal_p (operands[0], operands[3]))
4413 && peep2_regno_dead_p (0, CC_REG)
4414 && (rtx_equal_p (operands[0], operands[4])
4415 || (peep2_reg_dead_p (2, operands[0])
4416 && peep2_reg_dead_p (1, operands[4])))"
4417 [(parallel [(set (reg:CC_Z CC_REG)
4418 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4420 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4422 (ne (reg:CC_Z CC_REG) (const_int 0))
4423 (set (match_dup 4) (match_dup 5)))]
4425 if (!rtx_equal_p (operands[0], operands[2]))
4426 operands[5] = operands[2];
4427 else if (!rtx_equal_p (operands[0], operands[3]))
4428 operands[5] = operands[3];
4430 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4434 [(set (match_operand:SI 0 "dest_reg_operand" "")
4435 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4437 (set (match_operand:SI 4 "register_operand" "")
4438 (mult:SI (match_operand:SI 2 "register_operand")
4439 (match_operand:SI 3 "nonmemory_operand" "")))]
4441 && (rtx_equal_p (operands[0], operands[2])
4442 || rtx_equal_p (operands[0], operands[3]))
4443 && peep2_regno_dead_p (2, CC_REG)"
4444 [(parallel [(set (reg:CC_Z CC_REG)
4445 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4447 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4448 (set (match_dup 4) (match_dup 5))
4450 (eq (reg:CC_Z CC_REG) (const_int 0))
4451 (set (match_dup 4) (const_int 0)))]
4452 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4454 ;; Instructions generated through builtins
4456 (define_insn "clrsbsi2"
4457 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4458 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4463 [(set_attr "length" "4,8")
4464 (set_attr "type" "two_cycle_core,two_cycle_core")])
4466 (define_insn "norm_f"
4467 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4468 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4469 (set (reg:CC_ZN CC_REG)
4470 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4475 [(set_attr "length" "4,8")
4476 (set_attr "type" "two_cycle_core,two_cycle_core")])
4478 (define_insn_and_split "clrsbhi2"
4479 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4480 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4484 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4485 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4487 (define_insn "normw"
4488 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4490 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4495 [(set_attr "length" "4,8")
4496 (set_attr "type" "two_cycle_core,two_cycle_core")])
4498 (define_expand "clzsi2"
4500 [(set (match_operand:SI 0 "register_operand" "")
4501 (clz:SI (match_operand:SI 1 "register_operand" "")))
4502 (clobber (match_dup 2))])]
4504 "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);")
4506 (define_insn_and_split "*arc_clzsi2"
4507 [(set (match_operand:SI 0 "register_operand" "=r")
4508 (clz:SI (match_operand:SI 1 "register_operand" "r")))
4509 (clobber (reg:CC_ZN CC_REG))]
4515 emit_insn (gen_norm_f (operands[0], operands[1]));
4519 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4520 gen_rtx_SET (operands[0], const0_rtx)));
4524 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4525 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4529 (define_expand "ctzsi2"
4530 [(match_operand:SI 0 "register_operand" "")
4531 (match_operand:SI 1 "register_operand" "")]
4534 emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4538 (define_insn_and_split "arc_ctzsi2"
4539 [(set (match_operand:SI 0 "register_operand" "=r")
4540 (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4541 (clobber (reg:CC_ZN CC_REG))
4542 (clobber (match_scratch:SI 2 "=&r"))]
4548 rtx temp = operands[0];
4550 if (reg_overlap_mentioned_p (temp, operands[1])
4551 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4552 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4555 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4556 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4557 emit_insn (gen_clrsbsi2 (operands[0], temp));
4561 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4562 gen_rtx_SET (operands[0], GEN_INT (32))));
4566 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4567 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4574 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4575 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4582 [(set_attr "length" "4,8,4")
4583 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4585 (define_insn "divaw"
4586 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4587 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4588 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4590 "TARGET_ARC700 || TARGET_EA_SET"
4594 divaw \t%0, %1, %S2"
4595 [(set_attr "length" "4,8,8")
4596 (set_attr "type" "divaw,divaw,divaw")])
4599 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4606 [(set_attr "length" "4,4,8")
4607 (set_attr "type" "misc,misc,misc")
4608 (set_attr "predicable" "yes,no,yes")
4609 (set_attr "cond" "clob,clob,clob")])
4612 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4616 [(set_attr "length" "4")
4617 (set_attr "type" "misc")])
4620 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4624 [(set_attr "length" "4")
4625 (set_attr "type" "misc")
4626 (set_attr "cond" "clob")])
4629 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4633 [(set_attr "length" "4")
4634 (set_attr "type" "misc")])
4637 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4647 [(set_attr "length" "4")
4648 (set_attr "type" "misc")])
4651 (define_insn "sleep"
4652 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4654 "check_if_valid_sleep_operand(operands,0)"
4656 [(set_attr "length" "4")
4657 (set_attr "type" "misc")])
4659 (define_insn "core_read"
4660 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4661 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4662 VUNSPEC_ARC_CORE_READ))]
4665 if (check_if_valid_regno_const (operands, 1))
4666 return \"mov \t%0, r%1\";
4667 return \"mov \t%0, r%1\";
4669 [(set_attr "length" "4")
4670 (set_attr "type" "unary")])
4672 (define_insn "core_write"
4673 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4674 (match_operand:SI 1 "general_operand" "Hn,!r")]
4675 VUNSPEC_ARC_CORE_WRITE)]
4678 if (check_if_valid_regno_const (operands, 1))
4679 return \"mov \tr%1, %0\";
4680 return \"mov \tr%1, %0\";
4682 [(set_attr "length" "4")
4683 (set_attr "type" "unary")])
4686 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4687 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4691 [(set_attr "length" "4,8,4,8")
4692 (set_attr "type" "lr,lr,lr,lr")])
4695 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4696 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4700 [(set_attr "length" "8,4,8,4")
4701 (set_attr "type" "sr,sr,sr,sr")])
4703 (define_insn "trap_s"
4704 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4705 VUNSPEC_ARC_TRAP_S)]
4706 "!TARGET_ARC600_FAMILY"
4708 if (which_alternative == 0)
4710 arc_toggle_unalign ();
4711 return \"trap_s %0\";
4714 /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4715 because *.md files do not get scanned by exgettext. */
4716 fatal_error (input_location,
4717 \"operand to trap_s should be an unsigned 6-bit value\");
4719 [(set_attr "length" "2")
4720 (set_attr "type" "misc")])
4722 (define_insn "unimp_s"
4723 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4724 VUNSPEC_ARC_UNIMP_S)]
4725 "!TARGET_ARC600_FAMILY"
4727 [(set_attr "length" "4")
4728 (set_attr "type" "misc")])
4730 ;; End of instructions generated through builtins
4732 ; Since the demise of REG_N_SETS as reliable data readily available to the
4733 ; target, it is no longer possible to find out
4734 ; in the prologue / epilogue expanders how many times blink is set.
4735 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4736 ; any explicit use of blink will cause it to be saved; hence we cannot
4737 ; represent the blink use in return / sibcall instructions themselves, and
4738 ; instead have to show it in EPILOGUE_USES and must explicitly
4739 ; forbid instructions that change blink in the return / sibcall delay slot.
4740 (define_expand "sibcall"
4741 [(parallel [(call (match_operand 0 "memory_operand" "")
4742 (match_operand 1 "general_operand" ""))
4744 (use (match_operand 2 "" ""))])]
4748 rtx callee = XEXP (operands[0], 0);
4750 if (operands[2] == NULL_RTX)
4751 operands[2] = const0_rtx;
4752 if (GET_CODE (callee) != REG
4753 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4754 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4758 (define_expand "sibcall_value"
4759 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4760 (call (match_operand 1 "memory_operand" "")
4761 (match_operand 2 "general_operand" "")))
4763 (use (match_operand 3 "" ""))])]
4767 rtx callee = XEXP (operands[1], 0);
4769 if (operands[3] == NULL_RTX)
4770 operands[3] = const0_rtx;
4771 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4772 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4776 (define_insn "*sibcall_insn"
4777 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4778 "Cbp,Cbr,Rs5,Rsc,Cal"))
4779 (match_operand 1 "" ""))
4781 (use (match_operand 2 "" ""))]
4789 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4790 (set_attr "predicable" "yes,no,no,yes,yes")
4791 (set_attr "iscompact" "false,false,maybe,false,false")
4792 (set_attr "is_SIBCALL" "yes")]
4795 (define_insn "*sibcall_value_insn"
4796 [(set (match_operand 0 "dest_reg_operand" "")
4797 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4798 "Cbp,Cbr,Rs5,Rsc,Cal"))
4799 (match_operand 2 "" "")))
4801 (use (match_operand 3 "" ""))]
4809 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4810 (set_attr "predicable" "yes,no,no,yes,yes")
4811 (set_attr "iscompact" "false,false,maybe,false,false")
4812 (set_attr "is_SIBCALL" "yes")]
4815 (define_expand "prologue"
4819 arc_expand_prologue ();
4823 (define_expand "epilogue"
4827 arc_expand_epilogue (0);
4831 (define_expand "sibcall_epilogue"
4835 arc_expand_epilogue (1);
4839 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4840 ; in the prologue / epilogue expanders how many times blink is set.
4841 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4842 ; any explicit use of blink will cause it to be saved; hence we cannot
4843 ; represent the blink use in return / sibcall instructions themselves, and
4844 ; instead have to show it in EPILOGUE_USES and must explicitly
4845 ; forbid instructions that change blink in the return / sibcall delay slot.
4846 (define_insn "simple_return"
4851 = gen_rtx_REG (Pmode,
4852 arc_return_address_register (arc_compute_function_type
4856 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
4860 if (TARGET_PAD_RETURN)
4862 output_asm_insn (\"j%!%* [%0]%&\", ®);
4866 (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
4867 (match_test "TARGET_V2"))
4868 (const_string "brcc_no_delay_slot")]
4869 (const_string "return")))
4870 ; predicable won't help here since the canonical rtl looks different
4873 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4874 (symbol_ref "ARC_FUNCTION_ILINK1"))
4875 (match_test "TARGET_V2"))
4876 (const_string "nocond")]
4877 (const_string "canuse")))
4878 (set (attr "iscompact")
4879 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4880 (symbol_ref "ARC_FUNCTION_NORMAL"))
4881 (const_string "maybe")]
4882 (const_string "false")))
4883 (set (attr "length")
4884 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4885 (symbol_ref "ARC_FUNCTION_NORMAL"))
4889 (define_insn "p_return_i"
4891 (if_then_else (match_operator 0 "proper_comparison_operator"
4892 [(reg CC_REG) (const_int 0)])
4893 (simple_return) (pc)))]
4896 && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
4899 xop[0] = operands[0];
4901 = gen_rtx_REG (Pmode,
4902 arc_return_address_register (arc_compute_function_type
4905 if (TARGET_PAD_RETURN)
4907 output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4908 /* record the condition in case there is a delay insn. */
4909 arc_ccfsm_record_condition (xop[0], false, insn, 0);
4912 [(set_attr "type" "return")
4913 (set_attr "cond" "use")
4914 (set (attr "iscompact")
4915 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4916 (symbol_ref "ARC_FUNCTION_NORMAL"))
4917 (const_string "maybe")]
4918 (const_string "false")))
4919 (set (attr "length")
4920 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4921 (symbol_ref "ARC_FUNCTION_NORMAL"))
4923 (not (match_operand 0 "equality_comparison_operator" ""))
4925 (eq_attr "delay_slot_filled" "yes")
4929 (define_insn_and_split "eh_return"
4931 (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4932 (clobber (match_scratch:SI 1 "=X,r"))
4933 (clobber (match_scratch:SI 2 "=&r,r"))]
4937 [(set (match_dup 2) (match_dup 0))]
4939 int offs = arc_return_slot_offset ();
4942 operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4945 if (!register_operand (operands[0], Pmode)
4946 && !satisfies_constraint_C32 (operands[0]))
4948 emit_move_insn (operands[1], operands[0]);
4949 operands[0] = operands[1];
4951 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4952 if (!strict_memory_address_p (Pmode, addr))
4954 emit_move_insn (operands[2], addr);
4957 operands[2] = gen_frame_mem (Pmode, addr);
4960 [(set_attr "length" "12")])
4962 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4963 ;; non-constant predicate.
4964 (define_expand "return"
4968 ;; Comment in final.c (insn_current_reference_address) says
4969 ;; forward branch addresses are calculated from the next insn after branch
4970 ;; and for backward branches, it is calculated from the branch insn start.
4971 ;; The shortening logic here is tuned to accomodate this behavior
4972 ;; ??? This should be grokked by the ccfsm machinery.
4973 (define_insn "cbranchsi4_scratch"
4975 (if_then_else (match_operator 0 "proper_comparison_operator"
4976 [(match_operand:SI 1 "register_operand" "c,c, c")
4977 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4978 (label_ref (match_operand 3 "" ""))
4980 (clobber (match_operand 4 "cc_register" ""))]
4982 || (TARGET_EARLY_CBRANCHSI
4983 && brcc_nolimm_operator (operands[0], VOIDmode)))
4984 && !CROSSING_JUMP_P (insn)"
4986 switch (get_attr_length (insn))
4988 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4989 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4990 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4991 return \"br%d0%* %1, %B2, %^%l3\";
4994 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
4995 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4998 [(set_attr "cond" "clob, clob, clob")
5001 (match_test "valid_brcc_with_delay_p (operands)")
5002 (const_string "brcc")
5003 (const_string "brcc_no_delay_slot")))
5004 ; For forward branches, we need to account not only for the distance to
5005 ; the target, but also the difference between pcl and pc, the instruction
5006 ; length, and any delay insn, if present.
5009 (cond ; the outer cond does a test independent of branch shortening.
5010 [(match_operand 0 "brcc_nolimm_operator" "")
5012 [(and (match_operand:CC_Z 4 "cc_register")
5013 (eq_attr "delay_slot_filled" "no")
5014 (ge (minus (match_dup 3) (pc)) (const_int -128))
5015 (le (minus (match_dup 3) (pc))
5016 (minus (const_int 122)
5017 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5019 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5020 (le (minus (match_dup 3) (pc))
5021 (minus (const_int 244)
5022 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5024 (and (match_operand:SI 1 "compact_register_operand" "")
5025 (match_operand:SI 2 "compact_hreg_operand" ""))
5028 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5029 (le (minus (match_dup 3) (pc)) (const_int 244)))
5031 (and (match_operand:SI 1 "compact_register_operand" "")
5032 (match_operand:SI 2 "compact_hreg_operand" ""))
5035 (set (attr "iscompact")
5036 (if_then_else (match_test "get_attr_length (insn) & 2")
5037 (const_string "true") (const_string "false")))])
5039 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5040 (define_insn "*bbit"
5043 (match_operator 3 "equality_comparison_operator"
5044 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5046 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5048 (label_ref (match_operand 0 "" ""))
5050 (clobber (reg:CC_ZN CC_REG))]
5051 "!CROSSING_JUMP_P (insn)"
5053 switch (get_attr_length (insn))
5055 case 4: return (GET_CODE (operands[3]) == EQ
5056 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5058 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5059 default: gcc_unreachable ();
5062 [(set_attr "type" "brcc")
5063 (set_attr "cond" "clob")
5064 (set (attr "length")
5065 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5066 (le (minus (match_dup 0) (pc))
5067 (minus (const_int 248)
5068 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5070 (eq (symbol_ref "which_alternative") (const_int 0))
5073 (set (attr "iscompact")
5074 (if_then_else (match_test "get_attr_length (insn) == 6")
5075 (const_string "true") (const_string "false")))])
5077 ; ??? When testing a bit from a DImode register, combine creates a
5078 ; zero_extract in DImode. This goes via an AND with a DImode constant,
5079 ; so can only be observed on 64 bit hosts.
5080 (define_insn_and_split "*bbit_di"
5083 (match_operator 3 "equality_comparison_operator"
5084 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
5086 (match_operand 2 "immediate_operand" "L,L"))
5088 (label_ref (match_operand 0 "" ""))
5090 (clobber (reg:CC_ZN CC_REG))]
5091 "!CROSSING_JUMP_P (insn)"
5095 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
5096 (clobber (reg:CC_ZN CC_REG))])]
5100 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5101 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5105 ; operand 0 is the loop count pseudo register
5106 ; operand 1 is the loop end pattern
5107 (define_expand "doloop_begin"
5108 [(use (match_operand 0 "register_operand" ""))
5109 (use (match_operand 1 "" ""))]
5112 /* Using the INSN_UID of the loop end pattern to identify it causes
5113 trouble with -fcompare-debug, so allocate a debug-independent
5114 id instead. We use negative numbers so that we can use the same
5115 slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
5116 still be able to tell what kind of number this is. */
5117 static HOST_WIDE_INT loop_end_id = 0;
5119 rtx id = GEN_INT (--loop_end_id);
5120 XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
5121 emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
5122 const0_rtx, const0_rtx));
5126 ; ??? can't describe the insn properly as then the optimizers try to
5128 ;(define_insn "doloop_begin_i"
5129 ; [(set (reg:SI LP_START) (pc))
5130 ; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_ARC_LP))
5131 ; (use (match_operand 0 "const_int_operand" "n"))]
5133 ; "lp .L__GCC__LP%0"
5136 ; The operands of doloop_end_i are also read / written by arc_reorg with
5137 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
5138 ; might have to adjust arc_reorg.
5139 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
5140 ; by arc_reorg. arc_reorg might also alter operand 0.
5142 ; N in XVECEXP PATTERN (lp, 0 N)
5144 ; 0 unspec UNSPEC_ARC_LP identify pattern
5145 ; 1 clobber LP_START show LP_START is set
5146 ; 2 clobber LP_END show LP_END is set
5147 ; 3 use operand0 loop count pseudo register
5148 ; 4 use operand1 before arc_reorg: -id
5149 ; after : CODE_LABEL_NUMBER of loop top label
5150 ; 5 use operand2 INSN_UID of loop end insn
5151 ; 6 use operand3 loop setup not at start (1 above, 2 below)
5152 ; 7 use operand4 LABEL_REF of top label, if not
5153 ; immediately following
5154 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
5155 ; instruction that was not at the start of the loop.
5156 ; There is no point is reloading this insn - then lp_count would still not
5157 ; be available for the loop end.
5158 (define_insn "doloop_begin_i"
5159 [(unspec:SI [(pc)] UNSPEC_ARC_LP)
5160 (clobber (reg:SI LP_START))
5161 (clobber (reg:SI LP_END))
5162 (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
5163 (use (match_operand 1 "const_int_operand" "n,n,C_0"))
5164 (use (match_operand 2 "const_int_operand" "n,n,X"))
5165 (use (match_operand 3 "const_int_operand" "C_0,n,X"))
5166 (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
5172 rtx loop_start = operands[4];
5174 if (CONST_INT_P (loop_start))
5175 loop_start = NULL_RTX;
5176 /* Size implications of the alignment will be taken care of by the
5177 alignment inserted at the loop start. */
5178 if (LOOP_ALIGN (0) && INTVAL (operands[1]))
5180 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5181 arc_clear_unalign ();
5183 if (!INTVAL (operands[1]))
5184 return "; LITTLE LOST LOOP";
5185 if (loop_start && flag_pic)
5187 /* ??? Can do better for when a scratch register
5188 is known. But that would require extra testing. */
5189 return "push_s r0\;add r0,pcl,%4@pcl\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1@pcl\;sr r0,[3]; LP_END\;pop_s r0";
5191 /* Check if the loop end is in range to be set by the lp instruction. */
5192 size = INTVAL (operands[3]) < 2 ? 0 : 2048;
5193 for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
5197 if (recog_memoized (scan) == CODE_FOR_doloop_end_i
5198 && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
5199 == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
5201 len = get_attr_length (scan);
5204 /* Try to verify that there are at least three instruction fetches
5205 between the loop setup and the first encounter of the loop end. */
5206 for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
5210 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
5211 scan = seq->insn (0);
5214 if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
5217 if (simplejump_p (scan))
5219 scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
5223 rtx lab = JUMP_LABEL (scan);
5228 = next_active_insn (NEXT_INSN (PREV_INSN (scan)));
5230 && recog_memoized (next_scan) != CODE_FOR_doloop_begin_i)
5233 /* JUMP_LABEL might be simple_return instead if an insn. */
5240 rtx_insn *next_lab = next_active_insn (as_a<rtx_insn *> (lab));
5242 && recog_memoized (next_lab) != CODE_FOR_doloop_begin_i)
5249 len = get_attr_length (scan);
5250 /* Size estimation of asms assumes that each line which is nonempty
5251 codes an insn, and that each has a long immediate. For minimum insn
5252 count, assume merely that a nonempty asm has at least one insn. */
5253 if (GET_CODE (PATTERN (scan)) == ASM_INPUT
5254 || asm_noperands (PATTERN (scan)) >= 0)
5255 n_insns += (len != 0);
5257 n_insns += (len > 4 ? 2 : (len ? 1 : 0));
5261 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5262 arc_clear_unalign ();
5264 gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5265 if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5269 /* ??? Can do better for when a scratch register
5270 is known. But that would require extra testing. */
5271 arc_clear_unalign ();
5272 return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1@pcl\;sr r0,[3]; LP_END\;pop_s r0";
5274 output_asm_insn ((size < 2048
5275 ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5277 output_asm_insn (loop_start
5278 ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5280 if (TARGET_ARC600 && n_insns < 1)
5281 output_asm_insn ("nop", operands);
5282 return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5284 else if (TARGET_ARC600 && n_insns < 3)
5286 /* At least four instructions are needed between the setting of LP_COUNT
5287 and the loop end - but the lp instruction qualifies as one. */
5288 rtx_insn *prev = prev_nonnote_insn (insn);
5290 if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5291 output_asm_insn ("nop", operands);
5293 return "lp .L__GCC__LP%1";
5295 [(set_attr "type" "loop_setup")
5296 (set_attr_alternative "length"
5297 ; FIXME: length is usually 4, but we need branch shortening
5298 ; to get this right.
5299 ; [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
5300 [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
5301 (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
5303 ;; ??? we should really branch shorten this insn, but then we'd
5304 ;; need a proper label first. N.B. the end label can not only go out
5305 ;; of range when it is far away, but also when it precedes the loop -
5306 ;; which, unfortunately, it sometimes does, when the loop "optimizer"
5307 ;; messes things up.
5310 ; operand 0 is the loop count pseudo register
5311 ; operand 1 is the label to jump to at the top of the loop
5312 ; Use this for the ARC600 and ARC700.
5313 ; ??? ARC600 might want to check if the loop has few iteration and only a
5314 ; single insn - loop setup is expensive then.
5315 (define_expand "doloop_end"
5316 [(use (match_operand 0 "register_operand" ""))
5317 (use (label_ref (match_operand 1 "" "")))]
5320 /* We could do smaller bivs with biv widening, and wider bivs by having
5321 a high-word counter in an outer loop - but punt on this for now. */
5322 if (GET_MODE (operands[0]) != SImode)
5324 emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
5328 (define_insn_and_split "doloop_end_i"
5330 (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5332 (label_ref (match_operand 1 "" ""))
5334 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5335 (use (reg:SI LP_START))
5336 (use (reg:SI LP_END))
5337 (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
5338 (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5342 rtx_insn *prev = prev_nonnote_insn (insn);
5344 /* If there is an immediately preceding label, we must output a nop,
5345 lest a branch to that label will fall out of the loop.
5346 ??? We could try to avoid this by claiming to have a delay slot if there
5347 is a preceding label, and outputting the delay slot insn instead, if
5349 Or we could have some optimization that changes the source edge to update
5350 the loop count and jump to the loop start instead. */
5351 /* For ARC600, we must also prevent jumps inside the loop and jumps where
5352 the loop counter value is live at the target from being directly at the
5353 loop end. Being sure that the loop counter is dead at the target is
5354 too much hair - we can't rely on data flow information at this point -
5355 so insert a nop for all branches.
5356 The ARC600 also can't read the loop counter in the last insn of a loop. */
5358 output_asm_insn (\"nop%?\", operands);
5359 return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5361 "&& memory_operand (operands[0], SImode)"
5364 emit_move_insn (operands[3], operands[0]);
5365 emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5368 [(set_attr "type" "loop_end")
5369 (set (attr "length")
5370 (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
5371 (const_int 4) (const_int 0)))]
5374 ; This pattern is generated by arc_reorg when there is no recognizable
5376 (define_insn "*doloop_fallback"
5377 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5379 (label_ref (match_operand 1 "" ""))
5381 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5382 ; avoid fooling the loop optimizer into assuming this is a special insn.
5384 "*return get_attr_length (insn) == 8
5385 ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5386 : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5387 [(set (attr "length")
5388 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
5389 (le (minus (match_dup 1) (pc)) (const_int 244)))
5390 (const_int 8) (const_int 12)))
5391 (set_attr "type" "brcc_no_delay_slot")
5392 (set_attr "cond" "nocond")]
5395 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5396 (define_insn "doloop_fallback_m"
5397 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5399 (label_ref (match_operand 1 "" ""))
5401 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5402 (set (match_operand:SI 2 "memory_operand" "=m")
5403 (plus:SI (match_dup 0) (const_int -1)))]
5404 ; avoid fooling the loop optimizer into assuming this is a special insn.
5406 "*return get_attr_length (insn) == 12
5407 ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5408 : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5409 [(set (attr "length")
5410 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5411 (le (minus (match_dup 1) (pc)) (const_int 244)))
5412 (const_int 12) (const_int 16)))
5413 (set_attr "type" "brcc_no_delay_slot")
5414 (set_attr "cond" "nocond")]
5417 (define_expand "movmemsi"
5418 [(match_operand:BLK 0 "" "")
5419 (match_operand:BLK 1 "" "")
5420 (match_operand:SI 2 "nonmemory_operand" "")
5421 (match_operand 3 "immediate_operand" "")]
5423 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5425 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5426 ;; to the point that we can generate cmove instructions.
5427 (define_expand "cbranch<mode>4"
5428 [(set (reg:CC CC_REG)
5429 (compare:CC (match_operand:SDF 1 "register_operand" "")
5430 (match_operand:SDF 2 "register_operand" "")))
5433 (match_operator 0 "comparison_operator" [(reg CC_REG)
5435 (label_ref (match_operand 3 "" ""))
5438 "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5440 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5441 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5442 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5443 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5447 (define_expand "cmp_float"
5448 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5449 (clobber (reg:SI RETURN_ADDR_REGNUM))
5450 (clobber (reg:SI R12_REG))])]
5454 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5455 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5456 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5458 (define_insn "*cmpsf_<cmp>"
5459 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5460 (clobber (reg:SI RETURN_ADDR_REGNUM))
5461 (clobber (reg:SI R12_REG))]
5462 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5463 && SFUNC_CHECK_PREDICABLE"
5464 "*return arc_output_libcall (\"__<cmp>sf2\");"
5465 [(set_attr "is_sfunc" "yes")
5466 (set_attr "predicable" "yes")])
5468 ;; N.B. for "*cmpdf_ord":
5469 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5470 ;; for the floating point emulation to recognize the NaN.
5471 (define_insn "*cmpdf_<cmp>"
5472 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5473 (clobber (reg:SI RETURN_ADDR_REGNUM))
5474 (clobber (reg:SI R12_REG))]
5475 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5476 && SFUNC_CHECK_PREDICABLE"
5477 "*return arc_output_libcall (\"__<cmp>df2\");"
5478 [(set_attr "is_sfunc" "yes")
5479 (set_attr "predicable" "yes")])
5481 (define_insn "abssf2"
5482 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5483 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5486 [(set_attr "type" "unary")
5487 (set_attr "iscompact" "maybe,false,false")
5488 (set_attr "length" "2,4,4")
5489 (set_attr "predicable" "no,yes,no")])
5491 (define_insn "negsf2"
5492 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5493 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5496 [(set_attr "type" "unary")
5497 (set_attr "predicable" "yes,no")])
5499 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5500 (define_insn "*millicode_thunk_st"
5501 [(match_parallel 0 "millicode_store_operation"
5502 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5505 output_asm_insn ("bl%* __st_r13_to_%0",
5506 &SET_SRC (XVECEXP (operands[0], 0,
5507 XVECLEN (operands[0], 0) - 2)));
5510 [(set_attr "type" "call")])
5512 (define_insn "*millicode_thunk_ld"
5513 [(match_parallel 0 "millicode_load_clob_operation"
5514 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5517 output_asm_insn ("bl%* __ld_r13_to_%0",
5518 &SET_DEST (XVECEXP (operands[0], 0,
5519 XVECLEN (operands[0], 0) - 2)));
5522 [(set_attr "type" "call")])
5524 ; the sibthunk restores blink, so we use the return rtx.
5525 (define_insn "*millicode_sibthunk_ld"
5526 [(match_parallel 0 "millicode_load_operation"
5528 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5529 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5532 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5533 &SET_DEST (XVECEXP (operands[0], 0,
5534 XVECLEN (operands[0], 0) - 1)));
5537 [(set_attr "type" "call")
5538 (set_attr "is_SIBCALL" "yes")])
5540 (define_insn "tls_load_tp_soft"
5541 [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5542 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5544 "*return arc_output_libcall (\"__read_tp\");"
5545 [(set_attr "is_sfunc" "yes")
5546 (set_attr "predicable" "yes")])
5548 (define_insn "tls_gd_get_addr"
5549 [(set (reg:SI R0_REG)
5550 (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5551 "symbolic_operand" "X,X")]
5554 (clobber (reg:SI RETURN_ADDR_REGNUM))]
5556 ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5557 [(set_attr "type" "call")
5558 ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5559 (set_attr "predicable" "no")])
5561 ;; For thread pointer builtins
5562 (define_expand "get_thread_pointersi"
5563 [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5565 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5567 (define_expand "set_thread_pointersi"
5568 [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5570 "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5572 ;; If hardware floating point is available, don't define a negdf pattern;
5573 ;; it would be something like:
5574 ;;(define_insn "negdf2"
5575 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5576 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5577 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5580 ;; bxor%? %H0,%H1,31
5581 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5582 ;; drsubh%F0%F1 0,0,0
5583 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5584 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5585 ;; (set_attr "iscompact" "false,false,false,false")
5586 ;; (set_attr "length" "4,4,8,12")
5587 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5588 ;; and this suffers from always requiring a long immediate when using
5589 ;; the floating point hardware.
5590 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5591 ;; constant zero efficiently into a register when we want to do the
5592 ;; computation using the floating point hardware. There should be a special
5593 ;; subdf alternative that matches a zero operand 1, which then can allow
5594 ;; to use bxor to flip the high bit of an integer register.
5595 ;; ??? we actually can't use the floating point hardware for neg, because
5596 ;; this would not work right for -0. OTOH optabs.c has already code
5597 ;; to synthesyze negate by flipping the sign bit.
5600 (define_insn "bswapsi2"
5601 [(set (match_operand:SI 0 "register_operand" "= r,r")
5602 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5603 "TARGET_V2 && TARGET_SWAP"
5605 [(set_attr "length" "4,8")
5606 (set_attr "type" "two_cycle_core")])
5608 (define_expand "prefetch"
5609 [(prefetch (match_operand:SI 0 "address_operand" "")
5610 (match_operand:SI 1 "const_int_operand" "")
5611 (match_operand:SI 2 "const_int_operand" ""))]
5615 (define_insn "prefetch_1"
5616 [(prefetch (match_operand:SI 0 "register_operand" "r")
5617 (match_operand:SI 1 "const_int_operand" "n")
5618 (match_operand:SI 2 "const_int_operand" "n"))]
5621 if (INTVAL (operands[1]))
5622 return "prefetchw [%0]";
5624 return "prefetch [%0]";
5626 [(set_attr "type" "load")
5627 (set_attr "length" "4")])
5629 (define_insn "prefetch_2"
5630 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5631 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5632 (match_operand:SI 2 "const_int_operand" "n,n,n")
5633 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5636 if (INTVAL (operands[2]))
5637 return "prefetchw [%0, %1]";
5639 return "prefetch [%0, %1]";
5641 [(set_attr "type" "load")
5642 (set_attr "length" "4,4,8")])
5644 (define_insn "prefetch_3"
5645 [(prefetch (match_operand:SI 0 "address_operand" "p")
5646 (match_operand:SI 1 "const_int_operand" "n")
5647 (match_operand:SI 2 "const_int_operand" "n"))]
5650 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5651 if (INTVAL (operands[1]))
5652 return "prefetchw%U0 %0";
5654 return "prefetch%U0 %0";
5656 [(set_attr "type" "load")
5657 (set_attr "length" "8")])
5659 (define_insn "divsi3"
5660 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5661 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5662 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5665 [(set_attr "length" "4,4,8,4,4,4,8,8")
5666 (set_attr "iscompact" "false")
5667 (set_attr "type" "div_rem")
5668 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5669 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5672 (define_insn "udivsi3"
5673 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5674 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5675 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5678 [(set_attr "length" "4,4,8,4,4,4,8,8")
5679 (set_attr "iscompact" "false")
5680 (set_attr "type" "div_rem")
5681 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5682 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5685 (define_insn "modsi3"
5686 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5687 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5688 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5691 [(set_attr "length" "4,4,8,4,4,4,8,8")
5692 (set_attr "iscompact" "false")
5693 (set_attr "type" "div_rem")
5694 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5695 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5698 (define_insn "umodsi3"
5699 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5700 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5701 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5704 [(set_attr "length" "4,4,8,4,4,4,8,8")
5705 (set_attr "iscompact" "false")
5706 (set_attr "type" "div_rem")
5707 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5708 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5711 ;; SETcc instructions
5712 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5714 (define_insn "arcset<code>"
5715 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5716 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5717 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5718 "TARGET_V2 && TARGET_CODE_DENSITY"
5719 "set<code>%? %0, %1, %2"
5720 [(set_attr "length" "4,4,4,4,4,8,8")
5721 (set_attr "iscompact" "false")
5722 (set_attr "type" "compare")
5723 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5724 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5727 (define_insn "arcsetltu"
5728 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5729 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5730 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5731 "TARGET_V2 && TARGET_CODE_DENSITY"
5732 "setlo%? %0, %1, %2"
5733 [(set_attr "length" "4,4,4,4,4,8,8")
5734 (set_attr "iscompact" "false")
5735 (set_attr "type" "compare")
5736 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5737 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5740 (define_insn "arcsetgeu"
5741 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5742 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5743 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5744 "TARGET_V2 && TARGET_CODE_DENSITY"
5745 "seths%? %0, %1, %2"
5746 [(set_attr "length" "4,4,4,4,4,8,8")
5747 (set_attr "iscompact" "false")
5748 (set_attr "type" "compare")
5749 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5750 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5753 ;; Special cases of SETCC
5754 (define_insn_and_split "arcsethi"
5755 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5756 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5757 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5758 "TARGET_V2 && TARGET_CODE_DENSITY"
5759 "setlo%? %0, %2, %1"
5761 && CONST_INT_P (operands[2])
5762 && satisfies_constraint_C62 (operands[2])"
5765 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5766 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5767 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5770 [(set_attr "length" "4,4,4,8")
5771 (set_attr "iscompact" "false")
5772 (set_attr "type" "compare")
5773 (set_attr "predicable" "yes,no,no,no")
5774 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5777 (define_insn_and_split "arcsetls"
5778 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5779 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5780 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5781 "TARGET_V2 && TARGET_CODE_DENSITY"
5782 "seths%? %0, %2, %1"
5784 && CONST_INT_P (operands[2])
5785 && satisfies_constraint_C62 (operands[2])"
5788 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5789 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5790 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5793 [(set_attr "length" "4,4,4,8")
5794 (set_attr "iscompact" "false")
5795 (set_attr "type" "compare")
5796 (set_attr "predicable" "yes,no,no,no")
5797 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5800 ; Any mode that needs to be solved by secondary reload
5801 (define_mode_iterator SRI [QI HI])
5803 (define_expand "reload_<mode>_load"
5804 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5805 (match_operand:SRI 1 "memory_operand" "m")
5806 (match_operand:SI 2 "register_operand" "=&r")])]
5809 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5813 (define_expand "reload_<mode>_store"
5814 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5815 (match_operand:SRI 1 "register_operand" "r")
5816 (match_operand:SI 2 "register_operand" "=&r")])]
5819 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5824 (define_insn "extzvsi"
5825 [(set (match_operand:SI 0 "register_operand" "=r , r , r, r, r")
5826 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, 0, r")
5827 (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5828 (match_operand:SI 3 "const_int_operand" "i , i , i, i, i")))]
5829 "TARGET_HS && TARGET_BARREL_SHIFTER"
5831 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5832 operands[2] = GEN_INT (assemble_op2);
5833 return "xbfu%? %0,%1,%2";
5835 [(set_attr "type" "shift")
5836 (set_attr "iscompact" "false")
5837 (set_attr "length" "4,4,4,8,8")
5838 (set_attr "predicable" "yes,no,no,yes,no")
5839 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
5841 (define_insn "kflag"
5842 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5849 [(set_attr "length" "4,4,8")
5850 (set_attr "type" "misc,misc,misc")
5851 (set_attr "predicable" "yes,no,yes")
5852 (set_attr "cond" "clob,clob,clob")])
5855 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5856 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5860 [(set_attr "length" "4")
5861 (set_attr "type" "misc")])
5864 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5865 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5867 "TARGET_NORM && TARGET_V2"
5871 [(set_attr "length" "4,8")
5872 (set_attr "type" "two_cycle_core,two_cycle_core")])
5874 (define_insn "ffs_f"
5875 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5876 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5878 (set (reg:CC_ZN CC_REG)
5879 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5880 "TARGET_NORM && TARGET_V2"
5884 [(set_attr "length" "4,8")
5885 (set_attr "type" "two_cycle_core,two_cycle_core")])
5887 (define_expand "ffssi2"
5888 [(parallel [(set (match_dup 2)
5889 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5891 (set (reg:CC_ZN CC_REG)
5892 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5893 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5894 (set (match_operand:SI 0 "dest_reg_operand" "")
5895 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5898 "TARGET_NORM && TARGET_V2"
5900 operands[2] = gen_reg_rtx (SImode);
5904 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5905 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5907 "TARGET_NORM && TARGET_V2"
5911 [(set_attr "length" "4,8")
5912 (set_attr "type" "two_cycle_core,two_cycle_core")])
5915 [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5919 [(set_attr "length" "4")
5920 (set_attr "type" "misc")])
5925 (define_expand "addsf3"
5926 [(set (match_operand:SF 0 "register_operand" "")
5927 (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5928 (match_operand:SF 2 "nonmemory_operand" "")))]
5929 "TARGET_FP_SP_BASE || TARGET_SPFP"
5931 if (!register_operand (operands[1], SFmode)
5932 && !register_operand (operands[2], SFmode))
5933 operands[1] = force_reg (SFmode, operands[1]);
5937 (define_expand "subsf3"
5938 [(set (match_operand:SF 0 "register_operand" "")
5939 (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5940 (match_operand:SF 2 "nonmemory_operand" "")))]
5941 "TARGET_FP_SP_BASE || TARGET_SPFP"
5943 if (!register_operand (operands[1], SFmode)
5944 && !register_operand (operands[2], SFmode))
5945 operands[1] = force_reg (SFmode, operands[1]);
5949 (define_expand "mulsf3"
5950 [(set (match_operand:SF 0 "register_operand" "")
5951 (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5952 (match_operand:SF 2 "nonmemory_operand" "")))]
5953 "TARGET_FP_SP_BASE || TARGET_SPFP"
5955 if (!register_operand (operands[1], SFmode)
5956 && !register_operand (operands[2], SFmode))
5957 operands[1] = force_reg (SFmode, operands[1]);
5961 (define_expand "adddf3"
5962 [(set (match_operand:DF 0 "double_register_operand" "")
5963 (plus:DF (match_operand:DF 1 "double_register_operand" "")
5964 (match_operand:DF 2 "nonmemory_operand" "")))]
5965 "TARGET_FP_DP_BASE || TARGET_DPFP"
5969 if (GET_CODE (operands[2]) == CONST_DOUBLE)
5971 rtx first, second, tmp;
5972 split_double (operands[2], &first, &second);
5973 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5974 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5975 operands[2], tmp, const0_rtx));
5978 emit_insn (gen_adddf3_insn (operands[0], operands[1],
5979 operands[2], const1_rtx, const1_rtx));
5982 else if (TARGET_FP_DP_BASE)
5984 if (!even_register_operand (operands[2], DFmode))
5985 operands[2] = force_reg (DFmode, operands[2]);
5987 if (!even_register_operand (operands[1], DFmode))
5988 operands[1] = force_reg (DFmode, operands[1]);
5995 (define_expand "subdf3"
5996 [(set (match_operand:DF 0 "double_register_operand" "")
5997 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5998 (match_operand:DF 2 "nonmemory_operand" "")))]
5999 "TARGET_FP_DP_BASE || TARGET_DPFP"
6003 if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
6004 operands[1] = force_reg (DFmode, operands[1]);
6005 if ((GET_CODE (operands[1]) == CONST_DOUBLE)
6006 || GET_CODE (operands[2]) == CONST_DOUBLE)
6008 rtx first, second, tmp;
6009 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
6010 split_double (operands[const_index], &first, &second);
6011 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
6012 emit_insn (gen_subdf3_insn (operands[0], operands[1],
6013 operands[2], tmp, const0_rtx));
6016 emit_insn (gen_subdf3_insn (operands[0], operands[1],
6017 operands[2], const1_rtx, const1_rtx));
6020 else if (TARGET_FP_DP_BASE)
6022 if (!even_register_operand (operands[2], DFmode))
6023 operands[2] = force_reg (DFmode, operands[2]);
6025 if (!even_register_operand (operands[1], DFmode))
6026 operands[1] = force_reg (DFmode, operands[1]);
6033 (define_expand "muldf3"
6034 [(set (match_operand:DF 0 "double_register_operand" "")
6035 (mult:DF (match_operand:DF 1 "double_register_operand" "")
6036 (match_operand:DF 2 "nonmemory_operand" "")))]
6037 "TARGET_FP_DP_BASE || TARGET_DPFP"
6041 if (GET_CODE (operands[2]) == CONST_DOUBLE)
6043 rtx first, second, tmp;
6044 split_double (operands[2], &first, &second);
6045 tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
6046 emit_insn (gen_muldf3_insn (operands[0], operands[1],
6047 operands[2], tmp, const0_rtx));
6050 emit_insn (gen_muldf3_insn (operands[0], operands[1],
6051 operands[2], const1_rtx, const1_rtx));
6054 else if (TARGET_FP_DP_BASE)
6056 if (!even_register_operand (operands[2], DFmode))
6057 operands[2] = force_reg (DFmode, operands[2]);
6059 if (!even_register_operand (operands[1], DFmode))
6060 operands[1] = force_reg (DFmode, operands[1]);
6067 (define_expand "divsf3"
6068 [(set (match_operand:SF 0 "register_operand" "")
6069 (div:SF (match_operand:SF 1 "nonmemory_operand" "")
6070 (match_operand:SF 2 "nonmemory_operand" "")))]
6071 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
6073 if (TARGET_FPX_QUARK)
6075 operands[1] = force_reg (SFmode, operands[1]);
6076 operands[2] = force_reg (SFmode, operands[2]);
6080 if (!register_operand (operands[1], SFmode)
6081 && !register_operand (operands[2], SFmode))
6082 operands[1] = force_reg (SFmode, operands[1]);
6087 (define_expand "sqrtsf2"
6088 [(set (match_operand:SF 0 "register_operand" "")
6089 (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
6090 "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
6092 if (TARGET_FPX_QUARK)
6094 operands[1] = force_reg (SFmode, operands[1]);
6098 ;; SF->SI (using rounding towards zero)
6099 (define_expand "fix_truncsfsi2"
6100 [(set (match_operand:SI 0 "register_operand" "")
6101 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
6102 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
6106 (define_expand "floatsisf2"
6107 [(set (match_operand:SF 0 "register_operand" "")
6108 (float:SF (match_operand:SI 1 "register_operand" "")))]
6109 "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
6112 (define_expand "extzv"
6113 [(set (match_operand:SI 0 "register_operand" "")
6114 (zero_extract:SI (match_operand:SI 1 "register_operand" "")
6115 (match_operand:SI 2 "const_int_operand" "")
6116 (match_operand:SI 3 "const_int_operand" "")))]
6117 "TARGET_NPS_BITOPS")
6119 ; We need a sanity check in the instuction predicate because combine
6120 ; will throw any old rubbish at us and see what sticks.
6121 (define_insn "*extzv_i"
6122 [(set (match_operand:SI 0 "register_operand" "=Rrq")
6123 (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
6124 (match_operand:SI 2 "const_int_operand" "n")
6125 (match_operand:SI 3 "const_int_operand" "n")))]
6126 "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
6127 "movb.cl %0,%1,0,%3,%2"
6128 [(set_attr "type" "shift")
6129 (set_attr "length" "4")])
6131 (define_expand "insv"
6132 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
6133 (match_operand:SI 1 "const_int_operand" "")
6134 (match_operand:SI 2 "const_int_operand" ""))
6135 (match_operand:SI 3 "nonmemory_operand" ""))]
6138 int size = INTVAL (operands[1]);
6140 if (size != 1 && size != 2 && size != 4 && size != 8)
6141 operands[3] = force_reg (SImode, operands[3]);
6144 (define_insn "*insv_i"
6145 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
6146 (match_operand:SI 1 "const_int_operand" "C18,n")
6147 (match_operand:SI 2 "const_int_operand" "n,n"))
6148 (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
6150 && (register_operand (operands[3], SImode)
6151 || satisfies_constraint_C18 (operands[1]))"
6153 movbi %0,%0,%3,%2,%1
6154 movb %0,%0,%3,%2,0,%1"
6155 [(set_attr "type" "shift")
6156 (set_attr "length" "4")])
6158 (define_insn "*movb"
6159 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6160 (match_operand:SI 1 "const_int_operand" "n")
6161 (match_operand:SI 2 "const_int_operand" "n"))
6162 (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6164 (match_operand:SI 4 "const_int_operand" "n")))]
6166 "movb %0,%0,%3,%2,%4,%1"
6167 [(set_attr "type" "shift")
6168 (set_attr "length" "4")])
6170 (define_insn "*movb_signed"
6171 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6172 (match_operand:SI 1 "const_int_operand" "n")
6173 (match_operand:SI 2 "const_int_operand" "n"))
6174 (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6176 (match_operand:SI 4 "const_int_operand" "n")))]
6178 "movb %0,%0,%3,%2,%4,%1"
6179 [(set_attr "type" "shift")
6180 (set_attr "length" "4")])
6182 (define_insn "*movb_high"
6183 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6184 (match_operand:SI 1 "const_int_operand" "n")
6185 (match_operand:SI 2 "const_int_operand" "n"))
6186 (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6187 (match_operand:SI 4 "const_int_operand" "n")))]
6189 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6190 "movb %0,%0,%3,%2,%4,%1"
6191 [(set_attr "type" "shift")
6192 (set_attr "length" "4")])
6194 ; N.B.: when processing signed bitfields that fit in the top half of
6195 ; a word, gcc will use a narrow sign extending load, and in this case
6196 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6197 (define_insn "*movb_high_signed"
6198 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6199 (match_operand:SI 1 "const_int_operand" "n")
6200 (match_operand:SI 2 "const_int_operand" "n"))
6201 (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6202 (match_operand:SI 4 "const_int_operand" "n")))]
6204 && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6205 "movb %0,%0,%3,%2,%4,%1"
6206 [(set_attr "type" "shift")
6207 (set_attr "length" "4")])
6210 [(set (match_operand:SI 0 "register_operand" "")
6211 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6212 (match_operand:SI 2 "const_int_operand" ""))
6213 (subreg:SI (match_operand 3 "") 0)))]
6215 && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6216 && !reg_overlap_mentioned_p (operands[0], operands[1])"
6217 [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6218 (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6220 "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6222 (define_insn "*mrgb"
6223 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6224 (match_operand:SI 1 "const_int_operand" "n")
6225 (match_operand:SI 2 "const_int_operand" "n"))
6226 (zero_extract:SI (match_dup 0) (match_dup 1)
6227 (match_operand:SI 3 "const_int_operand" "n")))
6228 (set (zero_extract:SI (match_dup 0)
6229 (match_operand:SI 4 "const_int_operand" "n")
6230 (match_operand:SI 5 "const_int_operand" "n"))
6231 (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6233 (match_operand:SI 7 "const_int_operand" "n")))]
6236 output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6237 /* The ;%? updates the known unalignment. */
6238 return arc_short_long (insn, ";%?", "nop_s");
6240 [(set_attr "type" "shift")
6241 (set_attr "length" "6")
6242 (set_attr "iscompact" "true")])
6244 ;; combine fumbles combination of two movb patterns, and then the
6245 ;; combination is rejected by combinable_i3pat.
6246 ;; Thus, we can only use a peephole2 to combine two such insns.
6249 [(set (match_operand:SI 0 "register_operand" "")
6250 (match_operand:SI 1 "register_operand" ""))
6251 (set (zero_extract:SI (match_dup 0)
6252 (match_operand:SI 2 "const_int_operand" "")
6253 (match_operand:SI 3 "const_int_operand" ""))
6254 (zero_extract:SI (match_dup 1)
6256 (match_operand:SI 4 "const_int_operand" "")))
6257 (match_operand 9) ; unrelated insn scheduled here
6258 (set (zero_extract:SI (match_dup 0)
6259 (match_operand:SI 5 "const_int_operand" "")
6260 (match_operand:SI 6 "const_int_operand" ""))
6261 (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6263 (match_operand:SI 8 "const_int_operand" "")))]
6265 // Check that the second movb doesn't clobber an input of the extra insn.
6266 && !reg_overlap_mentioned_p (operands[0], operands[9])
6268 && !reg_set_p (operands[0], operands[9])
6269 && !reg_set_p (operands[7], operands[9])"
6270 [(set (match_dup 0) (match_dup 1))
6271 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6272 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6273 (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6274 (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6278 [(set (match_operand:SI 0 "register_operand" "")
6279 (match_operand:SI 1 "register_operand" ""))
6280 (set (zero_extract:SI (match_dup 0)
6281 (match_operand:SI 2 "const_int_operand" "")
6282 (match_operand:SI 3 "const_int_operand" ""))
6283 (zero_extract:SI (match_dup 1)
6285 (match_operand:SI 4 "const_int_operand" "")))
6286 (set (match_dup 1) (match_operand 8))
6287 (set (zero_extract:SI (match_dup 0)
6288 (match_operand:SI 5 "const_int_operand" "")
6289 (match_operand:SI 6 "const_int_operand" ""))
6290 (zero_extract:SI (match_dup 1) (match_dup 5)
6291 (match_operand:SI 7 "const_int_operand" "")))]
6293 && !reg_overlap_mentioned_p (operands[0], operands[8])"
6294 [(set (match_dup 0) (match_dup 1))
6295 (set (match_dup 1) (match_dup 8))
6296 (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6297 (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6298 (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6299 (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6302 (define_insn "*rotrsi3_cnt1"
6303 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
6304 (rotatert:SI (match_operand:SI 1 "register_operand" "c")
6308 [(set_attr "type" "shift")
6309 (set_attr "predicable" "no")
6310 (set_attr "length" "4")])
6312 (define_insn "*ashlsi2_cnt1"
6313 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6314 (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6318 [(set_attr "type" "shift")
6319 (set_attr "iscompact" "maybe,false")
6320 (set_attr "predicable" "no,no")])
6322 (define_insn "*lshrsi3_cnt1"
6323 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6324 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6328 [(set_attr "type" "shift")
6329 (set_attr "iscompact" "maybe,false")
6330 (set_attr "predicable" "no,no")])
6332 (define_insn "*ashrsi3_cnt1"
6333 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
6334 (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6338 [(set_attr "type" "shift")
6339 (set_attr "iscompact" "maybe,false")
6340 (set_attr "predicable" "no,no")])
6343 [(set (match_operand:SI 0 "register_operand" "")
6344 (zero_extract:SI (match_dup 0)
6345 (match_operand:SI 1 "const_int_operand" "")
6346 (match_operand:SI 2 "const_int_operand" "")))
6347 (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6352 && !reg_overlap_mentioned_p (operands[0], operands[3])"
6353 [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6354 (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6356 ;; Dummy pattern used as a place holder for automatically saved
6358 (define_insn "stack_irq_dwarf"
6359 [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6362 [(set_attr "length" "0")])
6364 ;; MAC and DMPY instructions
6365 (define_insn_and_split "maddsidi4"
6366 [(set (match_operand:DI 0 "register_operand" "=r")
6369 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6370 (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6371 (match_operand:DI 3 "register_operand" "r")))]
6374 "TARGET_PLUS_DMPY && reload_completed"
6377 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6378 emit_move_insn (acc_reg, operands[3]);
6379 if (TARGET_PLUS_MACD)
6380 emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6383 emit_insn (gen_mac (operands[1], operands[2]));
6384 emit_move_insn (operands[0], acc_reg);
6388 [(set_attr "type" "multi")
6389 (set_attr "length" "36")])
6392 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6395 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6396 (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
6397 (reg:DI ARCV2_ACC)))
6398 (set (reg:DI ARCV2_ACC)
6400 (mult:DI (sign_extend:DI (match_dup 1))
6401 (sign_extend:DI (match_dup 2)))
6402 (reg:DI ARCV2_ACC)))]
6405 [(set_attr "length" "4,4,8")
6406 (set_attr "type" "multi")
6407 (set_attr "predicable" "yes,no,no")
6408 (set_attr "cond" "canuse,nocond,nocond")])
6411 [(set (reg:DI ARCV2_ACC)
6413 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6414 (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6415 (reg:DI ARCV2_ACC)))]
6418 [(set_attr "length" "4,8")
6419 (set_attr "type" "multi")
6420 (set_attr "predicable" "no")
6421 (set_attr "cond" "nocond")])
6424 [(set (reg:DI ARCV2_ACC)
6426 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6427 (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6428 (reg:DI ARCV2_ACC)))
6429 (set (match_operand:SI 2 "register_operand" "")
6430 (match_operand:SI 3 "accl_operand" ""))]
6434 emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6438 (define_insn "mac_r"
6439 [(set (match_operand:SI 0 "register_operand" "=r,r")
6442 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6443 (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6444 (reg:DI ARCV2_ACC))))
6445 (clobber (reg:DI ARCV2_ACC))]
6448 [(set_attr "length" "4,8")
6449 (set_attr "type" "multi")
6450 (set_attr "predicable" "no")
6451 (set_attr "cond" "nocond")])
6453 (define_insn_and_split "umaddsidi4"
6454 [(set (match_operand:DI 0 "register_operand" "=r")
6457 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6458 (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6459 (match_operand:DI 3 "register_operand" "r")))]
6462 "TARGET_PLUS_DMPY && reload_completed"
6465 rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6466 emit_move_insn (acc_reg, operands[3]);
6467 if (TARGET_PLUS_MACD)
6468 emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6471 emit_insn (gen_macu (operands[1], operands[2]));
6472 emit_move_insn (operands[0], acc_reg);
6476 [(set_attr "type" "multi")
6477 (set_attr "length" "36")])
6479 (define_insn "macdu"
6480 [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r")
6483 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6484 (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
6485 (reg:DI ARCV2_ACC)))
6486 (set (reg:DI ARCV2_ACC)
6488 (mult:DI (zero_extend:DI (match_dup 1))
6489 (zero_extend:DI (match_dup 2)))
6490 (reg:DI ARCV2_ACC)))]
6493 [(set_attr "length" "4,4,8")
6494 (set_attr "type" "multi")
6495 (set_attr "predicable" "yes,no,no")
6496 (set_attr "cond" "canuse,nocond,nocond")])
6499 [(set (reg:DI ARCV2_ACC)
6501 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6502 (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6503 (reg:DI ARCV2_ACC)))]
6506 [(set_attr "length" "4,8")
6507 (set_attr "type" "multi")
6508 (set_attr "predicable" "no")
6509 (set_attr "cond" "nocond")])
6512 [(set (reg:DI ARCV2_ACC)
6514 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6515 (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6516 (reg:DI ARCV2_ACC)))
6517 (set (match_operand:SI 2 "register_operand" "")
6518 (match_operand:SI 3 "accl_operand" ""))]
6522 emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6526 (define_insn "macu_r"
6527 [(set (match_operand:SI 0 "register_operand" "=r,r")
6530 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6531 (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6532 (reg:DI ARCV2_ACC))))
6533 (clobber (reg:DI ARCV2_ACC))]
6536 [(set_attr "length" "4,8")
6537 (set_attr "type" "multi")
6538 (set_attr "predicable" "no")
6539 (set_attr "cond" "nocond")])
6541 (define_insn "mpyd_arcv2hs"
6542 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6543 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6544 (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6545 (set (reg:DI ARCV2_ACC)
6547 (sign_extend:DI (match_dup 1))
6548 (sign_extend:DI (match_dup 2))))]
6551 [(set_attr "length" "4,4")
6552 (set_attr "iscompact" "false")
6553 (set_attr "type" "multi")
6554 (set_attr "predicable" "yes,no")
6555 (set_attr "cond" "canuse,nocond")])
6557 (define_insn "mpyd_imm_arcv2hs"
6558 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6559 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6560 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6561 (set (reg:DI ARCV2_ACC)
6562 (mult:DI (sign_extend:DI (match_dup 1))
6566 [(set_attr "length" "4,4,4,8,8")
6567 (set_attr "iscompact" "false")
6568 (set_attr "type" "multi")
6569 (set_attr "predicable" "yes,no,no,yes,no")
6570 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6572 (define_insn "mpydu_arcv2hs"
6573 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r")
6574 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c"))
6575 (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c"))))
6576 (set (reg:DI ARCV2_ACC)
6577 (mult:DI (zero_extend:DI (match_dup 1))
6578 (zero_extend:DI (match_dup 2))))]
6581 [(set_attr "length" "4,4")
6582 (set_attr "iscompact" "false")
6583 (set_attr "type" "multi")
6584 (set_attr "predicable" "yes,no")
6585 (set_attr "cond" "canuse,nocond")])
6587 (define_insn "mpydu_imm_arcv2hs"
6588 [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r")
6589 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c"))
6590 (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal")))
6591 (set (reg:DI ARCV2_ACC)
6592 (mult:DI (zero_extend:DI (match_dup 1))
6596 [(set_attr "length" "4,4,4,8,8")
6597 (set_attr "iscompact" "false")
6598 (set_attr "type" "multi")
6599 (set_attr "predicable" "yes,no,no,yes,no")
6600 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6602 (define_insn "stack_tie"
6603 [(set (mem:BLK (scratch))
6604 (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
6605 (match_operand:SI 1 "register_operand" "rb")]
6606 UNSPEC_ARC_STKTIE))]
6609 [(set_attr "length" "0")
6610 (set_attr "iscompact" "false")
6611 (set_attr "type" "block")]
6614 ;; include the arc-FPX instructions
6617 ;; include the arc-FPU instructions
6620 (include "simdext.md")
6622 ;; include atomic extensions
6623 (include "atomic.md")