1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2016 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 ;; Profiling support and performance improvements by
13 ;; Joern Rennecke (joern.rennecke@embecosm.com)
15 ;; Support for DSP multiply instructions and mul64
16 ;; instructions for ARC600; and improvements in flag setting
18 ;; Muhammad Khurram Riaz (Khurram.Riaz@arc.com)
20 ;; This file is part of GCC.
22 ;; GCC is free software; you can redistribute it and/or modify
23 ;; it under the terms of the GNU General Public License as published by
24 ;; the Free Software Foundation; either version 3, or (at your option)
27 ;; GCC is distributed in the hope that it will be useful,
28 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
29 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 ;; GNU General Public License for more details.
32 ;; You should have received a copy of the GNU General Public License
33 ;; along with GCC; see the file COPYING3. If not see
34 ;; <http://www.gnu.org/licenses/>.
36 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
38 ;; <op> dest, src Two operand instruction's syntax
39 ;; <op> dest, src1, src2 Three operand instruction's syntax
41 ;; ARC and ARCompact PREDICATES:
43 ;; comparison_operator LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
44 ;; memory_operand memory [m]
45 ;; immediate_operand immediate constant [IKLMNOP]
46 ;; register_operand register [rq]
47 ;; general_operand register, memory, constant [rqmIKLMNOP]
49 ;; Note that the predicates are only used when selecting a pattern
50 ;; to determine if an operand is valid.
52 ;; The constraints then select which of the possible valid operands
53 ;; is present (and guide register selection). The actual assembly
54 ;; instruction is then selected on the basis of the constraints.
56 ;; ARC and ARCompact CONSTRAINTS:
58 ;; b stack pointer r28
59 ;; f frame pointer r27
60 ;; Rgp global pointer r26
61 ;; g general reg, memory, constant
64 ;; q registers commonly used in
65 ;; 16-bit insns r0-r3, r12-r15
66 ;; c core registers r0-r60, ap, pcl
67 ;; r general registers r0-r28, blink, ap, pcl
69 ;; H fp 16-bit constant
70 ;; I signed 12-bit immediate (for ARCompact)
71 ;; K unsigned 3-bit immediate (for ARCompact)
72 ;; L unsigned 6-bit immediate (for ARCompact)
73 ;; M unsinged 5-bit immediate (for ARCompact)
74 ;; O unsinged 7-bit immediate (for ARCompact)
75 ;; P unsinged 8-bit immediate (for ARCompact)
76 ;; N constant '1' (for ARCompact)
80 ;; -> prefetch instruction
82 ;; -----------------------------------------------------------------------------
84 ;; Include DFA scheduluers
85 (include ("arc600.md"))
86 (include ("arc700.md"))
87 (include ("arcEM.md"))
88 (include ("arcHS.md"))
92 (include ("predicates.md"))
93 (include ("constraints.md"))
94 ;; -----------------------------------------------------------------------------
98 ;; -----------------------------------------------------------------------------
99 ;; Symbolic name Value Desc.
100 ;; -----------------------------------------------------------------------------
101 ;; UNSPEC_PLT 3 symbol to be referenced through the PLT
102 ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT
103 ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the
104 ;; GOTBASE.(Referenced as @GOTOFF)
105 ;; ----------------------------------------------------------------------------
107 (define_c_enum "unspec" [
138 (define_c_enum "vunspec" [
145 VUNSPEC_ARC_CORE_READ
146 VUNSPEC_ARC_CORE_WRITE
155 VUNSPEC_ARC_STACK_IRQ
157 VUNSPEC_ARC_DEXCL_NORES
166 [(UNSPEC_PROF 18) ; profile callgraph counter
176 (RETURN_ADDR_REGNUM 31)
186 (define_attr "is_sfunc" "no,yes" (const_string "no"))
188 ;; Insn type. Used to default other attribute values.
189 ; While the attribute is_sfunc is set for any call of a special function,
190 ; the instruction type sfunc is used only for the special call sequence
191 ; that loads the (pc-relative) function address into r12 and then calls
195 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
196 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
197 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
198 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
199 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
200 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
201 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
202 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
203 simd_valign, simd_valign_with_acc, simd_vcontrol,
204 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem"
205 (cond [(eq_attr "is_sfunc" "yes")
206 (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
207 (match_test "flag_pic") (const_string "sfunc")]
208 (const_string "call_no_delay_slot"))]
209 (const_string "binary")))
211 ;; The following three attributes are mixed case so that they can be
212 ;; used conveniently with the CALL_ATTR macro.
213 (define_attr "is_CALL" "no,yes"
214 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
215 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
216 (const_string "no")))
218 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
220 (define_attr "is_NON_SIBCALL" "no,yes"
221 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
222 (eq_attr "is_CALL" "yes") (const_string "yes")]
223 (const_string "no")))
226 ;; Attribute describing the processor
227 (define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
228 (const (symbol_ref "arc_cpu_attr")))
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"
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 (const_string "yes")))
281 (define_attr "predicable" "no,yes" (const_string "no"))
282 ;; if 'predicable' were not so brain-dead, we would specify:
283 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
284 ;; (eq_attr "iscompact" "maybe") (const_string "no")]
285 ;; (const_string "yes"))
286 ;; and then for everything but calls, we could just set the cond attribute.
288 ;; Condition codes: this one is used by final_prescan_insn to speed up
289 ;; conditionalizing instructions. It saves having to scan the rtl to see if
290 ;; it uses or alters the condition codes.
292 ;; USE: This insn uses the condition codes (eg: a conditional branch).
293 ;; CANUSE: This insn can use the condition codes (for conditional execution).
294 ;; SET: All condition codes are set by this insn.
295 ;; SET_ZN: the Z and N flags are set by this insn.
296 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
297 ;; CLOB: The condition codes are set to unknown values by this insn.
298 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
300 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
302 [(and (eq_attr "predicable" "yes")
303 (eq_attr "is_sfunc" "no")
304 (eq_attr "delay_slot_filled" "no"))
305 (const_string "canuse")
307 (eq_attr "type" "call")
308 (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
309 (match_test "!flag_pic") (const_string "canuse_limm")]
310 (const_string "nocond"))
312 (eq_attr "iscompact" "maybe,false")
313 (cond [ (and (eq_attr "type" "move")
314 (match_operand 1 "immediate_operand" ""))
316 (ior (match_operand 1 "u6_immediate_operand" "")
317 (match_operand 1 "long_immediate_operand" ""))
318 (const_string "canuse")
319 (const_string "canuse_limm"))
321 (eq_attr "type" "binary")
322 (cond [(ne (symbol_ref "REGNO (operands[0])")
323 (symbol_ref "REGNO (operands[1])"))
324 (const_string "nocond")
325 (match_operand 2 "register_operand" "")
326 (const_string "canuse")
327 (match_operand 2 "u6_immediate_operand" "")
328 (const_string "canuse")
329 (match_operand 2 "long_immediate_operand" "")
330 (const_string "canuse")
331 (match_operand 2 "const_int_operand" "")
332 (const_string "canuse_limm")]
333 (const_string "nocond"))
335 (eq_attr "type" "compare")
338 (eq_attr "type" "cmove,branch")
341 (eq_attr "is_sfunc" "yes")
342 (cond [(match_test "(TARGET_MEDIUM_CALLS
343 && !TARGET_LONG_CALLS_SET
345 (const_string "canuse_limm_add")
346 (match_test "(TARGET_MEDIUM_CALLS
347 && !TARGET_LONG_CALLS_SET)")
348 (const_string "canuse_limm")]
349 (const_string "canuse"))
353 (const_string "nocond"))]
355 (cond [(eq_attr "type" "compare")
358 (eq_attr "type" "cmove,branch")
363 (const_string "nocond"))))
365 /* ??? Having all these patterns gives ifcvt more freedom to generate
366 inefficient code. It seem to operate on the premise that
367 register-register copies and registers are free. I see better code
368 with -fno-if-convert now than without. */
370 [(match_operator 0 "proper_comparison_operator"
371 [(reg CC_REG) (const_int 0)])]
375 ;; Length (in # of bytes, long immediate constants counted too).
376 ;; ??? There's a nasty interaction between the conditional execution fsm
377 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
378 (define_attr "length" ""
380 [(eq_attr "iscompact" "true,maybe")
382 [(eq_attr "type" "sfunc")
383 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
386 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)]
389 (eq_attr "iscompact" "true_limm")
392 (eq_attr "iscompact" "maybe_limm")
393 (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
396 (eq_attr "type" "load")
398 (match_operand 1 "long_immediate_loadstore_operand" "")
399 (const_int 8) (const_int 4))
401 (eq_attr "type" "store")
403 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
404 (match_operand 1 "immediate_operand" ""))
405 (const_int 8) (const_int 4))
407 (eq_attr "type" "move,unary")
409 [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
410 (match_operand 1 "register_operand" "") (const_int 4)
411 (match_operand 1 "long_immediate_operand" "") (const_int 8)
412 (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
415 (and (eq_attr "type" "shift")
416 (match_operand 1 "immediate_operand"))
418 (eq_attr "type" "binary,shift")
420 (ior (match_operand 2 "long_immediate_operand" "")
421 (and (ne (symbol_ref "REGNO (operands[0])")
422 (symbol_ref "REGNO (operands[1])"))
423 (eq (match_operand 2 "u6_immediate_operand" "")
426 (const_int 8) (const_int 4))
428 (eq_attr "type" "cmove")
429 (if_then_else (match_operand 1 "register_operand" "")
430 (const_int 4) (const_int 8))
432 (eq_attr "type" "call_no_delay_slot") (const_int 8)
438 ;; The length here is the length of a single asm. Unfortunately it might be
439 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
440 ;; lament asm's not being put in delay slots?
442 (define_asm_attributes
443 [(set_attr "length" "8")
444 (set_attr "type" "multi")
445 (set_attr "cond" "clob") ])
448 ;; The first two cond clauses and the default are necessary for correctness;
449 ;; the remaining cond clause is mainly an optimization, as otherwise nops
450 ;; would be inserted; however, if we didn't do this optimization, we would
451 ;; have to be more conservative in our length calculations.
453 (define_attr "in_delay_slot" "false,true"
454 (cond [(eq_attr "type" "uncond_branch,jump,branch,
455 call,sfunc,call_no_delay_slot,
456 brcc, brcc_no_delay_slot,loop_setup,loop_end")
457 (const_string "false")
458 (match_test "arc_write_ext_corereg (insn)")
459 (const_string "false")
460 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
461 next_active_insn (insn))")
462 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
463 + arc_hazard (insn, next_active_insn (insn)))"))
464 (const_string "false")
465 (eq_attr "iscompact" "maybe") (const_string "true")
468 (if_then_else (eq_attr "length" "2,4")
469 (const_string "true")
470 (const_string "false"))))
472 ; must not put an insn inside that refers to blink.
473 (define_attr "in_call_delay_slot" "false,true"
474 (cond [(eq_attr "in_delay_slot" "false")
475 (const_string "false")
476 (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
477 (const_string "false")]
478 (const_string "true")))
480 (define_attr "in_sfunc_delay_slot" "false,true"
481 (cond [(eq_attr "in_call_delay_slot" "false")
482 (const_string "false")
483 (match_test "arc_regno_use_in (12, PATTERN (insn))")
484 (const_string "false")]
485 (const_string "true")))
487 ;; Instructions that we can put into a delay slot and conditionalize.
488 (define_attr "cond_delay_insn" "no,yes"
489 (cond [(eq_attr "cond" "!canuse") (const_string "no")
490 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
492 (eq_attr "length" "2,4") (const_string "yes")]
493 (const_string "no")))
495 (define_attr "in_ret_delay_slot" "no,yes"
496 (cond [(eq_attr "in_delay_slot" "false")
498 (match_test "regno_clobbered_p
499 (arc_return_address_regs
500 [arc_compute_function_type (cfun)],
503 (const_string "yes")))
505 (define_attr "cond_ret_delay_insn" "no,yes"
506 (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
507 (eq_attr "cond_delay_insn" "no") (const_string "no")]
508 (const_string "yes")))
510 (define_attr "annul_ret_delay_insn" "no,yes"
511 (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
512 (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
513 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
514 (const_string "yes")]
515 (const_string "no")))
518 ;; Delay slot definition for ARCompact ISA
520 ;; When outputting an annul-true insn elegible for cond-exec
521 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
522 ;; for ARC600; we could also use this for ARC700 if the branch can't be
523 ;; unaligned and is at least somewhat likely (add parameter for this).
525 (define_delay (eq_attr "type" "call")
526 [(eq_attr "in_call_delay_slot" "true")
527 (eq_attr "in_call_delay_slot" "true")
530 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
531 (eq_attr "type" "brcc"))
532 [(eq_attr "in_delay_slot" "true")
533 (eq_attr "in_delay_slot" "true")
536 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
537 (eq_attr "type" "brcc"))
538 [(eq_attr "in_delay_slot" "true")
543 (eq_attr "type" "return")
544 [(eq_attr "in_ret_delay_slot" "yes")
545 (eq_attr "annul_ret_delay_insn" "yes")
546 (eq_attr "cond_ret_delay_insn" "yes")])
548 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
549 ;; non-taken case, so the only meaningful way to have an annull-true
550 ;; filled delay slot is to conditionalize the delay slot insn.
551 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
552 (eq_attr "type" "branch,uncond_branch,jump")
553 (match_test "!optimize_size"))
554 [(eq_attr "in_delay_slot" "true")
555 (eq_attr "cond_delay_insn" "yes")
556 (eq_attr "cond_delay_insn" "yes")])
558 ;; For ARC700, anything goes for annulled-true insns, since there is no
559 ;; penalty for the unexposed delay slot when the branch is not taken,
560 ;; however, we must avoid things that have a delay slot themselvese to
561 ;; avoid confusing gcc.
562 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
563 (eq_attr "type" "branch,uncond_branch,jump")
564 (match_test "!optimize_size"))
565 [(eq_attr "in_delay_slot" "true")
566 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
567 (eq_attr "cond_delay_insn" "yes")])
569 ;; -mlongcall -fpic sfuncs use r12 to load the function address
570 (define_delay (eq_attr "type" "sfunc")
571 [(eq_attr "in_sfunc_delay_slot" "true")
572 (eq_attr "in_sfunc_delay_slot" "true")
574 ;; ??? need to use a working strategy for canuse_limm:
575 ;; - either canuse_limm is not eligible for delay slots, and has no
576 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
577 ;; somehow modify them to become inelegible for delay slots if a decision
578 ;; is made that makes conditional execution required.
580 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
582 (cond [(symbol_ref "arc_tune == TUNE_ARC600")
583 (const_string "arc600")
584 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
585 (const_string "arc700_4_2_std")
586 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
587 (const_string "arc700_4_2_xmac")]
588 (const_string "none"))))
590 (define_attr "tune_arc700" "false,true"
591 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
592 (const_string "true")
593 (const_string "false")))
595 ;; Move instructions.
596 (define_expand "movqi"
597 [(set (match_operand:QI 0 "move_dest_operand" "")
598 (match_operand:QI 1 "general_operand" ""))]
600 "if (prepare_move_operands (operands, QImode)) DONE;")
602 ; In order to allow the ccfsm machinery to do its work, the leading compact
603 ; alternatives say 'canuse' - there is another alternative that will match
604 ; when the condition codes are used.
605 ; Rcq won't match if the condition is actually used; to avoid a spurious match
606 ; via q, q is inactivated as constraint there.
607 ; Likewise, the length of an alternative that might be shifted to conditional
608 ; execution must reflect this, lest out-of-range branches are created.
609 ; The iscompact attribute allows the epilogue expander to know for which
610 ; insns it should lengthen the return insn.
611 (define_insn "*movqi_insn"
612 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
613 (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
614 "register_operand (operands[0], QImode)
615 || register_operand (operands[1], QImode)"
630 [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
631 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
632 (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no")
633 (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*")])
635 (define_expand "movhi"
636 [(set (match_operand:HI 0 "move_dest_operand" "")
637 (match_operand:HI 1 "general_operand" ""))]
639 "if (prepare_move_operands (operands, HImode)) DONE;")
641 (define_insn "*movhi_insn"
642 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
643 (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac, ?i,?i,T,Rcq,m,c,?Rac,i"))]
644 "register_operand (operands[0], HImode)
645 || register_operand (operands[1], HImode)
646 || (CONSTANT_P (operands[1])
647 /* Don't use a LIMM that we could load with a single insn - we loose
648 delay-slot filling opportunities. */
649 && !satisfies_constraint_I (operands[1])
650 && satisfies_constraint_Usc (operands[0]))"
666 [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
667 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
668 (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no")
669 (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*")])
671 (define_expand "movsi"
672 [(set (match_operand:SI 0 "move_dest_operand" "")
673 (match_operand:SI 1 "general_operand" ""))]
675 "if (prepare_move_operands (operands, SImode)) DONE;")
677 ; In order to allow the ccfsm machinery to do its work, the leading compact
678 ; alternatives say 'canuse' - there is another alternative that will match
679 ; when the condition codes are used.
680 ; Rcq won't match if the condition is actually used; to avoid a spurious match
681 ; via q, q is inactivated as constraint there.
682 ; Likewise, the length of an alternative that might be shifted to conditional
683 ; execution must reflect this, lest out-of-range branches are created.
684 ; the iscompact attribute allows the epilogue expander to know for which
685 ; insns it should lengthen the return insn.
686 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
687 (define_insn "*movsi_insn"
688 [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,m,???m,VUsc")
689 (match_operand:SI 1 "move_src_operand" " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))]
690 "register_operand (operands[0], SImode)
691 || register_operand (operands[1], SImode)
692 || (CONSTANT_P (operands[1])
693 /* Don't use a LIMM that we could load with a single insn - we loose
694 delay-slot filling opportunities. */
695 && !satisfies_constraint_I (operands[1])
696 && satisfies_constraint_Usc (operands[0]))"
703 ror %0,((%1*2+1) & 0x3f) ;5
706 * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
711 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
712 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
718 [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store")
719 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
720 ; Use default length for iscompact to allow for COND_EXEC. But set length
722 (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
723 (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no")
724 (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
726 ;; Sometimes generated by the epilogue code. We don't want to
727 ;; recognize these addresses in general, because the limm is costly,
728 ;; and we can't use them for stores. */
729 (define_insn "*movsi_pre_mod"
730 [(set (match_operand:SI 0 "register_operand" "=w")
733 (plus:SI (reg:SI SP_REG)
734 (match_operand 1 "immediate_operand" "Cal")))))]
737 [(set_attr "type" "load")
738 (set_attr "length" "8")])
740 ;; Store a value to directly to memory. The location might also be cached.
741 ;; Since the cached copy can cause a write-back at unpredictable times,
742 ;; we first write cached, then we write uncached.
743 (define_insn "store_direct"
744 [(set (match_operand:SI 0 "move_dest_operand" "=m")
745 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
748 "st%U0 %1,%0\;st%U0.di %1,%0"
749 [(set_attr "type" "store")])
751 (define_insn_and_split "*movsi_set_cc_insn"
752 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
753 (match_operator:CC_ZN 3 "zn_compare_operator"
754 [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
755 (set (match_operand:SI 0 "register_operand" "=w,w,w")
759 ; splitting to 'tst' allows short insns and combination into brcc.
760 "reload_completed && operands_match_p (operands[0], operands[1])"
761 [(set (match_dup 2) (match_dup 3))]
763 [(set_attr "type" "compare")
764 (set_attr "predicable" "no,yes,yes")
765 (set_attr "cond" "set_zn")
766 (set_attr "length" "4,4,8")])
768 (define_insn "unary_comparison"
769 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
770 (match_operator:CC_ZN 3 "zn_compare_operator"
771 [(match_operator:SI 2 "unary_operator"
772 [(match_operand:SI 1 "register_operand" "c")])
776 [(set_attr "type" "compare")
777 (set_attr "cond" "set_zn")])
780 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
781 (define_insn "*unary_comparison_result_used"
782 [(set (match_operand 2 "cc_register" "")
783 (match_operator 4 "zn_compare_operator"
784 [(match_operator:SI 3 "unary_operator"
785 [(match_operand:SI 1 "register_operand" "c")])
787 (set (match_operand:SI 0 "register_operand" "=w")
791 [(set_attr "type" "compare")
792 (set_attr "cond" "set_zn")
793 (set_attr "length" "4")])
797 (match_operand 0 "cc_register" "")
798 (match_operator 3 "zn_compare_operator"
800 (match_operand:SI 1 "register_operand"
801 "%Rcq,Rcq, c, c, c, c, c, c")
802 (match_operand:SI 2 "nonmemory_operand"
803 " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal"))
805 "(register_operand (operands[1], SImode)
806 && nonmemory_operand (operands[2], SImode))
807 || (memory_operand (operands[1], SImode)
808 && satisfies_constraint_Cux (operands[2]))"
810 switch (which_alternative)
812 case 0: case 2: case 3: case 7:
813 return \"tst%? %1,%2\";
815 return \"btst%? %1,%z2\";
817 return \"bmsk%?.f 0,%1,%Z2%&\";
819 return \"bclr%?.f 0,%1,%M2%&\";
821 return \"bic%?.f 0,%1,%n2-1\";
826 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
827 (set_attr "type" "compare")
828 (set_attr "length" "*,*,4,4,4,4,4,8")
829 (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
830 (set_attr "cond" "set_zn")])
832 (define_insn "*commutative_binary_comparison"
833 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
834 (match_operator:CC_ZN 5 "zn_compare_operator"
835 [(match_operator:SI 4 "commutative_operator"
836 [(match_operand:SI 1 "register_operand" "%c,c,c")
837 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
839 (clobber (match_scratch:SI 3 "=X,1,X"))]
842 [(set_attr "type" "compare")
843 (set_attr "cond" "set_zn")
844 (set_attr "length" "4,4,8")])
846 ; for flag setting 'add' instructions like if (a+b) { ...}
847 ; the combiner needs this pattern
848 (define_insn "*addsi_compare"
849 [(set (reg:CC_ZN CC_REG)
850 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
851 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
854 [(set_attr "cond" "set")
855 (set_attr "type" "compare")
856 (set_attr "length" "4")])
858 ; for flag setting 'add' instructions like if (a+b < a) { ...}
859 ; the combiner needs this pattern
860 (define_insn "addsi_compare_2"
861 [(set (reg:CC_C CC_REG)
862 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
863 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
867 [(set_attr "cond" "set")
868 (set_attr "type" "compare")
869 (set_attr "length" "4,8")])
871 (define_insn "*addsi_compare_3"
872 [(set (reg:CC_C CC_REG)
873 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
874 (match_operand:SI 1 "register_operand" "c"))
878 [(set_attr "cond" "set")
879 (set_attr "type" "compare")
880 (set_attr "length" "4")])
882 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
883 (define_insn "*commutative_binary_comparison_result_used"
884 [(set (match_operand 3 "cc_register" "")
885 (match_operator 5 "zn_compare_operator"
886 ; We can accept any commutative operator except mult because
887 ; our 'w' class below could try to use LP_COUNT.
888 [(match_operator:SI 4 "commutative_operator_sans_mult"
889 [(match_operand:SI 1 "register_operand" "c,0,c")
890 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
892 (set (match_operand:SI 0 "register_operand" "=w,w,w")
895 "%O4.f %0,%1,%2 ; non-mult commutative"
896 [(set_attr "type" "compare,compare,compare")
897 (set_attr "cond" "set_zn,set_zn,set_zn")
898 (set_attr "length" "4,4,8")])
900 ; a MULT-specific version of this pattern to avoid touching the
902 (define_insn "*commutative_binary_mult_comparison_result_used"
903 [(set (match_operand 3 "cc_register" "")
904 (match_operator 5 "zn_compare_operator"
905 [(match_operator:SI 4 "mult_operator"
906 [(match_operand:SI 1 "register_operand" "c,0,c")
907 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
909 ; Make sure to use the W class to not touch LP_COUNT.
910 (set (match_operand:SI 0 "register_operand" "=W,W,W")
912 "!TARGET_ARC600_FAMILY"
913 "%O4.f %0,%1,%2 ; mult commutative"
914 [(set_attr "type" "compare,compare,compare")
915 (set_attr "cond" "set_zn,set_zn,set_zn")
916 (set_attr "length" "4,4,8")])
918 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
919 (define_insn "*noncommutative_binary_comparison_result_used"
920 [(set (match_operand 3 "cc_register" "")
921 (match_operator 5 "zn_compare_operator"
922 [(match_operator:SI 4 "noncommutative_operator"
923 [(match_operand:SI 1 "register_operand" "c,0,c")
924 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
926 (set (match_operand:SI 0 "register_operand" "=w,w,w")
928 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
930 [(set_attr "type" "compare,compare,compare")
931 (set_attr "cond" "set_zn,set_zn,set_zn")
932 (set_attr "length" "4,4,8")])
934 (define_insn "*noncommutative_binary_comparison"
935 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
936 (match_operator:CC_ZN 5 "zn_compare_operator"
937 [(match_operator:SI 4 "noncommutative_operator"
938 [(match_operand:SI 1 "register_operand" "c,c,c")
939 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
941 (clobber (match_scratch:SI 3 "=X,1,X"))]
942 "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
944 [(set_attr "type" "compare")
945 (set_attr "cond" "set_zn")
946 (set_attr "length" "4,4,8")])
948 (define_expand "bic_f_zn"
950 [(set (reg:CC_ZN CC_REG)
952 (and:SI (match_operand:SI 1 "register_operand" "")
953 (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
955 (set (match_operand:SI 0 "register_operand" "")
956 (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
959 (define_insn "*bic_f"
960 [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
961 (match_operator 4 "zn_compare_operator"
962 [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
964 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
966 (set (match_operand:SI 0 "register_operand" "=w,w,w")
967 (and:SI (match_dup 1) (not:SI (match_dup 2))))]
970 [(set_attr "type" "compare,compare,compare")
971 (set_attr "cond" "set_zn,set_zn,set_zn")
972 (set_attr "length" "4,4,8")])
974 (define_expand "movdi"
975 [(set (match_operand:DI 0 "move_dest_operand" "")
976 (match_operand:DI 1 "general_operand" ""))]
980 /* Everything except mem = const or mem = mem can be done easily. */
982 if (GET_CODE (operands[0]) == MEM)
983 operands[1] = force_reg (DImode, operands[1]);
986 (define_insn_and_split "*movdi_insn"
987 [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m")
988 (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
989 "register_operand (operands[0], DImode)
990 || register_operand (operands[1], DImode)"
993 switch (which_alternative)
1000 && ((even_register_operand (operands[0], DImode)
1001 && memory_operand (operands[1], DImode))
1002 || (memory_operand (operands[0], DImode)
1003 && even_register_operand (operands[1], DImode))))
1004 return \"ldd%U1%V1 %0,%1%&\";
1009 && ((even_register_operand (operands[0], DImode)
1010 && memory_operand (operands[1], DImode))
1011 || (memory_operand (operands[0], DImode)
1012 && even_register_operand (operands[1], DImode))))
1013 return \"std%U0%V0 %1,%0\";
1020 arc_split_move (operands);
1023 [(set_attr "type" "move,move,load,store")
1024 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1025 (set_attr "length" "8,16,*,*")])
1028 ;; Floating point move insns.
1030 (define_expand "movsf"
1031 [(set (match_operand:SF 0 "general_operand" "")
1032 (match_operand:SF 1 "general_operand" ""))]
1034 "if (prepare_move_operands (operands, SFmode)) DONE;")
1036 (define_insn "*movsf_insn"
1037 [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
1038 (match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
1039 "register_operand (operands[0], SFmode)
1040 || register_operand (operands[1], SFmode)"
1046 [(set_attr "type" "move,move,load,store")
1047 (set_attr "predicable" "yes,yes,no,no")])
1049 (define_expand "movdf"
1050 [(set (match_operand:DF 0 "nonimmediate_operand" "")
1051 (match_operand:DF 1 "general_operand" ""))]
1053 "if (prepare_move_operands (operands, DFmode)) DONE;")
1055 (define_insn_and_split "*movdf_insn"
1056 [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
1057 (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1058 "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1061 switch (which_alternative)
1067 && ((even_register_operand (operands[0], DFmode)
1068 && memory_operand (operands[1], DFmode))
1069 || (memory_operand (operands[0], DFmode)
1070 && even_register_operand (operands[1], DFmode))))
1071 return \"ldd%U1%V1 %0,%1%&\";
1076 && ((even_register_operand (operands[0], DFmode)
1077 && memory_operand (operands[1], DFmode))
1078 || (memory_operand (operands[0], DFmode)
1079 && even_register_operand (operands[1], DFmode))))
1080 return \"std%U0%V0 %1,%0\";
1087 arc_split_move (operands);
1090 [(set_attr "type" "move,move,move,move,load,store")
1091 (set_attr "predicable" "no,no,yes,yes,no,no")
1092 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1093 (set_attr "length" "4,16,8,16,16,16")])
1095 (define_insn_and_split "*movdf_insn_nolrsr"
1096 [(set (match_operand:DF 0 "register_operand" "=r")
1097 (match_operand:DF 1 "arc_double_register_operand" "D"))
1098 (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1100 "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1105 (set (match_dup 0) (match_dup 3))
1107 ; daddh?? r1, r0, r0
1109 (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1112 (use (match_dup 0)) ; used to block can_combine_p
1113 (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1116 ; We have to do this twice, once to read the value into R0 and
1117 ; second time to put back the contents which the first DEXCLx
1118 ; will have overwritten
1120 (set (match_dup 4) ; aka r0result
1122 (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL ))
1123 ; Generate the second, which makes sure operand5 and operand4 values
1124 ; are put back in the Dx register properly.
1125 (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL_NORES )
1127 ; Note: we cannot use a (clobber (match_scratch)) here because
1128 ; the combine pass will end up replacing uses of it with 0
1130 "operands[3] = CONST0_RTX (DFmode);
1131 operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1132 operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1133 [(set_attr "type" "move")])
1135 ;; Load/Store with update instructions.
1137 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1138 ;; hardware can also do cases where the increment is not the size of the
1141 ;; In all these cases, we use operands 0 and 1 for the register being
1142 ;; incremented because those are the operands that local-alloc will
1143 ;; tie and these are the pair most likely to be tieable (and the ones
1144 ;; that will benefit the most).
1146 ;; We use match_operator here because we need to know whether the memory
1147 ;; object is volatile or not.
1150 ;; Note: loadqi_update has no 16-bit variant
1151 (define_insn "*loadqi_update"
1152 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1153 (match_operator:QI 4 "any_mem_operand"
1154 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1155 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
1156 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1157 (plus:SI (match_dup 1) (match_dup 2)))]
1159 "ldb.a%V4 %3,[%0,%S2]"
1160 [(set_attr "type" "load,load")
1161 (set_attr "length" "4,8")])
1163 (define_insn "*load_zeroextendqisi_update"
1164 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1165 (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1166 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1167 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
1168 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1169 (plus:SI (match_dup 1) (match_dup 2)))]
1171 "ldb.a%V4 %3,[%0,%S2]"
1172 [(set_attr "type" "load,load")
1173 (set_attr "length" "4,8")])
1175 (define_insn "*load_signextendqisi_update"
1176 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1177 (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1178 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1179 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
1180 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1181 (plus:SI (match_dup 1) (match_dup 2)))]
1183 "ldb.x.a%V4 %3,[%0,%S2]"
1184 [(set_attr "type" "load,load")
1185 (set_attr "length" "4,8")])
1187 (define_insn "*storeqi_update"
1188 [(set (match_operator:QI 4 "any_mem_operand"
1189 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1190 (match_operand:SI 2 "short_immediate_operand" "I"))])
1191 (match_operand:QI 3 "register_operand" "c"))
1192 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1193 (plus:SI (match_dup 1) (match_dup 2)))]
1195 "stb.a%V4 %3,[%0,%2]"
1196 [(set_attr "type" "store")
1197 (set_attr "length" "4")])
1199 ;; ??? pattern may have to be re-written
1200 ;; Note: no 16-bit variant for this pattern
1201 (define_insn "*loadhi_update"
1202 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1203 (match_operator:HI 4 "any_mem_operand"
1204 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1205 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
1206 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1207 (plus:SI (match_dup 1) (match_dup 2)))]
1209 "ld%_.a%V4 %3,[%0,%S2]"
1210 [(set_attr "type" "load,load")
1211 (set_attr "length" "4,8")])
1213 (define_insn "*load_zeroextendhisi_update"
1214 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1215 (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1216 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1217 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
1218 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1219 (plus:SI (match_dup 1) (match_dup 2)))]
1221 "ld%_.a%V4 %3,[%0,%S2]"
1222 [(set_attr "type" "load,load")
1223 (set_attr "length" "4,8")])
1225 ;; Note: no 16-bit variant for this instruction
1226 (define_insn "*load_signextendhisi_update"
1227 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1228 (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1229 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1230 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
1231 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1232 (plus:SI (match_dup 1) (match_dup 2)))]
1234 "ld%_.x.a%V4 %3,[%0,%S2]"
1235 [(set_attr "type" "load,load")
1236 (set_attr "length" "4,8")])
1238 (define_insn "*storehi_update"
1239 [(set (match_operator:HI 4 "any_mem_operand"
1240 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1241 (match_operand:SI 2 "short_immediate_operand" "I"))])
1242 (match_operand:HI 3 "register_operand" "c"))
1243 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1244 (plus:SI (match_dup 1) (match_dup 2)))]
1246 "st%_.a%V4 %3,[%0,%2]"
1247 [(set_attr "type" "store")
1248 (set_attr "length" "4")])
1250 ;; No 16-bit variant for this instruction pattern
1251 (define_insn "*loadsi_update"
1252 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1253 (match_operator:SI 4 "any_mem_operand"
1254 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1255 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
1256 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1257 (plus:SI (match_dup 1) (match_dup 2)))]
1259 "ld.a%V4 %3,[%0,%S2]"
1260 [(set_attr "type" "load,load")
1261 (set_attr "length" "4,8")])
1263 (define_insn "*storesi_update"
1264 [(set (match_operator:SI 4 "any_mem_operand"
1265 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1266 (match_operand:SI 2 "short_immediate_operand" "I"))])
1267 (match_operand:SI 3 "register_operand" "c"))
1268 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1269 (plus:SI (match_dup 1) (match_dup 2)))]
1271 "st.a%V4 %3,[%0,%2]"
1272 [(set_attr "type" "store")
1273 (set_attr "length" "4")])
1275 (define_insn "*loadsf_update"
1276 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1277 (match_operator:SF 4 "any_mem_operand"
1278 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1279 (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
1280 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1281 (plus:SI (match_dup 1) (match_dup 2)))]
1283 "ld.a%V4 %3,[%0,%S2]"
1284 [(set_attr "type" "load,load")
1285 (set_attr "length" "4,8")])
1287 (define_insn "*storesf_update"
1288 [(set (match_operator:SF 4 "any_mem_operand"
1289 [(plus:SI (match_operand:SI 1 "register_operand" "0")
1290 (match_operand:SI 2 "short_immediate_operand" "I"))])
1291 (match_operand:SF 3 "register_operand" "c"))
1292 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1293 (plus:SI (match_dup 1) (match_dup 2)))]
1295 "st.a%V4 %3,[%0,%2]"
1296 [(set_attr "type" "store")
1297 (set_attr "length" "4")])
1299 ;; Conditional move instructions.
1301 (define_expand "movsicc"
1302 [(set (match_operand:SI 0 "dest_reg_operand" "")
1303 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1304 (match_operand:SI 2 "nonmemory_operand" "")
1305 (match_operand:SI 3 "register_operand" "")))]
1307 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1310 (define_expand "movdicc"
1311 [(set (match_operand:DI 0 "dest_reg_operand" "")
1312 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1313 (match_operand:DI 2 "nonmemory_operand" "")
1314 (match_operand:DI 3 "register_operand" "")))]
1316 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1319 (define_expand "movsfcc"
1320 [(set (match_operand:SF 0 "dest_reg_operand" "")
1321 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1322 (match_operand:SF 2 "nonmemory_operand" "")
1323 (match_operand:SF 3 "register_operand" "")))]
1325 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1327 (define_expand "movdfcc"
1328 [(set (match_operand:DF 0 "dest_reg_operand" "")
1329 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1330 (match_operand:DF 2 "nonmemory_operand" "")
1331 (match_operand:DF 3 "register_operand" "")))]
1333 "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1335 (define_insn "*movsicc_insn"
1336 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1337 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1338 [(match_operand 4 "cc_register" "") (const_int 0)])
1339 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1340 (match_operand:SI 2 "register_operand" "0,0")))]
1343 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1344 && satisfies_constraint_Rcq (operands[0]))
1345 return "sub%?.ne %0,%0,%0";
1346 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1347 if ((optimize_size && (!TARGET_ARC600_FAMILY))
1348 && rtx_equal_p (operands[1], constm1_rtx)
1349 && GET_CODE (operands[3]) == LTU)
1350 return "sbc.cs %0,%0,%0";
1351 return "mov.%d3 %0,%S1";
1353 [(set_attr "type" "cmove,cmove")
1354 (set_attr "length" "4,8")])
1356 ; Try to generate more short moves, and/or less limms, by substituting a
1357 ; conditional move with a conditional sub.
1359 [(set (match_operand:SI 0 "compact_register_operand")
1360 (match_operand:SI 1 "const_int_operand"))
1362 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1363 [(match_operand 4 "cc_register" "") (const_int 0)])
1364 (match_operand:SI 2 "const_int_operand" "")
1366 "!satisfies_constraint_P (operands[1])
1367 && satisfies_constraint_P (operands[2])
1368 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1369 [(set (match_dup 0) (match_dup 2))
1373 (plus:SI (match_dup 0) (match_dup 1))))]
1374 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1375 GET_MODE (operands[4])),
1376 VOIDmode, operands[4], const0_rtx);
1377 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1379 (define_insn "*movdicc_insn"
1380 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1381 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1382 [(match_operand 4 "cc_register" "") (const_int 0)])
1383 (match_operand:DI 1 "nonmemory_operand" "c,i")
1384 (match_operand:DI 2 "register_operand" "0,0")))]
1388 switch (which_alternative)
1392 /* We normally copy the low-numbered register first. However, if
1393 the first register operand 0 is the same as the second register of
1394 operand 1, we must copy in the opposite order. */
1395 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1396 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1398 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1400 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1405 [(set_attr "type" "cmove,cmove")
1406 (set_attr "length" "8,16")])
1409 (define_insn "*movsfcc_insn"
1410 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1411 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1412 [(match_operand 4 "cc_register" "") (const_int 0)])
1413 (match_operand:SF 1 "nonmemory_operand" "c,E")
1414 (match_operand:SF 2 "register_operand" "0,0")))]
1418 mov.%d3 %0,%1 ; %A1"
1419 [(set_attr "type" "cmove,cmove")])
1421 (define_insn "*movdfcc_insn"
1422 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1423 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1424 [(match_operand 4 "cc_register" "") (const_int 0)])
1425 (match_operand:DF 2 "nonmemory_operand" "c,E")
1426 (match_operand:DF 3 "register_operand" "0,0")))]
1430 switch (which_alternative)
1434 /* We normally copy the low-numbered register first. However, if
1435 the first register operand 0 is the same as the second register of
1436 operand 1, we must copy in the opposite order. */
1437 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1438 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1440 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1442 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1446 [(set_attr "type" "cmove,cmove")
1447 (set_attr "length" "8,16")])
1450 (define_insn "*zero_extendqihi2_i"
1451 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
1452 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
1460 [(set_attr "type" "unary,unary,unary,unary,load")
1461 (set_attr "iscompact" "maybe,true,false,false,false")
1462 (set_attr "predicable" "no,no,yes,no,no")])
1464 (define_expand "zero_extendqihi2"
1465 [(set (match_operand:HI 0 "dest_reg_operand" "")
1466 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1468 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1471 (define_insn "*zero_extendqisi2_ac"
1472 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
1473 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
1483 [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1484 (set_attr "iscompact" "maybe,true,false,false,true,true,false")
1485 (set_attr "predicable" "no,no,yes,no,no,no,no")])
1487 (define_expand "zero_extendqisi2"
1488 [(set (match_operand:SI 0 "dest_reg_operand" "")
1489 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1491 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1494 (define_insn "*zero_extendhisi2_i"
1495 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
1496 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
1506 [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1507 (set_attr "iscompact" "maybe,true,false,false,true,false,false")
1508 (set_attr "predicable" "no,no,yes,no,no,no,no")])
1511 (define_expand "zero_extendhisi2"
1512 [(set (match_operand:SI 0 "dest_reg_operand" "")
1513 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1515 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1518 ;; Sign extension instructions.
1520 (define_insn "*extendqihi2_i"
1521 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
1522 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
1528 [(set_attr "type" "unary,unary,load")
1529 (set_attr "iscompact" "true,false,false")])
1532 (define_expand "extendqihi2"
1533 [(set (match_operand:HI 0 "dest_reg_operand" "")
1534 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1536 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1539 (define_insn "*extendqisi2_ac"
1540 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1541 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1547 [(set_attr "type" "unary,unary,load")
1548 (set_attr "iscompact" "true,false,false")])
1550 (define_expand "extendqisi2"
1551 [(set (match_operand:SI 0 "dest_reg_operand" "")
1552 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1554 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1557 (define_insn "*extendhisi2_i"
1558 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1559 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1565 [(set_attr "type" "unary,unary,load")
1566 (set_attr "iscompact" "true,false,false")])
1568 (define_expand "extendhisi2"
1569 [(set (match_operand:SI 0 "dest_reg_operand" "")
1570 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1572 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1575 ;; Unary arithmetic insns
1577 ;; We allow constant operands to enable late constant propagation, but it is
1578 ;; not worth while to have more than one dedicated alternative to output them -
1579 ;; if we are really worried about getting these the maximum benefit of all
1580 ;; the available alternatives, we should add an extra pass to fold such
1581 ;; operations to movsi.
1583 ;; Absolute instructions
1585 (define_insn "*abssi2_mixed"
1586 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1587 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1590 [(set_attr "type" "two_cycle_core")
1591 (set_attr "iscompact" "true")])
1593 (define_insn "abssi2"
1594 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1595 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1598 [(set_attr "type" "two_cycle_core")
1599 (set_attr "length" "*,4,8")
1600 (set_attr "iscompact" "true,false,false")])
1602 ;; Maximum and minimum insns
1604 (define_insn "smaxsi3"
1605 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1606 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1607 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1610 [(set_attr "type" "two_cycle_core")
1611 (set_attr "length" "4,4,8")
1612 (set_attr "predicable" "yes,no,no")]
1615 (define_insn "sminsi3"
1616 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1617 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1618 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1621 [(set_attr "type" "two_cycle_core")
1622 (set_attr "length" "4,4,8")
1623 (set_attr "predicable" "yes,no,no")]
1626 ;; Arithmetic instructions.
1628 ; We say an insn can be conditionalized if this doesn't introduce a long
1629 ; immediate. We set the type such that we still have good scheduling if the
1630 ; insn is conditionalized.
1631 ; ??? It would make sense to allow introduction of long immediates, but
1632 ; we'd need to communicate to the ccfsm machinery the extra cost.
1633 ; The alternatives in the constraints still serve three purposes:
1634 ; - estimate insn size assuming conditional execution
1635 ; - guide reload to re-order the second and third operand to get a better fit.
1636 ; - give tentative insn type to guide scheduling
1637 ; N.B. "%" for commutativity doesn't help when there is another matching
1638 ; (but longer) alternative.
1639 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1640 ; register class 'W' instead of 'w'.
1641 (define_insn_and_split "*addsi3_mixed"
1642 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
1643 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq,Rcw,Rcw,Rcq,Rcb,Rcq, Rcw, Rcqq,Rcqq, W, W,W, W,Rcqq,Rcw, W")
1644 (plus:SI (match_operand:SI 1 "register_operand" "%0, c, 0, c, 0, 0,Rcb, 0, Rcqq, 0, c, c,0, 0, 0, 0, c")
1645 (match_operand:SI 2 "nonmemory_operand" "cL, 0, cL, 0,CL2,Csp,CM4,cCca,RcqqK, cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1648 arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1651 "&& reload_completed && get_attr_length (insn) == 8
1652 && satisfies_constraint_I (operands[2])
1653 && GET_CODE (PATTERN (insn)) != COND_EXEC"
1654 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1655 "split_addsi (operands);"
1656 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1657 (set (attr "iscompact")
1658 (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1659 (const_string "false")
1660 (match_operand 2 "long_immediate_operand" "")
1661 (const_string "maybe_limm")]
1662 (const_string "maybe")))
1663 (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1664 (set_attr "predicable" "no,no,yes,yes,no,no,no,yes,no,no,no,no,no,no,no,yes,no")
1665 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1668 ;; ARCv2 MPYW and MPYUW
1669 (define_expand "mulhisi3"
1670 [(set (match_operand:SI 0 "register_operand" "")
1671 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1672 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1675 if (CONSTANT_P (operands[2]))
1677 emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1683 (define_insn "mulhisi3_imm"
1684 [(set (match_operand:SI 0 "register_operand" "=r,r,r, r, r")
1685 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0, 0, r"))
1686 (match_operand:HI 2 "short_const_int_operand" "L,L,I,C16,C16")))]
1689 [(set_attr "length" "4,4,4,8,8")
1690 (set_attr "iscompact" "false")
1691 (set_attr "type" "mul16_em")
1692 (set_attr "predicable" "yes,no,no,yes,no")
1693 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1696 (define_insn "mulhisi3_reg"
1697 [(set (match_operand:SI 0 "register_operand" "=Rcqq,r,r")
1698 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " 0,0,r"))
1699 (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1702 [(set_attr "length" "*,4,4")
1703 (set_attr "iscompact" "maybe,false,false")
1704 (set_attr "type" "mul16_em")
1705 (set_attr "predicable" "yes,yes,no")
1706 (set_attr "cond" "canuse,canuse,nocond")
1709 (define_expand "umulhisi3"
1710 [(set (match_operand:SI 0 "register_operand" "")
1711 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1712 (zero_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1715 if (CONSTANT_P (operands[2]))
1717 emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1723 (define_insn "umulhisi3_imm"
1724 [(set (match_operand:SI 0 "register_operand" "=r, r,r, r, r")
1725 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " 0, r,0, 0, r"))
1726 (match_operand:HI 2 "short_const_int_operand" " L, L,I,C16,C16")))]
1729 [(set_attr "length" "4,4,4,8,8")
1730 (set_attr "iscompact" "false")
1731 (set_attr "type" "mul16_em")
1732 (set_attr "predicable" "yes,no,no,yes,no")
1733 (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1736 (define_insn "umulhisi3_reg"
1737 [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r")
1738 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " 0, 0, r"))
1739 (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1742 [(set_attr "length" "*,4,4")
1743 (set_attr "iscompact" "maybe,false,false")
1744 (set_attr "type" "mul16_em")
1745 (set_attr "predicable" "yes,yes,no")
1746 (set_attr "cond" "canuse,canuse,nocond")
1749 ;; ARC700/ARC600/V2 multiply
1752 (define_expand "mulsi3"
1753 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1754 (mult:SI (match_operand:SI 1 "register_operand" "")
1755 (match_operand:SI 2 "nonmemory_operand" "")))]
1760 if (!register_operand (operands[0], SImode))
1762 rtx result = gen_reg_rtx (SImode);
1764 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1765 emit_move_insn (operands[0], result);
1769 else if (TARGET_MUL64_SET)
1771 emit_insn (gen_mulsi_600 (operands[1], operands[2],
1772 gen_mlo (), gen_mhi ()));
1773 emit_move_insn (operands[0], gen_mlo ());
1776 else if (TARGET_MULMAC_32BY16_SET)
1778 if (immediate_operand (operands[2], SImode)
1779 && INTVAL (operands[2]) >= 0
1780 && INTVAL (operands[2]) <= 65535)
1782 emit_insn (gen_umul_600 (operands[1], operands[2],
1783 gen_acc2 (), gen_acc1 ()));
1784 emit_move_insn (operands[0], gen_acc2 ());
1787 operands[2] = force_reg (SImode, operands[2]);
1788 emit_insn (gen_umul_600 (operands[1], operands[2],
1789 gen_acc2 (), gen_acc1 ()));
1790 emit_insn (gen_mac_600 (operands[1], operands[2],
1791 gen_acc2 (), gen_acc1 ()));
1792 emit_move_insn (operands[0], gen_acc2 ());
1797 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1798 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1799 emit_insn (gen_mulsi3_600_lib ());
1800 emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1805 ; mululw conditional execution without a LIMM clobbers an input register;
1806 ; we'd need a different pattern to describe this.
1807 ; To make the conditional execution valid for the LIMM alternative, we
1808 ; have to emit the LIMM before the register operand.
1809 (define_insn "umul_600"
1810 [(set (match_operand:SI 2 "acc2_operand" "")
1811 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1812 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
1816 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1817 "TARGET_MULMAC_32BY16_SET"
1821 [(set_attr "length" "4,4,8")
1822 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1823 (set_attr "predicable" "no, no, yes")
1824 (set_attr "cond" "nocond, canuse_limm, canuse")])
1826 (define_insn "mac_600"
1827 [(set (match_operand:SI 2 "acc2_operand" "")
1829 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1831 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
1836 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1837 "TARGET_MULMAC_32BY16_SET"
1838 "machlw%? 0, %0, %1"
1839 [(set_attr "length" "4,4,8")
1840 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1841 (set_attr "predicable" "no, no, yes")
1842 (set_attr "cond" "nocond, canuse_limm, canuse")])
1844 (define_insn "mulsi_600"
1845 [(set (match_operand:SI 2 "mlo_operand" "")
1846 (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")
1847 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
1848 (clobber (match_operand:SI 3 "mhi_operand" ""))]
1850 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
1851 ; using a machine code pattern that only allows "L" constraint constants.
1852 ; "mul64%? \t0, %0, %1%&"
1854 if (satisfies_constraint_I (operands[1])
1855 && !satisfies_constraint_L (operands[1]))
1857 /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS */
1858 int n = true_regnum (operands[0]);
1859 int i = INTVAL (operands[1]);
1860 asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
1861 asm_fprintf (asm_out_file, "\t.short %d`",
1862 ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
1863 return "; mul64%? \t0, %0, %1%&";
1865 return "mul64%? \t0, %0, %1%&";
1867 [(set_attr "length" "*,4,4,8")
1868 (set_attr "iscompact" "maybe,false,false,false")
1869 (set_attr "type" "multi,multi,multi,multi")
1870 (set_attr "predicable" "yes,yes,no,yes")
1871 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1873 ; If we compile without an mul option enabled, but link with libraries
1874 ; for a mul option, we'll see clobbers of multiplier output registers.
1875 ; There is also an implementation using norm that clobbers the loop registers.
1876 (define_insn "mulsi3_600_lib"
1877 [(set (reg:SI R0_REG)
1878 (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
1879 (clobber (reg:SI RETURN_ADDR_REGNUM))
1880 (clobber (reg:SI R1_REG))
1881 (clobber (reg:SI R2_REG))
1882 (clobber (reg:SI R3_REG))
1883 (clobber (reg:DI MUL64_OUT_REG))
1884 (clobber (reg:SI LP_COUNT))
1885 (clobber (reg:SI LP_START))
1886 (clobber (reg:SI LP_END))
1887 (clobber (reg:CC CC_REG))]
1889 && SFUNC_CHECK_PREDICABLE"
1890 "*return arc_output_libcall (\"__mulsi3\");"
1891 [(set_attr "is_sfunc" "yes")
1892 (set_attr "predicable" "yes")])
1894 (define_insn "mulsidi_600"
1895 [(set (reg:DI MUL64_OUT_REG)
1896 (mult:DI (sign_extend:DI
1897 (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c"))
1899 ; assembler issue for "I", see mulsi_600
1900 ; (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))]
1901 (match_operand:SI 1 "register_operand" "Rcq#q,cL,L,C32"))))]
1903 "mul64%? \t0, %0, %1%&"
1904 [(set_attr "length" "*,4,4,8")
1905 (set_attr "iscompact" "maybe,false,false,false")
1906 (set_attr "type" "multi,multi,multi,multi")
1907 (set_attr "predicable" "yes,yes,no,yes")
1908 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1910 (define_insn "umulsidi_600"
1911 [(set (reg:DI MUL64_OUT_REG)
1912 (mult:DI (zero_extend:DI
1913 (match_operand:SI 0 "register_operand" "%c,c,c"))
1915 ; assembler issue for "I", see mulsi_600
1916 ; (match_operand:SI 1 "register_operand" "cL,I,Cal"))))]
1917 (match_operand:SI 1 "register_operand" "cL,L,C32"))))]
1919 "mulu64%? \t0, %0, %1%&"
1920 [(set_attr "length" "4,4,8")
1921 (set_attr "iscompact" "false")
1922 (set_attr "type" "umulti")
1923 (set_attr "predicable" "yes,no,yes")
1924 (set_attr "cond" "canuse,canuse_limm,canuse")])
1926 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
1927 ; may not be used as destination constraint.
1929 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
1930 ; but mpyu is faster for the standard multiplier.
1931 ; Note: we must make sure LP_COUNT is not one of the destination
1932 ; registers, since it cannot be the destination of a multi-cycle insn
1934 (define_insn "mulsi3_700"
1935 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r")
1936 (mult:SI (match_operand:SI 1 "register_operand" " 0,c,0,0,c")
1937 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
1940 [(set_attr "length" "4,4,4,8,8")
1941 (set_attr "type" "umulti")
1942 (set_attr "predicable" "yes,no,no,yes,no")
1943 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
1945 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
1946 ; short variant. LP_COUNT constraints are still valid.
1947 (define_insn "mulsi3_v2"
1948 [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcqq,Rcr, r,r,Rcr, r")
1949 (mult:SI (match_operand:SI 1 "register_operand" "%0, 0, c,0, 0, c")
1950 (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
1953 [(set_attr "length" "*,4,4,4,8,8")
1954 (set_attr "iscompact" "maybe,false,false,false,false,false")
1955 (set_attr "type" "umulti")
1956 (set_attr "predicable" "no,yes,no,no,yes,no")
1957 (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
1959 (define_expand "mulsidi3"
1960 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1961 (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" ""))
1962 (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
1968 operands[2] = force_reg (SImode, operands[2]);
1969 if (!register_operand (operands[0], DImode))
1971 rtx result = gen_reg_rtx (DImode);
1973 operands[2] = force_reg (SImode, operands[2]);
1974 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
1975 emit_move_insn (operands[0], result);
1979 else if (TARGET_MUL64_SET)
1981 operands[2] = force_reg (SImode, operands[2]);
1982 emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
1983 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
1986 else if (TARGET_MULMAC_32BY16_SET)
1988 rtx result_hi = gen_highpart(SImode, operands[0]);
1989 rtx result_low = gen_lowpart(SImode, operands[0]);
1991 emit_insn (gen_mul64_600 (operands[1], operands[2]));
1992 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
1993 emit_move_insn (result_low, gen_acc2 ());
1998 (define_insn "mul64_600"
2000 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2002 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2007 "TARGET_MULMAC_32BY16_SET"
2009 [(set_attr "length" "4,4,8")
2010 (set_attr "type" "mulmac_600")
2011 (set_attr "predicable" "no,no,yes")
2012 (set_attr "cond" "nocond, canuse_limm, canuse")])
2015 ;; ??? check if this is canonical rtl
2016 (define_insn "mac64_600"
2019 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2021 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2022 (const_int 16) (const_int 16))
2025 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2028 (mult:DI (sign_extend:DI (match_dup 1))
2030 (sign_extract:DI (match_dup 2)
2031 (const_int 16) (const_int 16))
2034 (const_int 32) (const_int 32)))]
2035 "TARGET_MULMAC_32BY16_SET"
2036 "machlw%? %0, %1, %2"
2037 [(set_attr "length" "4,4,8")
2038 (set_attr "type" "mulmac_600")
2039 (set_attr "predicable" "no,no,yes")
2040 (set_attr "cond" "nocond, canuse_limm, canuse")])
2043 ;; DI <- DI(signed SI) * DI(signed SI)
2044 (define_insn_and_split "mulsidi3_700"
2045 [(set (match_operand:DI 0 "register_operand" "=&r")
2046 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2047 (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2050 "&& reload_completed"
2053 int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2054 int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2055 rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2056 rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2057 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2058 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2061 [(set_attr "type" "multi")
2062 (set_attr "length" "8")])
2064 (define_insn "mulsi3_highpart"
2065 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2069 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2070 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2074 [(set_attr "length" "4,4,8,8")
2075 (set_attr "type" "multi")
2076 (set_attr "predicable" "yes,no,yes,no")
2077 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2079 ; Note that mpyhu has the same latency as mpy / mpyh,
2080 ; thus we use the type multi.
2081 (define_insn "*umulsi3_highpart_i"
2082 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2086 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2087 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, i,i")))
2091 [(set_attr "length" "4,4,8,8")
2092 (set_attr "type" "multi")
2093 (set_attr "predicable" "yes,no,yes,no")
2094 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2096 ; Implementations include additional labels for umulsidi3, so we got all
2097 ; the same clobbers - plus one for the result low part. */
2098 (define_insn "umulsi3_highpart_600_lib_le"
2099 [(set (reg:SI R1_REG)
2102 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2103 (zero_extend:DI (reg:SI R1_REG)))
2105 (clobber (reg:SI RETURN_ADDR_REGNUM))
2106 (clobber (reg:SI R0_REG))
2107 (clobber (reg:DI R2_REG))
2108 (clobber (reg:SI R12_REG))
2109 (clobber (reg:DI MUL64_OUT_REG))
2110 (clobber (reg:CC CC_REG))]
2113 && SFUNC_CHECK_PREDICABLE"
2114 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2115 [(set_attr "is_sfunc" "yes")
2116 (set_attr "predicable" "yes")])
2118 (define_insn "umulsi3_highpart_600_lib_be"
2119 [(set (reg:SI R0_REG)
2122 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2123 (zero_extend:DI (reg:SI R1_REG)))
2125 (clobber (reg:SI RETURN_ADDR_REGNUM))
2126 (clobber (reg:SI R1_REG))
2127 (clobber (reg:DI R2_REG))
2128 (clobber (reg:SI R12_REG))
2129 (clobber (reg:DI MUL64_OUT_REG))
2130 (clobber (reg:CC CC_REG))]
2133 && SFUNC_CHECK_PREDICABLE"
2134 "*return arc_output_libcall (\"__umulsi3_highpart\");"
2135 [(set_attr "is_sfunc" "yes")
2136 (set_attr "predicable" "yes")])
2138 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2139 ;; need a separate pattern for immediates
2140 ;; ??? This is fine for combine, but not for reload.
2141 (define_insn "umulsi3_highpart_int"
2142 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2146 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2147 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2151 [(set_attr "length" "4,4,4,8,8")
2152 (set_attr "type" "multi")
2153 (set_attr "predicable" "yes,no,no,yes,no")
2154 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2156 (define_expand "umulsi3_highpart"
2157 [(set (match_operand:SI 0 "general_operand" "")
2161 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2162 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2164 "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2167 rtx target = operands[0];
2171 emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2172 emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2173 if (TARGET_BIG_ENDIAN)
2174 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2176 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2177 emit_move_insn (target, gen_rtx_REG (SImode, 0));
2181 if (!register_operand (target, SImode))
2182 target = gen_reg_rtx (SImode);
2184 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2185 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2186 operands[2], SImode);
2187 else if (!immediate_operand (operands[2], SImode))
2188 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2189 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2190 if (target != operands[0])
2191 emit_move_insn (operands[0], target);
2195 (define_expand "umulsidi3"
2196 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2197 (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" ""))
2198 (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2203 operands[2] = force_reg (SImode, operands[2]);
2204 if (!register_operand (operands[0], DImode))
2206 rtx result = gen_reg_rtx (DImode);
2208 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2209 emit_move_insn (operands[0], result);
2213 else if (TARGET_MUL64_SET)
2215 operands[2] = force_reg (SImode, operands[2]);
2216 emit_insn (gen_umulsidi_600 (operands[1], operands[2]));
2217 emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2220 else if (TARGET_MULMAC_32BY16_SET)
2222 rtx result_hi = gen_reg_rtx (SImode);
2223 rtx result_low = gen_reg_rtx (SImode);
2225 result_hi = gen_highpart(SImode , operands[0]);
2226 result_low = gen_lowpart(SImode , operands[0]);
2228 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2229 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2230 emit_move_insn (result_low, gen_acc2 ());
2235 emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2236 emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2237 emit_insn (gen_umulsidi3_600_lib ());
2238 emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2243 (define_insn "umul64_600"
2245 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2247 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2252 "TARGET_MULMAC_32BY16_SET"
2256 [(set_attr "length" "4,4,8")
2257 (set_attr "type" "mulmac_600")
2258 (set_attr "predicable" "no,no,yes")
2259 (set_attr "cond" "nocond, canuse_limm, canuse")])
2262 (define_insn "umac64_600"
2265 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2267 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2268 (const_int 16) (const_int 16))
2271 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2274 (mult:DI (zero_extend:DI (match_dup 1))
2276 (zero_extract:DI (match_dup 2)
2277 (const_int 16) (const_int 16))
2280 (const_int 32) (const_int 32)))]
2281 "TARGET_MULMAC_32BY16_SET"
2282 "machulw%? %0, %1, %2"
2283 [(set_attr "length" "4,4,8")
2284 (set_attr "type" "mulmac_600")
2285 (set_attr "predicable" "no,no,yes")
2286 (set_attr "cond" "nocond, canuse_limm, canuse")])
2290 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2291 (define_insn_and_split "umulsidi3_700"
2292 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2293 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2294 (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2300 int hi = !TARGET_BIG_ENDIAN;
2302 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2303 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2304 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2305 emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2308 [(set_attr "type" "umulti")
2309 (set_attr "length" "8")])
2311 (define_insn "umulsidi3_600_lib"
2312 [(set (reg:DI R0_REG)
2313 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2314 (zero_extend:DI (reg:SI R1_REG))))
2315 (clobber (reg:SI RETURN_ADDR_REGNUM))
2316 (clobber (reg:DI R2_REG))
2317 (clobber (reg:SI R12_REG))
2318 (clobber (reg:DI MUL64_OUT_REG))
2319 (clobber (reg:CC CC_REG))]
2321 && SFUNC_CHECK_PREDICABLE"
2322 "*return arc_output_libcall (\"__umulsidi3\");"
2323 [(set_attr "is_sfunc" "yes")
2324 (set_attr "predicable" "yes")])
2328 [(set (reg:DI R0_REG)
2329 (mult:DI (zero_extend:DI (reg:SI R0_REG))
2330 (zero_extend:DI (reg:SI R1_REG))))
2331 (clobber (reg:SI RETURN_ADDR_REGNUM))
2332 (clobber (reg:DI R2_REG))
2333 (clobber (reg:SI R12_REG))
2334 (clobber (reg:DI MUL64_OUT_REG))
2335 (clobber (reg:CC CC_REG))])]
2337 && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2340 if (TARGET_BIG_ENDIAN)
2341 emit_insn (gen_umulsi3_highpart_600_lib_be ());
2343 emit_insn (gen_umulsi3_highpart_600_lib_le ());
2347 (define_expand "addsi3"
2348 [(set (match_operand:SI 0 "dest_reg_operand" "")
2349 (plus:SI (match_operand:SI 1 "register_operand" "")
2350 (match_operand:SI 2 "nonmemory_operand" "")))]
2352 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2354 operands[2]=force_reg(SImode, operands[2]);
2356 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2358 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2363 (define_expand "adddi3"
2364 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2365 (plus:DI (match_operand:DI 1 "register_operand" "")
2366 (match_operand:DI 2 "nonmemory_operand" "")))
2367 (clobber (reg:CC CC_REG))])]
2370 if (TARGET_EXPAND_ADDDI)
2372 rtx l0 = gen_lowpart (SImode, operands[0]);
2373 rtx h0 = disi_highpart (operands[0]);
2374 rtx l1 = gen_lowpart (SImode, operands[1]);
2375 rtx h1 = disi_highpart (operands[1]);
2376 rtx l2 = gen_lowpart (SImode, operands[2]);
2377 rtx h2 = disi_highpart (operands[2]);
2378 rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2380 if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2382 emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2383 emit_insn (gen_sbc (h0, h1,
2384 gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2388 emit_insn (gen_add_f (l0, l1, l2));
2389 emit_insn (gen_adc (h0, h1, h2));
2394 ; This assumes that there can be no strictly partial overlap between
2395 ; operands[1] and operands[2].
2396 (define_insn_and_split "*adddi3_i"
2397 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2398 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2399 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2400 (clobber (reg:CC CC_REG))]
2406 int hi = !TARGET_BIG_ENDIAN;
2408 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2409 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2410 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2411 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2412 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2413 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2416 if (l2 == const0_rtx)
2418 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2419 emit_move_insn (l0, l1);
2420 emit_insn (gen_addsi3 (h0, h1, h2));
2421 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2422 emit_move_insn (l0, l1);
2425 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2426 && INTVAL (operands[2]) >= -0x7fffffff)
2428 emit_insn (gen_subdi3_i (operands[0], operands[1],
2429 GEN_INT (-INTVAL (operands[2]))));
2432 if (rtx_equal_p (l0, h1))
2434 if (h2 != const0_rtx)
2435 emit_insn (gen_addsi3 (h0, h1, h2));
2436 else if (!rtx_equal_p (h0, h1))
2437 emit_move_insn (h0, h1);
2438 emit_insn (gen_add_f (l0, l1, l2));
2442 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2443 gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2446 emit_insn (gen_add_f (l0, l1, l2));
2447 emit_insn (gen_adc (h0, h1, h2));
2450 [(set_attr "cond" "clob")
2451 (set_attr "type" "binary")
2452 (set_attr "length" "16,16,20")])
2454 (define_insn "add_f"
2455 [(set (reg:CC_C CC_REG)
2457 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2458 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2460 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2461 (plus:SI (match_dup 1) (match_dup 2)))]
2464 [(set_attr "cond" "set")
2465 (set_attr "type" "compare")
2466 (set_attr "length" "4,4,8")])
2468 (define_insn "*add_f_2"
2469 [(set (reg:CC_C CC_REG)
2471 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2472 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2474 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2475 (plus:SI (match_dup 1) (match_dup 2)))]
2478 [(set_attr "cond" "set")
2479 (set_attr "type" "compare")
2480 (set_attr "length" "4,4,8")])
2482 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2483 ; needlessly prioritizing the matching constraint.
2484 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2485 ; execution is used where possible.
2486 (define_insn_and_split "adc"
2487 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2488 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2489 (match_operand:SI 1 "nonmemory_operand"
2491 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2492 "register_operand (operands[1], SImode)
2493 || register_operand (operands[2], SImode)"
2500 ; if we have a bad schedule after sched2, split.
2502 && !optimize_size && (!TARGET_ARC600_FAMILY)
2503 && arc_scheduling_not_expected ()
2504 && arc_sets_cc_p (prev_nonnote_insn (insn))
2505 /* If next comes a return or other insn that needs a delay slot,
2506 expect the adc to get into the delay slot. */
2507 && next_nonnote_insn (insn)
2508 && !arc_need_delay (next_nonnote_insn (insn))
2509 /* Restore operands before emitting. */
2510 && (extract_insn_cached (insn), 1)"
2511 [(set (match_dup 0) (match_dup 3))
2513 (ltu (reg:CC_C CC_REG) (const_int 0))
2514 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2515 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2516 [(set_attr "cond" "use")
2517 (set_attr "type" "cc_arith")
2518 (set_attr "length" "4,4,4,4,8")])
2520 ; combiner-splitter cmp / scc -> cmp / adc
2522 [(set (match_operand:SI 0 "dest_reg_operand" "")
2523 (gtu:SI (match_operand:SI 1 "register_operand" "")
2524 (match_operand:SI 2 "register_operand" "")))
2525 (clobber (reg CC_REG))]
2527 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2528 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2530 ; combine won't work when an intermediate result is used later...
2531 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2533 [(set (match_operand:SI 0 "dest_reg_operand" "")
2534 (plus:SI (match_operand:SI 1 "register_operand" "")
2535 (match_operand:SI 2 "nonmemory_operand" "")))
2536 (set (reg:CC_C CC_REG)
2537 (compare:CC_C (match_dup 0)
2538 (match_operand:SI 3 "nonmemory_operand" "")))]
2539 "rtx_equal_p (operands[1], operands[3])
2540 || rtx_equal_p (operands[2], operands[3])"
2542 [(set (reg:CC_C CC_REG)
2543 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2545 (plus:SI (match_dup 1) (match_dup 2)))])])
2547 ; ??? need to delve into combine to find out why this is not useful.
2548 ; We'd like to be able to grok various C idioms for carry bit usage.
2549 ;(define_insn "*adc_0"
2550 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2551 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2552 ; (match_operand:SI 1 "register_operand" "c")))]
2555 ; [(set_attr "cond" "use")
2556 ; (set_attr "type" "cc_arith")
2557 ; (set_attr "length" "4")])
2560 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2561 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2562 ; (match_operand:SI 2 "register_operand" "c"))
2563 ; (match_operand:SI 3 "register_operand" "c")))
2564 ; (clobber (reg CC_REG))]
2566 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2567 ; (set (match_dup 0)
2568 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2571 (define_expand "subsi3"
2572 [(set (match_operand:SI 0 "dest_reg_operand" "")
2573 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2574 (match_operand:SI 2 "nonmemory_operand" "")))]
2580 if (!register_operand (operands[2], SImode))
2582 operands[1] = force_reg (SImode, operands[1]);
2585 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2586 operands[c] = force_reg (SImode, operands[c]);
2587 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2588 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2591 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2592 ; combine should make such an insn go away.
2593 (define_insn_and_split "subsi3_insn"
2594 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2595 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0, 0, cL,c,L,I,Cal,Cal, c")
2596 (match_operand:SI 2 "nonmemory_operand" "Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2597 "register_operand (operands[1], SImode)
2598 || register_operand (operands[2], SImode)"
2609 "reload_completed && get_attr_length (insn) == 8
2610 && satisfies_constraint_I (operands[1])
2611 && GET_CODE (PATTERN (insn)) != COND_EXEC"
2612 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2613 "split_subsi (operands);"
2614 [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2615 (set_attr "length" "*,4,4,4,4,4,8,8,8")
2616 (set_attr "predicable" "yes,yes,yes,no,no,no,yes,no,no")
2617 (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2619 (define_expand "subdi3"
2620 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2621 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2622 (match_operand:DI 2 "nonmemory_operand" "")))
2623 (clobber (reg:CC CC_REG))])]
2626 if (!register_operand (operands[2], DImode))
2627 operands[1] = force_reg (DImode, operands[1]);
2628 if (TARGET_EXPAND_ADDDI)
2630 rtx l0 = gen_lowpart (SImode, operands[0]);
2631 rtx h0 = disi_highpart (operands[0]);
2632 rtx l1 = gen_lowpart (SImode, operands[1]);
2633 rtx h1 = disi_highpart (operands[1]);
2634 rtx l2 = gen_lowpart (SImode, operands[2]);
2635 rtx h2 = disi_highpart (operands[2]);
2636 rtx cc_c = gen_rtx_REG (CC_Cmode, CC_REG);
2638 emit_insn (gen_sub_f (l0, l1, l2));
2639 emit_insn (gen_sbc (h0, h1, h2, cc_c));
2644 (define_insn_and_split "subdi3_i"
2645 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2646 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2647 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2648 (clobber (reg:CC CC_REG))]
2649 "register_operand (operands[1], DImode)
2650 || register_operand (operands[2], DImode)"
2655 int hi = !TARGET_BIG_ENDIAN;
2657 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2658 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2659 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2660 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2661 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2662 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2664 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2666 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2667 if (!rtx_equal_p (h0, h1))
2668 emit_insn (gen_rtx_SET (h0, h1));
2669 emit_insn (gen_sub_f (l0, l1, l2));
2673 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2674 gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2677 emit_insn (gen_sub_f (l0, l1, l2));
2678 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2681 [(set_attr "cond" "clob")
2682 (set_attr "length" "16,16,16,20,20")])
2684 (define_insn "*sbc_0"
2685 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2686 (minus:SI (match_operand:SI 1 "register_operand" "c")
2687 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2691 [(set_attr "cond" "use")
2692 (set_attr "type" "cc_arith")
2693 (set_attr "length" "4")])
2695 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2696 ; needlessly prioritizing the matching constraint.
2697 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2698 ; is used where possible.
2699 (define_insn_and_split "sbc"
2700 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2701 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2703 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2705 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2706 "register_operand (operands[1], SImode)
2707 || register_operand (operands[2], SImode)"
2714 ; if we have a bad schedule after sched2, split.
2716 && !optimize_size && (!TARGET_ARC600_FAMILY)
2717 && arc_scheduling_not_expected ()
2718 && arc_sets_cc_p (prev_nonnote_insn (insn))
2719 /* If next comes a return or other insn that needs a delay slot,
2720 expect the adc to get into the delay slot. */
2721 && next_nonnote_insn (insn)
2722 && !arc_need_delay (next_nonnote_insn (insn))
2723 /* Restore operands before emitting. */
2724 && (extract_insn_cached (insn), 1)"
2725 [(set (match_dup 0) (match_dup 4))
2727 (ltu (reg:CC_C CC_REG) (const_int 0))
2728 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2729 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2730 [(set_attr "cond" "use")
2731 (set_attr "type" "cc_arith")
2732 (set_attr "length" "4,4,4,4,8")])
2734 (define_insn "sub_f"
2735 [(set (reg:CC CC_REG)
2736 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2737 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2738 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2739 (minus:SI (match_dup 1) (match_dup 2)))]
2740 "register_operand (operands[1], SImode)
2741 || register_operand (operands[2], SImode)"
2749 [(set_attr "type" "compare")
2750 (set_attr "length" "4,4,4,4,8,8")])
2752 ; combine won't work when an intermediate result is used later...
2753 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2755 [(set (reg:CC CC_REG)
2756 (compare:CC (match_operand:SI 1 "register_operand" "")
2757 (match_operand:SI 2 "nonmemory_operand" "")))
2758 (set (match_operand:SI 0 "dest_reg_operand" "")
2759 (minus:SI (match_dup 1) (match_dup 2)))]
2762 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2763 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
2766 [(set (reg:CC CC_REG)
2767 (compare:CC (match_operand:SI 1 "register_operand" "")
2768 (match_operand:SI 2 "nonmemory_operand" "")))
2769 (set (match_operand 3 "" "") (match_operand 4 "" ""))
2770 (set (match_operand:SI 0 "dest_reg_operand" "")
2771 (minus:SI (match_dup 1) (match_dup 2)))]
2772 "!reg_overlap_mentioned_p (operands[3], operands[1])
2773 && !reg_overlap_mentioned_p (operands[3], operands[2])
2774 && !reg_overlap_mentioned_p (operands[0], operands[4])
2775 && !reg_overlap_mentioned_p (operands[0], operands[3])"
2777 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2778 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2779 (set (match_dup 3) (match_dup 4))])
2781 (define_insn "*add_n"
2782 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
2783 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
2784 (match_operand:SI 2 "_2_4_8_operand" ""))
2785 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
2787 "add%z2%? %0,%3,%1%&"
2788 [(set_attr "type" "shift")
2789 (set_attr "length" "*,4,4,8,4,8")
2790 (set_attr "predicable" "yes,yes,no,no,no,no")
2791 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
2792 (set_attr "iscompact" "maybe,false,false,false,false,false")])
2794 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2795 ;; what synth_mult likes.
2796 (define_insn "*sub_n"
2797 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2798 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2799 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2800 (match_operand:SI 3 "_2_4_8_operand" ""))))]
2803 [(set_attr "type" "shift")
2804 (set_attr "length" "4,4,8")
2805 (set_attr "predicable" "yes,no,no")
2806 (set_attr "cond" "canuse,nocond,nocond")
2807 (set_attr "iscompact" "false")])
2809 ; ??? check if combine matches this.
2810 (define_insn "*bset"
2811 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2812 (ior:SI (ashift:SI (const_int 1)
2813 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2814 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2817 [(set_attr "length" "4,4,8")
2818 (set_attr "predicable" "yes,no,no")
2819 (set_attr "cond" "canuse,nocond,nocond")]
2822 ; ??? check if combine matches this.
2823 (define_insn "*bxor"
2824 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2825 (xor:SI (ashift:SI (const_int 1)
2826 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2827 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2830 [(set_attr "length" "4,4,8")
2831 (set_attr "predicable" "yes,no,no")
2832 (set_attr "cond" "canuse,nocond,nocond")]
2835 ; ??? check if combine matches this.
2836 (define_insn "*bclr"
2837 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2838 (and:SI (not:SI (ashift:SI (const_int 1)
2839 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
2840 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2843 [(set_attr "length" "4,4,8")
2844 (set_attr "predicable" "yes,no,no")
2845 (set_attr "cond" "canuse,nocond,nocond")]
2848 ; ??? FIXME: find combine patterns for bmsk.
2850 ;;Following are the define_insns added for the purpose of peephole2's
2852 ; see also iorsi3 for use with constant bit number.
2853 (define_insn "*bset_insn"
2854 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2855 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2856 (ashift:SI (const_int 1)
2857 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2860 bset%? %0,%1,%2 ;;peep2, constr 1
2861 bset %0,%1,%2 ;;peep2, constr 2
2862 bset %0,%S1,%2 ;;peep2, constr 3"
2863 [(set_attr "length" "4,4,8")
2864 (set_attr "predicable" "yes,no,no")
2865 (set_attr "cond" "canuse,nocond,nocond")]
2868 ; see also xorsi3 for use with constant bit number.
2869 (define_insn "*bxor_insn"
2870 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2871 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2872 (ashift:SI (const_int 1)
2873 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2879 [(set_attr "length" "4,4,8")
2880 (set_attr "predicable" "yes,no,no")
2881 (set_attr "cond" "canuse,nocond,nocond")]
2884 ; see also andsi3 for use with constant bit number.
2885 (define_insn "*bclr_insn"
2886 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2887 (and:SI (not:SI (ashift:SI (const_int 1)
2888 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
2889 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
2895 [(set_attr "length" "4,4,8")
2896 (set_attr "predicable" "yes,no,no")
2897 (set_attr "cond" "canuse,nocond,nocond")]
2900 ; see also andsi3 for use with constant bit number.
2901 (define_insn "*bmsk_insn"
2902 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2903 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2904 (plus:SI (ashift:SI (const_int 1)
2905 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
2913 [(set_attr "length" "4,4,8")
2914 (set_attr "predicable" "yes,no,no")
2915 (set_attr "cond" "canuse,nocond,nocond")]
2918 ;;Instructions added for peephole2s end
2920 ;; Boolean instructions.
2922 (define_expand "andsi3"
2923 [(set (match_operand:SI 0 "dest_reg_operand" "")
2924 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2925 (match_operand:SI 2 "nonmemory_operand" "")))]
2927 "if (!satisfies_constraint_Cux (operands[2]))
2928 operands[1] = force_reg (SImode, operands[1]);
2929 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
2930 operands[1] = arc_rewrite_small_data (operands[1]);")
2932 (define_insn "andsi3_i"
2933 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw, w, w, w, w,w,Rcw, w, W")
2934 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,0, 0, c, o")
2935 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, C1p, Ccp, Cux, cL, 0,C1p,Ccp,CnL, I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))]
2936 "(register_operand (operands[1], SImode)
2937 && nonmemory_operand (operands[2], SImode))
2938 || (memory_operand (operands[1], SImode)
2939 && satisfies_constraint_Cux (operands[2]))"
2942 switch (which_alternative)
2944 case 0: case 5: case 10: case 11: case 15: case 16: case 17:
2945 return \"and%? %0,%1,%2%&\";
2947 return \"and%? %0,%2,%1%&\";
2948 case 2: case 7: case 12:
2949 return \"bmsk%? %0,%1,%Z2%&\";
2950 case 3: case 8: case 13:
2951 return \"bclr%? %0,%1,%M2%&\";
2953 return (INTVAL (operands[2]) == 0xff
2954 ? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\");
2955 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
2957 if (TARGET_BIG_ENDIAN)
2961 xop[0] = operands[0];
2962 xop[1] = adjust_address (operands[1], QImode,
2963 INTVAL (operands[2]) == 0xff ? 3 : 2);
2964 output_asm_insn (INTVAL (operands[2]) == 0xff
2965 ? \"ldb %0,%1\" : \"ld%_ %0,%1\",
2969 return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\";
2974 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
2975 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
2976 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
2977 (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no")
2978 (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2980 ; combiner splitter, pattern found in ldtoa.c .
2981 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
2983 [(set (reg:CC_Z CC_REG)
2984 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
2985 (match_operand 1 "const_int_operand" ""))
2986 (match_operand 2 "const_int_operand" "")))
2987 (clobber (match_operand:SI 3 "register_operand" ""))]
2988 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
2990 (plus:SI (match_dup 0) (match_dup 4)))
2991 (set (reg:CC_Z CC_REG)
2992 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
2994 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
2996 ;;bic define_insn that allows limm to be the first operand
2997 (define_insn "*bicsi3_insn"
2998 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
2999 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3000 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3003 bic%? %0, %2, %1%& ;;constraint 0
3004 bic%? %0,%2,%1 ;;constraint 1
3005 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3006 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3007 bic %0,%2,%1 ;;constraint 4
3008 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3009 bic %0,%S2,%1 ;;constraint 6"
3010 [(set_attr "length" "*,4,4,8,4,8,8")
3011 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3012 (set_attr "predicable" "no,yes,no,yes,no,no,no")
3013 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3015 (define_insn "iorsi3"
3016 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3017 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3018 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3021 switch (which_alternative)
3023 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3024 return \"or%? %0,%1,%2%&\";
3026 return \"or%? %0,%2,%1%&\";
3027 case 2: case 5: case 8:
3028 return \"bset%? %0,%1,%z2%&\";
3032 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3033 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3034 (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3035 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3037 (define_insn "xorsi3"
3038 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3039 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3040 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3043 switch (which_alternative)
3045 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3046 return \"xor%? %0,%1,%2%&\";
3048 return \"xor%? %0,%2,%1%&\";
3050 return \"bxor%? %0,%1,%z2\";
3055 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3056 (set_attr "type" "binary")
3057 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3058 (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3059 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3061 (define_insn "negsi2"
3062 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3063 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3066 [(set_attr "type" "unary")
3067 (set_attr "iscompact" "maybe,true,false,false")
3068 (set_attr "predicable" "no,no,yes,no")])
3070 (define_insn "one_cmplsi2"
3071 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3072 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3075 [(set_attr "type" "unary,unary")
3076 (set_attr "iscompact" "true,false")])
3078 (define_insn_and_split "one_cmpldi2"
3079 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3080 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3083 "&& reload_completed"
3084 [(set (match_dup 2) (not:SI (match_dup 3)))
3085 (set (match_dup 4) (not:SI (match_dup 5)))]
3087 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3089 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3090 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3091 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3092 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3094 [(set_attr "type" "unary,unary")
3095 (set_attr "cond" "nocond,nocond")
3096 (set_attr "length" "4,8")])
3098 ;; Shift instructions.
3100 (define_expand "ashlsi3"
3101 [(set (match_operand:SI 0 "dest_reg_operand" "")
3102 (ashift:SI (match_operand:SI 1 "register_operand" "")
3103 (match_operand:SI 2 "nonmemory_operand" "")))]
3107 if (!TARGET_BARREL_SHIFTER)
3109 emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3114 (define_expand "ashrsi3"
3115 [(set (match_operand:SI 0 "dest_reg_operand" "")
3116 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3117 (match_operand:SI 2 "nonmemory_operand" "")))]
3121 if (!TARGET_BARREL_SHIFTER)
3123 emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3128 (define_expand "lshrsi3"
3129 [(set (match_operand:SI 0 "dest_reg_operand" "")
3130 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3131 (match_operand:SI 2 "nonmemory_operand" "")))]
3135 if (!TARGET_BARREL_SHIFTER)
3137 emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3142 (define_insn "shift_si3"
3143 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3144 (match_operator:SI 3 "shift4_operator"
3145 [(match_operand:SI 1 "register_operand" "0")
3146 (match_operand:SI 2 "const_int_operand" "n")]))
3147 (clobber (match_scratch:SI 4 "=&r"))
3148 (clobber (reg:CC CC_REG))
3150 "!TARGET_BARREL_SHIFTER"
3151 "* return output_shift (operands);"
3152 [(set_attr "type" "shift")
3153 (set_attr "length" "16")])
3155 (define_insn "shift_si3_loop"
3156 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3157 (match_operator:SI 3 "shift_operator"
3158 [(match_operand:SI 1 "register_operand" "0,0")
3159 (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3160 (clobber (match_scratch:SI 4 "=X,X"))
3161 (clobber (reg:SI LP_COUNT))
3162 (clobber (reg:SI LP_START))
3163 (clobber (reg:SI LP_END))
3164 (clobber (reg:CC CC_REG))
3166 "!TARGET_BARREL_SHIFTER"
3167 "* return output_shift (operands);"
3168 [(set_attr "type" "shift")
3169 (set_attr "length" "16,20")])
3171 ; asl, asr, lsr patterns:
3172 ; There is no point in including an 'I' alternative since only the lowest 5
3173 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3174 ; is defined in an external symbol, as we don't have special relocations
3175 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3176 ; provide one alternatice for this, without condexec support.
3177 (define_insn "*ashlsi3_insn"
3178 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3179 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3180 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3181 "TARGET_BARREL_SHIFTER
3182 && (register_operand (operands[1], SImode)
3183 || register_operand (operands[2], SImode))"
3185 [(set_attr "type" "shift")
3186 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3187 (set_attr "predicable" "no,no,no,yes,no,no")
3188 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3190 (define_insn "*ashrsi3_insn"
3191 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3192 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3193 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3194 "TARGET_BARREL_SHIFTER
3195 && (register_operand (operands[1], SImode)
3196 || register_operand (operands[2], SImode))"
3198 [(set_attr "type" "shift")
3199 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3200 (set_attr "predicable" "no,no,no,yes,no,no")
3201 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3203 (define_insn "*lshrsi3_insn"
3204 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3205 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3206 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3207 "TARGET_BARREL_SHIFTER
3208 && (register_operand (operands[1], SImode)
3209 || register_operand (operands[2], SImode))"
3210 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3211 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3212 [(set_attr "type" "shift")
3213 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3214 (set_attr "predicable" "no,no,no,yes,no,no")
3215 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3217 (define_insn "rotrsi3"
3218 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3219 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3220 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3221 "TARGET_BARREL_SHIFTER"
3223 [(set_attr "type" "shift,shift,shift")
3224 (set_attr "predicable" "yes,no,no")
3225 (set_attr "length" "4,4,8")])
3227 ;; Compare / branch instructions.
3229 (define_expand "cbranchsi4"
3230 [(set (reg:CC CC_REG)
3231 (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3232 (match_operand:SI 2 "nonmemory_operand" "")))
3235 (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3237 (label_ref (match_operand 3 "" ""))
3241 gcc_assert (XEXP (operands[0], 0) == operands[1]);
3242 gcc_assert (XEXP (operands[0], 1) == operands[2]);
3243 operands[0] = gen_compare_reg (operands[0], VOIDmode);
3244 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3248 ;; ??? Could add a peephole to generate compare with swapped operands and
3249 ;; modifed cc user if second, but not first operand is a compact register.
3250 (define_insn "cmpsi_cc_insn_mixed"
3251 [(set (reg:CC CC_REG)
3252 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c")
3253 (match_operand:SI 1 "nonmemory_operand" "cO,cI,cL, Cal, Cal")))]
3256 [(set_attr "type" "compare")
3257 (set_attr "iscompact" "true,false,false,true_limm,false")
3258 (set_attr "predicable" "no,no,yes,no,yes")
3259 (set_attr "cond" "set")
3260 (set_attr "length" "*,4,4,*,8")])
3262 (define_insn "*cmpsi_cc_zn_insn"
3263 [(set (reg:CC_ZN CC_REG)
3264 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3268 [(set_attr "type" "compare,compare")
3269 (set_attr "iscompact" "true,false")
3270 (set_attr "predicable" "no,yes")
3271 (set_attr "cond" "set_zn")
3272 (set_attr "length" "*,4")])
3274 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3275 (define_insn "*btst"
3276 [(set (reg:CC_ZN CC_REG)
3278 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3280 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3284 [(set_attr "iscompact" "true,false")
3285 (set_attr "predicable" "no,yes")
3286 (set_attr "cond" "set")
3287 (set_attr "type" "compare")
3288 (set_attr "length" "*,4")])
3290 ; combine suffers from 'simplifications' that replace a one-bit zero
3291 ; extract with a shift if it can prove that the upper bits are zero.
3292 ; arc_reorg sees the code after sched2, which can have caused our
3293 ; inputs to be clobbered even if they were not clobbered before.
3294 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3295 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3296 ; bbit (i.e. bad scheduling) and missed conditional execution,
3297 ; so make this an option.
3299 [(set (reg:CC_ZN CC_REG)
3301 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3303 (match_operand:SI 1 "nonmemory_operand" ""))
3306 (if_then_else (match_operator 3 "equality_comparison_operator"
3307 [(reg:CC_ZN CC_REG) (const_int 0)])
3308 (label_ref (match_operand 2 "" ""))
3310 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3311 [(parallel [(set (pc)
3314 [(zero_extract:SI (match_dup 0)
3315 (const_int 1) (match_dup 1))
3317 (label_ref (match_dup 2))
3319 (clobber (reg:CC_ZN CC_REG))])])
3321 (define_insn "*cmpsi_cc_z_insn"
3322 [(set (reg:CC_Z CC_REG)
3323 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3324 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3329 [(set_attr "type" "compare,compare")
3330 (set_attr "iscompact" "true,false")
3331 (set_attr "cond" "set,set_zn")
3332 (set_attr "length" "*,4")])
3334 (define_insn "*cmpsi_cc_c_insn"
3335 [(set (reg:CC_C CC_REG)
3336 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, c,Rcqq, c")
3337 (match_operand:SI 1 "nonmemory_operand" "cO, cI, Cal,Cal")))]
3340 [(set_attr "type" "compare")
3341 (set_attr "iscompact" "true,false,true_limm,false")
3342 (set_attr "cond" "set")
3343 (set_attr "length" "*,4,*,8")])
3345 ;; Next come the scc insns.
3347 (define_expand "cstoresi4"
3348 [(set (match_operand:SI 0 "dest_reg_operand" "")
3349 (match_operator:SI 1 "ordered_comparison_operator"
3350 [(match_operand:SI 2 "nonmemory_operand" "")
3351 (match_operand:SI 3 "nonmemory_operand" "")]))]
3354 if (!TARGET_CODE_DENSITY)
3356 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3357 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3358 operands[1] = gen_compare_reg (operands[1], SImode);
3359 emit_insn (gen_scc_insn (operands[0], operands[1]));
3362 if (!register_operand (operands[2], SImode))
3363 operands[2] = force_reg (SImode, operands[2]);
3367 (define_mode_iterator SDF [SF DF])
3369 (define_expand "cstore<mode>4"
3370 [(set (reg:CC CC_REG)
3371 (compare:CC (match_operand:SDF 2 "register_operand" "")
3372 (match_operand:SDF 3 "register_operand" "")))
3373 (set (match_operand:SI 0 "dest_reg_operand" "")
3374 (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3379 gcc_assert (XEXP (operands[1], 0) == operands[2]);
3380 gcc_assert (XEXP (operands[1], 1) == operands[3]);
3381 operands[1] = gen_compare_reg (operands[1], SImode);
3382 emit_insn (gen_scc_insn (operands[0], operands[1]));
3386 ; We need a separate expander for this lest we loose the mode of CC_REG
3387 ; when match_operator substitutes the literal operand into the comparison.
3388 (define_expand "scc_insn"
3389 [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3391 (define_insn_and_split "*scc_insn"
3392 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3393 (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3397 [(set (match_dup 0) (const_int 1))
3400 (set (match_dup 0) (const_int 0)))]
3403 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3404 GET_MODE (XEXP (operands[1], 0))),
3406 XEXP (operands[1], 0), XEXP (operands[1], 1));
3408 [(set_attr "type" "unary")])
3410 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3411 ;; that is one lower if the carry flag is set.
3413 ;; ??? Look up negscc insn. See pa.md for example.
3414 (define_insn "*neg_scc_insn"
3415 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3416 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3417 [(reg CC_REG) (const_int 0)])))]
3419 "mov %0,-1\;sub.%D1 %0,%0,%0"
3420 [(set_attr "type" "unary")
3421 (set_attr "length" "8")])
3423 (define_insn "*not_scc_insn"
3424 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3425 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3426 [(reg CC_REG) (const_int 0)])))]
3428 "mov %0,1\;sub.%d1 %0,%0,%0"
3429 [(set_attr "type" "unary")
3430 (set_attr "length" "8")])
3432 ; cond_exec patterns
3433 (define_insn "*movsi_ne"
3435 (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0))
3436 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
3437 (match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))]
3440 * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3443 [(set_attr "type" "cmove,cmove,cmove")
3444 (set_attr "iscompact" "true,false,false")
3445 (set_attr "length" "2,4,8")])
3447 (define_insn "*movsi_cond_exec"
3449 (match_operator 3 "proper_comparison_operator"
3450 [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3451 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3452 (match_operand:SI 1 "nonmemory_operand" "Lc,?Cal")))]
3455 [(set_attr "type" "cmove")
3456 (set_attr "length" "4,8")])
3458 (define_insn "*commutative_cond_exec"
3460 (match_operator 5 "proper_comparison_operator"
3461 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3462 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3463 (match_operator:SI 3 "commutative_operator"
3464 [(match_operand:SI 1 "register_operand" "%0,0")
3465 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3468 arc_output_commutative_cond_exec (operands, true);
3471 [(set_attr "cond" "use")
3472 (set_attr "type" "cmove")
3473 (set_attr_alternative "length"
3476 [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3481 (define_insn "*sub_cond_exec"
3483 (match_operator 4 "proper_comparison_operator"
3484 [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3485 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3486 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3487 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3493 [(set_attr "cond" "use")
3494 (set_attr "type" "cmove")
3495 (set_attr "length" "4,4,8")])
3497 (define_insn "*noncommutative_cond_exec"
3499 (match_operator 5 "proper_comparison_operator"
3500 [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3501 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3502 (match_operator:SI 3 "noncommutative_operator"
3503 [(match_operand:SI 1 "register_operand" "0,0")
3504 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3507 [(set_attr "cond" "use")
3508 (set_attr "type" "cmove")
3509 (set_attr "length" "4,8")])
3511 ;; These control RTL generation for conditional jump insns
3512 ;; Match both normal and inverted jump.
3514 ; We need a separate expander for this lest we loose the mode of CC_REG
3515 ; when match_operator substitutes the literal operand into the comparison.
3516 (define_expand "branch_insn"
3518 (if_then_else (match_operand 1 "" "")
3519 (label_ref (match_operand 0 "" ""))
3522 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3523 ; are three reasons why we need to consider branches to be length 6:
3524 ; - annull-false delay slot insns are implemented using conditional execution,
3525 ; thus preventing short insn formation where used.
3526 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3527 ; using conditional execution, preventing short insn formation where used.
3528 ; - for ARC700: likely or somewhat likely taken branches are made long and
3529 ; unaligned if possible to avoid branch penalty.
3530 (define_insn "*branch_insn"
3532 (if_then_else (match_operator 1 "proper_comparison_operator"
3533 [(reg CC_REG) (const_int 0)])
3534 (label_ref (match_operand 0 "" ""))
3539 if (arc_ccfsm_branch_deleted_p ())
3541 arc_ccfsm_record_branch_deleted ();
3542 return \"; branch deleted, next insns conditionalized\";
3546 arc_ccfsm_record_condition (operands[1], false, insn, 0);
3547 if (get_attr_length (insn) == 2)
3548 return \"b%d1%? %^%l0%&\";
3550 return \"b%d1%# %^%l0\";
3553 [(set_attr "type" "branch")
3557 (eq_attr "delay_slot_filled" "yes")
3562 (match_operand 1 "equality_comparison_operator" "")
3563 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3564 (gt (minus (match_dup 0) (pc))
3565 (minus (const_int 506)
3566 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3567 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3568 (lt (minus (match_dup 0) (pc)) (const_int -64))
3569 (gt (minus (match_dup 0) (pc))
3570 (minus (const_int 58)
3571 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3576 (set (attr "iscompact")
3577 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3578 (const_string "false")))])
3580 (define_insn "*rev_branch_insn"
3582 (if_then_else (match_operator 1 "proper_comparison_operator"
3583 [(reg CC_REG) (const_int 0)])
3585 (label_ref (match_operand 0 "" ""))))]
3586 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3589 if (arc_ccfsm_branch_deleted_p ())
3591 arc_ccfsm_record_branch_deleted ();
3592 return \"; branch deleted, next insns conditionalized\";
3596 arc_ccfsm_record_condition (operands[1], true, insn, 0);
3597 if (get_attr_length (insn) == 2)
3598 return \"b%D1%? %^%l0\";
3600 return \"b%D1%# %^%l0\";
3603 [(set_attr "type" "branch")
3607 (eq_attr "delay_slot_filled" "yes")
3612 (match_operand 1 "equality_comparison_operator" "")
3613 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3614 (gt (minus (match_dup 0) (pc))
3615 (minus (const_int 506)
3616 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3617 (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3618 (lt (minus (match_dup 0) (pc)) (const_int -64))
3619 (gt (minus (match_dup 0) (pc))
3620 (minus (const_int 58)
3621 (symbol_ref "get_attr_delay_slot_length (insn)")))))
3626 (set (attr "iscompact")
3627 (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3628 (const_string "false")))])
3630 ;; Unconditional and other jump instructions.
3632 (define_expand "jump"
3633 [(set (pc) (label_ref (match_operand 0 "" "")))]
3637 (define_insn "jump_i"
3638 [(set (pc) (label_ref (match_operand 0 "" "")))]
3639 "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3641 [(set_attr "type" "uncond_branch")
3642 (set (attr "iscompact")
3643 (if_then_else (match_test "get_attr_length (insn) == 2")
3644 (const_string "true") (const_string "false")))
3645 (set_attr "cond" "canuse")
3646 (set (attr "length")
3648 ; In arc_reorg we just guesstimate; might be more or less than 4.
3649 (match_test "arc_branch_size_unknown_p ()")
3652 (eq_attr "delay_slot_filled" "yes")
3655 (match_test "CROSSING_JUMP_P (insn)")
3658 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3659 (gt (minus (match_dup 0) (pc))
3660 (minus (const_int 506)
3661 (symbol_ref "get_attr_delay_slot_length (insn)"))))
3665 (define_insn "indirect_jump"
3666 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3669 [(set_attr "type" "jump")
3670 (set_attr "iscompact" "false,false,false,maybe,false")
3671 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3673 ;; Implement a switch statement.
3675 (define_expand "casesi"
3677 (minus:SI (match_operand:SI 0 "register_operand" "")
3678 (match_operand:SI 1 "nonmemory_operand" "")))
3679 (set (reg:CC CC_REG)
3680 (compare:CC (match_dup 5)
3681 (match_operand:SI 2 "nonmemory_operand" "")))
3683 (if_then_else (gtu (reg:CC CC_REG)
3685 (label_ref (match_operand 4 "" ""))
3688 (unspec:SI [(match_operand 3 "" "")
3689 (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
3690 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
3696 operands[5] = gen_reg_rtx (SImode);
3697 operands[6] = gen_reg_rtx (SImode);
3698 operands[7] = operands[3];
3699 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
3700 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
3701 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
3702 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
3703 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
3704 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
3705 if (TARGET_COMPACT_CASESI)
3707 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
3711 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
3712 if (flag_pic || !cse_not_expected)
3713 operands[3] = force_reg (Pmode, operands[3]);
3714 emit_insn (gen_casesi_load (operands[6],
3715 operands[3], operands[5], operands[7]));
3716 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
3717 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
3718 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
3723 (define_insn "casesi_load"
3724 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
3725 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
3726 (match_operand:SI 2 "register_operand" "Rcq,c,c")
3727 (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
3731 rtx diff_vec = PATTERN (next_nonnote_insn (operands[3]));
3733 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
3735 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
3736 gcc_assert (GET_MODE (diff_vec) == SImode);
3737 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
3740 switch (GET_MODE (diff_vec))
3743 return \"ld.as %0,[%1,%2]%&\";
3745 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3746 return \"ld%_.as %0,[%1,%2]\";
3747 return \"ld%_.x.as %0,[%1,%2]\";
3749 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3750 return \"ldb%? %0,[%1,%2]%&\";
3751 return \"ldb.x %0,[%1,%2]\";
3756 [(set_attr "type" "load")
3757 (set_attr_alternative "iscompact"
3759 [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn (operands[3])))")
3760 (symbol_ref "QImode"))
3761 (const_string "false")
3762 (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn (operands[3]))).offset_unsigned")
3763 (const_string "false")]
3764 (const_string "true"))
3765 (const_string "false")
3766 (const_string "false")])
3767 (set_attr_alternative "length"
3769 [(eq_attr "iscompact" "false") (const_int 4)
3770 ; We have to mention (match_dup 3) to convince genattrtab.c that this
3771 ; is a varying length insn.
3772 (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
3773 (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
3778 ; Unlike the canonical tablejump, this pattern always uses a jump address,
3779 ; even for CASE_VECTOR_PC_RELATIVE.
3780 (define_insn "casesi_jump"
3781 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
3782 (use (label_ref (match_operand 1 "" "")))]
3785 [(set_attr "type" "jump")
3786 (set_attr "iscompact" "false,maybe,false")
3787 (set_attr "cond" "canuse")])
3789 (define_insn "casesi_compact_jump"
3791 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
3793 (use (label_ref (match_operand 1 "" "")))
3794 (clobber (match_scratch:SI 2 "=q,0"))]
3795 "TARGET_COMPACT_CASESI"
3798 rtx diff_vec = PATTERN (next_nonnote_insn (operands[1]));
3799 int unalign = arc_get_unalign ();
3803 xop[0] = operands[0];
3804 xop[2] = operands[2];
3805 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
3807 switch (GET_MODE (diff_vec))
3810 /* Max length can be 12 in this case, but this is OK because
3811 2 of these are for alignment, and are anticipated in the length
3812 of the ADDR_DIFF_VEC. */
3813 if (unalign && !satisfies_constraint_Rcq (xop[0]))
3814 s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
3816 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
3818 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
3819 arc_clear_unalign ();
3822 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3824 if (satisfies_constraint_Rcq (xop[0]))
3826 s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
3827 xop[1] = GEN_INT ((10 - unalign) / 2U);
3831 s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
3832 xop[1] = GEN_INT (10 + unalign);
3837 if (satisfies_constraint_Rcq (xop[0]))
3839 s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
3840 xop[1] = GEN_INT ((10 - unalign) / 2U);
3844 s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
3845 xop[1] = GEN_INT (10 + unalign);
3848 arc_toggle_unalign ();
3851 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
3853 if ((rtx_equal_p (xop[2], xop[0])
3854 || find_reg_note (insn, REG_DEAD, xop[0]))
3855 && satisfies_constraint_Rcq (xop[0]))
3857 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
3858 xop[1] = GEN_INT (8 + unalign);
3862 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
3863 xop[1] = GEN_INT (10 + unalign);
3864 arc_toggle_unalign ();
3867 else if ((rtx_equal_p (xop[0], xop[2])
3868 || find_reg_note (insn, REG_DEAD, xop[0]))
3869 && satisfies_constraint_Rcq (xop[0]))
3871 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
3872 xop[1] = GEN_INT (10 - unalign);
3873 arc_toggle_unalign ();
3877 /* ??? Length is 12. */
3878 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
3879 xop[1] = GEN_INT (8 + unalign);
3885 output_asm_insn (s, xop);
3886 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
3888 [(set_attr "length" "10")
3889 (set_attr "type" "jump")
3890 (set_attr "iscompact" "true")
3891 (set_attr "cond" "nocond")])
3893 (define_expand "call"
3894 ;; operands[1] is stack_size_rtx
3895 ;; operands[2] is next_arg_register
3896 [(parallel [(call (match_operand:SI 0 "call_operand" "")
3897 (match_operand 1 "" ""))
3898 (clobber (reg:SI 31))])]
3903 gcc_assert (MEM_P (operands[0]));
3904 callee = XEXP (operands[0], 0);
3905 if (crtl->profile && arc_profile_call (callee))
3907 emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
3912 /* This is to decide if we should generate indirect calls by loading the
3913 32 bit address of the callee into a register before performing the
3914 branch and link - this exposes cse opportunities.
3915 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
3916 if (GET_CODE (callee) != REG
3917 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3918 XEXP (operands[0], 0) = force_reg (Pmode, callee);
3923 ; Rcq, which is used in alternative 0, checks for conditional execution.
3924 ; At instruction output time, if it doesn't match and we end up with
3925 ; alternative 1 ("q"), that means that we can't use the short form.
3926 (define_insn "*call_i"
3927 [(call (mem:SI (match_operand:SI 0
3928 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3929 (match_operand 1 "" ""))
3930 (clobber (reg:SI 31))]
3941 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
3942 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
3943 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
3944 (set_attr "length" "*,*,4,4,4,4,4,8")])
3946 (define_insn "call_prof"
3947 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
3948 (match_operand 1 "" ""))
3949 (clobber (reg:SI 31))
3956 [(set_attr "type" "call,call_no_delay_slot")
3957 (set_attr "predicable" "yes,yes")
3958 (set_attr "length" "4,8")])
3960 (define_expand "call_value"
3961 ;; operand 2 is stack_size_rtx
3962 ;; operand 3 is next_arg_register
3963 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
3964 (call (match_operand:SI 1 "call_operand" "")
3965 (match_operand 2 "" "")))
3966 (clobber (reg:SI 31))])]
3972 gcc_assert (MEM_P (operands[1]));
3973 callee = XEXP (operands[1], 0);
3974 if (crtl->profile && arc_profile_call (callee))
3976 emit_call_insn (gen_call_value_prof (operands[0],
3977 gen_rtx_SYMBOL_REF (Pmode,
3982 /* See the comment in define_expand \"call\". */
3983 if (GET_CODE (callee) != REG
3984 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
3985 XEXP (operands[1], 0) = force_reg (Pmode, callee);
3989 ; Rcq, which is used in alternative 0, checks for conditional execution.
3990 ; At instruction output time, if it doesn't match and we end up with
3991 ; alternative 1 ("q"), that means that we can't use the short form.
3992 (define_insn "*call_value_i"
3993 [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
3994 (call (mem:SI (match_operand:SI 1
3995 "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
3996 (match_operand 2 "" "")))
3997 (clobber (reg:SI 31))]
4008 [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4009 (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4010 (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4011 (set_attr "length" "*,*,4,4,4,4,4,8")])
4013 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4014 ; use it for lack of inter-procedural branch shortening.
4015 ; Link-time relaxation would help...
4018 (define_insn "call_value_prof"
4019 [(set (match_operand 0 "dest_reg_operand" "=r,r")
4020 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
4021 (match_operand 2 "" "")))
4022 (clobber (reg:SI 31))
4029 [(set_attr "type" "call,call_no_delay_slot")
4030 (set_attr "predicable" "yes,yes")
4031 (set_attr "length" "4,8")])
4037 [(set_attr "type" "misc")
4038 (set_attr "iscompact" "true")
4039 (set_attr "cond" "canuse")
4040 (set_attr "length" "2")])
4043 [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4046 [(set_attr "type" "misc")
4047 (set_attr "iscompact" "true")
4048 (set_attr "length" "2")])
4050 ;; Special pattern to flush the icache.
4051 ;; ??? Not sure what to do here. Some ARC's are known to support this.
4053 (define_insn "flush_icache"
4054 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4057 [(set_attr "type" "misc")])
4059 ;; Split up troublesome insns for better scheduling.
4061 ;; Peepholes go at the end.
4062 ;;asl followed by add can be replaced by an add{1,2,3}
4063 ;; Three define_peepholes have been added for this optimization
4064 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4065 ;; can be generated by combine. Check if these peepholes still provide
4068 ;; -------------------------------------------------------------
4069 ;; Pattern 1 : r0 = r1 << {i}
4070 ;; r3 = r4/INT + r0 ;;and commutative
4073 ;; add{i} r3,r4/INT,r1
4074 ;; -------------------------------------------------------------
4075 ;; ??? This should be covered by combine, alas, at times combine gets
4076 ;; too clever for it's own good: when the shifted input is known to be
4077 ;; either 0 or 1, the operation will be made into an if-then-else, and
4078 ;; thus fail to match the add_n pattern. Example: _mktm_r, line 85 in
4079 ;; newlib/libc/time/mktm_r.c .
4082 [(set (match_operand:SI 0 "dest_reg_operand" "")
4083 (ashift:SI (match_operand:SI 1 "register_operand" "")
4084 (match_operand:SI 2 "const_int_operand" "")))
4085 (set (match_operand:SI 3 "dest_reg_operand" "")
4086 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4087 (match_operand:SI 5 "nonmemory_operand" "")))]
4088 "(INTVAL (operands[2]) == 1
4089 || INTVAL (operands[2]) == 2
4090 || INTVAL (operands[2]) == 3)
4091 && (true_regnum (operands[4]) == true_regnum (operands[0])
4092 || true_regnum (operands[5]) == true_regnum (operands[0]))
4093 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4094 ;; the preparation statements take care to put proper operand in operands[4]
4095 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4097 (plus:SI (mult:SI (match_dup 1)
4100 "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4101 operands[4] = operands[5];
4102 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4105 ;; -------------------------------------------------------------
4106 ;; Pattern 1 : r0 = r1 << {i}
4111 ;; -------------------------------------------------------------
4112 ;; ??? This should be covered by combine, alas, at times combine gets
4113 ;; too clever for it's own good: when the shifted input is known to be
4114 ;; either 0 or 1, the operation will be made into an if-then-else, and
4115 ;; thus fail to match the sub_n pattern. Example: __ieee754_yn, line 239 in
4116 ;; newlib/libm/math/e_jn.c .
4119 [(set (match_operand:SI 0 "dest_reg_operand" "")
4120 (ashift:SI (match_operand:SI 1 "register_operand" "")
4121 (match_operand:SI 2 "const_int_operand" "")))
4122 (set (match_operand:SI 3 "dest_reg_operand" "")
4123 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4125 "(INTVAL (operands[2]) == 1
4126 || INTVAL (operands[2]) == 2
4127 || INTVAL (operands[2]) == 3)
4128 && (peep2_reg_dead_p (2, operands[0])
4129 || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4131 (minus:SI (match_dup 4)
4132 (mult:SI (match_dup 1)
4134 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4139 ; When using the high single bit, the result of a multiply is either
4140 ; the original number or zero. But MPY costs 4 cycles, which we
4141 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4143 [(set (match_operand:SI 0 "dest_reg_operand" "")
4144 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4146 (set (match_operand:SI 4 "register_operand" "")
4147 (mult:SI (match_operand:SI 2 "register_operand")
4148 (match_operand:SI 3 "nonmemory_operand" "")))]
4150 && (rtx_equal_p (operands[0], operands[2])
4151 || rtx_equal_p (operands[0], operands[3]))
4152 && peep2_regno_dead_p (0, CC_REG)
4153 && (rtx_equal_p (operands[0], operands[4])
4154 || (peep2_reg_dead_p (2, operands[0])
4155 && peep2_reg_dead_p (1, operands[4])))"
4156 [(parallel [(set (reg:CC_Z CC_REG)
4157 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4159 (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4161 (ne (reg:CC_Z CC_REG) (const_int 0))
4162 (set (match_dup 4) (match_dup 5)))]
4164 if (!rtx_equal_p (operands[0], operands[2]))
4165 operands[5] = operands[2];
4166 else if (!rtx_equal_p (operands[0], operands[3]))
4167 operands[5] = operands[3];
4169 operands[5] = operands[4]; /* Actually a no-op... presumably rare. */
4173 [(set (match_operand:SI 0 "dest_reg_operand" "")
4174 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4176 (set (match_operand:SI 4 "register_operand" "")
4177 (mult:SI (match_operand:SI 2 "register_operand")
4178 (match_operand:SI 3 "nonmemory_operand" "")))]
4180 && (rtx_equal_p (operands[0], operands[2])
4181 || rtx_equal_p (operands[0], operands[3]))
4182 && peep2_regno_dead_p (2, CC_REG)"
4183 [(parallel [(set (reg:CC_Z CC_REG)
4184 (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4186 (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4187 (set (match_dup 4) (match_dup 5))
4189 (eq (reg:CC_Z CC_REG) (const_int 0))
4190 (set (match_dup 4) (const_int 0)))]
4191 "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4193 ;; Instructions generated through builtins
4195 (define_insn "clrsbsi2"
4196 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4197 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4202 [(set_attr "length" "4,8")
4203 (set_attr "type" "two_cycle_core,two_cycle_core")])
4205 (define_insn "norm_f"
4206 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4207 (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4208 (set (reg:CC_ZN CC_REG)
4209 (compare:CC_ZN (match_dup 1) (const_int 0)))]
4214 [(set_attr "length" "4,8")
4215 (set_attr "type" "two_cycle_core,two_cycle_core")])
4217 (define_insn_and_split "clrsbhi2"
4218 [(set (match_operand:HI 0 "dest_reg_operand" "=w,w")
4219 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4223 [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4224 "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4226 (define_insn "normw"
4227 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4229 (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4234 [(set_attr "length" "4,8")
4235 (set_attr "type" "two_cycle_core,two_cycle_core")])
4237 (define_expand "clzsi2"
4238 [(set (match_operand:SI 0 "dest_reg_operand" "")
4239 (clz:SI (match_operand:SI 1 "register_operand" "")))]
4242 emit_insn (gen_norm_f (operands[0], operands[1]));
4246 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4247 gen_rtx_SET (operands[0], const0_rtx)));
4251 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4252 gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4256 (define_expand "ctzsi2"
4257 [(set (match_operand:SI 0 "register_operand" "")
4258 (ctz:SI (match_operand:SI 1 "register_operand" "")))]
4261 rtx temp = operands[0];
4263 if (reg_overlap_mentioned_p (temp, operands[1])
4264 || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4265 && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4267 temp = gen_reg_rtx (SImode);
4268 emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4269 emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4270 emit_insn (gen_clrsbsi2 (temp, temp));
4274 gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4275 gen_rtx_SET (operands[0], GEN_INT (32))));
4279 gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4280 gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), temp))));
4286 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
4287 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4294 [(set_attr "length" "4,8,4")
4295 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4297 (define_insn "divaw"
4298 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4299 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4300 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4302 "TARGET_ARC700 || TARGET_EA_SET"
4306 divaw \t%0, %1, %S2"
4307 [(set_attr "length" "4,8,8")
4308 (set_attr "type" "divaw,divaw,divaw")])
4311 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4318 [(set_attr "length" "4,4,8")
4319 (set_attr "type" "misc,misc,misc")
4320 (set_attr "predicable" "yes,no,yes")
4321 (set_attr "cond" "clob,clob,clob")])
4324 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4328 [(set_attr "length" "4")
4329 (set_attr "type" "misc")])
4332 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4336 [(set_attr "length" "4")
4337 (set_attr "type" "misc")
4338 (set_attr "cond" "clob")])
4341 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4345 [(set_attr "length" "4")
4346 (set_attr "type" "misc")])
4349 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4359 [(set_attr "length" "4")
4360 (set_attr "type" "misc")])
4363 (define_insn "sleep"
4364 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4366 "check_if_valid_sleep_operand(operands,0)"
4368 [(set_attr "length" "4")
4369 (set_attr "type" "misc")])
4371 (define_insn "core_read"
4372 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
4373 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4374 VUNSPEC_ARC_CORE_READ))]
4377 if (check_if_valid_regno_const (operands, 1))
4378 return \"mov \t%0, r%1\";
4379 return \"mov \t%0, r%1\";
4381 [(set_attr "length" "4")
4382 (set_attr "type" "unary")])
4384 (define_insn "core_write"
4385 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4386 (match_operand:SI 1 "general_operand" "Hn,!r")]
4387 VUNSPEC_ARC_CORE_WRITE)]
4390 if (check_if_valid_regno_const (operands, 1))
4391 return \"mov \tr%1, %0\";
4392 return \"mov \tr%1, %0\";
4394 [(set_attr "length" "4")
4395 (set_attr "type" "unary")])
4398 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
4399 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4403 [(set_attr "length" "4,8,4,8")
4404 (set_attr "type" "lr,lr,lr,lr")])
4407 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4408 (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4412 [(set_attr "length" "8,4,8,4")
4413 (set_attr "type" "sr,sr,sr,sr")])
4415 (define_insn "trap_s"
4416 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4417 VUNSPEC_ARC_TRAP_S)]
4418 "!TARGET_ARC600_FAMILY"
4420 if (which_alternative == 0)
4422 arc_toggle_unalign ();
4423 return \"trap_s %0\";
4426 /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4427 because *.md files do not get scanned by exgettext. */
4428 fatal_error (input_location,
4429 \"operand to trap_s should be an unsigned 6-bit value\");
4431 [(set_attr "length" "2")
4432 (set_attr "type" "misc")])
4434 (define_insn "unimp_s"
4435 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4436 VUNSPEC_ARC_UNIMP_S)]
4437 "!TARGET_ARC600_FAMILY"
4439 [(set_attr "length" "4")
4440 (set_attr "type" "misc")])
4442 ;; End of instructions generated through builtins
4444 ; Since the demise of REG_N_SETS as reliable data readily available to the
4445 ; target, it is no longer possible to find out
4446 ; in the prologue / epilogue expanders how many times blink is set.
4447 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4448 ; any explicit use of blink will cause it to be saved; hence we cannot
4449 ; represent the blink use in return / sibcall instructions themselves, and
4450 ; instead have to show it in EPILOGUE_USES and must explicitly
4451 ; forbid instructions that change blink in the return / sibcall delay slot.
4452 (define_expand "sibcall"
4453 [(parallel [(call (match_operand 0 "memory_operand" "")
4454 (match_operand 1 "general_operand" ""))
4456 (use (match_operand 2 "" ""))])]
4460 rtx callee = XEXP (operands[0], 0);
4462 if (operands[2] == NULL_RTX)
4463 operands[2] = const0_rtx;
4464 if (crtl->profile && arc_profile_call (callee))
4466 emit_insn (gen_sibcall_prof
4467 (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4468 operands[1], operands[2]));
4471 if (GET_CODE (callee) != REG
4472 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4473 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4477 (define_expand "sibcall_value"
4478 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4479 (call (match_operand 1 "memory_operand" "")
4480 (match_operand 2 "general_operand" "")))
4482 (use (match_operand 3 "" ""))])]
4486 rtx callee = XEXP (operands[1], 0);
4488 if (operands[3] == NULL_RTX)
4489 operands[3] = const0_rtx;
4490 if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
4492 emit_insn (gen_sibcall_value_prof
4493 (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
4494 operands[2], operands[3]));
4497 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4498 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4502 (define_insn "*sibcall_insn"
4503 [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4504 "Cbp,Cbr,Rs5,Rsc,Cal"))
4505 (match_operand 1 "" ""))
4507 (use (match_operand 2 "" ""))]
4515 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4516 (set_attr "predicable" "yes,no,no,yes,yes")
4517 (set_attr "iscompact" "false,false,maybe,false,false")
4518 (set_attr "is_SIBCALL" "yes")]
4521 (define_insn "*sibcall_value_insn"
4522 [(set (match_operand 0 "dest_reg_operand" "")
4523 (call (mem:SI (match_operand:SI 1 "call_address_operand"
4524 "Cbp,Cbr,Rs5,Rsc,Cal"))
4525 (match_operand 2 "" "")))
4527 (use (match_operand 3 "" ""))]
4535 [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4536 (set_attr "predicable" "yes,no,no,yes,yes")
4537 (set_attr "iscompact" "false,false,maybe,false,false")
4538 (set_attr "is_SIBCALL" "yes")]
4541 (define_insn "sibcall_prof"
4542 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
4543 (match_operand 1 "" ""))
4545 (use (match_operand 2 "" ""))
4552 [(set_attr "type" "call,call_no_delay_slot")
4553 (set_attr "predicable" "yes")
4554 (set_attr "is_SIBCALL" "yes")]
4557 (define_insn "sibcall_value_prof"
4558 [(set (match_operand 0 "dest_reg_operand" "")
4559 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
4560 (match_operand 2 "" "")))
4562 (use (match_operand 3 "" ""))
4569 [(set_attr "type" "call,call_no_delay_slot")
4570 (set_attr "predicable" "yes")
4571 (set_attr "is_SIBCALL" "yes")]
4574 (define_expand "prologue"
4578 arc_expand_prologue ();
4582 (define_expand "epilogue"
4586 arc_expand_epilogue (0);
4590 (define_expand "sibcall_epilogue"
4594 arc_expand_epilogue (1);
4598 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4599 ; in the prologue / epilogue expanders how many times blink is set.
4600 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4601 ; any explicit use of blink will cause it to be saved; hence we cannot
4602 ; represent the blink use in return / sibcall instructions themselves, and
4603 ; instead have to show it in EPILOGUE_USES and must explicitly
4604 ; forbid instructions that change blink in the return / sibcall delay slot.
4605 (define_insn "simple_return"
4610 = gen_rtx_REG (Pmode,
4611 arc_return_address_regs[arc_compute_function_type (cfun)]);
4613 if (arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1
4618 if (TARGET_PAD_RETURN)
4620 output_asm_insn (\"j%!%* [%0]%&\", ®);
4623 [(set_attr "type" "return")
4624 ; predicable won't help here since the canonical rtl looks different
4627 (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4628 (symbol_ref "ARC_FUNCTION_ILINK1"))
4629 (match_test "TARGET_V2"))
4630 (const_string "nocond")]
4631 (const_string "canuse")))
4632 (set (attr "iscompact")
4633 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4634 (symbol_ref "ARC_FUNCTION_NORMAL"))
4635 (const_string "maybe")]
4636 (const_string "false")))
4637 (set (attr "length")
4638 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4639 (symbol_ref "ARC_FUNCTION_NORMAL"))
4643 (define_insn "p_return_i"
4645 (if_then_else (match_operator 0 "proper_comparison_operator"
4646 [(reg CC_REG) (const_int 0)])
4647 (simple_return) (pc)))]
4650 && arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1)"
4653 xop[0] = operands[0];
4655 = gen_rtx_REG (Pmode,
4656 arc_return_address_regs[arc_compute_function_type (cfun)]);
4658 if (TARGET_PAD_RETURN)
4660 output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4661 /* record the condition in case there is a delay insn. */
4662 arc_ccfsm_record_condition (xop[0], false, insn, 0);
4665 [(set_attr "type" "return")
4666 (set_attr "cond" "use")
4667 (set (attr "iscompact")
4668 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4669 (symbol_ref "ARC_FUNCTION_NORMAL"))
4670 (const_string "maybe")]
4671 (const_string "false")))
4672 (set (attr "length")
4673 (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4674 (symbol_ref "ARC_FUNCTION_NORMAL"))
4676 (not (match_operand 0 "equality_comparison_operator" ""))
4678 (eq_attr "delay_slot_filled" "yes")
4682 (define_insn_and_split "eh_return"
4684 (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4685 (clobber (match_scratch:SI 1 "=X,r"))
4686 (clobber (match_scratch:SI 2 "=&r,r"))]
4690 [(set (match_dup 2) (match_dup 0))]
4692 int offs = arc_return_slot_offset ();
4695 operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4698 if (!register_operand (operands[0], Pmode)
4699 && !satisfies_constraint_C32 (operands[0]))
4701 emit_move_insn (operands[1], operands[0]);
4702 operands[0] = operands[1];
4704 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4705 if (!strict_memory_address_p (Pmode, addr))
4707 emit_move_insn (operands[2], addr);
4710 operands[2] = gen_frame_mem (Pmode, addr);
4713 [(set_attr "length" "12")])
4715 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4716 ;; non-constant predicate.
4717 (define_expand "return"
4721 ;; Comment in final.c (insn_current_reference_address) says
4722 ;; forward branch addresses are calculated from the next insn after branch
4723 ;; and for backward branches, it is calculated from the branch insn start.
4724 ;; The shortening logic here is tuned to accomodate this behaviour
4725 ;; ??? This should be grokked by the ccfsm machinery.
4726 (define_insn "cbranchsi4_scratch"
4728 (if_then_else (match_operator 0 "proper_comparison_operator"
4729 [(match_operand:SI 1 "register_operand" "c,c, c")
4730 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4731 (label_ref (match_operand 3 "" ""))
4733 (clobber (match_operand 4 "cc_register" ""))]
4735 || (TARGET_EARLY_CBRANCHSI
4736 && brcc_nolimm_operator (operands[0], VOIDmode)))
4737 && !CROSSING_JUMP_P (insn)"
4739 switch (get_attr_length (insn))
4741 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4742 case 4: return \"br%d0%* %1, %B2, %^%l3\";
4743 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4744 return \"br%d0%* %1, %B2, %^%l3\";
4746 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
4747 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4750 [(set_attr "cond" "clob, clob, clob")
4753 (match_test "valid_brcc_with_delay_p (operands)")
4754 (const_string "brcc")
4755 (const_string "brcc_no_delay_slot")))
4756 ; For forward branches, we need to account not only for the distance to
4757 ; the target, but also the difference between pcl and pc, the instruction
4758 ; length, and any delay insn, if present.
4761 (cond ; the outer cond does a test independent of branch shortening.
4762 [(match_operand 0 "brcc_nolimm_operator" "")
4764 [(and (match_operand:CC_Z 4 "cc_register")
4765 (eq_attr "delay_slot_filled" "no")
4766 (ge (minus (match_dup 3) (pc)) (const_int -128))
4767 (le (minus (match_dup 3) (pc))
4768 (minus (const_int 122)
4769 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4771 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
4772 (le (minus (match_dup 3) (pc))
4773 (minus (const_int 244)
4774 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4776 (match_operand:SI 1 "compact_register_operand" "")
4779 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
4780 (le (minus (match_dup 3) (pc)) (const_int 244)))
4782 (match_operand:SI 1 "compact_register_operand" "")
4785 (set (attr "iscompact")
4786 (if_then_else (match_test "get_attr_length (insn) & 2")
4787 (const_string "true") (const_string "false")))])
4789 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
4790 (define_insn "*bbit"
4793 (match_operator 3 "equality_comparison_operator"
4794 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
4796 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
4798 (label_ref (match_operand 0 "" ""))
4800 (clobber (reg:CC_ZN CC_REG))]
4801 "!CROSSING_JUMP_P (insn)"
4803 switch (get_attr_length (insn))
4805 case 4: return (GET_CODE (operands[3]) == EQ
4806 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
4808 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
4809 default: gcc_unreachable ();
4812 [(set_attr "type" "brcc")
4813 (set_attr "cond" "clob")
4814 (set (attr "length")
4815 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
4816 (le (minus (match_dup 0) (pc))
4817 (minus (const_int 248)
4818 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4820 (eq (symbol_ref "which_alternative") (const_int 0))
4823 (set (attr "iscompact")
4824 (if_then_else (match_test "get_attr_length (insn) == 6")
4825 (const_string "true") (const_string "false")))])
4827 ; ??? When testing a bit from a DImode register, combine creates a
4828 ; zero_extract in DImode. This goes via an AND with a DImode constant,
4829 ; so can only be observed on 64 bit hosts.
4830 (define_insn_and_split "*bbit_di"
4833 (match_operator 3 "equality_comparison_operator"
4834 [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
4836 (match_operand 2 "immediate_operand" "L,L"))
4838 (label_ref (match_operand 0 "" ""))
4840 (clobber (reg:CC_ZN CC_REG))]
4841 "!CROSSING_JUMP_P (insn)"
4845 [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
4846 (clobber (reg:CC_ZN CC_REG))])]
4850 xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
4851 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
4855 ; operand 0 is the loop count pseudo register
4856 ; operand 1 is the loop end pattern
4857 (define_expand "doloop_begin"
4858 [(use (match_operand 0 "register_operand" ""))
4859 (use (match_operand 1 "" ""))]
4862 /* Using the INSN_UID of the loop end pattern to identify it causes
4863 trouble with -fcompare-debug, so allocate a debug-independent
4864 id instead. We use negative numbers so that we can use the same
4865 slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
4866 still be able to tell what kind of number this is. */
4867 static HOST_WIDE_INT loop_end_id = 0;
4869 rtx id = GEN_INT (--loop_end_id);
4870 XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
4871 emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
4872 const0_rtx, const0_rtx));
4876 ; ??? can't describe the insn properly as then the optimizers try to
4878 ;(define_insn "doloop_begin_i"
4879 ; [(set (reg:SI LP_START) (pc))
4880 ; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_ARC_LP))
4881 ; (use (match_operand 0 "const_int_operand" "n"))]
4883 ; "lp .L__GCC__LP%0"
4886 ; The operands of doloop_end_i are also read / written by arc_reorg with
4887 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
4888 ; might have to adjust arc_reorg.
4889 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
4890 ; by arc_reorg. arc_reorg might also alter operand 0.
4892 ; N in XVECEXP PATTERN (lp, 0 N)
4894 ; 0 unspec UNSPEC_ARC_LP identify pattern
4895 ; 1 clobber LP_START show LP_START is set
4896 ; 2 clobber LP_END show LP_END is set
4897 ; 3 use operand0 loop count pseudo register
4898 ; 4 use operand1 before arc_reorg: -id
4899 ; after : CODE_LABEL_NUMBER of loop top label
4900 ; 5 use operand2 INSN_UID of loop end insn
4901 ; 6 use operand3 loop setup not at start (1 above, 2 below)
4902 ; 7 use operand4 LABEL_REF of top label, if not
4903 ; immediately following
4904 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
4905 ; instruction that was not at the start of the loop.
4906 ; There is no point is reloading this insn - then lp_count would still not
4907 ; be available for the loop end.
4908 (define_insn "doloop_begin_i"
4909 [(unspec:SI [(pc)] UNSPEC_ARC_LP)
4910 (clobber (reg:SI LP_START))
4911 (clobber (reg:SI LP_END))
4912 (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
4913 (use (match_operand 1 "const_int_operand" "n,n,C_0"))
4914 (use (match_operand 2 "const_int_operand" "n,n,X"))
4915 (use (match_operand 3 "const_int_operand" "C_0,n,X"))
4916 (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
4922 rtx loop_start = operands[4];
4924 if (CONST_INT_P (loop_start))
4925 loop_start = NULL_RTX;
4926 /* Size implications of the alignment will be taken care of by the
4927 alignment inserted at the loop start. */
4928 if (LOOP_ALIGN (0) && INTVAL (operands[1]))
4930 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4931 arc_clear_unalign ();
4933 if (!INTVAL (operands[1]))
4934 return "; LITTLE LOST LOOP";
4935 if (loop_start && flag_pic)
4937 /* ??? Can do better for when a scratch register
4938 is known. But that would require extra testing. */
4939 return "push_s r0\;add r0,pcl,%4-(.&-4)\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-(.&-4)\;sr r0,[3]; LP_END\;pop_s r0";
4941 /* Check if the loop end is in range to be set by the lp instruction. */
4942 size = INTVAL (operands[3]) < 2 ? 0 : 2048;
4943 for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
4947 if (recog_memoized (scan) == CODE_FOR_doloop_end_i
4948 && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
4949 == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
4951 len = get_attr_length (scan);
4954 /* Try to verify that there are at least three instruction fetches
4955 between the loop setup and the first encounter of the loop end. */
4956 for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
4960 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
4961 scan = seq->insn (0);
4964 if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
4967 if (simplejump_p (scan))
4969 scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
4972 if (JUMP_LABEL (scan)
4973 /* JUMP_LABEL might be simple_return instead if an insn. */
4974 && (!INSN_P (JUMP_LABEL (scan))
4975 || (!next_active_insn (JUMP_LABEL (scan))
4976 || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
4977 != CODE_FOR_doloop_begin_i)))
4978 && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
4980 (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
4981 != CODE_FOR_doloop_begin_i)))
4986 len = get_attr_length (scan);
4987 /* Size estimation of asms assumes that each line which is nonempty
4988 codes an insn, and that each has a long immediate. For minimum insn
4989 count, assume merely that a nonempty asm has at least one insn. */
4990 if (GET_CODE (PATTERN (scan)) == ASM_INPUT
4991 || asm_noperands (PATTERN (scan)) >= 0)
4992 n_insns += (len != 0);
4994 n_insns += (len > 4 ? 2 : (len ? 1 : 0));
4998 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
4999 arc_clear_unalign ();
5001 gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5002 if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5006 /* ??? Can do better for when a scratch register
5007 is known. But that would require extra testing. */
5008 arc_clear_unalign ();
5009 return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0";
5011 output_asm_insn ((size < 2048
5012 ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5014 output_asm_insn (loop_start
5015 ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5017 if (TARGET_ARC600 && n_insns < 1)
5018 output_asm_insn ("nop", operands);
5019 return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5021 else if (TARGET_ARC600 && n_insns < 3)
5023 /* At least four instructions are needed between the setting of LP_COUNT
5024 and the loop end - but the lp instruction qualifies as one. */
5025 rtx_insn *prev = prev_nonnote_insn (insn);
5027 if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5028 output_asm_insn ("nop", operands);
5030 return "lp .L__GCC__LP%1";
5032 [(set_attr "type" "loop_setup")
5033 (set_attr_alternative "length"
5034 ; FIXME: length is usually 4, but we need branch shortening
5035 ; to get this right.
5036 ; [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
5037 [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
5038 (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
5040 ;; ??? we should really branch shorten this insn, but then we'd
5041 ;; need a proper label first. N.B. the end label can not only go out
5042 ;; of range when it is far away, but also when it precedes the loop -
5043 ;; which, unfortunately, it sometimes does, when the loop "optimizer"
5044 ;; messes things up.
5047 ; operand 0 is the loop count pseudo register
5048 ; operand 1 is the label to jump to at the top of the loop
5049 ; Use this for the ARC600 and ARC700.
5050 ; ??? ARC600 might want to check if the loop has few iteration and only a
5051 ; single insn - loop setup is expensive then.
5052 (define_expand "doloop_end"
5053 [(use (match_operand 0 "register_operand" ""))
5054 (use (label_ref (match_operand 1 "" "")))]
5057 /* We could do smaller bivs with biv widening, and wider bivs by having
5058 a high-word counter in an outer loop - but punt on this for now. */
5059 if (GET_MODE (operands[0]) != SImode)
5061 emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
5065 (define_insn_and_split "doloop_end_i"
5067 (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5069 (label_ref (match_operand 1 "" ""))
5071 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5072 (use (reg:SI LP_START))
5073 (use (reg:SI LP_END))
5074 (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
5075 (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5079 rtx_insn *prev = prev_nonnote_insn (insn);
5081 /* If there is an immediately preceding label, we must output a nop,
5082 lest a branch to that label will fall out of the loop.
5083 ??? We could try to avoid this by claiming to have a delay slot if there
5084 is a preceding label, and outputting the delay slot insn instead, if
5086 Or we could have some optimization that changes the source edge to update
5087 the loop count and jump to the loop start instead. */
5088 /* For ARC600, we must also prevent jumps inside the loop and jumps where
5089 the loop counter value is live at the target from being directly at the
5090 loop end. Being sure that the loop counter is dead at the target is
5091 too much hair - we can't rely on data flow information at this point -
5092 so insert a nop for all branches.
5093 The ARC600 also can't read the loop counter in the last insn of a loop. */
5095 output_asm_insn (\"nop%?\", operands);
5096 return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5098 "&& memory_operand (operands[0], SImode)"
5101 emit_move_insn (operands[3], operands[0]);
5102 emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5105 [(set_attr "type" "loop_end")
5106 (set (attr "length")
5107 (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
5108 (const_int 4) (const_int 0)))]
5111 ; This pattern is generated by arc_reorg when there is no recognizable
5113 (define_insn "*doloop_fallback"
5114 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5116 (label_ref (match_operand 1 "" ""))
5118 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5119 ; avoid fooling the loop optimizer into assuming this is a special insn.
5121 "*return get_attr_length (insn) == 8
5122 ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5123 : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5124 [(set (attr "length")
5125 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
5126 (le (minus (match_dup 1) (pc)) (const_int 244)))
5127 (const_int 8) (const_int 12)))
5128 (set_attr "type" "brcc_no_delay_slot")
5129 (set_attr "cond" "nocond")]
5132 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5133 (define_insn "doloop_fallback_m"
5134 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5136 (label_ref (match_operand 1 "" ""))
5138 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5139 (set (match_operand:SI 2 "memory_operand" "=m")
5140 (plus:SI (match_dup 0) (const_int -1)))]
5141 ; avoid fooling the loop optimizer into assuming this is a special insn.
5143 "*return get_attr_length (insn) == 12
5144 ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5145 : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5146 [(set (attr "length")
5147 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5148 (le (minus (match_dup 1) (pc)) (const_int 244)))
5149 (const_int 12) (const_int 16)))
5150 (set_attr "type" "brcc_no_delay_slot")
5151 (set_attr "cond" "nocond")]
5154 (define_expand "movmemsi"
5155 [(match_operand:BLK 0 "" "")
5156 (match_operand:BLK 1 "" "")
5157 (match_operand:SI 2 "nonmemory_operand" "")
5158 (match_operand 3 "immediate_operand" "")]
5160 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5162 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5163 ;; to the point that we can generate cmove instructions.
5164 (define_expand "cbranch<mode>4"
5165 [(set (reg:CC CC_REG)
5166 (compare:CC (match_operand:SDF 1 "register_operand" "")
5167 (match_operand:SDF 2 "register_operand" "")))
5170 (match_operator 0 "comparison_operator" [(reg CC_REG)
5172 (label_ref (match_operand 3 "" ""))
5177 gcc_assert (XEXP (operands[0], 0) == operands[1]);
5178 gcc_assert (XEXP (operands[0], 1) == operands[2]);
5179 operands[0] = gen_compare_reg (operands[0], VOIDmode);
5180 emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5184 (define_expand "cmp_float"
5185 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5186 (clobber (reg:SI RETURN_ADDR_REGNUM))
5187 (clobber (reg:SI R12_REG))])]
5191 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5192 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5193 (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5195 (define_insn "*cmpsf_<cmp>"
5196 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5197 (clobber (reg:SI RETURN_ADDR_REGNUM))
5198 (clobber (reg:SI R12_REG))]
5199 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5200 && SFUNC_CHECK_PREDICABLE"
5201 "*return arc_output_libcall (\"__<cmp>sf2\");"
5202 [(set_attr "is_sfunc" "yes")
5203 (set_attr "predicable" "yes")])
5205 ;; N.B. for "*cmpdf_ord":
5206 ;; double precision fpx sets bit 31 for NaNs. We need bit 51 set
5207 ;; for the floating point emulation to recognize the NaN.
5208 (define_insn "*cmpdf_<cmp>"
5209 [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5210 (clobber (reg:SI RETURN_ADDR_REGNUM))
5211 (clobber (reg:SI R12_REG))]
5212 "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5213 && SFUNC_CHECK_PREDICABLE"
5214 "*return arc_output_libcall (\"__<cmp>df2\");"
5215 [(set_attr "is_sfunc" "yes")
5216 (set_attr "predicable" "yes")])
5218 (define_insn "abssf2"
5219 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5220 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5223 [(set_attr "type" "unary")
5224 (set_attr "iscompact" "maybe,false,false")
5225 (set_attr "length" "2,4,4")
5226 (set_attr "predicable" "no,yes,no")])
5228 (define_insn "negsf2"
5229 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5230 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5233 [(set_attr "type" "unary")
5234 (set_attr "predicable" "yes,no")])
5236 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5237 (define_insn "*millicode_thunk_st"
5238 [(match_parallel 0 "millicode_store_operation"
5239 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5242 output_asm_insn ("bl%* __st_r13_to_%0",
5243 &SET_SRC (XVECEXP (operands[0], 0,
5244 XVECLEN (operands[0], 0) - 2)));
5247 [(set_attr "type" "call")])
5249 (define_insn "*millicode_thunk_ld"
5250 [(match_parallel 0 "millicode_load_clob_operation"
5251 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5254 output_asm_insn ("bl%* __ld_r13_to_%0",
5255 &SET_DEST (XVECEXP (operands[0], 0,
5256 XVECLEN (operands[0], 0) - 2)));
5259 [(set_attr "type" "call")])
5261 ; the sibthunk restores blink, so we use the return rtx.
5262 (define_insn "*millicode_sibthunk_ld"
5263 [(match_parallel 0 "millicode_load_operation"
5265 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5266 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5269 output_asm_insn ("b%* __ld_r13_to_%0_ret",
5270 &SET_DEST (XVECEXP (operands[0], 0,
5271 XVECLEN (operands[0], 0) - 1)));
5274 [(set_attr "type" "call")
5275 (set_attr "is_SIBCALL" "yes")])
5277 ;; If hardware floating point is available, don't define a negdf pattern;
5278 ;; it would be something like:
5279 ;;(define_insn "negdf2"
5280 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5281 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5282 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5285 ;; bxor%? %H0,%H1,31
5286 ;; bxor %H0,%H1,31 ` mov %L0,%L1
5287 ;; drsubh%F0%F1 0,0,0
5288 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5289 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5290 ;; (set_attr "iscompact" "false,false,false,false")
5291 ;; (set_attr "length" "4,4,8,12")
5292 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
5293 ;; and this suffers from always requiring a long immediate when using
5294 ;; the floating point hardware.
5295 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5296 ;; constant zero efficiently into a register when we want to do the
5297 ;; computation using the floating point hardware. There should be a special
5298 ;; subdf alternative that matches a zero operand 1, which then can allow
5299 ;; to use bxor to flip the high bit of an integer register.
5300 ;; ??? we actually can't use the floating point hardware for neg, because
5301 ;; this would not work right for -0. OTOH optabs.c has already code
5302 ;; to synthesyze negate by flipping the sign bit.
5305 (define_insn "bswapsi2"
5306 [(set (match_operand:SI 0 "register_operand" "= r,r")
5307 (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5308 "TARGET_V2 && TARGET_SWAP"
5310 [(set_attr "length" "4,8")
5311 (set_attr "type" "two_cycle_core")])
5313 (define_expand "prefetch"
5314 [(prefetch (match_operand:SI 0 "address_operand" "")
5315 (match_operand:SI 1 "const_int_operand" "")
5316 (match_operand:SI 2 "const_int_operand" ""))]
5320 (define_insn "prefetch_1"
5321 [(prefetch (match_operand:SI 0 "register_operand" "r")
5322 (match_operand:SI 1 "const_int_operand" "n")
5323 (match_operand:SI 2 "const_int_operand" "n"))]
5326 if (INTVAL (operands[1]))
5327 return "prefetchw [%0]";
5329 return "prefetch [%0]";
5331 [(set_attr "type" "load")
5332 (set_attr "length" "4")])
5334 (define_insn "prefetch_2"
5335 [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5336 (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5337 (match_operand:SI 2 "const_int_operand" "n,n,n")
5338 (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5341 if (INTVAL (operands[2]))
5342 return "prefetchw [%0, %1]";
5344 return "prefetch [%0, %1]";
5346 [(set_attr "type" "load")
5347 (set_attr "length" "4,4,8")])
5349 (define_insn "prefetch_3"
5350 [(prefetch (match_operand:SI 0 "address_operand" "p")
5351 (match_operand:SI 1 "const_int_operand" "n")
5352 (match_operand:SI 2 "const_int_operand" "n"))]
5355 operands[0] = gen_rtx_MEM (SImode, operands[0]);
5356 if (INTVAL (operands[1]))
5357 return "prefetchw%U0 %0";
5359 return "prefetch%U0 %0";
5361 [(set_attr "type" "load")
5362 (set_attr "length" "8")])
5364 (define_insn "divsi3"
5365 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5366 (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5367 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5370 [(set_attr "length" "4,4,8,4,4,4,8,8")
5371 (set_attr "iscompact" "false")
5372 (set_attr "type" "div_rem")
5373 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5374 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5377 (define_insn "udivsi3"
5378 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5379 (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5380 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5383 [(set_attr "length" "4,4,8,4,4,4,8,8")
5384 (set_attr "iscompact" "false")
5385 (set_attr "type" "div_rem")
5386 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5387 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5390 (define_insn "modsi3"
5391 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5392 (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5393 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5396 [(set_attr "length" "4,4,8,4,4,4,8,8")
5397 (set_attr "iscompact" "false")
5398 (set_attr "type" "div_rem")
5399 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5400 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5403 (define_insn "umodsi3"
5404 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r,r,r, r, r")
5405 (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0, 0, r")
5406 (match_operand:SI 2 "nonmemory_operand" "r,r, r,L,L,I,Cal,Cal")))]
5409 [(set_attr "length" "4,4,8,4,4,4,8,8")
5410 (set_attr "iscompact" "false")
5411 (set_attr "type" "div_rem")
5412 (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5413 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5416 ;; SETcc instructions
5417 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5419 (define_insn "arcset<code>"
5420 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
5421 (arcCC_cond:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0,0,r")
5422 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5423 "TARGET_V2 && TARGET_CODE_DENSITY"
5424 "set<code>%? %0, %1, %2"
5425 [(set_attr "length" "4,4,4,4,4,8,8")
5426 (set_attr "iscompact" "false")
5427 (set_attr "type" "compare")
5428 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5429 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5432 (define_insn "arcsetltu"
5433 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5434 (ltu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5435 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5436 "TARGET_V2 && TARGET_CODE_DENSITY"
5437 "setlo%? %0, %1, %2"
5438 [(set_attr "length" "4,4,4,4,4,8,8")
5439 (set_attr "iscompact" "false")
5440 (set_attr "type" "compare")
5441 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5442 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5445 (define_insn "arcsetgeu"
5446 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r, r, r")
5447 (geu:SI (match_operand:SI 1 "register_operand" "0,r,0,r,0, 0, r")
5448 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I, n, n")))]
5449 "TARGET_V2 && TARGET_CODE_DENSITY"
5450 "seths%? %0, %1, %2"
5451 [(set_attr "length" "4,4,4,4,4,8,8")
5452 (set_attr "iscompact" "false")
5453 (set_attr "type" "compare")
5454 (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5455 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5458 ;; Special cases of SETCC
5459 (define_insn_and_split "arcsethi"
5460 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5461 (gtu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5462 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5463 "TARGET_V2 && TARGET_CODE_DENSITY"
5464 "setlo%? %0, %2, %1"
5466 && CONST_INT_P (operands[2])
5467 && satisfies_constraint_C62 (operands[2])"
5470 /* sethi a,b,u6 => seths a,b,u6 + 1. */
5471 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5472 emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5475 [(set_attr "length" "4,4,4,8")
5476 (set_attr "iscompact" "false")
5477 (set_attr "type" "compare")
5478 (set_attr "predicable" "yes,no,no,no")
5479 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5482 (define_insn_and_split "arcsetls"
5483 [(set (match_operand:SI 0 "register_operand" "=r,r, r,r")
5484 (leu:SI (match_operand:SI 1 "register_operand" "r,r, r,r")
5485 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5486 "TARGET_V2 && TARGET_CODE_DENSITY"
5487 "seths%? %0, %2, %1"
5489 && CONST_INT_P (operands[2])
5490 && satisfies_constraint_C62 (operands[2])"
5493 /* setls a,b,u6 => setlo a,b,u6 + 1. */
5494 operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5495 emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5498 [(set_attr "length" "4,4,4,8")
5499 (set_attr "iscompact" "false")
5500 (set_attr "type" "compare")
5501 (set_attr "predicable" "yes,no,no,no")
5502 (set_attr "cond" "canuse,nocond,nocond,nocond")]
5505 ; Any mode that needs to be solved by secondary reload
5506 (define_mode_iterator SRI [QI HI])
5508 (define_expand "reload_<mode>_load"
5509 [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5510 (match_operand:SRI 1 "memory_operand" "m")
5511 (match_operand:SI 2 "register_operand" "=&r")])]
5514 arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5518 (define_expand "reload_<mode>_store"
5519 [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5520 (match_operand:SRI 1 "register_operand" "r")
5521 (match_operand:SI 2 "register_operand" "=&r")])]
5524 arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5529 (define_insn "extzvsi"
5530 [(set (match_operand:SI 0 "register_operand" "=r , r , r, r, r")
5531 (zero_extract:SI (match_operand:SI 1 "register_operand" "0 , r , 0, 0, r")
5532 (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5533 (match_operand:SI 3 "const_int_operand" "i , i , i, i, i")))]
5534 "TARGET_HS && TARGET_BARREL_SHIFTER"
5536 int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5537 operands[2] = GEN_INT (assemble_op2);
5538 return "xbfu%? %0,%1,%2";
5540 [(set_attr "type" "shift")
5541 (set_attr "iscompact" "false")
5542 (set_attr "length" "4,4,4,8,8")
5543 (set_attr "predicable" "yes,no,no,yes,no")
5544 (set_attr "cond" "canuse,nocond,nocond,canuse,nocond")])
5546 (define_insn "kflag"
5547 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5554 [(set_attr "length" "4,4,8")
5555 (set_attr "type" "misc,misc,misc")
5556 (set_attr "predicable" "yes,no,yes")
5557 (set_attr "cond" "clob,clob,clob")])
5560 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
5561 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5565 [(set_attr "length" "4")
5566 (set_attr "type" "misc")])
5569 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5570 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5572 "TARGET_NORM && TARGET_V2"
5576 [(set_attr "length" "4,8")
5577 (set_attr "type" "two_cycle_core,two_cycle_core")])
5579 (define_insn "ffs_f"
5580 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5581 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5583 (set (reg:CC_ZN CC_REG)
5584 (compare:CC_ZN (match_dup 1) (const_int 0)))]
5585 "TARGET_NORM && TARGET_V2"
5589 [(set_attr "length" "4,8")
5590 (set_attr "type" "two_cycle_core,two_cycle_core")])
5592 (define_expand "ffssi2"
5593 [(parallel [(set (match_dup 2)
5594 (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5596 (set (reg:CC_ZN CC_REG)
5597 (compare:CC_ZN (match_dup 1) (const_int 0)))])
5598 (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5599 (set (match_operand:SI 0 "dest_reg_operand" "")
5600 (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5603 "TARGET_NORM && TARGET_V2"
5605 operands[2] = gen_reg_rtx (SImode);
5609 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5610 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5612 "TARGET_NORM && TARGET_V2"
5616 [(set_attr "length" "4,8")
5617 (set_attr "type" "two_cycle_core,two_cycle_core")])
5620 [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5624 [(set_attr "length" "4")
5625 (set_attr "type" "misc")])
5627 ;; include the arc-FPX instructions
5630 (include "simdext.md")
5632 ;; include atomic extensions
5633 (include "atomic.md")