1 ;; Machine description of the ARC ARCompact cpu for GNU C compiler
2 ;; Copyright (C) 1994, 1997, 1999, 2006, 2007, 2008, 2009
3 ;; Free Software Foundation, Inc.
5 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com)
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@arc.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 [IJKLMNOP]
46 ;; register_operand register [rq]
47 ;; general_operand register, memory, constant [rqmIJKLMNOP]
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 ;; signed 9-bit immediate (for ARCtangent-A4)
72 ;; J long immediate (signed 32-bit immediate)
73 ;; K unsigned 3-bit immediate (for ARCompact)
74 ;; L unsigned 6-bit immediate (for ARCompact)
75 ;; M unsinged 5-bit immediate (for ARCompact)
76 ;; O unsinged 7-bit immediate (for ARCompact)
77 ;; P unsinged 8-bit immediate (for ARCompact)
78 ;; N constant '1' (for ARCompact)
81 ;; ashwin : include options.h from build dir
86 ;; -> Supporting arith/logic insns which update the status flag based on the
87 ;; operation result (i.e <op>.f type insns).
88 ;; -> conditional jump Jcc
89 ;; -> prefetch instruction
92 ;; -----------------------------------------------------------------------------
94 ;; Include DFA scheduluers
95 (include ("arc600.md"))
96 (include ("arc700.md"))
100 (include ("predicates.md"))
101 (include ("constraints.md"))
102 ;; -----------------------------------------------------------------------------
106 ;; -----------------------------------------------------------------------------
107 ;; Symbolic name Value Desc.
108 ;; -----------------------------------------------------------------------------
109 ;; UNSPEC_PLT 3 symbol to be referenced through the PLT
110 ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT
111 ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the
112 ;; GOTBASE.(Referenced as @GOTOFF)
113 ;; ----------------------------------------------------------------------------
117 [(UNSPEC_NORM 11) ; norm generation through builtins. candidate for scheduling
118 (UNSPEC_NORMW 12) ; normw generation through builtins. candidate for scheduling
119 (UNSPEC_SWAP 13) ; swap generation through builtins. candidate for scheduling
120 (UNSPEC_MUL64 14) ; mul64 generation through builtins. candidate for scheduling
121 (UNSPEC_MULU64 15) ; mulu64 generation through builtins. candidate for scheduling
122 (UNSPEC_DIVAW 16) ; divaw generation through builtins. candidate for scheduling
124 (UNSPEC_PROF 18) ; profile callgraph counter
125 (UNSPEC_LP 19) ; to set LP_END
127 (VUNSPEC_RTIE 17) ; blockage insn for rtie generation
128 (VUNSPEC_SYNC 18) ; blockage insn for sync generation
129 (VUNSPEC_BRK 19) ; blockage insn for brk generation
130 (VUNSPEC_FLAG 20) ; blockage insn for flag generation
131 (VUNSPEC_SLEEP 21) ; blockage insn for sleep generation
132 (VUNSPEC_SWI 22) ; blockage insn for swi generation
133 (VUNSPEC_CORE_READ 23) ; blockage insn for reading a core register
134 (VUNSPEC_CORE_WRITE 24) ; blockage insn for writing to a core register
135 (VUNSPEC_LR 25) ; blockage insn for reading an auxillary register
136 (VUNSPEC_SR 26) ; blockage insn for writing to an auxillary register
137 (VUNSPEC_TRAP_S 27) ; blockage insn for trap_s generation
138 (VUNSPEC_UNIMP_S 28) ; blockage insn for unimp_s generation
143 (RETURN_ADDR_REGNUM 31)
151 (define_attr "is_sfunc" "no,yes" (const_string "no"))
153 ;; Insn type. Used to default other attribute values.
156 "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
157 brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
158 multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
159 misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
160 simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
161 simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
162 simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
163 simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
164 simd_valign, simd_valign_with_acc, simd_vcontrol,
165 simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma"
166 (cond [(eq_attr "is_sfunc" "yes")
167 (cond [(eq (symbol_ref "TARGET_LONG_CALLS_SET") (const_int 0))
168 (const_string "call")
169 (ne (symbol_ref "flag_pic") (const_int 0))
170 (const_string "sfunc")]
171 (const_string "call_no_delay_slot"))]
172 (const_string "binary")))
174 ;; The following three attributes are mixed case so that they can be
175 ;; used conveniently with the CALL_ATTR macro.
176 (define_attr "is_CALL" "no,yes"
177 (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
178 (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
179 (const_string "no")))
181 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
183 (define_attr "is_NON_SIBCALL" "no,yes"
184 (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
185 (eq_attr "is_CALL" "yes") (const_string "yes")]
186 (const_string "no")))
189 ;; Attribute describing the processor
190 (define_attr "cpu" "A4,A5,ARC600,ARC700"
191 (const (symbol_ref "arc_cpu_attr")))
193 ;; true for compact instructions (those with _s suffix)
194 ;; "maybe" means compact unless we conditionalize the insn.
195 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
196 (cond [(eq_attr "type" "sfunc")
197 (const_string "maybe")]
198 (const_string "false")))
201 ;; Condition codes: this one is used by final_prescan_insn to speed up
202 ;; conditionalizing instructions. It saves having to scan the rtl to see if
203 ;; it uses or alters the condition codes.
205 ;; USE: This insn uses the condition codes (eg: a conditional branch).
206 ;; CANUSE: This insn can use the condition codes (for conditional execution).
207 ;; SET: All condition codes are set by this insn.
208 ;; SET_ZN: the Z and N flags are set by this insn.
209 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
210 ;; CLOB: The condition codes are set to unknown values by this insn.
211 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
213 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
214 (if_then_else (eq_attr "cpu" "A4")
215 (cond [(and (eq_attr "type" "unary,move")
216 (match_operand 1 "register_operand" ""))
217 (const_string "canuse")
219 (and (eq_attr "type" "binary")
220 (match_operand 2 "register_operand" ""))
221 (const_string "canuse")
223 (eq_attr "type" "compare")
226 (eq_attr "type" "cmove,branch")
229 (eq_attr "type" "multi,misc,shift")
230 (const_string "clob")
233 (const_string "nocond"))
235 (if_then_else (eq_attr "iscompact" "maybe,false")
236 (cond [(eq_attr "type" "unary,move")
238 (ior (match_operand 1 "u6_immediate_operand" "")
239 (match_operand 1 "long_immediate_operand" ""))
240 (const_string "canuse")
241 (const_string "nocond"))
243 (eq_attr "type" "binary")
244 (cond [(ne (symbol_ref "REGNO (operands[0])")
245 (symbol_ref "REGNO (operands[1])"))
246 (const_string "nocond")
247 (match_operand 2 "register_operand" "")
248 (const_string "canuse")
249 (match_operand 2 "u6_immediate_operand" "")
250 (const_string "canuse")
251 (match_operand 2 "long_immediate_operand" "")
252 (const_string "canuse")
253 (match_operand 2 "const_int_operand" "")
254 (const_string "canuse_limm")]
255 (const_string "nocond"))
257 (eq_attr "type" "compare")
260 (eq_attr "type" "cmove,branch")
263 (eq_attr "is_sfunc" "yes")
264 (cond [(ne (symbol_ref "(TARGET_MEDIUM_CALLS
265 && !TARGET_LONG_CALLS_SET
268 (const_string "canuse_limm_add")
269 (ne (symbol_ref "(TARGET_MEDIUM_CALLS
270 && !TARGET_LONG_CALLS_SET)")
272 (const_string "canuse_limm")]
273 (const_string "canuse"))
277 (const_string "nocond"))
279 (cond [(eq_attr "type" "compare")
282 (eq_attr "type" "cmove,branch")
287 (const_string "nocond")))))
289 (define_attr "verify_short" "no,yes"
291 (ne (symbol_ref "arc_verify_short (insn, insn_current_address & 2, 0)")
293 (const_string "yes") (const_string "no")))
295 ; Is there an instruction that we are actually putting into the delay slot?
296 (define_attr "delay_slot_filled" "no,yes"
297 (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
299 (ne (symbol_ref "!TARGET_AT_DBR_CONDEXEC
300 && INSN_ANNULLED_BRANCH_P (insn)
301 && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
304 (const_string "yes")))
306 ; Is a delay slot present for purposes of shorten_branches?
307 ; We have to take the length of this insn into account for forward branches
308 ; even if we don't put the insn actually into a delay slot.
309 (define_attr "delay_slot_present" "no,yes"
310 (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
312 (const_string "yes")))
314 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
315 ; length of a different insn with the same uid.
316 (define_attr "delay_slot_length" ""
317 (cond [(ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) == insn") (const_int 0))
319 (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
320 - get_attr_length (insn)")))
323 ;; The length variations of ARCompact can't be expressed with the traditional
324 ;; mechanisms in a way that avoids infinite looping in shorten_branches.
325 ;; Given a set of potentially short insns, we could express the effect of
326 ;; arc_verify_short returing zero as an alignment of the current or the
327 ;; following insn, depending on alignment.
328 ;; However, which branch / jump insns are potentially short in turn depends
329 ;; on instruction length.
330 (define_attr "lock_length" "" (const_int 0))
332 ;; Length (in # of bytes, long immediate constants counted too).
333 ;; ??? There's a nasty interaction between the conditional execution fsm
334 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
335 (define_attr "length" ""
337 [(eq_attr "lock_length" "!0") (const_int 2)
339 (cond [(eq_attr "type" "load")
341 (match_operand 1 "long_immediate_loadstore_operand" "")
342 (const_int 8) (const_int 4))
344 (eq_attr "type" "store")
346 (match_operand 0 "long_immediate_loadstore_operand" "")
347 (const_int 8) (const_int 4))
349 (eq_attr "type" "move,unary,compare")
350 (if_then_else (match_operand 1 "long_immediate_operand" "")
351 (const_int 8) (const_int 4))
353 (eq_attr "type" "binary")
354 (if_then_else (match_operand 2 "long_immediate_operand" "")
355 (const_int 8) (const_int 4))
357 (eq_attr "type" "cmove")
358 (if_then_else (match_operand 1 "register_operand" "")
359 (const_int 4) (const_int 8))
361 (eq_attr "type" "multi") (const_int 8)
362 (eq_attr "cond" "set,set_zn,clob") (const_int 8)
367 (eq_attr "iscompact" "true,maybe")
368 ; The length can vary because of ADJUST_INSN_LENGTH.
369 ; make sure that variable_length_p will be true.
371 [(and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
373 (eq_attr "verify_short" "yes")
377 (eq_attr "iscompact" "true_limm,maybe_limm")
379 [(and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
381 (eq_attr "verify_short" "yes")
386 (cond [(eq_attr "type" "load")
388 (match_operand 1 "long_immediate_loadstore_operand" "")
389 (const_int 8) (const_int 4))
391 (eq_attr "type" "store")
393 (ior (match_operand 0 "long_immediate_loadstore_operand" "")
394 (match_operand 1 "immediate_operand" ""))
395 (const_int 8) (const_int 4))
397 (eq_attr "type" "move,unary")
398 (if_then_else (match_operand 1 "long_immediate_operand" "")
399 (const_int 8) (const_int 4))
401 ;; Added this for adjusting length of nops, for bbit offset calculation to be correct
403 (eq_attr "type" "compare")
404 (if_then_else (match_operand 1 "long_immediate_operand" "")
405 (if_then_else (eq_attr "cpu" "ARC700")
406 (const_int 8) (const_int 12))
408 (if_then_else (eq_attr "cpu" "ARC700")
409 (const_int 4) (const_int 8)))
412 (and (eq_attr "type" "shift")
413 (match_operand 1 "immediate_operand"))
415 (eq_attr "type" "binary,shift")
417 (ior (match_operand 2 "long_immediate_operand" "")
418 (and (ne (symbol_ref "REGNO(operands[0])")
419 (symbol_ref "REGNO(operands[1])"))
420 (eq (match_operand 2 "u6_immediate_operand" "")
423 (const_int 8) (const_int 4))
425 (eq_attr "type" "cmove")
426 (if_then_else (match_operand 1 "register_operand" "")
427 (const_int 4) (const_int 8))
429 (eq_attr "type" "call_no_delay_slot") (const_int 8)
435 ;; The length here is the length of a single asm. Unfortunately it might be
436 ;; 4 or 8 so we must allow for 8. That's ok though. How often will users
437 ;; lament asm's not being put in delay slots?
439 (define_asm_attributes
440 [(set_attr "length" "8")
441 (set_attr "type" "multi")
442 (set_attr "cond" "clob") ])
445 ;; The first two cond clauses and the default are necessary for correctness;
446 ;; the remaining cond clause is mainly an optimization, as otherwise nops
447 ;; would be inserted; however, if we didn't do this optimization, we would
448 ;; have to be more conservative in our length calculations.
450 (define_attr "in_delay_slot" "false,true"
451 (cond [(eq_attr "type" "uncond_branch,jump,branch,
452 call,sfunc,call_no_delay_slot,
453 brcc, brcc_no_delay_slot,loop_setup,loop_end")
454 (const_string "false")
455 (ne (symbol_ref "arc_write_ext_corereg (insn)") (const_int 0))
456 (const_string "false")
457 (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
458 next_active_insn (insn))")
459 (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
460 + arc_hazard (insn, next_active_insn (insn)))"))
461 (const_string "false")
464 (if_then_else (eq_attr "length" "2,4")
465 (const_string "true")
466 (const_string "false"))))
468 ; must not put an insn inside that refers to blink.
469 (define_attr "in_call_delay_slot" "false,true"
470 (cond [(eq_attr "in_delay_slot" "false")
471 (const_string "false")
472 (ne (symbol_ref "arc_regno_use_in (RETURN_ADDR_REGNUM,
475 (const_string "false")]
476 (const_string "true")))
478 (define_attr "in_sfunc_delay_slot" "false,true"
479 (cond [(eq_attr "in_call_delay_slot" "false")
480 (const_string "false")
481 (ne (symbol_ref "arc_regno_use_in (12, PATTERN (insn))")
483 (const_string "false")]
484 (const_string "true")))
486 ;; Instructions that we can put into a delay slot and conditionalize.
487 (define_attr "cond_delay_insn" "no,yes"
488 (cond [(eq_attr "cond" "!canuse") (const_string "no")
489 (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
491 (eq_attr "length" "2,4") (const_string "yes")]
492 (const_string "no")))
494 (define_attr "in_ret_delay_slot" "no,yes"
495 (cond [(eq_attr "in_delay_slot" "false")
497 (ne (symbol_ref "regno_clobbered_p
498 (arc_return_address_regs
499 [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")))
511 (define_delay (and (eq_attr "type" "call,branch,uncond_branch,jump")
512 (ne (symbol_ref "TARGET_A4") (const_int 0)))
513 [(eq_attr "in_delay_slot" "true")
514 (eq_attr "in_delay_slot" "true")
515 (eq_attr "in_delay_slot" "true")])
517 ;; Delay slot definition for ARCompact ISA
519 ;; When outputting an annul-true insn elegible for cond-exec
520 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
521 ;; for ARC600; we could also use this for ARC700 if the branch can't be
522 ;; unaligned and is at least somewhat likely (add parameter for this).
524 ;; (define_delay (and (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
525 ;; (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0)))
526 ;; [(eq_attr "in_delay_slot" "true")
527 ;; (eq_attr "in_delay_slot" "true")
529 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0))
530 (eq_attr "type" "call"))
531 [(eq_attr "in_call_delay_slot" "true")
532 (eq_attr "in_call_delay_slot" "true")
535 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT
536 && !TARGET_AT_DBR_CONDEXEC")
538 (eq_attr "type" "brcc"))
539 [(eq_attr "in_delay_slot" "true")
540 (eq_attr "in_delay_slot" "true")
543 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT && TARGET_AT_DBR_CONDEXEC")
545 (eq_attr "type" "brcc"))
546 [(eq_attr "in_delay_slot" "true")
551 (and (ne (symbol_ref "TARGET_ARCOMPACT")
553 (eq_attr "type" "return"))
554 [(eq_attr "in_ret_delay_slot" "yes")
555 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
556 (eq_attr "cond_ret_delay_insn" "yes")])
558 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
559 ;; non-taken case, so the only meaningful way to have an annull-true
560 ;; filled delay slot is to conditionalize the delay slot insn.
561 (define_delay (and (ne (symbol_ref "TARGET_AT_DBR_CONDEXEC") (const_int 0))
562 (eq_attr "type" "branch,uncond_branch,jump")
563 (eq (symbol_ref "optimize_size") (const_int 0)))
564 [(eq_attr "in_delay_slot" "true")
565 (eq_attr "cond_delay_insn" "yes")
566 (eq_attr "cond_delay_insn" "yes")])
568 ;; For ARC700, anything goes for annulled-true insns, since there is no
569 ;; penalty for the unexposed delay slot when the branch is not taken,
570 ;; however, we must avoid things that have a delay slot themselvese to
571 ;; avoid confucing gcc.
572 (define_delay (and (ne (symbol_ref "!TARGET_AT_DBR_CONDEXEC") (const_int 0))
573 (eq_attr "type" "branch,uncond_branch,jump")
574 (eq (symbol_ref "optimize_size") (const_int 0)))
575 [(eq_attr "in_delay_slot" "true")
576 (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
577 (eq_attr "cond_delay_insn" "yes")])
579 ;; -mlongcall -fpic sfuncs use r12 to load the function address
580 (define_delay (and (ne (symbol_ref "TARGET_ARCOMPACT") (const_int 0))
581 (eq_attr "type" "sfunc"))
582 [(eq_attr "in_sfunc_delay_slot" "true")
583 (eq_attr "in_sfunc_delay_slot" "true")
585 ;; ??? need to use a working strategy for canuse_limm:
586 ;; - either canuse_limm is not eligible for delay slots, and has no
587 ;; delay slots, or arc_reorg has to treat them as nocond, or it has to
588 ;; somehow modify them to become inelegible for delay slots if a decision
589 ;; is made that makes conditional execution required.
591 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
593 (cond [(symbol_ref "arc_tune == TUNE_ARC600")
594 (const_string "arc600")
595 (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
596 (const_string "arc700_4_2_std")
597 (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
598 (const_string "arc700_4_2_xmac")]
599 (const_string "none"))))
601 (define_attr "tune_arc700" "false,true"
602 (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
603 (const_string "true")
604 (const_string "false")))
606 ;; Function units of the ARC
608 ;; (define_function_unit {name} {num-units} {n-users} {test}
609 ;; {ready-delay} {issue-delay} [{conflict-list}])
611 ;; 1) A conditional jump cannot immediately follow the insn setting the flags in pre ARC700 processors.
612 ;; The ARC700 has no problems with consecutive instructions setting and
614 ;; (define_function_unit "compare" 1 0 (and (eq_attr "type" "compare") (not (eq_attr "cpu" "ARC700"))) 2 2 [(eq_attr "type" "branch")])
615 ;; (define_function_unit "compare" 1 0 (and (eq_attr "type" "compare") (eq_attr "cpu" "ARC700") ) 1 1 [(eq_attr "type" "branch")])
617 ;; 2) References to loaded registers should wait a cycle.
619 ;; Memory with load-delay of 1 (i.e., 2 cycle load).
620 ;; (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0)
622 ;; Units that take one cycle do not need to be specified.
624 ;; Move instructions.
625 (define_expand "movqi"
626 [(set (match_operand:QI 0 "move_dest_operand" "")
627 (match_operand:QI 1 "general_operand" ""))]
629 "if (prepare_move_operands (operands, QImode)) DONE;")
631 ; In order to allow the ccfsm machinery to do its work, the leading compact
632 ; alternatives say 'canuse' - there is another alternative that will match
633 ; when the condition codes are used.
634 ; Rcq won't match if the condition is actually used; to avoid a spurious match
635 ; via q, q is inactivated as constraint there.
636 ; Likewise, the length of an alternative that might be shifted to conditional
637 ; execution must reflect this, lest out-of-range branches are created.
638 ; The iscompact attribute allows the epilogue expander to know for which
639 ; insns it should lengthen the return insn.
640 (define_insn "*movqi_insn"
641 [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
642 (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
643 "register_operand (operands[0], QImode)
644 || register_operand (operands[1], QImode)"
659 [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
660 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
661 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond")])
663 (define_expand "movhi"
664 [(set (match_operand:HI 0 "move_dest_operand" "")
665 (match_operand:HI 1 "general_operand" ""))]
667 "if (prepare_move_operands (operands, HImode)) DONE;")
669 (define_insn "*movhi_insn"
670 [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
671 (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac, ?i,?i,T,Rcq,m,c,?Rac,i"))]
672 "register_operand (operands[0], HImode)
673 || register_operand (operands[1], HImode)
674 || (CONSTANT_P (operands[1])
675 /* Don't use a LIMM that we could load with a single insn - we loose
676 delay-slot filling opportunities. */
677 && !satisfies_constraint_I (operands[1])
678 && satisfies_constraint_Usc (operands[0]))"
694 [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
695 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
696 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond")])
698 (define_expand "movsi"
699 [(set (match_operand:SI 0 "move_dest_operand" "")
700 (match_operand:SI 1 "general_operand" ""))]
702 "if (prepare_move_operands (operands, SImode)) DONE;")
705 ; In order to allow the ccfsm machinery to do its work, the leading compact
706 ; alternatives say 'canuse' - there is another alternative that will match
707 ; when the condition codes are used.
708 ; Rcq won't match if the condition is actually used; to avoid a spurious match
709 ; via q, q is inactivated as constraint there.
710 ; Likewise, the length of an alternative that might be shifted to conditional
711 ; execution must reflect this, lest out-of-range branches are created.
712 ; the iscompact attribute allows the epilogue expander to know for which
713 ; insns it should lengthen the return insn.
714 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
715 (define_insn "*movsi_insn"
716 [(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")
717 (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"))]
718 "register_operand (operands[0], SImode)
719 || register_operand (operands[1], SImode)
720 || (CONSTANT_P (operands[1])
721 /* Don't use a LIMM that we could load with a single insn - we loose
722 delay-slot filling opportunities. */
723 && !satisfies_constraint_I (operands[1])
724 && satisfies_constraint_Usc (operands[0]))"
731 ror %0,((%1*2+1) & 0x3f)
734 * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
739 * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
740 * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
746 [(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")
747 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
748 ; Use default length for iscompact to mark length varying. But set length
750 (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
751 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse_limm,canuse_limm,canuse,nocond,nocond,canuse,canuse,nocond,nocond,nocond,nocond,nocond,nocond,nocond,nocond,nocond")])
753 ;; sometimes generated by the epilogue code. We don't want to
754 ;; recognize these addresses in general, because the limm is costly,
755 ;; and we can't use them for stores. */
756 (define_insn "*movsi_pre_mod"
757 [(set (match_operand:SI 0 "register_operand" "=w")
760 (plus:SI (reg:SI SP_REG)
761 (match_operand 1 "immediate_operand" "Cal")))))]
764 [(set_attr "type" "load")
765 (set_attr "length" "8")])
767 /* Store a value to directly to memory. The location might also be cached.
768 Since the cached copy can cause a write-back at unpredictable times,
769 we first write cached, then we write uncached. */
770 (define_insn "store_direct"
771 [(set (match_operand:SI 0 "move_dest_operand" "=m")
772 (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
775 "st%U0 %1,%0\;st%U0.di %1,%0"
776 [(set_attr "type" "store")])
778 (define_insn "*movsi_set_cc_insn"
779 [(set (match_operand:CC_ZN 2 "cc_set_register" "")
780 (match_operator 3 "zn_compare_operator"
781 [(match_operand:SI 1 "nonmemory_operand" "cI,Cal") (const_int 0)]))
782 (set (match_operand:SI 0 "register_operand" "=w,w")
786 [(set_attr "type" "compare")
787 (set_attr "cond" "set_zn")
788 (set_attr "length" "4,8")])
790 (define_insn "unary_comparison"
791 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
792 (match_operator 3 "zn_compare_operator"
793 [(match_operator:SI 2 "unary_operator"
794 [(match_operand:SI 1 "register_operand" "c")])
798 [(set_attr "type" "compare")
799 (set_attr "cond" "set_zn")])
802 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
803 (define_insn "*unary_comparison_result_used"
804 [(set (match_operand 2 "cc_register" "")
805 (match_operator 4 "zn_compare_operator"
806 [(match_operator:SI 3 "unary_operator"
807 [(match_operand:SI 1 "register_operand" "c")])
809 (set (match_operand:SI 0 "register_operand" "=w")
813 [(set_attr "type" "compare")
814 (set_attr "cond" "set_zn")
815 (set_attr "length" "4")])
819 (match_operand 0 "cc_register" "")
820 (match_operator 3 "zn_compare_operator"
822 (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c, c")
823 (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,CnL,Cal"))
826 && ((register_operand (operands[1], SImode)
827 && nonmemory_operand (operands[2], SImode))
828 || (memory_operand (operands[1], SImode)
829 && satisfies_constraint_Cux (operands[2])))"
831 switch (which_alternative)
833 case 0: case 2: case 6:
834 return \"tst%? %1,%2\";
836 return \"btst%? %1,%z2\";
838 return \"bmsk%?.f 0,%1,%Z2%&\";
840 return \"bclr%?.f 0,%1,%M2%&\";
842 return \"bic%?.f 0,%1,%n2-1\";
847 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
848 (set_attr "type" "compare")
849 (set_attr "length" "*,*,4,4,4,4,8")
850 (set_attr "cond" "set_zn")])
852 (define_insn "*commutative_binary_comparison"
853 [(set (match_operand:CC_ZN 0 "cc_set_register" "")
854 (match_operator 5 "zn_compare_operator"
855 [(match_operator:SI 4 "commutative_operator"
856 [(match_operand:SI 1 "register_operand" "%c,c,c")
857 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
859 (clobber (match_scratch:SI 3 "=X,1,X"))]
862 [(set_attr "type" "compare")
863 (set_attr "cond" "set_zn")
864 (set_attr "length" "4,4,8")])
866 ; for flag setting 'add' instructions like if (a+b) { ...}
867 ; the combiner needs this pattern
868 (define_insn "*addsi_compare"
869 [(set (reg:CC_ZN CC_REG)
870 (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
871 (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
874 [(set_attr "cond" "set")
875 (set_attr "type" "compare")
876 (set_attr "length" "4")])
878 ; for flag setting 'add' instructions like if (a+b < a) { ...}
879 ; the combiner needs this pattern
880 (define_insn "addsi_compare_2"
881 [(set (reg:CC_C CC_REG)
882 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
883 (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
887 [(set_attr "cond" "set")
888 (set_attr "type" "compare")
889 (set_attr "length" "4,8")])
891 (define_insn "*addsi_compare_3"
892 [(set (reg:CC_C CC_REG)
893 (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
894 (match_operand:SI 1 "register_operand" "c"))
898 [(set_attr "cond" "set")
899 (set_attr "type" "compare")
900 (set_attr "length" "4")])
902 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
903 (define_insn "*commutative_binary_comparison_result_used"
904 [(set (match_operand 3 "cc_register" "")
905 (match_operator 5 "zn_compare_operator"
906 [(match_operator:SI 4 "commutative_operator"
907 [(match_operand:SI 1 "register_operand" "c,0,c")
908 (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
910 (set (match_operand:SI 0 "register_operand" "=w,w,w")
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")
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 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"))]
944 [(set_attr "type" "compare")
945 (set_attr "cond" "set_zn")
946 (set_attr "length" "4,4,8")])
948 (define_expand "movdi"
949 [(set (match_operand:DI 0 "move_dest_operand" "")
950 (match_operand:DI 1 "general_operand" ""))]
954 /* Everything except mem = const or mem = mem can be done easily. */
956 if (GET_CODE (operands[0]) == MEM)
957 operands[1] = force_reg (DImode, operands[1]);
960 (define_insn_and_split "*movdi_insn"
961 [(set (match_operand:DI 0 "move_dest_operand" "=w,w,r,m")
962 (match_operand:DI 1 "move_double_src_operand" "c,HJi,m,c"))]
963 "register_operand (operands[0], DImode)
964 || register_operand (operands[1], DImode)"
967 switch (which_alternative)
971 /* We normally copy the low-numbered register first. However, if
972 the first register operand 0 is the same as the second register of
973 operand 1, we must copy in the opposite order. */
974 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
975 return \"mov%? %R0,%R1\;mov%? %0,%1\";
977 return \"mov%? %0,%1\;mov%? %R0,%R1\";
979 return \"mov%? %L0,%L1\;mov%? %H0,%H1\";
981 /* If the low-address word is used in the address, we must load it
982 last. Otherwise, load it first. Note that we cannot have
983 auto-increment in that case since the address register is known to be
985 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
987 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
988 else switch (GET_CODE (XEXP(operands[1], 0)))
990 case POST_MODIFY: case POST_INC: case POST_DEC:
991 return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
992 case PRE_MODIFY: case PRE_INC: case PRE_DEC:
993 return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
995 return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
998 switch (GET_CODE (XEXP(operands[0], 0)))
1000 case POST_MODIFY: case POST_INC: case POST_DEC:
1001 return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
1002 case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1003 return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
1005 return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
1009 "&& reload_completed && optimize"
1010 [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
1011 "arc_split_move (operands);"
1012 [(set_attr "type" "move,move,load,store")
1013 ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1014 (set_attr "length" "8,16,16,16")])
1017 ;; Floating point move insns.
1019 (define_expand "movsf"
1020 [(set (match_operand:SF 0 "general_operand" "")
1021 (match_operand:SF 1 "general_operand" ""))]
1023 "if (prepare_move_operands (operands, SFmode)) DONE;")
1025 (define_insn "*movsf_insn"
1026 [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m")
1027 (match_operand:SF 1 "move_src_operand" "c,E,m,c"))]
1028 "register_operand (operands[0], SFmode)
1029 || register_operand (operands[1], SFmode)"
1035 [(set_attr "type" "move,move,load,store")])
1037 (define_expand "movdf"
1038 [(set (match_operand:DF 0 "general_operand" "")
1039 (match_operand:DF 1 "general_operand" ""))]
1041 "if (prepare_move_operands (operands, DFmode)) DONE;")
1043 (define_insn_and_split "*movdf_insn"
1044 [(set (match_operand:DF 0 "move_dest_operand" "=w,w,r,m,D,r")
1045 (match_operand:DF 1 "move_double_src_operand" "c,E,m,c,r,D"))]
1046 "register_operand (operands[0], DFmode)
1047 || register_operand (operands[1], DFmode)"
1050 switch (which_alternative)
1054 /* We normally copy the low-numbered register first. However, if
1055 the first register operand 0 is the same as the second register of
1056 operand 1, we must copy in the opposite order. */
1057 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1058 return \"mov %R0,%R1\;mov %0,%1\";
1060 return \"mov%? %0,%1\;mov%? %R0,%R1\";
1062 return \"mov%? %L0,%L1\;mov%? %H0,%H1 ; %A1\";
1064 /* If the low-address word is used in the address, we must load it
1065 last. Otherwise, load it first. Note that we cannot have
1066 auto-increment in that case since the address register is known to be
1068 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
1070 return \"ld%V1 %R0,%R1\;ld%V1 %0,%1\";
1071 else switch (GET_CODE (XEXP(operands[1], 0)))
1073 case POST_MODIFY: case POST_INC: case POST_DEC:
1074 return \"ld%V1 %R0,%R1\;ld%U1%V1 %0,%1\";
1075 case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1076 return \"ld%U1%V1 %0,%1\;ld%V1 %R0,%R1\";
1078 return \"ld%U1%V1 %0,%1\;ld%U1%V1 %R0,%R1\";
1081 switch (GET_CODE (XEXP(operands[0], 0)))
1083 case POST_MODIFY: case POST_INC: case POST_DEC:
1084 return \"st%V0 %R1,%R0\;st%U0%V0 %1,%0\";
1085 case PRE_MODIFY: case PRE_INC: case PRE_DEC:
1086 return \"st%U0%V0 %1,%0\;st%V0 %R1,%R0\";
1088 return \"st%U0%V0 %1,%0\;st%U0%V0 %R1,%R0\";
1093 fatal_error (\"DPFP register allocated without -mdpfp\\n\");
1095 return \"dexcl%F0 0, %H1, %L1\";
1097 return \"lr %H0,[%H1h]\;lr %L0,[%H1l] ; double reg moves\";
1101 "&& reload_completed && optimize
1102 /* Don't touch the DOUBLE_REGS alternatives. */
1103 && !refers_to_regno_p (40, 44, operands[0], 0)
1104 && !refers_to_regno_p (40, 44, operands[1], 0)"
1105 [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5))]
1106 "arc_split_move (operands);"
1107 [(set_attr "type" "move,move,load,store, move,lr")
1108 (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
1109 ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1110 (set_attr "length" "8,16,16,16,4,16")])
1112 ;; Load/Store with update instructions.
1114 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1115 ;; hardware can also do cases where the increment is not the size of the
1118 ;; In all these cases, we use operands 0 and 1 for the register being
1119 ;; incremented because those are the operands that local-alloc will
1120 ;; tie and these are the pair most likely to be tieable (and the ones
1121 ;; that will benefit the most).
1123 ;; We use match_operator here because we need to know whether the memory
1124 ;; object is volatile or not.
1127 ;; Note: loadqi_update has no 16-bit variant
1128 (define_insn "*loadqi_update"
1129 [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1130 (match_operator:QI 4 "load_update_operand"
1131 [(match_operand:SI 1 "register_operand" "0,0")
1132 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1133 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1134 (plus:SI (match_dup 1) (match_dup 2)))]
1136 "ldb.a%V4 %3,[%0,%S2]"
1137 [(set_attr "type" "load,load")
1138 (set_attr "length" "4,8")])
1140 (define_insn "*load_zeroextendqisi_update"
1141 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1142 (zero_extend:SI (match_operator:QI 4 "load_update_operand"
1143 [(match_operand:SI 1 "register_operand" "0,0")
1144 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1145 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1146 (plus:SI (match_dup 1) (match_dup 2)))]
1148 "ldb.a%V4 %3,[%0,%S2]"
1149 [(set_attr "type" "load,load")
1150 (set_attr "length" "4,8")])
1152 (define_insn "*load_signextendqisi_update"
1153 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1154 (sign_extend:SI (match_operator:QI 4 "load_update_operand"
1155 [(match_operand:SI 1 "register_operand" "0,0")
1156 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1157 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1158 (plus:SI (match_dup 1) (match_dup 2)))]
1160 "ldb.x.a%V4 %3,[%0,%S2]"
1161 [(set_attr "type" "load,load")
1162 (set_attr "length" "4,8")])
1164 (define_insn "*storeqi_update"
1165 [(set (match_operator:QI 4 "store_update_operand"
1166 [(match_operand:SI 1 "register_operand" "0")
1167 (match_operand:SI 2 "short_immediate_operand" "I")])
1168 (match_operand:QI 3 "register_operand" "c"))
1169 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1170 (plus:SI (match_dup 1) (match_dup 2)))]
1172 "stb.a%V4 %3,[%0,%2]"
1173 [(set_attr "type" "store")
1174 (set_attr "length" "4")])
1176 ;; ??? pattern may have to be re-written
1177 ;; Note: no 16-bit variant for this pattern
1178 (define_insn "*loadhi_update"
1179 [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1180 (match_operator:HI 4 "load_update_operand"
1181 [(match_operand:SI 1 "register_operand" "0,0")
1182 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1183 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1184 (plus:SI (match_dup 1) (match_dup 2)))]
1186 "ldw.a%V4 %3,[%0,%S2]"
1187 [(set_attr "type" "load,load")
1188 (set_attr "length" "4,8")])
1190 (define_insn "*load_zeroextendhisi_update"
1191 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1192 (zero_extend:SI (match_operator:HI 4 "load_update_operand"
1193 [(match_operand:SI 1 "register_operand" "0,0")
1194 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1195 (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1196 (plus:SI (match_dup 1) (match_dup 2)))]
1198 "ldw.a%V4 %3,[%0,%S2]"
1199 [(set_attr "type" "load,load")
1200 (set_attr "length" "4,8")])
1202 ;; Note: no 16-bit variant for this instruction
1203 (define_insn "*load_signextendhisi_update"
1204 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1205 (sign_extend:SI (match_operator:HI 4 "load_update_operand"
1206 [(match_operand:SI 1 "register_operand" "0,0")
1207 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")])))
1208 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1209 (plus:SI (match_dup 1) (match_dup 2)))]
1211 "ldw.x.a%V4 %3,[%0,%S2]"
1212 [(set_attr "type" "load,load")
1213 (set_attr "length" "4,8")])
1215 (define_insn "*storehi_update"
1216 [(set (match_operator:HI 4 "store_update_operand"
1217 [(match_operand:SI 1 "register_operand" "0")
1218 (match_operand:SI 2 "short_immediate_operand" "I")])
1219 (match_operand:HI 3 "register_operand" "c"))
1220 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1221 (plus:SI (match_dup 1) (match_dup 2)))]
1223 "stw.a%V4 %3,[%0,%2]"
1224 [(set_attr "type" "store")
1225 (set_attr "length" "4")])
1227 ;; No 16-bit variant for this instruction pattern
1228 (define_insn "*loadsi_update"
1229 [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1230 (match_operator:SI 4 "load_update_operand"
1231 [(match_operand:SI 1 "register_operand" "0,0")
1232 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1233 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1234 (plus:SI (match_dup 1) (match_dup 2)))]
1236 "ld.a%V4 %3,[%0,%S2]"
1237 [(set_attr "type" "load,load")
1238 (set_attr "length" "4,8")])
1240 (define_insn "*storesi_update"
1241 [(set (match_operator:SI 4 "store_update_operand"
1242 [(match_operand:SI 1 "register_operand" "0")
1243 (match_operand:SI 2 "short_immediate_operand" "I")])
1244 (match_operand:SI 3 "register_operand" "c"))
1245 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1246 (plus:SI (match_dup 1) (match_dup 2)))]
1248 "st.a%V4 %3,[%0,%2]"
1249 [(set_attr "type" "store")
1250 (set_attr "length" "4")])
1252 (define_insn "*loadsf_update"
1253 [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1254 (match_operator:SF 4 "load_update_operand"
1255 [(match_operand:SI 1 "register_operand" "0,0")
1256 (match_operand:SI 2 "nonmemory_operand" "rI,Cal")]))
1257 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1258 (plus:SI (match_dup 1) (match_dup 2)))]
1260 "ld.a%V4 %3,[%0,%S2]"
1261 [(set_attr "type" "load,load")
1262 (set_attr "length" "4,8")])
1264 (define_insn "*storesf_update"
1265 [(set (match_operator:SF 4 "store_update_operand"
1266 [(match_operand:SI 1 "register_operand" "0")
1267 (match_operand:SI 2 "short_immediate_operand" "I")])
1268 (match_operand:SF 3 "register_operand" "c"))
1269 (set (match_operand:SI 0 "dest_reg_operand" "=w")
1270 (plus:SI (match_dup 1) (match_dup 2)))]
1272 "st.a%V4 %3,[%0,%2]"
1273 [(set_attr "type" "store")
1274 (set_attr "length" "4")])
1276 ;; Conditional move instructions.
1278 (define_expand "movsicc"
1279 [(set (match_operand:SI 0 "dest_reg_operand" "")
1280 (if_then_else:SI (match_operand 1 "comparison_operator" "")
1281 (match_operand:SI 2 "nonmemory_operand" "")
1282 (match_operand:SI 3 "register_operand" "")))]
1286 enum rtx_code code = GET_CODE (operands[1]);
1288 operands[1] = gen_compare_reg (code, VOIDmode);
1292 (define_expand "movdicc"
1293 [(set (match_operand:DI 0 "dest_reg_operand" "")
1294 (if_then_else:DI(match_operand 1 "comparison_operator" "")
1295 (match_operand:DI 2 "nonmemory_operand" "")
1296 (match_operand:DI 3 "register_operand" "")))]
1300 enum rtx_code code = GET_CODE (operands[1]);
1302 operands[1] = gen_compare_reg (code, VOIDmode);
1306 (define_expand "movsfcc"
1307 [(set (match_operand:SF 0 "dest_reg_operand" "")
1308 (if_then_else:SF (match_operand 1 "comparison_operator" "")
1309 (match_operand:SF 2 "nonmemory_operand" "")
1310 (match_operand:SF 3 "register_operand" "")))]
1314 enum rtx_code code = GET_CODE (operands[1]);
1316 operands[1] = gen_compare_reg (code, VOIDmode);
1319 (define_expand "movdfcc"
1320 [(set (match_operand:DF 0 "dest_reg_operand" "")
1321 (if_then_else:DF (match_operand 1 "comparison_operator" "")
1322 (match_operand:DF 2 "nonmemory_operand" "")
1323 (match_operand:DF 3 "register_operand" "")))]
1327 enum rtx_code code = GET_CODE (operands[1]);
1329 operands[1] = gen_compare_reg (code, VOIDmode);
1332 (define_insn "*movsicc_insn"
1333 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1334 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1335 [(match_operand 4 "cc_register" "") (const_int 0)])
1336 (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1337 (match_operand:SI 2 "register_operand" "0,0")))]
1340 if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1341 && satisfies_constraint_Rcq (operands[0]))
1342 return "sub%?.ne %0,%0,%0";
1343 /* ??? might be good for speed on ARC600 too, *if* properly scheduled. */
1344 if ((TARGET_ARC700 || optimize_size)
1345 && rtx_equal_p (operands[1], constm1_rtx)
1346 && GET_CODE (operands[3]) == LTU)
1347 return "sbc.cs %0,%0,%0";
1348 return "mov.%d3 %0,%S1";
1350 [(set_attr "type" "cmove,cmove")
1351 (set_attr "length" "4,8")])
1353 ; Try to generate more short moves, and/or less limms, by substituting a
1354 ; conditional move with a conditional sub.
1356 [(set (match_operand:SI 0 "compact_register_operand")
1357 (match_operand:SI 1 "const_int_operand"))
1359 (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1360 [(match_operand 4 "cc_register" "") (const_int 0)])
1361 (match_operand:SI 2 "const_int_operand" "")
1363 "!satisfies_constraint_P (operands[1])
1364 && satisfies_constraint_P (operands[2])
1365 && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1366 [(set (match_dup 0) (match_dup 2))
1370 (plus:SI (match_dup 0) (match_dup 1))))]
1371 "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1372 GET_MODE (operands[4])),
1373 VOIDmode, operands[4], const0_rtx);
1374 operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1376 (define_insn "*movdicc_insn"
1377 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1378 (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1379 [(match_operand 4 "cc_register" "") (const_int 0)])
1380 (match_operand:DI 1 "nonmemory_operand" "c,Ji")
1381 (match_operand:DI 2 "register_operand" "0,0")))]
1385 switch (which_alternative)
1389 /* We normally copy the low-numbered register first. However, if
1390 the first register operand 0 is the same as the second register of
1391 operand 1, we must copy in the opposite order. */
1392 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1393 return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1395 return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1397 return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1402 [(set_attr "type" "cmove,cmove")
1403 (set_attr "length" "8,16")])
1406 (define_insn "*movsfcc_insn"
1407 [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1408 (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1409 [(match_operand 4 "cc_register" "") (const_int 0)])
1410 (match_operand:SF 1 "nonmemory_operand" "c,E")
1411 (match_operand:SF 2 "register_operand" "0,0")))]
1415 mov.%d3 %0,%1 ; %A1"
1416 [(set_attr "type" "cmove,cmove")])
1418 (define_insn "*movdfcc_insn"
1419 [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1420 (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1421 [(match_operand 4 "cc_register" "") (const_int 0)])
1422 (match_operand:DF 2 "nonmemory_operand" "c,E")
1423 (match_operand:DF 3 "register_operand" "0,0")))]
1427 switch (which_alternative)
1431 /* We normally copy the low-numbered register first. However, if
1432 the first register operand 0 is the same as the second register of
1433 operand 1, we must copy in the opposite order. */
1434 if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1435 return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1437 return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1439 return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1443 [(set_attr "type" "cmove,cmove")
1444 (set_attr "length" "8,16")])
1447 ;; TODO - Support push_s and pop_s insns
1448 ;; PUSH/POP instruction
1449 ;(define_insn "*pushsi"
1450 ; [(set (mem:SI (pre_dec:SI (reg:SI 28)))
1451 ; (match_operand:SI 0 "register_operand" "q"))]
1452 ; "TARGET_MIXED_CODE"
1454 ; [(set_attr "type" "push")
1455 ; (set_attr "iscompact" "true")
1456 ; (set_attr "length" "2")])
1458 ;(define_insn "*popsi"
1459 ; [(set (match_operand:SI 0 "register_operand" "=q")
1460 ; (mem:SI (post_inc:SI (reg:SI 28))))]
1461 ; "TARGET_MIXED_CODE"
1463 ; [(set_attr "type" "pop")
1464 ; (set_attr "iscompact" "true")
1465 ; (set_attr "length" "2")])
1467 ;; Zero extension instructions.
1468 ;; ??? We don't support volatile memrefs here, but I'm not sure why.
1470 (define_insn "*zero_extendqihi2_a4"
1471 [(set (match_operand:HI 0 "dest_reg_operand" "=r")
1472 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1475 [(set_attr "type" "unary")])
1477 (define_insn "*zero_extendqihi2_i"
1478 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
1479 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
1487 [(set_attr "type" "unary,unary,unary,unary,load")
1488 (set_attr "iscompact" "maybe,true,false,false,false")
1489 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond")])
1491 (define_expand "zero_extendqihi2"
1492 [(set (match_operand:HI 0 "dest_reg_operand" "")
1493 (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1495 "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1498 ;; (define_insn "zero_extendqihi2"
1499 ;; [(set (match_operand:HI 0 "register_operand" "=r,r")
1500 ;; (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1505 ;; [(set_attr "type" "unary,load")
1506 ;; (set_attr "cond" "nocond,nocond")])
1508 (define_insn "*zero_extendqisi2_a4"
1509 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1510 ; (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1511 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1516 [(set_attr "type" "unary,load")])
1518 (define_insn "*zero_extendqisi2_ac"
1519 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
1520 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
1523 switch (which_alternative)
1526 return \"extb%? %0,%1%&\";
1528 return \"bmsk%? %0,%1,7\";
1530 return \"extb %0,%1\";
1532 return \"ldb%? %0,%1%&\";
1534 return \"ldb%U1 %0,%1\";
1538 [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1539 (set_attr "iscompact" "maybe,true,false,false,true,true,false")
1540 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,nocond,nocond")])
1542 (define_expand "zero_extendqisi2"
1543 [(set (match_operand:SI 0 "dest_reg_operand" "")
1544 (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1546 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1548 ; (set_attr "length" "2,4,8")
1550 ;; (define_insn "zero_extendqisi2"
1551 ;; [(set (match_operand:SI 0 "register_operand" "=r,r")
1552 ;; (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1557 ;; [(set_attr "type" "unary,load")
1558 ;; (set_attr "cond" "nocond,nocond")])
1560 (define_insn "*zero_extendhisi2_a4"
1561 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
1562 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1565 [(set_attr "type" "unary")])
1567 (define_insn "*zero_extendhisi2_i"
1568 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
1569 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
1572 switch (which_alternative)
1575 return \"extw%? %0,%1%&\";
1577 return \"bmsk%? %0,%1,15\";
1579 return \"extw %0,%1\";
1581 return \"ldw%? %0,%1%&\";
1583 return \"ldw%U1 %0,%1\";
1585 return \"ldw%U1%V1 %0,%1\";
1589 [(set_attr "type" "unary,unary,unary,unary,load,load,load")
1590 (set_attr "iscompact" "maybe,true,false,false,true,false,false")
1591 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,nocond,nocond")])
1594 (define_expand "zero_extendhisi2"
1595 [(set (match_operand:SI 0 "dest_reg_operand" "")
1596 (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1598 "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1601 ;; (define_insn "zero_extendhisi2"
1602 ;; [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1603 ;; (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "r,m")))]
1608 ;; [(set_attr "type" "unary,load")
1609 ;; (set_attr "cond" "nocond,nocond")])
1611 ;; Sign extension instructions.
1613 (define_insn "*extendqihi2_a4"
1614 [(set (match_operand:HI 0 "dest_reg_operand" "=r")
1615 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1618 [(set_attr "type" "unary")])
1620 (define_insn "*extendqihi2_i"
1621 [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
1622 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
1628 [(set_attr "type" "unary,unary,load")
1629 (set_attr "iscompact" "true,false,false")
1630 (set_attr "cond" "nocond,nocond,nocond")])
1633 (define_expand "extendqihi2"
1634 [(set (match_operand:HI 0 "dest_reg_operand" "")
1635 (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1637 "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1640 ;; (define_insn "extendqihi2"
1641 ;; [(set (match_operand:HI 0 "register_operand" "=r,r")
1642 ;; (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1647 ;; [(set_attr "type" "unary,load")
1648 ;; (set_attr "cond" "nocond,nocond")])
1650 (define_insn "*extendqisi2_a4"
1651 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1652 ; (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1653 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "r,m")))]
1658 [(set_attr "type" "unary,load")])
1660 ;; (define_insn "*extendqisi2_mixed"
1661 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q")
1662 ;; (sign_extend:SI (match_operand:QI 1 "compact_register_operand" "q")))]
1663 ;; "TARGET_MIXED_CODE"
1665 ;; [(set_attr "type" "unary")
1666 ;; (set_attr "iscompact" "true")])
1668 (define_insn "*extendqisi2_ac"
1669 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1670 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1676 [(set_attr "type" "unary,unary,load")
1677 (set_attr "iscompact" "true,false,false")
1678 (set_attr "cond" "nocond,nocond,nocond")])
1680 (define_expand "extendqisi2"
1681 [(set (match_operand:SI 0 "dest_reg_operand" "")
1682 (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1684 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1687 (define_insn "*extendhisi2_a4"
1688 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
1689 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1692 [(set_attr "type" "unary")])
1694 ;; (define_insn "*extendhisi2_mixed"
1695 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q")
1696 ;; (sign_extend:SI (match_operand:HI 1 "compact_register_operand" "q")))]
1697 ;; "TARGET_MIXED_CODE"
1699 ;; [(set_attr "type" "unary")
1700 ;; (set_attr "iscompact" "true")])
1703 (define_insn "*extendhisi2_i"
1704 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
1705 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
1711 [(set_attr "type" "unary,unary,load")
1712 (set_attr "iscompact" "true,false,false")
1713 (set_attr "cond" "nocond,nocond,nocond")])
1715 (define_expand "extendhisi2"
1716 [(set (match_operand:SI 0 "dest_reg_operand" "")
1717 (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1719 "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1722 ;; Unary arithmetic insns
1724 ;; We allow constant operands to enable late constant propagation, but it is
1725 ;; not worth while to have more than one dedicated alternative to output them -
1726 ;; if we are really worried about getting these the maximum benefit of all
1727 ;; the available alternatives, we should add an extra pass to fold such
1728 ;; operations to movsi.
1730 ;; Absolute instructions
1732 (define_insn "*abssi2_mixed"
1733 [(set (match_operand:SI 0 "compact_register_operand" "=q")
1734 (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1737 [(set_attr "type" "two_cycle_core")
1738 (set_attr "iscompact" "true")])
1740 (define_insn "abssi2"
1741 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1742 (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1745 [(set_attr "type" "two_cycle_core")
1746 (set_attr "length" "*,4,8")
1747 (set_attr "iscompact" "true,false,false")
1748 (set_attr "cond" "nocond,nocond,nocond")])
1750 ;; Maximum and minimum insns
1752 (define_insn "smaxsi3"
1753 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1754 (smax:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1755 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1758 [(set_attr "type" "two_cycle_core")
1759 (set_attr "length" "4,4,8")
1760 (set_attr "cond" "canuse,nocond,nocond")]
1763 (define_insn "sminsi3"
1764 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
1765 (smin:SI (match_operand:SI 1 "register_operand" "%0, c, c")
1766 (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1769 [(set_attr "type" "two_cycle_core")
1770 (set_attr "length" "4,4,8")
1771 (set_attr "cond" "canuse,nocond,nocond")]
1774 ;; Arithmetic instructions.
1775 ;; (define_insn "*addsi3_mixed"
1776 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q,q,q,r")
1777 ;; (plus:SI (match_operand:SI 1 "compact_register_operand" "%q,0,0,r")
1778 ;; (match_operand:SI 2 "nonmemory_operand" "qK,rO,Ji,rJi")))]
1779 ;; "TARGET_MIXED_CODE"
1782 ;; switch (which_alternative)
1785 ;; return \"add_s %0,%1,%2\";
1787 ;; return \"add_s %0,%1,%2\";
1789 ;; if (INTVAL (operands[2]) < 0)
1790 ;; return \"sub%? %0,%1,%n2\";
1792 ;; return \"add%? %0,%1,%2\";
1794 ;; return \"add_s %0,%1,%S2\";
1796 ;; return \"add%? %0,%1,%S2\";
1801 ;; [(set_attr "iscompact" "true,true,true,false")
1802 ;; (set_attr "length" "*,*,6,8")
1803 ;; (set_attr "cond" "nocond,nocond,nocond,canuse")])
1805 ; We say an insn can be conditionalized if this doesn't introduce a long
1806 ; immediate. We set the type such that we still have good scheduling if the
1807 ; insn is conditionalized.
1808 ; ??? It would make sense to allow introduction of long immediates, but
1809 ; we'd need to communicate to the ccfsm machinery the extra cost.
1810 ; The alternatives in the constraints still serve three purposes:
1811 ; - estimate insn size assuming conditional execution
1812 ; - guide reload to re-order the second and third operand to get a better fit.
1813 ; - give tentative insn type to guide scheduling
1814 ; N.B. "%" for commutativity doesn't help when there is another matching
1815 ; (but longer) alternative.
1816 (define_insn_and_split "*addsi3_mixed"
1817 ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
1818 [(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")
1819 (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")
1820 (match_operand:SI 2 "nonmemory_operand" "cL, 0, cL, 0,CL2,Csp,CM4,cCca,RcqqK, cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1822 "*if (which_alternative == 6)
1823 return arc_short_long (insn, \"add%? %0,%1,%2\", \"add1 %0,%1,%2/2\");
1824 return arc_output_addsi (operands,
1825 arc_ccfsm_cond_exec_p () ? \"%?\" : \"\");"
1826 "&& reload_completed && get_attr_length (insn) == 8
1827 && satisfies_constraint_I (operands[2])"
1828 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1829 "split_addsi (operands);"
1830 [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*")
1831 (set (attr "iscompact")
1832 (cond [(eq (symbol_ref "*arc_output_addsi (operands, 0)") (const_int 0))
1833 (const_string "false")
1834 (match_operand 2 "long_immediate_operand" "")
1835 (const_string "maybe_limm")]
1836 (const_string "maybe")))
1837 (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8")
1838 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")])
1840 ;; (define_insn "*addsi3_mixed"
1841 ;; [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,q,q,r,r,r,r,r,r,r,r,r")
1842 ;; (plus:SI (match_operand:SI 1 "register_operand" "%q,0,0,0,0,r,0,r,0,0,r,0,r")
1843 ;; (match_operand:SI 2 "nonmemory_operand" "qK,rO,J,i,r,r,L,L,I,J,J,i,i")))]
1847 ;; switch (which_alternative)
1850 ;; return \"add_s %0,%1,%2\";
1852 ;; return \"add_s %0,%1,%2\";
1854 ;; return \"add%? %0,%1,%2\";
1856 ;; return \"add %0,%1,%2\";
1858 ;; return \"add%? %0,%1,%2\";
1860 ;; return \"add %0,%1,%2\";
1862 ;; return \"add %0,%1,%2\";
1865 ;; int intval = INTVAL (operands[2]);
1868 ;; if (-intval< 0x20)
1869 ;; return \"sub_s %0,%1,%n2\";
1871 ;; return \"sub %0,%1,%n2\";
1874 ;; return \"add_s %0,%1,%2\";
1877 ;; return \"add_s %0,%1,%S2\";
1879 ;; if (INTVAL (operands[2]) < 0)
1880 ;; return \"sub%? %0,%1,%n2\";
1882 ;; return \"add%? %0,%1,%2\";
1884 ;; if (INTVAL (operands[2]) < 0)
1885 ;; return \"sub %0,%1,%n2\";
1887 ;; return \"add %0,%1,%2\";
1889 ;; return \"add%? %0,%1,%S2\";
1891 ;; return \"add %0,%1,%S2\";
1896 ;; [(set_attr "iscompact" "true,true,false,true,false,false,false,false,false,false,false,false,false")
1897 ;; (set_attr "length" "2,2,8,6,4,4,4,4,4,8,8,8,8")
1898 ;; (set_attr "cond" "nocond,nocond,nocond,nocond,canuse,nocond,canuse,nocond,nocond,canuse,nocond,canuse,nocond")])
1900 ;; ARC700/ARC600 multiply
1903 (define_expand "mulsi3"
1904 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1905 (mult:SI (match_operand:SI 1 "register_operand" "")
1906 (match_operand:SI 2 "nonmemory_operand" "")))]
1907 "(TARGET_ARC700 && !TARGET_NOMPY_SET)
1908 || TARGET_MUL64_SET || TARGET_MULMAC_32BY16_SET"
1911 if ((TARGET_ARC700 && !TARGET_NOMPY_SET) &&
1912 !register_operand (operands[0], SImode))
1914 rtx result = gen_reg_rtx (SImode);
1916 emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1917 emit_move_insn (operands[0], result);
1920 else if (TARGET_MUL64_SET)
1922 emit_insn (gen_mulsi_600 (operands[1], operands[2],
1923 gen_mlo (), gen_mhi ()));
1924 emit_move_insn (operands[0], gen_mlo ());
1927 else if (TARGET_MULMAC_32BY16_SET)
1929 if (immediate_operand (operands[2], SImode)
1930 && INTVAL (operands[2]) >= 0
1931 && INTVAL (operands[2]) <= 65535)
1933 emit_insn (gen_umul_600 (operands[1], operands[2],
1934 gen_acc2 (), gen_acc1 ()));
1935 emit_move_insn (operands[0], gen_acc2 ());
1938 operands[2] = force_reg (SImode, operands[2]);
1939 emit_insn (gen_umul_600 (operands[1], operands[2],
1940 gen_acc2 (), gen_acc1 ()));
1941 emit_insn (gen_mac_600 (operands[1], operands[2],
1942 gen_acc2 (), gen_acc1 ()));
1943 emit_move_insn (operands[0], gen_acc2 ());
1948 ; mululw conditional execution without a LIMM clobbers an input register;
1949 ; we'd need a different pattern to describe this.
1950 (define_insn "umul_600"
1951 [(set (match_operand:SI 2 "acc2_operand" "")
1952 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1953 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,J")
1956 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1957 "TARGET_MULMAC_32BY16_SET"
1958 "mululw%? 0, %0, %1"
1959 [(set_attr "length" "4,4,8")
1960 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1961 (set_attr "cond" "nocond, canuse_limm, canuse")])
1963 (define_insn "mac_600"
1964 [(set (match_operand:SI 2 "acc2_operand" "")
1966 (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
1968 (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,J")
1973 (clobber (match_operand:SI 3 "acc1_operand" ""))]
1974 "TARGET_MULMAC_32BY16_SET"
1975 "machlw%? 0, %0, %1"
1976 [(set_attr "length" "4,4,8")
1977 (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
1978 (set_attr "cond" "nocond, canuse_limm, canuse")])
1980 (define_insn "mulsi_600"
1981 [(set (match_operand:SI 2 "mlo_operand" "")
1982 (mult:SI (match_operand:SI 0 "register_operand" "Rcq#q,c,c,%c")
1983 (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,J")))
1984 (clobber (match_operand:SI 3 "mhi_operand" ""))]
1986 "mul64%? \t0, %0, %1%&"
1987 [(set_attr "length" "*,4,4,8")
1988 (set_attr "iscompact" "maybe,false,false,false")
1989 (set_attr "type" "multi,multi,multi,multi")
1990 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
1992 (define_insn "mulsidi_600"
1994 (mult:DI (sign_extend:DI
1995 (match_operand:SI 0 "register_operand" "Rcq#q,c,c,%c"))
1997 (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,J"))))]
1999 "mul64%? \t0, %0, %1%&"
2000 [(set_attr "length" "*,4,4,8")
2001 (set_attr "iscompact" "maybe,false,false,false")
2002 (set_attr "type" "multi,multi,multi,multi")
2003 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2005 (define_insn "umulsidi_600"
2007 (mult:DI (zero_extend:DI
2008 (match_operand:SI 0 "register_operand" "Rcq#q,c,c,%c"))
2010 (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,J"))))]
2012 "mulu64%? \t0, %0, %1%&"
2013 [(set_attr "length" "*,4,4,8")
2014 (set_attr "iscompact" "maybe,false,false,false")
2015 (set_attr "type" "umulti")
2016 (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2018 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2019 ; may not be used as destination constraint.
2021 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2022 ; but mpyu is faster for the standard multiplier.
2023 (define_insn "mulsi3_700"
2024 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcr, r,r,Rcr, r")
2025 (mult:SI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c")
2026 (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2027 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2029 [(set_attr "length" "4,4,4,8,8")
2030 (set_attr "type" "umulti")
2031 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2034 (define_expand "mulsidi3"
2035 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2036 (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" ""))
2037 (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2038 "(TARGET_ARC700 && !TARGET_NOMPY_SET)
2039 || TARGET_MULMAC_32BY16_SET"
2042 if ((TARGET_ARC700 && !TARGET_NOMPY_SET))
2044 operands[2] = force_reg (SImode, operands[2]);
2045 if (!register_operand (operands[0], DImode))
2047 rtx result = gen_reg_rtx (DImode);
2049 operands[2] = force_reg (SImode, operands[2]);
2050 emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2051 emit_move_insn (operands[0], result);
2055 if (TARGET_MUL64_SET)
2057 operands[2] = force_reg (SImode, operands[2]);
2058 emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
2059 emit_move_insn (operands[0], gen_rtx_REG (DImode, 58));
2061 else if (TARGET_MULMAC_32BY16_SET)
2063 rtx result_hi = gen_highpart(SImode, operands[0]);
2064 rtx result_low = gen_lowpart(SImode, operands[0]);
2066 emit_insn (gen_mul64_600 (operands[1], operands[2]));
2067 emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2068 emit_move_insn (result_low, gen_acc2 ());
2073 (define_insn "mul64_600"
2075 (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "c,c,c"))
2076 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand" "c,L,J")
2080 "TARGET_MULMAC_32BY16_SET"
2082 [(set_attr "length" "4,4,8")
2083 (set_attr "type" "mulmac_600")
2084 (set_attr "cond" "nocond, canuse_limm, canuse")])
2087 ;; ??? check if this is canonical rtl
2088 (define_insn "mac64_600"
2091 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2093 (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,J")
2094 (const_int 16) (const_int 16))
2097 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2100 (mult:DI (sign_extend:DI (match_dup 1))
2102 (sign_extract:DI (match_dup 2)
2103 (const_int 16) (const_int 16))
2106 (const_int 32) (const_int 32)))]
2107 "TARGET_MULMAC_32BY16_SET"
2108 "machlw%? %0, %1, %2"
2109 [(set_attr "length" "4,4,8")
2110 (set_attr "type" "mulmac_600")
2111 (set_attr "cond" "nocond, canuse_limm, canuse")])
2114 ;; DI <- DI(signed SI) * DI(signed SI)
2115 (define_insn_and_split "mulsidi3_700"
2116 [(set (match_operand:DI 0 "register_operand" "=&r")
2117 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2118 (sign_extend:DI (match_operand:SI 2 "register_operand" "cL"))))]
2119 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2124 int hi = !TARGET_BIG_ENDIAN;
2126 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2127 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2128 emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2129 emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2132 [(set_attr "type" "multi")
2133 (set_attr "length" "8")])
2135 (define_insn "mulsi3_highpart"
2136 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2140 (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2141 (sign_extend:DI (match_operand:SI 2 "extend_operand" "c,c, s,s")))
2143 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2145 [(set_attr "length" "4,4,8,8")
2146 (set_attr "type" "multi")
2147 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2149 ; Note that mpyhu has the same latency as mpy / mpyh,
2150 ; thus we use the type multi.
2151 (define_insn "*umulsi3_highpart_i"
2152 [(set (match_operand:SI 0 "register_operand" "=Rcr,r,Rcr,r")
2156 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c, 0,c"))
2157 (zero_extend:DI (match_operand:SI 2 "extend_operand" "c,c, s,s")))
2159 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2161 [(set_attr "length" "4,4,8,8")
2162 (set_attr "type" "multi")
2163 (set_attr "cond" "canuse,nocond,canuse,nocond")])
2165 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2166 ;; need a separate pattern for immediates
2167 ;; ??? This is fine for combine, but not for reload.
2168 (define_insn "umulsi3_highpart_int"
2169 [(set (match_operand:SI 0 "register_operand" "=Rcr, r, r,Rcr, r")
2173 (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c, 0, 0, c"))
2174 (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2176 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2178 [(set_attr "length" "4,4,4,8,8")
2179 (set_attr "type" "multi")
2180 (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2182 (define_expand "umulsi3_highpart"
2183 [(set (match_operand:SI 0 "general_operand" "")
2187 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2188 (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2190 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2193 rtx target = operands[0];
2195 if (!register_operand (target, SImode))
2196 target = gen_reg_rtx (SImode);
2198 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2199 operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2200 operands[2], SImode);
2201 else if (!immediate_operand (operands[2], SImode))
2202 operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2203 emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2204 if (target != operands[0])
2205 emit_move_insn (operands[0], target);
2209 (define_expand "umulsidi3"
2210 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2211 (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" ""))
2212 (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))]
2213 "(TARGET_ARC700 && !TARGET_NOMPY_SET)
2214 || TARGET_MULMAC_32BY16_SET"
2217 if ((TARGET_ARC700 && !TARGET_NOMPY_SET))
2219 operands[2] = force_reg (SImode, operands[2]);
2220 if (!register_operand (operands[0], DImode))
2222 rtx result = gen_reg_rtx (DImode);
2224 emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2225 emit_move_insn (operands[0], result);
2229 else if (TARGET_MUL64_SET)
2231 operands[2] = force_reg (SImode, operands[2]);
2232 emit_insn (gen_mulsidi_600 (operands[1], operands[2]));
2233 emit_move_insn (operands[0], gen_rtx_REG (DImode, 58));
2235 else if (TARGET_MULMAC_32BY16_SET)
2237 rtx result_hi = gen_reg_rtx (SImode);
2238 rtx result_low = gen_reg_rtx (SImode);
2240 result_hi = gen_highpart(SImode , operands[0]);
2241 result_low = gen_lowpart(SImode , operands[0]);
2243 emit_insn (gen_umul64_600 (operands[1], operands[2]));
2244 emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2245 emit_move_insn (result_low, gen_acc2 ());
2250 (define_insn "umul64_600"
2252 (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "c,c,c"))
2253 (zero_extract:DI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2257 "TARGET_MULMAC_32BY16_SET"
2258 "mululw%? 0, %0, %1"
2259 [(set_attr "length" "4,4,8")
2260 (set_attr "type" "mulmac_600")
2261 (set_attr "cond" "nocond, canuse_limm, canuse")])
2264 (define_insn "umac64_600"
2267 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2269 (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2270 (const_int 16) (const_int 16))
2273 (set (match_operand:SI 0 "register_operand" "=w,w,w")
2276 (mult:DI (zero_extend:DI (match_dup 1))
2278 (zero_extract:DI (match_dup 2)
2279 (const_int 16) (const_int 16))
2282 (const_int 32) (const_int 32)))]
2283 "TARGET_MULMAC_32BY16_SET"
2284 "machulw%? %0, %1, %2"
2285 [(set_attr "length" "4,4,8")
2286 (set_attr "type" "mulmac_600")
2287 (set_attr "cond" "nocond, canuse_limm, canuse")])
2291 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2292 (define_insn_and_split "umulsidi3_700"
2293 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2294 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2295 (zero_extend:DI (match_operand:SI 2 "register_operand" "c"))))]
2296 ;; (zero_extend:DI (match_operand:SI 2 "register_operand" "rL"))))]
2297 "TARGET_ARC700 && !TARGET_NOMPY_SET"
2302 int hi = !TARGET_BIG_ENDIAN;
2304 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2305 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2306 emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2307 emit_insn (gen_mulsi3_700 (l0, operands[1], operands[2]));
2310 [(set_attr "type" "umulti")
2311 (set_attr "length" "8")])
2313 (define_expand "addsi3"
2314 [(set (match_operand:SI 0 "dest_reg_operand" "")
2315 (plus:SI (match_operand:SI 1 "register_operand" "")
2316 (match_operand:SI 2 "nonmemory_operand" "")))]
2318 "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2]) )
2320 operands[2]=force_reg(SImode, operands[2]);
2322 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2324 operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2329 (define_insn "*addsi3_insn_a4"
2330 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r,r,r,r")
2331 (plus:SI (match_operand:SI 1 "register_operand" "%0,r,0,r,0,0,r,0,r")
2332 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,J,J,i,i")))]
2336 switch (which_alternative)
2339 return \"add %0,%1,%2\";
2341 return \"add%? %0,%1,%2\";
2343 return \"add %0,%1,%2\";
2345 return \"add%? %0,%1,%2\";
2347 return \"add %0,%1,%2\";
2349 if (INTVAL (operands[2]) < 0)
2350 return \"sub %0,%1,%n2\";
2352 return \"add %0,%1,%2\";
2354 if (INTVAL (operands[2]) < 0)
2355 return \"sub%? %0,%1,%n2\";
2357 return \"add%? %0,%1,%2\";
2359 return \"add %0,%1,%S2\";
2361 return \"add%? %0,%1,%S2\";
2366 [(set_attr "length" "4,4,4,4,4,8,8,8,8")
2367 (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond,canuse,nocond")]
2370 (define_expand "adddi3"
2371 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2372 (plus:DI (match_operand:DI 1 "register_operand" "")
2373 (match_operand:DI 2 "nonmemory_operand" "")))
2374 (clobber (reg:CC CC_REG))])]
2377 if (TARGET_EXPAND_ADDDI)
2379 rtx l0 = gen_lowpart (SImode, operands[0]);
2380 rtx h0 = disi_highpart (operands[0]);
2381 rtx l1 = gen_lowpart (SImode, operands[1]);
2382 rtx h1 = disi_highpart (operands[1]);
2383 rtx l2 = gen_lowpart (SImode, operands[2]);
2384 rtx h2 = disi_highpart (operands[2]);
2385 rtx cc_c = gen_rtx_REG (CC_Cmode, 61);
2387 if (CONST_INT_P (h2) && INTVAL (h2) < 0 && SIGNED_INT12 (INTVAL (h2)))
2389 emit_insn (gen_sub_f (l0, l1, gen_int_mode (-INTVAL (l2), SImode)));
2390 emit_insn (gen_sbc (h0, h1,
2391 gen_int_mode (-INTVAL (h2) - (l1 != 0), SImode),
2395 emit_insn (gen_add_f (l0, l1, l2));
2396 emit_insn (gen_adc (h0, h1, h2));
2401 ; This assumes that there can be no strictly partial overlap between
2402 ; operands[1] and operands[2].
2403 (define_insn_and_split "*adddi3_i"
2404 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2405 (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2406 (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2407 (clobber (reg:CC CC_REG))]
2413 int hi = !TARGET_BIG_ENDIAN;
2415 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2416 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2417 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2418 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2419 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2420 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2423 if (l2 == const0_rtx)
2425 if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2426 emit_move_insn (l0, l1);
2427 emit_insn (gen_addsi3 (h0, h1, h2));
2428 if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2429 emit_move_insn (l0, l1);
2432 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2433 && INTVAL (operands[2]) >= -0x7fffffff)
2435 emit_insn (gen_subdi3_i (operands[0], operands[1],
2436 GEN_INT (-INTVAL (operands[2]))));
2439 if (rtx_equal_p (l0, h1))
2441 if (h2 != const0_rtx)
2442 emit_insn (gen_addsi3 (h0, h1, h2));
2443 else if (!rtx_equal_p (h0, h1))
2444 emit_move_insn (h0, h1);
2445 emit_insn (gen_add_f (l0, l1, l2));
2449 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2450 gen_rtx_SET (VOIDmode, h0, plus_constant (h0, 1))));
2453 emit_insn (gen_add_f (l0, l1, l2));
2454 emit_insn (gen_adc (h0, h1, h2));
2457 [(set_attr "cond" "clob")
2458 (set_attr "type" "binary")
2459 (set_attr "length" "16,16,20")])
2461 (define_insn "add_f"
2462 [(set (reg:CC_C CC_REG)
2464 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2465 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2467 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2468 (plus:SI (match_dup 1) (match_dup 2)))]
2471 [(set_attr "cond" "set")
2472 (set_attr "type" "compare")
2473 (set_attr "length" "4,4,8")])
2475 (define_insn "*add_f_2"
2476 [(set (reg:CC_C CC_REG)
2478 (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2479 (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2481 (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2482 (plus:SI (match_dup 1) (match_dup 2)))]
2485 [(set_attr "cond" "set")
2486 (set_attr "type" "compare")
2487 (set_attr "length" "4,4,8")])
2489 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2490 ; needlessly prioritizing the matching constraint.
2491 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2492 ; execution ; is used where possible.
2493 (define_insn_and_split "adc"
2494 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2495 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2496 (match_operand:SI 1 "nonmemory_operand"
2498 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2499 "register_operand (operands[1], SImode)
2500 || register_operand (operands[2], SImode)"
2507 ; if we have a bad schedule after sched2, split.
2509 && !optimize_size && TARGET_ARC700
2510 && arc_scheduling_not_expected ()
2511 && arc_sets_cc_p (prev_nonnote_insn (insn))
2512 /* If next comes a return or other insn that needs a delay slot,
2513 expect the adc to get into the delay slot. */
2514 && next_nonnote_insn (insn)
2515 && !arc_need_delay (next_nonnote_insn (insn))
2516 /* Restore operands before emitting. */
2517 && (extract_insn_cached (insn), 1)"
2518 [(set (match_dup 0) (match_dup 3))
2520 (ltu (reg:CC_C CC_REG) (const_int 0))
2521 (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2522 "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2523 [(set_attr "cond" "use")
2524 (set_attr "type" "cc_arith")
2525 (set_attr "length" "4,4,4,4,8")])
2527 ; combiner-splitter cmp / scc -> cmp / adc
2529 [(set (match_operand:SI 0 "dest_reg_operand" "")
2530 (gtu:SI (match_operand:SI 1 "register_operand" "")
2531 (match_operand:SI 2 "register_operand" "")))
2532 (clobber (reg CC_REG))]
2534 [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2535 (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2537 ; combine won't work when an intermediate result is used later...
2538 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2540 [(set (match_operand:SI 0 "dest_reg_operand" "")
2541 (plus:SI (match_operand:SI 1 "register_operand" "")
2542 (match_operand:SI 2 "nonmemory_operand" "")))
2544 (compare:CC_C (match_dup 0)
2545 (match_operand:SI 3 "nonmemory_operand" "")))]
2546 "rtx_equal_p (operands[1], operands[3])
2547 || rtx_equal_p (operands[2], operands[3])"
2549 [(set (reg:CC_C CC_REG)
2550 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2552 (plus:SI (match_dup 1) (match_dup 2)))])])
2554 ;(define_insn "*adc_0"
2555 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2556 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2557 ; (match_operand:SI 1 "register_operand" "c")))]
2560 ; [(set_attr "cond" "use")
2561 ; (set_attr "type" "cc_arith")
2562 ; (set_attr "length" "4")])
2565 ; [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2566 ; (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2567 ; (match_operand:SI 2 "register_operand" "c"))
2568 ; (match_operand:SI 3 "register_operand" "c")))
2569 ; (clobber (reg CC_REG))]
2571 ; [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2572 ; (set (match_dup 0)
2573 ; (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2576 ;; (define_insn "*subsi3_mixed"
2577 ;; [(set (match_operand:SI 0 "register_operand" "=q,q,r")
2578 ;; (minus:SI (match_operand:SI 1 "register_operand" "q,0,r")
2579 ;; (match_operand:SI 2 "nonmemory_operand" "K,qM,rJ")))]
2580 ;; "TARGET_MIXED_CODE"
2585 ;; [(set_attr "iscompact" "true,true,false")
2586 ;; (set_attr "length" "2,2,*")])
2588 (define_expand "subsi3"
2589 [(set (match_operand:SI 0 "dest_reg_operand" "")
2590 (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2591 (match_operand:SI 2 "nonmemory_operand" "")))]
2597 if (!register_operand (operands[2], SImode))
2599 operands[1] = force_reg (SImode, operands[1]);
2602 if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c]) )
2603 operands[c] = force_reg (SImode, operands[c]);
2604 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2605 operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2608 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2609 ; combine should make such an insn go away.
2610 (define_insn_and_split "subsi3_insn"
2611 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,w,w,w, w, w, w")
2612 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0, 0, cL,c,L,I,Cal,Cal, c")
2613 (match_operand:SI 2 "nonmemory_operand" "Rcqq, c, 0,c,c,0, 0, c,Cal")))]
2614 "register_operand (operands[1], SImode)
2615 || register_operand (operands[2], SImode)"
2626 "reload_completed && get_attr_length (insn) == 8
2627 && satisfies_constraint_I (operands[1])"
2628 [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2629 "split_subsi (operands);"
2630 [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false")
2631 (set_attr "length" "*,4,4,4,4,4,8,8,8")
2632 (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
2634 (define_expand "subdi3"
2635 [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2636 (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2637 (match_operand:DI 2 "nonmemory_operand" "")))
2638 (clobber (reg:CC 61))])]
2641 if (!register_operand (operands[2], DImode))
2642 operands[1] = force_reg (DImode, operands[1]);
2643 if (TARGET_EXPAND_ADDDI)
2645 rtx l0 = gen_lowpart (SImode, operands[0]);
2646 rtx h0 = disi_highpart (operands[0]);
2647 rtx l1 = gen_lowpart (SImode, operands[1]);
2648 rtx h1 = disi_highpart (operands[1]);
2649 rtx l2 = gen_lowpart (SImode, operands[2]);
2650 rtx h2 = disi_highpart (operands[2]);
2651 rtx cc_c = gen_rtx_REG (CC_Cmode, 61);
2653 emit_insn (gen_sub_f (l0, l1, l2));
2654 emit_insn (gen_sbc (h0, h1, h2, cc_c));
2659 (define_insn_and_split "subdi3_i"
2660 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2661 (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2662 (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2663 (clobber (reg:CC 61))]
2664 "register_operand (operands[1], DImode)
2665 || register_operand (operands[2], DImode)"
2670 int hi = !TARGET_BIG_ENDIAN;
2672 rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2673 rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2674 rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2675 rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2676 rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2677 rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2679 if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2681 h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2682 if (!rtx_equal_p (h0, h1))
2683 emit_insn (gen_rtx_SET (VOIDmode, h0, h1));
2684 emit_insn (gen_sub_f (l0, l1, l2));
2688 gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2689 gen_rtx_SET (VOIDmode, h0, plus_constant (h0, -1))));
2692 emit_insn (gen_sub_f (l0, l1, l2));
2693 emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2696 [(set_attr "cond" "clob")
2697 (set_attr "length" "16,16,16,20,20")])
2699 (define_insn "*sbc_0"
2700 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2701 (minus:SI (match_operand:SI 1 "register_operand" "c")
2702 (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2706 [(set_attr "cond" "use")
2707 (set_attr "type" "cc_arith")
2708 (set_attr "length" "4")])
2710 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2711 ; needlessly prioritizing the matching constraint.
2712 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2713 ; is used where possible.
2714 (define_insn_and_split "sbc"
2715 [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2716 (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2718 (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2720 (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2721 "register_operand (operands[1], SImode)
2722 || register_operand (operands[2], SImode)"
2729 ; if we have a bad schedule after sched2, split.
2731 && !optimize_size && TARGET_ARC700
2732 && arc_scheduling_not_expected ()
2733 && arc_sets_cc_p (prev_nonnote_insn (insn))
2734 /* If next comes a return or other insn that needs a delay slot,
2735 expect the adc to get into the delay slot. */
2736 && next_nonnote_insn (insn)
2737 && !arc_need_delay (next_nonnote_insn (insn))
2738 /* Restore operands before emitting. */
2739 && (extract_insn_cached (insn), 1)"
2740 [(set (match_dup 0) (match_dup 4))
2742 (ltu (reg:CC_C CC_REG) (const_int 0))
2743 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2744 "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2745 [(set_attr "cond" "use")
2746 (set_attr "type" "cc_arith")
2747 (set_attr "length" "4,4,4,4,8")])
2749 (define_insn "sub_f"
2750 [(set (reg:CC CC_REG)
2751 (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2752 (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2753 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2754 (minus:SI (match_dup 1) (match_dup 2)))]
2755 "register_operand (operands[1], SImode)
2756 || register_operand (operands[2], SImode)"
2764 [(set_attr "type" "compare")
2765 (set_attr "length" "4,4,4,4,8,8")])
2767 ; combine won't work when an intermediate result is used later...
2768 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2770 [(set (reg:CC CC_REG)
2771 (compare:CC (match_operand:SI 1 "register_operand" "")
2772 (match_operand:SI 2 "nonmemory_operand" "")))
2773 (set (match_operand:SI 0 "dest_reg_operand" "")
2774 (minus:SI (match_dup 1) (match_dup 2)))]
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)))])])
2781 [(set (reg:CC CC_REG)
2782 (compare:CC (match_operand:SI 1 "register_operand" "")
2783 (match_operand:SI 2 "nonmemory_operand" "")))
2784 (set (match_operand 3 "" "") (match_operand 4 "" ""))
2785 (set (match_operand:SI 0 "dest_reg_operand" "")
2786 (minus:SI (match_dup 1) (match_dup 2)))]
2787 "!reg_overlap_mentioned_p (operands[3], operands[1])
2788 && !reg_overlap_mentioned_p (operands[3], operands[2])
2789 && !reg_overlap_mentioned_p (operands[0], operands[4])
2790 && !reg_overlap_mentioned_p (operands[0], operands[3])"
2792 [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
2793 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
2794 (set (match_dup 3) (match_dup 4))])
2796 (define_insn "*add_n"
2797 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,w,w")
2798 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c")
2799 (match_operand:SI 2 "_2_4_8_operand" ""))
2800 (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal")))]
2802 "add%z2%? %0,%3,%1%&"
2803 [(set_attr "type" "shift")
2804 (set_attr "length" "*,4,4,8")
2805 (set_attr "cond" "canuse,canuse,nocond,nocond")
2806 (set_attr "iscompact" "maybe,false,false,false")])
2808 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
2809 ;; what synth_mult likes.
2810 (define_insn "*sub_n"
2811 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2812 (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
2813 (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
2814 (match_operand:SI 3 "_2_4_8_operand" ""))))]
2817 [(set_attr "type" "shift")
2818 (set_attr "length" "4,4,8")
2819 (set_attr "cond" "canuse,nocond,nocond")
2820 (set_attr "iscompact" "false")])
2822 ; ??? check if combine matches this.
2823 (define_insn "*bset"
2824 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2825 (ior: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 "cond" "canuse,nocond,nocond")]
2834 ; ??? check if combine matches this.
2835 (define_insn "*bxor"
2836 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2837 (xor:SI (ashift:SI (const_int 1)
2838 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
2839 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2842 [(set_attr "length" "4,4,8")
2843 (set_attr "cond" "canuse,nocond,nocond")]
2846 ; ??? check if combine matches this.
2847 (define_insn "*bclr"
2848 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2849 (and:SI (not:SI (ashift:SI (const_int 1)
2850 (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
2851 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
2854 [(set_attr "length" "4,4,8")
2855 (set_attr "cond" "canuse,nocond,nocond")]
2858 ; ??? FIXME: find combine patterns for bmsk.
2860 ;;Following are the define_insns added for the purpose of peephole2's
2862 ; see also iorsi3 for use with constant bit number.
2863 (define_insn "*bset_insn"
2864 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2865 (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2866 (ashift:SI (const_int 1)
2867 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2870 bset%? %0,%1,%2 ;;peep2, constr 1
2871 bset %0,%1,%2 ;;peep2, constr 2
2872 bset %0,%S1,%2 ;;peep2, constr 3"
2873 [(set_attr "length" "4,4,8")]
2876 ; see also xorsi3 for use with constant bit number.
2877 (define_insn "*bxor_insn"
2878 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2879 (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2880 (ashift:SI (const_int 1)
2881 (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
2887 [(set_attr "length" "4,4,8")
2888 (set_attr "cond" "canuse,nocond,nocond")]
2891 ; see also andsi3 for use with constant bit number.
2892 (define_insn "*bclr_insn"
2893 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2894 (and:SI (not:SI (ashift:SI (const_int 1)
2895 (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
2896 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
2902 [(set_attr "length" "4,4,8")
2903 (set_attr "cond" "canuse,nocond,nocond")]
2906 ; see also andsi3 for use with constant bit number.
2907 (define_insn "*bmsk_insn"
2908 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
2909 (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
2910 (plus:SI (ashift:SI (const_int 1)
2911 (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
2919 [(set_attr "length" "4,4,8")]
2922 ;;Instructions added for peephole2s end
2924 ;; Boolean instructions.
2926 ;; (define_insn "*andsi3_mixed"
2927 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q")
2928 ;; (and:SI (match_operand:SI 1 "compact_register_operand" "0")
2929 ;; (match_operand:SI 2 "compact_register_operand" "q")))]
2930 ;; "TARGET_MIXED_CODE"
2932 ;; [(set_attr "iscompact" "true")
2933 ;; (set_attr "type" "binary")
2934 ;; (set_attr "length" "2")])
2936 (define_insn "*andsi3_insn_a4"
2937 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
2938 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2939 (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
2944 [(set_attr "type" "binary, binary")
2945 (set_attr "length" "4, 8")])
2947 (define_expand "andsi3"
2948 [(set (match_operand:SI 0 "dest_reg_operand" "")
2949 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
2950 (match_operand:SI 2 "nonmemory_operand" "")))]
2952 "if (!satisfies_constraint_Cux (operands[2]))
2953 operands[1] = force_reg (SImode, operands[1]);
2954 else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
2955 operands[1] = arc_rewrite_small_data (operands[1]);")
2957 (define_insn "andsi3_i"
2958 [(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")
2959 (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")
2960 (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")))]
2962 && ((register_operand (operands[1], SImode)
2963 && nonmemory_operand (operands[2], SImode))
2964 || (memory_operand (operands[1], SImode)
2965 && satisfies_constraint_Cux (operands[2])))"
2968 switch (which_alternative)
2970 case 0: case 5: case 10: case 11: case 15: case 16: case 17:
2971 return \"and%? %0,%1,%2%&\";
2973 return \"and%? %0,%2,%1%&\";
2974 case 2: case 7: case 12:
2975 return \"bmsk%? %0,%1,%Z2%&\";
2976 case 3: case 8: case 13:
2977 return \"bclr%? %0,%1,%M2%&\";
2979 return (INTVAL (operands[2]) == 0xff
2980 ? \"extb%? %0,%1%&\" : \"extw%? %0,%1%&\");
2981 case 9: case 14: return \"bic%? %0,%1,%n2-1\";
2983 if (TARGET_BIG_ENDIAN)
2987 xop[0] = operands[0];
2988 xop[1] = adjust_address (operands[1], QImode,
2989 INTVAL (operands[2]) == 0xff ? 3 : 2);
2990 output_asm_insn (INTVAL (operands[2]) == 0xff
2991 ? \"ldb %0,%1\" : \"ldw %0,%1\",
2995 return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ldw %0,%1\";
3000 [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3001 (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
3002 (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3003 (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3005 ; combiner splitter, pattern found in ldtoa.c .
3006 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3008 [(set (reg:CC_Z CC_REG)
3009 (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3010 (match_operand 1 "const_int_operand" ""))
3011 (match_operand 2 "const_int_operand" "")))
3012 (clobber (match_operand:SI 3 "register_operand" ""))]
3013 "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3015 (plus:SI (match_dup 0) (match_dup 4)))
3016 (set (reg:CC_Z CC_REG)
3017 (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3019 "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3021 ;; (define_insn "andsi3"
3022 ;; [(set (match_operand:SI 0 "register_operand" "=r,r")
3023 ;; (and:SI (match_operand:SI 1 "register_operand" "%r,r")
3024 ;; (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3029 ;; [(set_attr "type" "binary, binary")
3030 ;; (set_attr "length" "4, 8")])
3032 (define_insn_and_split "anddi3"
3033 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3034 (and:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3035 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3036 "TARGET_OLD_DI_PATTERNS"
3039 [(set (match_dup 3) (and:SI (match_dup 4) (match_dup 5)))
3040 (set (match_dup 6) (and:SI (match_dup 7) (match_dup 8)))]
3041 "arc_split_dilogic (operands, AND); DONE;"
3042 [(set_attr "length" "8,8,16,16")])
3044 ;; (define_insn "*bicsi3_insn_mixed"
3045 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q")
3046 ;; (and:SI (match_operand:SI 1 "compact_register_operand" "0")
3047 ;; (not:SI (match_operand:SI 2 "compact_register_operand" "q"))))]
3048 ;; "TARGET_MIXED_CODE"
3050 ;; [(set_attr "iscompact" "true")])
3053 ;;bic define_insn that allows limm to be the first operand
3054 (define_insn "*bicsi3_insn"
3055 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3056 (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3057 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3060 bic%? %0, %2, %1%& ;;constraint 0
3061 bic%? %0,%2,%1 ;;constraint 1
3062 bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
3063 bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3064 bic %0,%2,%1 ;;constraint 4
3065 bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
3066 bic %0,%S2,%1 ;;constraint 6"
3067 [(set_attr "length" "*,4,4,8,4,8,8")
3068 (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3069 (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3072 (define_insn "*iorsi3_a4"
3073 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3074 (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
3075 (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3080 [(set_attr "type" "binary, binary")
3081 (set_attr "length" "4, 8")])
3083 (define_insn "iorsi3"
3084 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w, w,w,Rcw, w")
3085 (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq, 0, 0, c, 0, 0, c, c,0, 0, c")
3086 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3089 switch (which_alternative)
3091 case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3092 return \"or%? %0,%1,%2%&\";
3094 return \"or%? %0,%2,%1%&\";
3095 case 2: case 5: case 8:
3096 return \"bset%? %0,%1,%z2%&\";
3100 [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3101 (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3102 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3104 ;; (define_insn "iorsi3"
3105 ;; [(set (match_operand:SI 0 "register_operand" "=r,r")
3106 ;; (ior:SI (match_operand:SI 1 "register_operand" "%r,r")
3107 ;; (match_operand:SI 2 "nonmemory_operand" "r,Ji")))]
3112 ;; [(set_attr "type" "binary, binary")
3113 ;; (set_attr "length" "4, 8")])
3115 (define_insn_and_split "iordi3"
3116 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3117 (ior:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3118 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3119 "TARGET_OLD_DI_PATTERNS"
3122 [(set (match_dup 3) (ior:SI (match_dup 4) (match_dup 5)))
3123 (set (match_dup 6) (ior:SI (match_dup 7) (match_dup 8)))]
3124 "arc_split_dilogic (operands, IOR); DONE;"
3125 [(set_attr "length" "8,8,16,16")])
3127 ;; (define_insn "*xorsi3_mixed"
3128 ;; [(set (match_operand:SI 0 "compact_register_operand" "=q")
3129 ;; (xor:SI (match_operand:SI 1 "compact_register_operand" "0")
3130 ;; (match_operand:SI 2 "compact_register_operand" "q")))]
3131 ;; "TARGET_MIXED_CODE"
3133 ;; [(set_attr "iscompact" "true")
3134 ;; (set_attr "length" "2")])
3136 (define_insn "xorsi3"
3137 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w, w,w, w, w")
3138 (xor:SI (match_operand:SI 1 "register_operand" "%0, Rcq, 0, c, 0, 0, c, c,0, 0, c")
3139 (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, cL, 0,C0p, I,cL,C0p,I,Cal,Cal")))]
3142 switch (which_alternative)
3144 case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3145 return \"xor%? %0,%1,%2%&\";
3147 return \"xor%? %0,%2,%1%&\";
3149 return \"bxor%? %0,%1,%z2\";
3154 [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3155 (set_attr "type" "binary")
3156 (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3157 (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3159 (define_insn_and_split "xordi3"
3160 [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,&w,w")
3161 (xor:DI (match_operand:DI 1 "register_operand" "%c,0,c,0")
3162 (match_operand:DI 2 "nonmemory_operand" "c,c,H,H")))]
3163 "TARGET_OLD_DI_PATTERNS"
3166 [(set (match_dup 3) (xor:SI (match_dup 4) (match_dup 5)))
3167 (set (match_dup 6) (xor:SI (match_dup 7) (match_dup 8)))]
3168 "arc_split_dilogic (operands, XOR); DONE;"
3169 [(set_attr "length" "8,8,16,16")])
3171 (define_insn "*negsi2_a4"
3172 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3173 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3176 [(set_attr "type" "unary")
3177 (set_attr "length" "4")])
3179 (define_insn "negsi2"
3180 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3181 (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3184 [(set_attr "type" "unary")
3185 (set_attr "iscompact" "maybe,true,false,false")
3186 (set_attr "cond" "canuse,nocond,canuse,nocond")])
3188 ;; (define_insn "negsi2"
3189 ;; [(set (match_operand:SI 0 "register_operand" "=r")
3190 ;; (neg:SI (match_operand:SI 1 "register_operand" "r")))]
3193 ;; [(set_attr "type" "unary")
3194 ;; (set_attr "length" "8")])
3196 (define_insn_and_split "negdi2"
3197 [(set (match_operand:DI 0 "dest_reg_operand" "=&w")
3198 (neg:DI (match_operand:DI 1 "register_operand" "c")))
3199 (clobber (reg:SI 61))]
3200 "TARGET_OLD_DI_PATTERNS"
3203 [(set (match_dup 0) (minus:DI (const_int 0) (match_dup 1)))]
3205 [(set_attr "type" "unary")
3206 (set_attr "cond" "clob")
3207 (set_attr "length" "16")])
3209 (define_insn "*one_cmplsi2_a4"
3210 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3211 (not:SI (match_operand:SI 1 "register_operand" "r")))]
3214 [(set_attr "type" "unary")
3215 (set_attr "cond" "nocond")])
3217 (define_insn "one_cmplsi2"
3218 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3219 (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3222 [(set_attr "type" "unary,unary")
3223 (set_attr "iscompact" "true,false")])
3225 ;; (define_insn "*one_cmplsi2_ac32"
3226 ;; [(set (match_operand:SI 0 "register_operand" "=r")
3227 ;; (not:SI (match_operand:SI 1 "register_operand" "r")))]
3228 ;; "TARGET_ARCOMPACT"
3230 ;; [(set_attr "type" "unary")
3231 ;; (set_attr "cond" "nocond")])
3233 (define_insn "*one_cmpldi2_a4"
3234 [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
3235 (not:DI (match_operand:DI 1 "register_operand" "r")))]
3237 "xor %H0,%H1,-1\;xor %L0,%L1,-1"
3238 [(set_attr "type" "unary")
3239 (set_attr "cond" "nocond")
3240 (set_attr "length" "16")])
3242 (define_insn_and_split "one_cmpldi2"
3243 [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3244 (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3247 "&& reload_completed"
3248 [(set (match_dup 2) (not:SI (match_dup 3)))
3249 (set (match_dup 4) (not:SI (match_dup 5)))]
3251 int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3253 operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3254 operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3255 operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3256 operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3258 [(set_attr "type" "unary,unary")
3259 (set_attr "cond" "nocond,nocond")
3260 (set_attr "length" "4,8")])
3262 ;; Shift instructions.
3264 (define_expand "ashlsi3"
3265 [(set (match_operand:SI 0 "dest_reg_operand" "")
3266 (ashift:SI (match_operand:SI 1 "register_operand" "")
3267 (match_operand:SI 2 "nonmemory_operand" "")))]
3271 if (!TARGET_SHIFTER)
3273 /* ashwin : all gen_rtx (VAR.. ) are converted to gen_rtx_VAR (..) */
3274 emit_insn (gen_rtx_PARALLEL
3277 gen_rtx_SET (VOIDmode, operands[0],
3278 gen_rtx_ASHIFT (SImode, operands[1], operands[2])),
3279 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3280 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 61))
3286 (define_expand "ashrsi3"
3287 [(set (match_operand:SI 0 "dest_reg_operand" "")
3288 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3289 (match_operand:SI 2 "nonmemory_operand" "")))]
3293 if (!TARGET_SHIFTER)
3295 emit_insn (gen_rtx_PARALLEL
3298 gen_rtx_SET (VOIDmode, operands[0],
3299 gen_rtx_ASHIFTRT (SImode, operands[1], operands[2])),
3300 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3301 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, 61)))));
3306 (define_expand "lshrsi3"
3307 [(set (match_operand:SI 0 "dest_reg_operand" "")
3308 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3309 (match_operand:SI 2 "nonmemory_operand" "")))]
3313 if (!TARGET_SHIFTER)
3315 emit_insn (gen_rtx_PARALLEL
3318 gen_rtx_SET (VOIDmode, operands[0],
3319 gen_rtx_LSHIFTRT (SImode, operands[1], operands[2])),
3320 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)),
3321 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode,61)))));
3326 (define_insn "*shift_si3"
3327 [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3328 (match_operator:SI 3 "shift_operator"
3329 [(match_operand:SI 1 "register_operand" "0")
3330 (match_operand:SI 2 "nonmemory_operand" "rJ")]))
3331 (clobber (match_scratch:SI 4 "=&r"))
3332 (clobber (reg:CC 61))
3335 "* return output_shift (operands);"
3336 [(set_attr "type" "shift")
3337 (set_attr "length" "32")])
3339 ; asl, asr, lsr patterns:
3340 ; There is no point in including an 'I' alternative since only the lowest 5
3341 ; bits are used for the shift. OTOH Cal can be useful if the shift amount
3342 ; is defined in an external symbol, as we don't have special relocations
3343 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3344 ; provide one alternatice for this, without condexec support.
3345 (define_insn "*ashlsi3_insn_mixed"
3346 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3347 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3348 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3350 && (register_operand (operands[1], SImode)
3351 || register_operand (operands[2], SImode))"
3353 [(set_attr "type" "shift")
3354 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3355 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3357 ;; (define_insn "*ashlsi3_insn"
3358 ;; [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3359 ;; (ashift:SI (match_operand:SI 1 "register_operand" "r,r,r,0")
3360 ;; (match_operand:SI 2 "nonmemory_operand" "N,r,Cal,rJ")))]
3367 ;; [(set_attr "type" "shift,shift,shift,shift")
3368 ;; (set_attr "length" "4, 4, 8, 8")
3369 ;; (set_attr "cond" "nocond,nocond,nocond,canuse")])
3371 ;; (define_insn "*ashrsi3_insn_mixed"
3372 ;; [(set (match_operand:SI 0 "register_operand" "=q,q,q,r,r")
3373 ;; (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,q,0,0,r")
3374 ;; (match_operand:SI 2 "nonmemory_operand" "N,K,qM,rJ,rJ")))]
3375 ;; "TARGET_MIXED_CODE"
3382 ;; [(set_attr "type" "shift,shift,shift,shift,shift")
3383 ;; (set_attr "iscompact" "true,true,true,false,false")])
3385 ;; (define_insn "*ashrsi3_insn"
3386 ;; [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3387 ;; (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
3388 ;; (match_operand:SI 2 "nonmemory_operand" "N,rJ,rJ")))]
3394 ;; [(set_attr "type" "shift,shift,shift")
3395 ;; (set_attr "cond" "nocond,canuse,nocond")])
3396 (define_insn "*ashrsi3_insn_mixed"
3397 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3398 (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3399 (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM, cL,cL,cCal")))]
3401 && (register_operand (operands[1], SImode)
3402 || register_operand (operands[2], SImode))"
3404 [(set_attr "type" "shift")
3405 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3406 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3408 ;; (define_insn "*lshrsi3_insn_mixed"
3409 ;; [(set (match_operand:SI 0 "register_operand" "=q,q,r")
3410 ;; (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,0,r")
3411 ;; (match_operand:SI 2 "nonmemory_operand" "N,qM,rJ")))]
3412 ;; "TARGET_MIXED_CODE"
3417 ;; [(set_attr "type" "shift,shift,shift")
3418 ;; (set_attr "iscompact" "true,true,false")])
3420 ;; (define_insn "*lshrsi3_insn"
3421 ;; [(set (match_operand:SI 0 "register_operand" "=r,r,r")
3422 ;; (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
3423 ;; (match_operand:SI 2 "nonmemory_operand" "N,rJ,rJ")))]
3429 ;; [(set_attr "type" "shift,shift,shift")
3430 ;; (set_attr "cond" "nocond,canuse,nocond")])
3431 (define_insn "*lshrsi3_insn_mixed"
3432 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcqq,Rcqq,Rcw, w, w")
3433 (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0, c,cCal")
3434 (match_operand:SI 2 "nonmemory_operand" "N, N,RcqqM, cL,cL,cCal")))]
3436 && (register_operand (operands[1], SImode)
3437 || register_operand (operands[2], SImode))"
3438 "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3439 ? \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3440 [(set_attr "type" "shift")
3441 (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3442 (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3444 (define_insn "rotrsi3"
3445 [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
3446 (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
3447 (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3450 [(set_attr "type" "shift,shift,shift")
3451 (set_attr "cond" "canuse,nocond,nocond")
3452 (set_attr "length" "4,4,8")])
3454 ;; Compare instructions.
3455 ;; This controls RTL generation and register allocation.
3457 ;; We generate RTL for comparisons and branches by having the cmpxx
3458 ;; patterns store away the operands. Then, the scc and bcc patterns
3459 ;; emit RTL for both the compare and the branch.
3461 (define_expand "cmpsi"
3463 (compare:CC (match_operand:SI 0 "register_operand" "")
3464 (match_operand:SI 1 "nonmemory_operand" "")))]
3468 arc_compare_op0 = operands[0];
3469 if (GET_CODE(operands[1]) == SYMBOL_REF && flag_pic)
3470 arc_compare_op1 = force_reg (SImode, operands[1]);
3472 arc_compare_op1 = operands[1];
3476 ;; ??? We may be able to relax this a bit by adding a new constraint for 0.
3477 ;; This assumes sub.f 0,symbol,0 is a valid insn.
3478 ;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
3479 ;; creating 8 byte insns we duplicate %1 in the destination reg of the insn
3480 ;; if it's a small constant.
3482 (define_insn "*cmpsi_cc_insn_a4"
3484 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r")
3485 (match_operand:SI 1 "nonmemory_operand" "r,I,Cal")))]
3491 [(set_attr "type" "compare,compare,compare")
3494 (define_insn "*cmpsi_cczn_insn_a4"
3495 [(set (reg:CC_ZN 61)
3496 (compare:CC_ZN (match_operand:SI 0 "register_operand" "r,r,r")
3497 (match_operand:SI 1 "nonmemory_operand" "r,I,Cal")))]
3503 [(set_attr "type" "compare,compare,compare")
3506 ;; (define_insn "*cmpsi_cc_insn_mixed"
3507 ;; [(set (reg:CC 61)
3508 ;; (compare:CC (match_operand:SI 0 "compact_register_operand" "q,r")
3509 ;; (match_operand:SI 1 "nonmemory_operand" "rO,rJ")))]
3510 ;; "TARGET_MIXED_CODE"
3514 ;; [(set_attr "type" "compare,compare")
3515 ;; (set_attr "iscompact" "true,false")])
3517 ;; (define_insn "*cmpsi_cc_insn"
3518 ;; [(set (reg:CC 61)
3519 ;; (compare:CC (match_operand:SI 0 "register_operand" "r")
3520 ;; (match_operand:SI 1 "nonmemory_operand" "rJ")))]
3521 ;; "TARGET_ARCOMPACT"
3523 ;; [(set_attr "type" "compare")
3526 ;; ??? Could add a peephole to generate compare with swapped operands and
3527 ;; modifed cc user if second, but not first operand is a compact register.
3528 (define_insn "cmpsi_cc_insn_mixed"
3530 (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, c, qRcq, c")
3531 (match_operand:SI 1 "nonmemory_operand" "cO,cI, Cal, Cal")))]
3534 [(set_attr "type" "compare")
3535 (set_attr "iscompact" "true,false,true_limm,false")
3536 (set_attr "cond" "set")
3537 (set_attr "length" "*,4,*,8")])
3539 (define_insn "*cmpsi_cc_zn_insn"
3540 [(set (reg:CC_ZN 61)
3541 (compare:CC_ZN (match_operand:SI 0 "register_operand" "qRcq,c")
3545 [(set_attr "type" "compare,compare")
3546 (set_attr "iscompact" "true,false")
3547 (set_attr "cond" "set_zn")
3548 (set_attr "length" "*,4")])
3550 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3551 (define_insn "*btst"
3552 [(set (reg:CC_ZN CC_REG)
3554 (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3556 (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3560 [(set_attr "iscompact" "true,false")
3561 (set_attr "cond" "set")
3562 (set_attr "type" "compare")
3563 (set_attr "length" "*,4")])
3565 ; combine suffers from 'simplifications' that replace a one-bit zero
3566 ; extract with a shift if it can prove that the upper bits are zero.
3567 ; arc_reorg sees the code after sched2, which can have caused our
3568 ; inputs to be clobbered even if they were not clobbered before.
3569 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3570 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3571 ; bbit (i.e. bad scheduling) and missed conditional execution,
3572 ; so make this an option.
3574 [(set (reg:CC_ZN CC_REG)
3576 (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3578 (match_operand:SI 1 "nonmemory_operand" ""))
3581 (if_then_else (match_operator 3 "equality_comparison_operator"
3582 [(reg:CC_ZN CC_REG) (const_int 0)])
3583 (label_ref (match_operand 2 "" ""))
3585 "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3586 [(parallel [(set (pc)
3589 [(zero_extract:SI (match_dup 0)
3590 (const_int 1) (match_dup 1))
3592 (label_ref (match_dup 2))
3594 (clobber (reg:CC_ZN CC_REG))])])
3596 (define_insn "*cmpsi_cc_z_insn"
3598 (compare:CC_Z (match_operand:SI 0 "register_operand" "qRcq,c")
3599 (match_operand:SI 1 "p2_immediate_operand" "O,n")))]
3604 [(set_attr "type" "compare,compare")
3605 (set_attr "iscompact" "true,false")
3606 (set_attr "cond" "set,set_zn")
3607 (set_attr "length" "*,4")])
3609 (define_insn "*cmpsi_cc_c_insn"
3611 (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, c,Rcqq, c")
3612 (match_operand:SI 1 "nonmemory_operand" "cO, cI, Cal,Cal")))]
3615 [(set_attr "type" "compare")
3616 (set_attr "iscompact" "true,false,true_limm,false")
3617 (set_attr "cond" "set")
3618 (set_attr "length" "*,4,*,8")])
3620 ;; Next come the scc insns.
3622 (define_expand "seq"
3623 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3627 operands[1] = gen_compare_reg (EQ, SImode);
3630 (define_expand "sne"
3631 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3635 operands[1] = gen_compare_reg (NE, SImode);
3638 (define_expand "sgt"
3639 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3643 operands[1] = gen_compare_reg (GT, SImode);
3646 (define_expand "sle"
3647 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3651 operands[1] = gen_compare_reg (LE, SImode);
3654 (define_expand "sge"
3655 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3659 operands[1] = gen_compare_reg (GE, SImode);
3662 (define_expand "slt"
3663 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3667 operands[1] = gen_compare_reg (LT, SImode);
3670 (define_expand "sgtu"
3671 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3675 operands[1] = gen_compare_reg (GTU, SImode);
3678 (define_expand "sleu"
3679 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3683 operands[1] = gen_compare_reg (LEU, SImode);
3686 (define_expand "sgeu"
3687 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3691 operands[1] = gen_compare_reg (GEU, SImode);
3694 (define_expand "sltu"
3695 [(set (match_operand:SI 0 "dest_reg_operand" "=r") (match_dup 1))]
3699 operands[1] = gen_compare_reg (LTU, SImode);
3702 (define_insn_and_split "*scc_insn"
3703 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3704 (match_operator:SI 1 "proper_comparison_operator" [(reg 61) (const_int 0)]))]
3708 [(set (match_dup 0) (const_int 1))
3711 (set (match_dup 0) (const_int 0)))]
3714 = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3715 GET_MODE (XEXP (operands[1], 0))),
3717 XEXP (operands[1], 0), XEXP (operands[1], 1));
3719 [(set_attr "type" "unary")])
3721 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3722 ;; that is one lower if the carry flag is set.
3724 ;; ??? Look up negscc insn. See pa.md for example.
3725 (define_insn "*neg_scc_insn"
3726 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3727 (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3728 [(reg 61) (const_int 0)])))]
3730 "mov %0,-1\;sub.%D1 %0,%0,%0"
3731 [(set_attr "type" "unary")
3732 (set_attr "length" "8")])
3734 (define_insn "*not_scc_insn"
3735 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3736 (not:SI (match_operator:SI 1 "proper_comparison_operator"
3737 [(reg 61) (const_int 0)])))]
3739 "mov %0,1\;sub.%d1 %0,%0,%0"
3740 [(set_attr "type" "unary")
3741 (set_attr "length" "8")])
3743 ; cond_exec patterns
3744 (define_insn "*movsi_ne"
3746 (ne (match_operand:CC_Z 2 "cc_use_register" "") (const_int 0))
3747 (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
3748 (match_operand:SI 1 "nonmemory_operand" "%C_0,Lc,?Cal")))]
3754 [(set_attr "type" "cmove,cmove,cmove")
3755 (set_attr "iscompact" "true,false,false")
3756 (set_attr "length" "*,4,8")])
3758 (define_insn "*movsi_cond_exec"
3760 (match_operator 3 "proper_comparison_operator"
3761 [(match_operand 2 "cc_register" "") (const_int 0)])
3762 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3763 (match_operand:SI 1 "nonmemory_operand" "%Lc,?Cal")))]
3766 [(set_attr "type" "cmove")
3767 (set_attr "length" "4,8")])
3769 (define_insn "*add_cond_exec"
3771 (match_operator 4 "proper_comparison_operator"
3772 [(match_operand 3 "cc_register" "") (const_int 0)])
3773 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3774 (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
3775 (match_operand:SI 2 "nonmemory_operand" "cCca,?Cal"))))]
3777 "*return arc_output_addsi (operands, \".%d4\");"
3778 [(set_attr "cond" "use")
3779 (set_attr "type" "cmove")
3780 (set_attr "length" "4,8")])
3782 ; ??? and could use bclr,bmsk
3783 ; ??? or / xor could use bset / bxor
3784 (define_insn "*commutative_cond_exec"
3786 (match_operator 5 "proper_comparison_operator"
3787 [(match_operand 4 "cc_register" "") (const_int 0)])
3788 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3789 (match_operator:SI 3 "commutative_operator"
3790 [(match_operand:SI 1 "register_operand" "%0,0")
3791 (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3794 [(set_attr "cond" "use")
3795 (set_attr "type" "cmove")
3796 (set_attr "length" "4,8")])
3798 (define_insn "*sub_cond_exec"
3800 (match_operator 4 "proper_comparison_operator"
3801 [(match_operand 3 "cc_register" "") (const_int 0)])
3802 (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3803 (minus:SI (match_operand:SI 1 "register_operand" "0,cL,Cal")
3804 (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3810 [(set_attr "cond" "use")
3811 (set_attr "type" "cmove")
3812 (set_attr "length" "4,4,8")])
3814 (define_insn "*noncommutative_cond_exec"
3816 (match_operator 5 "proper_comparison_operator"
3817 [(match_operand 4 "cc_register" "") (const_int 0)])
3818 (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3819 (match_operator:SI 3 "noncommutative_operator"
3820 [(match_operand:SI 1 "register_operand" "0,0")
3821 (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3824 [(set_attr "cond" "use")
3825 (set_attr "type" "cmove")
3826 (set_attr "length" "4,8")])
3828 ;; These control RTL generation for conditional jump insns
3830 (define_expand "beq"
3832 (if_then_else (match_dup 1)
3833 (label_ref (match_operand 0 "" ""))
3838 operands[1] = gen_compare_reg (EQ, VOIDmode);
3841 (define_expand "bne"
3843 (if_then_else (match_dup 1)
3844 (label_ref (match_operand 0 "" ""))
3849 operands[1] = gen_compare_reg (NE, VOIDmode);
3852 (define_expand "bgt"
3854 (if_then_else (match_dup 1)
3855 (label_ref (match_operand 0 "" ""))
3860 operands[1] = gen_compare_reg (GT, VOIDmode);
3863 (define_expand "ble"
3865 (if_then_else (match_dup 1)
3866 (label_ref (match_operand 0 "" ""))
3871 operands[1] = gen_compare_reg (LE, VOIDmode);
3874 (define_expand "bge"
3876 (if_then_else (match_dup 1)
3877 (label_ref (match_operand 0 "" ""))
3882 operands[1] = gen_compare_reg (GE, VOIDmode);
3885 (define_expand "blt"
3887 (if_then_else (match_dup 1)
3888 (label_ref (match_operand 0 "" ""))
3893 operands[1] = gen_compare_reg (LT, VOIDmode);
3896 (define_expand "bgtu"
3898 (if_then_else (match_dup 1)
3899 (label_ref (match_operand 0 "" ""))
3904 operands[1] = gen_compare_reg (GTU, VOIDmode);
3907 (define_expand "bleu"
3909 (if_then_else (match_dup 1)
3910 (label_ref (match_operand 0 "" ""))
3915 operands[1] = gen_compare_reg (LEU, VOIDmode);
3918 (define_expand "bgeu"
3920 (if_then_else (match_dup 1)
3921 (label_ref (match_operand 0 "" ""))
3926 operands[1] = gen_compare_reg (GEU, VOIDmode);
3929 (define_expand "bltu"
3931 (if_then_else (match_dup 1)
3932 (label_ref (match_operand 0 "" ""))
3937 operands[1] = gen_compare_reg (LTU, VOIDmode);
3940 (define_expand "bunge"
3942 (if_then_else (match_dup 1)
3943 (label_ref (match_operand 0 "" ""))
3948 operands[1] = gen_compare_reg (UNGE, VOIDmode);
3951 (define_expand "bungt"
3953 (if_then_else (match_dup 1)
3954 (label_ref (match_operand 0 "" ""))
3959 operands[1] = gen_compare_reg (UNGT, VOIDmode);
3962 (define_expand "bunle"
3964 (if_then_else (match_dup 1)
3965 (label_ref (match_operand 0 "" ""))
3970 operands[1] = gen_compare_reg (UNLE, VOIDmode);
3973 (define_expand "bunlt"
3975 (if_then_else (match_dup 1)
3976 (label_ref (match_operand 0 "" ""))
3981 operands[1] = gen_compare_reg (UNLT, VOIDmode);
3984 (define_expand "buneq"
3986 (if_then_else (match_dup 1)
3987 (label_ref (match_operand 0 "" ""))
3992 operands[1] = gen_compare_reg (UNEQ, VOIDmode);
3995 (define_expand "bltgt"
3997 (if_then_else (match_dup 1)
3998 (label_ref (match_operand 0 "" ""))
4003 operands[1] = gen_compare_reg (LTGT, VOIDmode);
4006 (define_expand "bordered"
4008 (if_then_else (match_dup 1)
4009 (label_ref (match_operand 0 "" ""))
4014 operands[1] = gen_compare_reg (ORDERED, VOIDmode);
4017 (define_expand "bunordered"
4019 (if_then_else (match_dup 1)
4020 (label_ref (match_operand 0 "" ""))
4025 operands[1] = gen_compare_reg (UNORDERED, VOIDmode);
4028 ;; Now match both normal and inverted jump.
4030 ;; TODO - supporting 16-bit conditional short branch insns if needed.
4032 ; (define_insn "*branch_insn_mixed"
4034 ; (if_then_else (match_operator 1 "comparison_operator"
4035 ; [(reg 61) (const_int 0)])
4036 ; (label_ref (match_operand 0 "" ""))
4038 ; "TARGET_MIXED_CODE"
4041 ; if (arc_ccfsm_branch_deleted_p ())
4043 ; arc_ccfsm_record_branch_deleted ();
4044 ; return \"; branch deleted, next insns conditionalized\";
4047 ; return \"b%d1_s %^%l0\";
4049 ; [(set_attr "type" "branch")])
4051 ; When estimating sizes during arc_reorg, when optimizing for speed, there
4052 ; are three reasons why we need to consider branches to be length 6:
4053 ; - unnull-false delay slot insns are implemented using conditional execution,
4054 ; thus preventing short insn formation where used.
4055 ; - for ARC600: unnul-true delay slot isnns are implemented where possile
4056 ; using conditional execution, preventing short insn formation where used.
4057 ; - for ARC700: likely or somewhat likely taken branches are made long and
4058 ; unaligned if possible to avoid branch penalty.
4059 (define_insn "*branch_insn"
4061 (if_then_else (match_operator 1 "proper_comparison_operator"
4062 [(reg 61) (const_int 0)])
4063 (label_ref (match_operand 0 "" ""))
4068 if (arc_ccfsm_branch_deleted_p ())
4070 arc_ccfsm_record_branch_deleted ();
4071 return \"; branch deleted, next insns conditionalized\";
4075 arc_ccfsm_record_condition (operands[1], 0, insn, 0);
4076 if (get_attr_length (insn) == 2)
4077 return \"b%d1%? %^%l0%&\";
4079 return \"b%d1%# %^%l0\";
4082 [(set_attr "type" "branch")
4084 (attr "lock_length")
4086 ; In arc_reorg we just guesstimate; might be more or less.
4087 (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4090 (eq_attr "delay_slot_filled" "yes")
4095 (match_operand 1 "equality_comparison_operator" "")
4096 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4097 (gt (minus (match_dup 0) (pc))
4098 (minus (const_int 506)
4099 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4100 (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4101 (gt (minus (match_dup 0) (pc))
4102 (minus (const_int 58)
4103 (symbol_ref "get_attr_delay_slot_length (insn)")))))
4107 (eq_attr "verify_short" "yes")
4110 (set (attr "iscompact")
4111 (cond [(eq_attr "lock_length" "2") (const_string "true")]
4112 (const_string "false")))])
4114 (define_insn "*rev_branch_insn"
4116 (if_then_else (match_operator 1 "proper_comparison_operator"
4117 [(reg 61) (const_int 0)])
4119 (label_ref (match_operand 0 "" ""))))]
4120 "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
4123 if (arc_ccfsm_branch_deleted_p ())
4125 arc_ccfsm_record_branch_deleted ();
4126 return \"; branch deleted, next insns conditionalized\";
4130 arc_ccfsm_record_condition (operands[1], 1, insn, 0);
4131 if (get_attr_length (insn) == 2)
4132 return \"b%D1%? %^%l0\";
4134 return \"b%D1%# %^%l0\";
4137 [(set_attr "type" "branch")
4139 (attr "lock_length")
4141 ; In arc_reorg we just guesstimate; might be more or less.
4142 (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4145 (eq_attr "delay_slot_filled" "yes")
4150 (match_operand 1 "equality_comparison_operator" "")
4151 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4152 (gt (minus (match_dup 0) (pc))
4153 (minus (const_int 506)
4154 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4155 (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4156 (gt (minus (match_dup 0) (pc))
4157 (minus (const_int 58)
4158 (symbol_ref "get_attr_delay_slot_length (insn)")))))
4162 (eq_attr "verify_short" "yes")
4165 (set (attr "iscompact")
4166 (cond [(eq_attr "lock_length" "2") (const_string "true")]
4167 (const_string "false")))])
4169 ;; Unconditional and other jump instructions.
4171 ;; TODO - supporting 16-bit short branch insns if needed.
4172 ;(define_insn "*jump_mixed"
4173 ; [(set (pc) (label_ref (match_operand 0 "" "")))]
4174 ; "TARGET_MIXED_CODE"
4176 ; [(set_attr "type" "uncond_branch")])
4178 (define_expand "jump"
4179 [(set (pc) (label_ref (match_operand 0 "" "")))]
4183 (define_insn "jump_i"
4184 [(set (pc) (label_ref (match_operand 0 "" "")))]
4185 "!TARGET_LONG_CALLS_SET || !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
4187 [(set_attr "type" "uncond_branch")
4188 (set (attr "iscompact")
4189 (if_then_else (eq_attr "lock_length" "2")
4190 (const_string "true") (const_string "false")))
4191 (set_attr "cond" "canuse")
4192 (set (attr "lock_length")
4194 ; In arc_reorg we just guesstimate; might be more or less.
4195 (ne (symbol_ref "arc_branch_size_unknown_p ()") (const_int 0))
4198 (eq_attr "delay_slot_filled" "yes")
4201 (ne (symbol_ref "find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)")
4205 (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4206 (gt (minus (match_dup 0) (pc))
4207 (minus (const_int 506)
4208 (symbol_ref "get_attr_delay_slot_length (insn)"))))
4211 (and (ne (symbol_ref "arc_ccfsm_advance_to (insn),
4212 arc_ccfsm_cond_exec_p ()")
4214 (ior (lt (minus (match_dup 0) (pc)) (const_int -64))
4215 (gt (minus (match_dup 0) (pc))
4216 (minus (const_int 58)
4218 "get_attr_delay_slot_length (insn)")))))
4221 (eq_attr "verify_short" "yes")
4226 (define_insn "indirect_jump"
4227 [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
4230 [(set_attr "type" "jump")
4231 (set_attr "iscompact" "false,false,false,maybe,false")
4232 (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
4234 ;; (define_insn "indirect_jump"
4235 ;; [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
4238 ;; [(set_attr "type" "jump")])
4240 ;; Implement a switch statement.
4241 ; ??? the following comment shows ignorance of gcc internals
4242 ; - or possibly code that old that it predates the current facilities.
4243 ;; This wouldn't be necessary in the non-pic case if we could distinguish
4244 ;; label refs of the jump table from other label refs. The problem is that
4245 ;; label refs are output as "%st(.LL42)" but we don't want the %st - we want
4246 ;; the real address since it's the address of the table.
4248 (define_expand "casesi"
4250 (minus:SI (match_operand:SI 0 "register_operand" "")
4251 (match_operand:SI 1 "nonmemory_operand" "")))
4252 (set (reg:CC CC_REG)
4253 (compare:CC (match_dup 5)
4254 (match_operand:SI 2 "nonmemory_operand" "")))
4256 (if_then_else (gtu (reg:CC 61)
4258 (label_ref (match_operand 4 "" ""))
4261 (unspec:SI [(match_operand 3 "" "")
4262 (match_dup 5) (match_dup 7)] UNSPEC_CASESI))
4263 (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
4269 operands[5] = gen_reg_rtx (SImode);
4270 operands[6] = gen_reg_rtx (SImode);
4271 operands[7] = operands[3];
4272 emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4273 emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4274 x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4275 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4276 gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4277 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
4278 if (TARGET_COMPACT_CASESI)
4280 emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4284 operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4285 if (flag_pic || !cse_not_expected)
4286 operands[3] = force_reg (Pmode, operands[3]);
4287 emit_insn (gen_casesi_load (operands[6],
4288 operands[3], operands[5], operands[7]));
4289 if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4290 emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4291 emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4296 (define_insn "casesi_load"
4297 [(set (match_operand:SI 0 "register_operand" "=Rcq,r,r")
4298 (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4299 (match_operand:SI 2 "register_operand" "Rcq,c,c")
4300 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))]
4304 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
4306 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4308 gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4309 gcc_assert (GET_MODE (diff_vec) == SImode);
4310 gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4313 switch (GET_MODE (diff_vec))
4316 return \"ld.as %0,[%1,%2]%&\";
4318 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4319 return \"ldw.as %0,[%1,%2]\";
4320 return \"ldw.x.as %0,[%1,%2]\";
4322 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4323 return \"ldb%? %0,[%1,%2]%&\";
4324 return \"ldb.x %0,[%1,%2]\";
4329 [(set_attr "type" "load")
4330 (set_attr_alternative "iscompact"
4332 [(ne (symbol_ref "GET_MODE (PATTERN (next_real_insn (operands[3])))")
4333 (symbol_ref "QImode"))
4334 (const_string "false")
4335 (eq (symbol_ref "ADDR_DIFF_VEC_FLAGS (PATTERN (next_real_insn (operands[3]))).offset_unsigned") (const_int 0))
4336 (const_string "false")]
4337 (const_string "true"))
4338 (const_string "false")
4339 (const_string "false")])
4340 (set_attr_alternative "length"
4342 [(eq_attr "iscompact" "false")
4344 (and (ne (symbol_ref "0") (const_int 0)) (eq (match_dup 0) (pc)))
4346 (eq_attr "verify_short" "yes")
4352 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4353 ; even for CASE_VECTOR_PC_RELATIVE.
4354 (define_insn "casesi_jump"
4355 [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4356 (use (label_ref (match_operand 1 "" "")))]
4359 [(set_attr "type" "jump")
4360 (set_attr "iscompact" "false,maybe,false")
4361 (set_attr "cond" "canuse")])
4363 (define_insn "casesi_compact_jump"
4365 (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4367 (use (label_ref (match_operand 1 "" "")))
4368 (clobber (match_scratch:SI 2 "=q,0"))]
4369 "TARGET_COMPACT_CASESI"
4372 rtx diff_vec = PATTERN (next_real_insn (operands[1]));
4373 int unalign = arc_get_unalign ();
4377 xop[0] = operands[0];
4378 xop[2] = operands[2];
4379 gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4381 switch (GET_MODE (diff_vec))
4384 /* Max length can be 12 in this case, but this is OK because
4385 2 of these are for alignment, and are anticipated in the length
4386 of the ADDR_DIFF_VEC. */
4387 if (unalign && !satisfies_constraint_Rcq (xop[0]))
4388 s = \"add2 %2,pcl,%0\n\tld_s%2,[%2,12]\";
4390 s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4392 s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4393 arc_clear_unalign ();
4396 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4398 if (satisfies_constraint_Rcq (xop[0]))
4400 s = \"add_s %2,%0,%1\n\tldw.as %2,[pcl,%2]\";
4401 xop[1] = GEN_INT ((10 - unalign) / 2U);
4405 s = \"add1 %2,pcl,%0\n\tldw_s %2,[%2,%1]\";
4406 xop[1] = GEN_INT (10 + unalign);
4411 if (satisfies_constraint_Rcq (xop[0]))
4413 s = \"add_s %2,%0,%1\n\tldw.x.as %2,[pcl,%2]\";
4414 xop[1] = GEN_INT ((10 - unalign) / 2U);
4418 s = \"add1 %2,pcl,%0\n\tldw_s.x %2,[%2,%1]\";
4419 xop[1] = GEN_INT (10 + unalign);
4422 arc_toggle_unalign ();
4425 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4427 if (rtx_equal_p (xop[2], xop[0])
4428 || find_reg_note (insn, REG_DEAD, xop[0]))
4430 s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4431 xop[1] = GEN_INT (8 + unalign);
4435 s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4436 xop[1] = GEN_INT (10 + unalign);
4437 arc_toggle_unalign ();
4440 else if (rtx_equal_p (xop[0], xop[2])
4441 || find_reg_note (insn, REG_DEAD, xop[0]))
4443 s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4444 xop[1] = GEN_INT (10 - unalign);
4445 arc_toggle_unalign ();
4449 /* ??? Length is 12. */
4450 s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4451 xop[1] = GEN_INT (8 + unalign);
4457 output_asm_insn (s, xop);
4458 return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4460 [(set_attr "length" "10")
4461 (set_attr "type" "jump")
4462 (set_attr "iscompact" "true")
4463 (set_attr "cond" "nocond")])
4465 ;; TODO: Splitting it up as separate patterns (when enabling this pattern) for
4466 ;; TARGET_MIXED_CODE so that length can be set correctly.
4467 (define_insn "tablejump"
4468 [(set (pc) (match_operand:SI 0 "address_operand" "p"))
4469 (use (label_ref (match_operand 1 "" "")))]
4470 "0 /* disabled -> using casesi now */"
4472 [(set_attr "type" "jump")])
4474 (define_expand "call"
4475 ;; operands[1] is stack_size_rtx
4476 ;; operands[2] is next_arg_register
4477 [(parallel [(call (match_operand:SI 0 "call_operand" "")
4478 (match_operand 1 "" ""))
4479 (clobber (reg:SI 31))])]
4484 gcc_assert (MEM_P (operands[0]));
4485 callee = XEXP (operands[0], 0);
4486 if (crtl->profile && arc_profile_call (callee))
4488 emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode,
4493 /* This is to decide if we should generate indirect calls by loading the
4494 32 bit address of the callee into a register before performing the
4495 branch and link - this exposes cse opportunities.
4496 Also, in weird cases like compile/20010107-1.c, we may get a PLUS. */
4497 if (GET_CODE (callee) != REG
4498 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4499 XEXP (operands[0], 0) = force_reg (Pmode, callee);
4504 (define_insn "*call_i"
4505 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Rcqq,c,Cbr,L,I,Cal"))
4506 (match_operand 1 "" ""))
4507 (clobber (reg:SI 31))]
4516 [(set_attr "type" "call,call,call,call,call,call_no_delay_slot")
4517 (set_attr "iscompact" "maybe,*,*,*,*,*")
4518 (set_attr_alternative "cond"
4519 [(const_string "canuse")
4520 (const_string "canuse")
4521 (cond [(eq (symbol_ref "TARGET_MEDIUM_CALLS") (const_int 0))
4522 (const_string "canuse")
4523 (eq_attr "delay_slot_filled" "yes")
4524 (const_string "nocond")
4525 (eq (symbol_ref "flag_pic") (const_int 0))
4526 (const_string "canuse_limm")]
4527 (const_string "nocond"))
4528 (const_string "canuse")
4529 (if_then_else (eq_attr "delay_slot_filled" "yes")
4530 (const_string "nocond")
4531 (const_string "canuse_limm"))
4532 (const_string "canuse")])
4533 (set_attr "length" "*,4,4,4,4,8")])
4535 (define_insn "call_prof"
4536 [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal"))
4537 (match_operand 1 "" ""))
4538 (clobber (reg:SI 31))
4545 [(set_attr "type" "call,call_no_delay_slot")
4546 (set_attr "cond" "canuse,canuse")
4547 (set_attr "length" "4,8")])
4549 (define_expand "call_value"
4550 ;; operand 2 is stack_size_rtx
4551 ;; operand 3 is next_arg_register
4552 [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4553 (call (match_operand:SI 1 "call_operand" "")
4554 (match_operand 2 "" "")))
4555 (clobber (reg:SI 31))])]
4561 gcc_assert (MEM_P (operands[1]));
4562 callee = XEXP (operands[1], 0);
4563 if (crtl->profile && arc_profile_call (callee))
4565 emit_call_insn (gen_call_value_prof (operands[0],
4566 gen_rtx_SYMBOL_REF (Pmode,
4571 /* See the comment in define_expand \"call\". */
4572 if (GET_CODE (callee) != REG
4573 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4574 XEXP (operands[1], 0) = force_reg (Pmode, callee);
4578 (define_insn "*call_value_i"
4579 [(set (match_operand 0 "dest_reg_operand" "=Rcqq,w, w,w,w, w")
4580 (call (mem:SI (match_operand:SI 1
4581 "call_address_operand" "Rcqq,c,Cbr,L,I,Cal"))
4582 (match_operand 2 "" "")))
4583 (clobber (reg:SI 31))]
4592 [(set_attr "type" "call,call,call,call,call,call_no_delay_slot")
4593 (set_attr "iscompact" "maybe,*,*,*,*,*")
4594 (set_attr_alternative "cond"
4595 [(const_string "canuse")
4596 (const_string "canuse")
4597 (cond [(eq (symbol_ref "TARGET_MEDIUM_CALLS") (const_int 0))
4598 (const_string "canuse")
4599 (eq_attr "delay_slot_filled" "yes")
4600 (const_string "nocond")
4601 (eq (symbol_ref "flag_pic") (const_int 0))
4602 (const_string "canuse_limm")]
4603 (const_string "nocond"))
4604 (const_string "canuse")
4605 (const_string "canuse_limm")
4606 (const_string "canuse")])
4607 (set_attr "length" "*,4,4,4,4,8")])
4610 ;; TODO - supporting 16-bit short "branch and link" insns if required.
4611 ;(define_insn "*call_value_via_label_mixed"
4612 ; [(set (match_operand 0 "register_operand" "=r")
4613 ; (call (mem:SI (match_operand:SI 1 "call_address_operand" ""))
4614 ; (match_operand 2 "" "")))
4615 ; (clobber (reg:SI 31))]
4616 ; "TARGET_MIXED_CODE"
4618 ; [(set_attr "type" "call")])
4620 (define_insn "call_value_prof"
4621 [(set (match_operand 0 "dest_reg_operand" "=r,r")
4622 (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal"))
4623 (match_operand 2 "" "")))
4624 (clobber (reg:SI 31))
4631 [(set_attr "type" "call,call_no_delay_slot")
4632 (set_attr "cond" "canuse,canuse")
4633 (set_attr "length" "4,8")])
4639 [(set_attr "type" "misc")
4640 (set_attr "iscompact" "true")
4641 (set_attr "cond" "canuse")
4642 (set_attr "length" "2")])
4644 ;; Special pattern to flush the icache.
4645 ;; ??? Not sure what to do here. Some ARC's are known to support this.
4647 (define_insn "flush_icache"
4648 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4651 [(set_attr "type" "misc")])
4653 ;; Split up troublesome insns for better scheduling.
4655 ;; Peepholes go at the end.
4656 ;;asl followed by add can be replaced by an add{1,2,3}
4657 ;; Three define_peepholes have been added for this optimization
4658 ;; ??? This used to target non-canonical rtl. Now we use add_n, which
4659 ;; can be generated by combine. Check if these peepholes still provide
4662 ;; -------------------------------------------------------------
4663 ;; Pattern 1 : r0 = r1 << {i}
4664 ;; r3 = r4/INT + r0 ;;and commutative
4667 ;; add{i} r3,r4/INT,r1
4668 ;; -------------------------------------------------------------
4671 [(set (match_operand:SI 0 "dest_reg_operand" "")
4672 (ashift:SI (match_operand:SI 1 "register_operand" "")
4673 (match_operand:SI 2 "const_int_operand" "")))
4674 (set (match_operand:SI 3 "dest_reg_operand" "")
4675 (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4676 (match_operand:SI 5 "nonmemory_operand" "")))]
4679 && (INTVAL (operands[2]) == 1
4680 || INTVAL (operands[2]) == 2
4681 || INTVAL (operands[2]) == 3)
4682 && (true_regnum (operands[4]) == true_regnum (operands[0])
4683 || true_regnum (operands[5]) == true_regnum (operands[0]))
4684 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4685 ;; the preparation statements take care to put proper operand in operands[4]
4686 ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4688 (plus:SI (mult:SI (match_dup 1)
4691 "DROSS (\"addn peephole2\");
4692 if (true_regnum (operands[4]) == true_regnum (operands[0]))
4693 operands[4] = operands[5];
4694 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4697 ;; triggered by -g -O2 -mARC600 -mmul64 -mnorm
4698 ;; libstdc++-v3/testsuite/23_containers/deque/check_construct_destroy.cc
4700 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
4701 (ashift:SI (match_operand:SI 1 "register_operand" "c,c")
4702 (match_operand:SI 2 "const_int_operand" "n,n")))
4703 (set (match_operand:SI 3 "dest_reg_operand" "=w,w")
4704 (plus:SI (match_operand:SI 4 "nonmemory_operand" "ci,0")
4705 (match_operand:SI 5 "nonmemory_operand" "0,ci")))]
4707 && (INTVAL (operands[2]) == 1
4708 || INTVAL (operands[2]) == 2
4709 || INTVAL (operands[2]) == 3)
4710 && (true_regnum (operands[4]) == true_regnum (operands[0])
4711 || true_regnum (operands[5]) == true_regnum (operands[0]))
4712 && arc_dead_or_set_postreload_p (insn, operands[0])"
4714 DROSS (\"addn_peephole\");
4715 /* This handles commutativity */
4716 if (which_alternative == 1)
4717 operands[4] = operands[5];
4718 switch (INTVAL (operands[2])) {
4719 case 1: return \"add1 %3,%S4,%1;;addi peephole - pattern 1\";
4720 case 2: return \"add2 %3,%S4,%1;;addi peephole - pattern 2\";
4721 case 3: return \"add3 %3,%S4,%1;;addi peephole - pattern 3\";
4722 default: gcc_unreachable ();
4725 [(set_attr "length" "8")]
4728 ; ??? For ARC700, bbit peepholes should be replaced with a combiner pattern
4729 ; combining a CC_Z btst with a bne/beq, and then properly branch shortened.
4730 ; The combined pattern should be grokked by the ccfsm machinery.
4731 ; For ARC600, the peephole should be adjusted to use btst as input.
4733 ; bbit0, bbit1 peephole that incorporates bic
4735 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4736 (and:SI (not:SI (match_operand:SI 1 "register_operand" "c"))
4737 (match_operand:SI 2 "immediate_operand" "Cal")))
4739 (compare:CC_ZN (match_dup 0)
4740 (match_operand:SI 3 "immediate_operand" "Cal")))
4742 (if_then_else (match_operator 4 "proper_comparison_operator"
4743 [(reg 61) (const_int 0)])
4744 (label_ref (match_operand 5 "" ""))
4748 && valid_bbit_pattern_p (operands,insn)
4749 && arc_dead_or_set_postreload_p (prev_nonnote_insn (insn), operands[0])
4750 && arc_dead_or_set_postreload_p (insn, XEXP (operands[4], 0))"
4751 "* return gen_bbit_bic_insns (operands);"
4752 [(set_attr "type" "branch")
4753 (set_attr "length" "4")]
4757 ; bbit0,bbit1 peephole optimization
4760 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4761 (and:SI (match_operand:SI 1 "register_operand" "%c")
4762 (match_operand:SI 2 "immediate_operand" "Cal")))
4764 (compare:CC_ZN (match_dup 0)
4765 (match_operand:SI 3 "immediate_operand" "Cal")))
4767 (if_then_else (match_operator 4 "proper_comparison_operator"
4768 [(reg 61) (const_int 0)])
4769 (label_ref (match_operand 5 "" ""))
4773 && valid_bbit_pattern_p (operands,insn)
4774 && arc_dead_or_set_postreload_p (prev_nonnote_insn(insn), operands [0])"
4775 "* return gen_bbit_insns(operands);"
4776 [ (set_attr "type" "branch")
4777 (set_attr "length" "4")])
4780 ;; bset peephole2 optimization
4782 [(set (match_operand:SI 0 "dest_reg_operand" "")
4784 (set (match_operand:SI 1 "dest_reg_operand" "")
4785 (ashift:SI (match_dup 0)
4786 (match_operand:SI 2 "register_operand" "")))
4787 (set (match_operand:SI 3 "dest_reg_operand" "")
4788 (ior:SI (match_operand:SI 4 "nonmemory_operand" "")
4789 (match_operand:SI 5 "nonmemory_operand" "")))]
4792 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[1]) == true_regnum (operands[0])))
4793 && (peep2_reg_dead_p (3, operands[1]) || (true_regnum (operands[3]) == true_regnum (operands[1])))
4794 && (true_regnum (operands[4]) == true_regnum (operands[1])
4795 || true_regnum (operands[5]) == true_regnum (operands[1]))"
4797 (ior:SI (match_dup 4)
4798 (ashift:SI (const_int 1) (match_dup 2))))]
4799 "DROSS (\"bset peephole2\");
4800 if (true_regnum (operands[4]) == true_regnum (operands[1]))
4801 operands[4] = operands[5];"
4805 ;; -------------------------------------------------------------
4806 ;; Pattern 1 : r0 = r1 << {i}
4811 ;; -------------------------------------------------------------
4814 [(set (match_operand:SI 0 "dest_reg_operand" "")
4815 (ashift:SI (match_operand:SI 1 "register_operand" "")
4816 (match_operand:SI 2 "const_int_operand" "")))
4817 (set (match_operand:SI 3 "dest_reg_operand" "")
4818 (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4822 && (INTVAL (operands[2]) == 1
4823 || INTVAL (operands[2]) == 2
4824 || INTVAL (operands[2]) == 3)
4825 && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4827 (minus:SI (match_dup 4)
4828 (mult:SI (match_dup 1)
4830 "DROSS (\"subn peephole2 1/2\");
4831 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4835 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4836 (ashift:SI (match_operand:SI 1 "register_operand" "c")
4837 (match_operand:SI 2 "const_int_operand" "i")))
4838 (set (match_operand:SI 3 "dest_reg_operand" "=r")
4839 (minus:SI (match_operand:SI 4 "nonmemory_operand" "cCal")
4843 && (INTVAL (operands[2]) == 1
4844 || INTVAL (operands[2]) == 2
4845 || INTVAL (operands[2]) == 3)
4846 && arc_dead_or_set_postreload_p (insn, operands[0])"
4849 DROSS (\"subn peephole 1/2\");
4850 switch (INTVAL (operands[2]))
4852 case 1: return \";;sub1 peephole - pattern 1\;sub1%? %3,%S4,%1\";
4853 case 2: return \";;sub2 peephole - pattern 1\;sub2%? %3,%S4,%1\";
4854 case 3: return \";;sub3 peephole - pattern 1\;sub3%? %3,%S4,%1\";
4855 default: gcc_unreachable ();
4858 [(set_attr "length" "4")]
4863 ;; -------------------------------------------------------------
4864 ;; Pattern 2 : r0 = r1 << {i}
4870 ;; -------------------------------------------------------------
4873 [(set (match_operand:SI 0 "dest_reg_operand" "")
4874 (ashift:SI (match_operand:SI 1 "register_operand" "")
4875 (match_operand:SI 2 "immediate_operand" "")))
4876 (set (match_operand:SI 3 "dest_reg_operand" "")
4877 (match_operand:SI 4 "immediate_operand" ""))
4878 (set (match_operand:SI 5 "dest_reg_operand" "")
4879 (minus:SI (match_dup 3)
4883 && GET_CODE (operands[2]) == CONST_INT
4884 && (INTVAL (operands[2]) == 1
4885 || INTVAL (operands[2]) == 2
4886 || INTVAL (operands[2]) == 3)
4887 && (peep2_reg_dead_p (3, operands[0]) || (true_regnum (operands[5]) == true_regnum (operands[0])))
4888 && (peep2_reg_dead_p (3, operands[3]) || (true_regnum (operands[5]) == true_regnum (operands[3])))"
4890 (minus:SI (match_dup 4)
4891 (mult:SI (match_dup 1)
4893 "DROSS (\"subn peephole2 2/2\");
4894 operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4898 [(set (match_operand:SI 0 "dest_reg_operand" "=w")
4899 (ashift:SI (match_operand:SI 1 "register_operand" "c")
4900 (match_operand:SI 2 "immediate_operand" "Cal")))
4901 (set (match_operand:SI 3 "dest_reg_operand" "=w")
4902 (match_operand:SI 4 "immediate_operand" "Cal"))
4903 (set (match_operand:SI 5 "dest_reg_operand" "=w")
4904 (minus:SI (match_dup 3)
4909 && GET_CODE (operands[2]) == CONST_INT
4910 && (INTVAL (operands[2]) == 1
4911 || INTVAL (operands[2]) == 2
4912 || INTVAL (operands[2]) == 3)
4913 && arc_dead_or_set_postreload_p (insn, operands[3])
4914 && arc_dead_or_set_postreload_p (insn, operands[0])"
4917 DROSS (\"subn peephole 2/2\");
4918 switch (INTVAL (operands[2]))
4920 case 1: return \";;sub1 peephole - pattern 2\;sub1%? %5,%S4,%1\";
4921 case 2: return \";;sub2 peephole - pattern 2\;sub2%? %5,%S4,%1\";
4922 case 3: return \";;sub3 peephole - pattern 2\;sub3%? %5,%S4,%1\";
4923 default: gcc_unreachable ();
4926 [(set_attr "length" "4")]
4931 [(set (match_operand:SI 0 "dest_reg_operand" "")
4933 (set (match_operand:SI 1 "dest_reg_operand" "")
4934 (ashift:SI (match_dup 0)
4935 (match_operand:SI 2 "register_operand" "")))
4936 (set (match_operand:SI 3 "dest_reg_operand" "")
4937 (xor:SI (match_operand:SI 4 "nonmemory_operand" "")
4938 (match_operand:SI 5 "nonmemory_operand" "")))
4943 && ( peep2_reg_dead_p (3, operands[1]) || ( true_regnum(operands[3])==true_regnum(operands[1]) ) )
4944 && ( peep2_reg_dead_p (2, operands[0]) || ( true_regnum(operands[1])==true_regnum(operands[0]) ) )
4945 && ( true_regnum(operands[4])==true_regnum(operands[1]) || true_regnum(operands[5])==true_regnum(operands[1]) )"
4947 ;; the preparation statements take care to put proper operand in operands[4]
4948 ;; operands[4] will always contain the correct operand
4950 (xor:SI (match_dup 4)
4951 (ashift:SI (const_int 1)
4952 (match_dup 2) ) ) ) ]
4954 "DROSS (\"bxor peephole2\");
4955 if ( true_regnum(operands[4])==true_regnum(operands[1]) )
4956 operands[4] = operands[5];
4960 ;; bclr peephole2 optimization
4962 [(set (match_operand:SI 0 "dest_reg_operand" "")
4964 (set (match_operand:SI 1 "dest_reg_operand" "")
4965 (ashift:SI (match_dup 0)
4966 (match_operand:SI 2 "register_operand" "")))
4967 (set (match_operand:SI 3 "dest_reg_operand" "")
4968 (and:SI (not:SI (match_dup 1))
4969 (match_operand:SI 4 "nonmemory_operand" "")))]
4972 && ( peep2_reg_dead_p (2, operands[0]) || true_regnum(operands[1])==true_regnum(operands[0]) )
4973 && ( peep2_reg_dead_p (3, operands[1]) || true_regnum(operands[3])==true_regnum(operands[1]) )"
4975 (and:SI (not:SI (ashift:SI (const_int 1)
4978 "DROSS (\"bclr peephole2\");"
4981 ;; bmsk peephole2 optimization
4983 [(set (match_operand:SI 0 "dest_reg_operand" "")
4984 (plus:SI (match_operand:SI 1 "register_operand" "")
4986 (set (match_operand:SI 2 "dest_reg_operand" "")
4988 (set (match_operand:SI 3 "dest_reg_operand" "")
4989 (ashift:SI (match_dup 2)
4991 (set (match_operand:SI 4 "dest_reg_operand" "")
4992 (plus:SI (match_dup 3)
4994 (set (match_operand:SI 5 "dest_reg_operand" "")
4995 (and:SI (match_operand:SI 6 "nonmemory_operand" "")
4996 (match_operand:SI 7 "nonmemory_operand" "")))
5000 && ( peep2_reg_dead_p (3, operands[0]) || true_regnum(operands[3])==true_regnum(operands[0]) )
5001 && ( peep2_reg_dead_p (3, operands[2]) || true_regnum(operands[3])==true_regnum(operands[2]) )
5002 && ( peep2_reg_dead_p (4, operands[3]) || true_regnum(operands[4])==true_regnum(operands[3]) )
5003 && ( peep2_reg_dead_p (5, operands[4]) || true_regnum(operands[5])==true_regnum(operands[4]) )
5004 && ( true_regnum(operands[6])==true_regnum(operands[4]) || true_regnum(operands[7])==true_regnum(operands[4]) )"
5006 (and:SI (match_dup 6)
5007 (plus:SI (ashift:SI (const_int 1)
5008 (plus:SI (match_dup 1)
5011 "DROSS (\"bmsk peephole2\");
5012 if ( true_regnum(operands[6])==true_regnum(operands[4]) )
5013 operands[6]=operands[7];
5017 ;; Instructions generated through builtins
5020 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5021 (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5027 [(set_attr "length" "4,8")
5028 (set_attr "type" "two_cycle_core,two_cycle_core")])
5030 (define_insn "normw"
5031 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
5032 (unspec:SI [(match_operand:HI 1 "general_operand" "cL,Cal")]
5038 [(set_attr "length" "4,8")
5039 (set_attr "type" "two_cycle_core,two_cycle_core")])
5043 [(set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
5044 (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
5051 [(set_attr "length" "4,8,4")
5052 (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
5054 ;; FIXME: an intrinsic for multiply is daft. Can we remove this?
5055 (define_insn "mul64"
5056 [(unspec [(match_operand:SI 0 "general_operand" "q,r,r,%r")
5057 (match_operand:SI 1 "general_operand" "q,rL,I,Cal")]
5061 mul64%? \t0, %0, %1%&
5064 mul64%? \t0, %0, %S1"
5065 [(set_attr "length" "2,4,4,8")
5066 (set_attr "iscompact" "true,false,false,false")
5067 (set_attr "type" "binary,binary,binary,binary")
5068 (set_attr "cond" "canuse,canuse, nocond, canuse")])
5070 (define_insn "mulu64"
5071 [(unspec [(match_operand:SI 0 "general_operand" "%r,r,r,r")
5072 (match_operand:SI 1 "general_operand" "rL,I,r,Cal")]
5076 mulu64%? \t0, %0, %1
5079 mulu64%? \t0, %0, %S1"
5080 [(set_attr "length" "4,4,4,8")
5081 (set_attr "type" "binary,binary,binary,binary")
5082 (set_attr "cond" "canuse,nocond,nocond,canuse")])
5084 (define_insn "divaw"
5085 [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
5086 (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
5087 (match_operand:SI 2 "general_operand" "r,r,Cal"))]
5089 "TARGET_EA_SET && TARGET_ARCOMPACT"
5093 divaw \t%0, %1, %S2"
5094 [(set_attr "length" "4,8,8")
5095 (set_attr "type" "divaw,divaw,divaw")])
5097 ; FIXME: The %? is of no use here, since cond is not canuse
5099 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5106 [(set_attr "length" "4,4,8")
5107 (set_attr "type" "misc,misc,misc")
5108 (set_attr "cond" "clob,clob,clob")])
5111 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5115 [(set_attr "length" "4")
5116 (set_attr "type" "misc")])
5119 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5123 [(set_attr "length" "4")
5124 (set_attr "type" "misc")
5125 (set_attr "cond" "clob")])
5128 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5132 [(set_attr "length" "4")
5133 (set_attr "type" "misc")])
5136 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5146 [(set_attr "length" "4")
5147 (set_attr "type" "misc")])
5150 (define_insn "sleep"
5151 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
5153 "(TARGET_A4 || check_if_valid_sleep_operand(operands,0))"
5158 return \"sleep %0\";
5160 [(set_attr "length" "4")
5161 (set_attr "type" "misc")])
5163 (define_insn "core_read"
5164 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
5165 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "HJ,!r")]
5166 VUNSPEC_CORE_READ))]
5169 if(check_if_valid_regno_const (operands,1))
5170 return \"mov \t%0, r%1\";
5171 return \"mov \t%0, r%1\";
5173 [(set_attr "length" "4")
5174 (set_attr "type" "unary")])
5176 (define_insn "core_write"
5177 [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
5178 (match_operand:SI 1 "general_operand" "HJ,!r")]
5179 VUNSPEC_CORE_WRITE)]
5182 if(check_if_valid_regno_const (operands,1))
5183 return \"mov \tr%1, %0\";
5184 return \"mov \tr%1, %0\";
5186 [(set_attr "length" "4")
5187 (set_attr "type" "unary")])
5190 [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r")
5191 (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HJ,r,D")]
5195 [(set_attr "length" "4,8,4,8")
5196 (set_attr "type" "lr,lr,lr,lr")])
5199 [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
5200 (match_operand:SI 1 "general_operand" "Ir,I,HJ,r")]
5204 [(set_attr "length" "8,4,8,4")
5205 (set_attr "type" "sr,sr,sr,sr")])
5207 (define_insn "trap_s"
5208 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
5212 if (which_alternative == 0)
5213 return \"trap_s %0\";
5215 fatal_error (\"Operand to trap_s should be an unsigned 6-bit value.\");
5217 [(set_attr "length" "4")
5218 (set_attr "type" "misc")])
5220 (define_insn "unimp_s"
5221 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
5225 [(set_attr "length" "4")
5226 (set_attr "type" "misc")])
5228 ;; End of instructions generated through builtins
5230 ; Since the demise of REG_N_SETS, it is no longer possible to find out
5231 ; in the prologue / epilogue expanders how many times blink is set.
5232 ; Using df_regs_ever_live_p to decide if blink needs saving means that
5233 ; any explicit use of blink will cause it to be saved; hence we cannot
5234 ; represent the blink use in return / sibcall instructions themselves, and
5235 ; instead have to show it in EPILOGUE_USES and must explicitly
5236 ; forbid instructions that change blink in the return / sibcall delay slot.
5237 (define_expand "sibcall"
5238 [(parallel [(call (match_operand 0 "memory_operand" "")
5239 (match_operand 1 "general_operand" ""))
5241 (use (match_operand 2 "" ""))])]
5245 rtx callee = XEXP (operands[0], 0);
5247 if (operands[2] == NULL_RTX)
5248 operands[2] = const0_rtx;
5249 if (crtl->profile && arc_profile_call (callee))
5251 emit_insn (gen_sibcall_prof
5252 (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
5253 operands[1], operands[2]));
5256 if (GET_CODE (callee) != REG
5257 && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
5258 XEXP (operands[0], 0) = force_reg (Pmode, callee);
5262 (define_expand "sibcall_value"
5263 [(parallel [(set (match_operand 0 "dest_reg_operand" "")
5264 (call (match_operand 1 "memory_operand" "")
5265 (match_operand 2 "general_operand" "")))
5267 (use (match_operand 3 "" ""))])]
5271 rtx callee = XEXP (operands[1], 0);
5273 if (operands[3] == NULL_RTX)
5274 operands[3] = const0_rtx;
5275 if (crtl->profile && arc_profile_call (XEXP (operands[1], 0)))
5277 emit_insn (gen_sibcall_value_prof
5278 (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"),
5279 operands[2], operands[3]));
5282 if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
5283 XEXP (operands[1], 0) = force_reg (Pmode, callee);
5287 (define_insn "*sibcall_insn"
5288 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Rs5,Rsc,Cal"))
5289 (match_operand 1 "" ""))
5291 (use (match_operand 2 "" ""))]
5298 [(set_attr "type" "call,call,call,call_no_delay_slot")
5299 (set_attr "iscompact" "false,maybe,false,false")
5300 (set_attr "is_SIBCALL" "yes")]
5303 (define_insn "*sibcall_value_insn"
5304 [(set (match_operand 0 "dest_reg_operand" "")
5305 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Rs5,Rsc,Cal"))
5306 (match_operand 2 "" "")))
5308 (use (match_operand 3 "" ""))]
5315 [(set_attr "type" "call,call,call,call_no_delay_slot")
5316 (set_attr "iscompact" "false,maybe,false,false")
5317 (set_attr "is_SIBCALL" "yes")]
5320 (define_insn "sibcall_prof"
5321 [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal"))
5322 (match_operand 1 "" ""))
5324 (use (match_operand 2 "" ""))
5331 [(set_attr "type" "call,call_no_delay_slot")
5332 (set_attr "is_SIBCALL" "yes")]
5335 (define_insn "sibcall_value_prof"
5336 [(set (match_operand 0 "dest_reg_operand" "")
5337 (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal"))
5338 (match_operand 2 "" "")))
5340 (use (match_operand 3 "" ""))
5347 [(set_attr "type" "call,call_no_delay_slot")
5348 (set_attr "is_SIBCALL" "yes")]
5351 (define_expand "prologue"
5355 arc_expand_prologue ();
5359 (define_expand "epilogue"
5363 arc_expand_epilogue (0);
5367 (define_expand "sibcall_epilogue"
5371 arc_expand_epilogue (1);
5375 ; Since the demise of REG_N_SETS, it is no longer possible to find out
5376 ; in the prologue / epilogue expanders how many times blink is set.
5377 ; Using df_regs_ever_live_p to decide if blink needs saving means that
5378 ; any explicit use of blink will cause it to be saved; hence we cannot
5379 ; represent the blink use in return / sibcall instructions themselves, and
5380 ; instead have to show it in EPILOGUE_USES and must explicitly
5381 ; forbid instructions that change blink in the return / sibcall delay slot.
5382 (define_insn "return_i"
5387 = gen_rtx_REG (Pmode,
5388 arc_return_address_regs[arc_compute_function_type (cfun)]);
5390 if (TARGET_PAD_RETURN)
5392 output_asm_insn (\"j%!%* [%0]%&\", ®);
5395 [(set_attr "type" "return")
5396 (set_attr "cond" "canuse")
5397 (set (attr "iscompact")
5398 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
5399 (symbol_ref "ARC_FUNCTION_NORMAL"))
5400 (const_string "maybe")]
5401 (const_string "false")))
5402 (set (attr "length")
5403 (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
5404 (symbol_ref "ARC_FUNCTION_NORMAL"))
5406 (and (ne (symbol_ref "0") (const_int 0))
5407 (ne (minus (match_dup 0) (pc)) (const_int 0)))
5409 (eq_attr "verify_short" "no")
5413 ;; Comment in final.c (insn_current_reference_address) says
5414 ;; forward branch addresses are calculated from the next insn after branch
5415 ;; and for backward branches, it is calculated from the branch insn start.
5416 ;; The shortening logic here is tuned to accomodate this behaviour
5417 ;; ??? This should be grokked by the ccfsm machinery.
5418 (define_insn "cbranchsi4_scratch"
5420 (if_then_else (match_operator 0 "proper_comparison_operator"
5421 [(match_operand:SI 1 "register_operand" "c,c, c")
5422 (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
5423 (label_ref (match_operand 3 "" ""))
5425 (clobber (match_operand 4 "cc_register" ""))]
5427 && (reload_completed
5428 || (TARGET_EARLY_CBRANCHSI
5429 && brcc_nolimm_operator (operands[0], VOIDmode)))
5430 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
5432 switch (get_attr_length (insn))
5434 case 2: return \"br%d0%? %1, %2, %^%l3%&\";
5435 case 4: return \"br%d0%* %1, %B2, %^%l3\";
5436 case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5437 return \"br%d0%* %1, %B2, %^%l3\";
5439 case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\";
5440 default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5443 [(set_attr "cond" "clob, clob, clob")
5444 (set (attr "iscompact")
5445 (cond [(eq_attr "lock_length" "2,6,10") (const_string "true")]
5446 (const_string "false")))
5449 (ne (symbol_ref "valid_brcc_with_delay_p (operands)") (const_int 0))
5450 (const_string "brcc")
5451 (const_string "brcc_no_delay_slot")))
5452 ; For forward branches, we need to account not only for the distance to
5453 ; the target, but also the difference between pcl and pc, the instruction
5454 ; length, and any delay insn, if present.
5456 (attr "lock_length")
5457 (cond ; the outer cond does a test independent of branch shortening.
5458 [(match_operand 0 "brcc_nolimm_operator" "")
5460 [(and (match_operand:CC_Z 4 "cc_register")
5461 (eq_attr "delay_slot_filled" "no")
5462 (ge (minus (match_dup 3) (pc)) (const_int -128))
5463 (le (minus (match_dup 3) (pc))
5464 (minus (const_int 122)
5465 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5467 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5468 (le (minus (match_dup 3) (pc))
5469 (minus (const_int 248)
5470 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5472 (match_operand:SI 1 "compact_register_operand" "")
5475 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5476 (le (minus (match_dup 3) (pc)) (const_int 244)))
5478 (match_operand:SI 1 "compact_register_operand" "")
5483 (cond ; the outer cond does a test independent of branch shortening.
5484 [(match_operand 0 "brcc_nolimm_operator" "")
5486 [(and (match_operand:CC_Z 4 "cc_register")
5487 (eq_attr "delay_slot_filled" "no")
5488 (ge (minus (match_dup 3) (pc)) (const_int -128))
5489 (le (minus (match_dup 3) (pc))
5490 (minus (const_int 122)
5491 (symbol_ref "get_attr_delay_slot_length (insn)")))
5492 (eq_attr "verify_short" "yes"))
5494 (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5495 (le (minus (match_dup 3) (pc))
5496 (minus (const_int 248)
5497 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5499 (and (match_operand:SI 1 "compact_register_operand" "")
5500 (eq_attr "verify_short" "yes"))
5503 (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5504 (le (minus (match_dup 3) (pc)) (const_int 244)))
5506 (and (match_operand:SI 1 "compact_register_operand" "")
5507 (eq_attr "verify_short" "yes"))
5511 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5512 (define_insn "*bbit"
5515 (match_operator 3 "equality_comparison_operator"
5516 [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5518 (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5520 (label_ref (match_operand 0 "" ""))
5522 (clobber (reg:CC_ZN CC_REG))]
5523 "!find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
5525 switch (get_attr_length (insn))
5527 case 4: return (GET_CODE (operands[3]) == EQ
5528 ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5530 case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5531 default: gcc_unreachable ();
5534 [(set_attr "type" "brcc")
5535 (set_attr "cond" "clob")
5536 (set (attr "lock_length")
5537 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5538 (le (minus (match_dup 0) (pc))
5539 (minus (const_int 248)
5540 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5542 (eq (symbol_ref "which_alternative") (const_int 0))
5545 (set (attr "length")
5546 (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5547 (le (minus (match_dup 0) (pc))
5548 (minus (const_int 248)
5549 (symbol_ref "get_attr_delay_slot_length (insn)"))))
5551 (and (eq (symbol_ref "which_alternative") (const_int 0))
5552 (eq_attr "verify_short" "yes"))
5555 (set (attr "iscompact")
5556 (if_then_else (eq_attr "lock_length" "6")
5557 (const_string "true") (const_string "false")))])
5559 ; operand 0 is the loop count pseudo register
5560 ; operand 1 is the number of loop iterations or 0 if it is unknown
5561 ; operand 2 is the maximum number of loop iterations
5562 ; operand 3 is the number of levels of enclosed loops
5563 ; operand 4 is the loop end pattern
5564 (define_expand "doloop_begin"
5565 [(use (match_operand 0 "register_operand" ""))
5566 (use (match_operand:QI 1 "const_int_operand" ""))
5567 (use (match_operand:QI 2 "const_int_operand" ""))
5568 (use (match_operand:QI 3 "const_int_operand" ""))
5569 (use (match_operand 4 "" ""))]
5572 if (INTVAL (operands[3]) > 1)
5574 emit_insn (gen_doloop_begin_i (operands[0], const0_rtx,
5575 GEN_INT (INSN_UID (operands[4])),
5576 const0_rtx, const0_rtx));
5580 ; ??? can't describe the insn properly as then the optimizers try to
5582 ;(define_insn "doloop_begin_i"
5583 ; [(set (reg:SI LP_START) (pc))
5584 ; (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_LP))
5585 ; (use (match_operand 0 "const_int_operand" "n"))]
5587 ; "lp .L__GCC__LP%0"
5590 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
5591 ; instruction that was not at the start of the loop.
5592 ; There is no point is reloading this insn - then lp_count would still not
5593 ; be available for the loop end.
5594 (define_insn "doloop_begin_i"
5595 [(unspec:SI [(pc)] UNSPEC_LP)
5596 (clobber (reg:SI LP_START))
5597 (clobber (reg:SI LP_END))
5598 (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
5599 (use (match_operand 1 "const_int_operand" "n,n,C_0"))
5600 (use (match_operand 2 "const_int_operand" "n,n,X"))
5601 (use (match_operand 3 "const_int_operand" "C_0,n,X"))
5602 (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
5608 rtx loop_start = operands[4];
5610 if (CONST_INT_P (loop_start))
5611 loop_start = NULL_RTX;
5612 /* Size implications of the alignment will be taken care off by the
5613 alignemnt inserted at the loop start. */
5614 if (LOOP_ALIGN (0) && INTVAL (operands[1]))
5615 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5616 if (!INTVAL (operands[1]))
5617 return "; LITTLE LOST LOOP";
5618 if (loop_start && flag_pic)
5619 /* ??? Can do better for when a scratch register
5620 is known. But that would require extra testing. */
5621 return ".p2align 2\;push_s r0\;add r0,pcl,%4-.+2\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0";
5622 /* Check if the loop end is in range to be set by the lp instruction. */
5623 size = INTVAL (operands[3]) < 2 ? 0 : 2048;
5624 for (size = 0, scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
5628 if (recog_memoized (scan) == CODE_FOR_doloop_end_i
5629 && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
5630 == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
5632 len = get_attr_length (scan);
5635 /* Try to verify that there are at least three instruction fetches
5636 between the loop setup and the first encounter of the loop end. */
5637 for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
5641 if (GET_CODE (PATTERN (scan)) == SEQUENCE)
5642 scan = XVECEXP (PATTERN (scan), 0, 0);
5645 if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
5648 if (simplejump_p (scan))
5650 insn = XEXP (SET_SRC (PATTERN (scan)), 0);
5653 if (JUMP_LABEL (scan)
5654 && (!next_active_insn (JUMP_LABEL (scan))
5655 || (recog_memoized (next_active_insn (JUMP_LABEL (scan)))
5656 != CODE_FOR_doloop_begin_i))
5657 && (!next_active_insn (NEXT_INSN (PREV_INSN (scan)))
5659 (next_active_insn (NEXT_INSN (PREV_INSN (scan))))
5660 != CODE_FOR_doloop_begin_i)))
5665 len = get_attr_length (scan);
5666 /* Size estimation of asms assumes that each line which is nonempty
5667 codes an insn, and that each has a long immediate. For minimum insn
5668 count, assume merely that a nonempty asm has at least one insn. */
5669 if (GET_CODE (PATTERN (scan)) == ASM_INPUT
5670 || asm_noperands (PATTERN (scan)) >= 0)
5671 n_insns += (len != 0);
5673 n_insns += (len > 4 ? 2 : (len ? 1 : 0));
5676 asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5677 gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5678 if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5681 /* ??? Can do better for when a scratch register
5682 is known. But that would require extra testing. */
5683 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";
5684 output_asm_insn ((size < 2048
5685 ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5687 output_asm_insn (loop_start
5688 ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5690 if (TARGET_ARC600 && n_insns < 1)
5691 output_asm_insn ("nop", operands);
5692 return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5694 else if (TARGET_ARC600 && n_insns < 3)
5696 /* At least four instructions are needed between the setting of LP_COUNT
5697 and the loop end - but the lp instruction qualifies as one. */
5698 rtx prev = prev_nonnote_insn (insn);
5700 if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5701 output_asm_insn ("nop", operands);
5703 return "lp .L__GCC__LP%1";
5705 [(set_attr "type" "loop_setup")
5706 (set_attr_alternative "length"
5707 [(if_then_else (ne (symbol_ref "TARGET_ARC600") (const_int 0))
5708 (const_int 16) (const_int 4))
5709 (if_then_else (ne (symbol_ref "flag_pic") (const_int 0))
5710 (const_int 28) (const_int 16))
5712 ;; ??? strictly speaking, we should branch shorten this insn, but then
5713 ;; we'd need a proper label first. We could say it is always 24 bytes in
5714 ;; length, but that would be very pessimistic; also, when the loop insn
5715 ;; goes out of range, it is very likely that the same insns that have
5716 ;; done so will already have made all other small offset branches go out
5717 ;; of range, making the need for exact length information here mostly
5721 ; operand 0 is the loop count pseudo register
5722 ; operand 1 is the number of loop iterations or 0 if it is unknown
5723 ; operand 2 is the maximum number of loop iterations
5724 ; operand 3 is the number of levels of enclosed loops
5725 ; operand 4 is the label to jump to at the top of the loop
5726 ; operand 5 is nonzero if the loop is entered at its top.
5727 ; Use this for the ARC600 and ARC700. For ARCtangent-A5, this is unsafe
5728 ; without further checking for nearby branches etc., and without proper
5729 ; annotation of shift patterns that clobber lp_count
5730 ; ??? ARC600 might want to check if the loop has few iteration and only a
5731 ; single insn - loop setup is expensive then.
5732 (define_expand "doloop_end"
5733 [(use (match_operand 0 "register_operand" ""))
5734 (use (match_operand:QI 1 "const_int_operand" ""))
5735 (use (match_operand:QI 2 "const_int_operand" ""))
5736 (use (match_operand:QI 3 "const_int_operand" ""))
5737 (use (label_ref (match_operand 4 "" "")))
5738 (use (match_operand:QI 5 "const_int_operand" ""))]
5739 "(TARGET_ARC600 || TARGET_ARC700) && arc_experimental_mask & 1"
5741 if (INTVAL (operands[3]) > 1)
5743 /* Setting up the loop with two sr isntructions costs 6 cycles. */
5744 if (TARGET_ARC700 && !INTVAL (operands[5])
5745 && INTVAL (operands[1]) && INTVAL (operands[1]) <= (flag_pic ? 6 : 3))
5747 /* We could do smaller bivs with biv widening, and wider bivs by having
5748 a high-word counter in an outer loop - but punt on this for now. */
5749 if (GET_MODE (operands[0]) != SImode)
5751 emit_jump_insn (gen_doloop_end_i (operands[0], operands[4], const0_rtx));
5755 (define_insn_and_split "doloop_end_i"
5757 (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5759 (label_ref (match_operand 1 "" ""))
5761 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5762 (use (reg:SI LP_START))
5763 (use (reg:SI LP_END))
5764 (use (match_operand 2 "const_int_operand" "n,???C_0,???X"))
5765 (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5769 rtx prev = prev_nonnote_insn (insn);
5771 /* If there is an immediately preceding label, we must output a nop,
5772 lest a branch to that label will fall out of the loop.
5773 ??? We could try to avoid this by claiming to have a delay slot if there
5774 is a preceding label, and outputting the delay slot insn instead, if
5776 Or we could have some optimization that changes the source edge to update
5777 the loop count and jump to the loop start instead. */
5778 /* For ARC600, we must also prevent jumps inside the loop and jumps where
5779 the loop counter value is live at the target from being directly at the
5780 loop end. Being sure that the loop counter is dead at the target is
5781 too much hair - we can't rely on data flow information at this point -
5782 so insert a nop for all branches.
5783 The ARC600 also can't read the loop counter in the last insn of a loop. */
5785 output_asm_insn (\"nop%?\", operands);
5786 return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5788 "&& memory_operand (operands[0], SImode)"
5791 emit_move_insn (operands[3], operands[0]);
5792 emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5795 [(set_attr "type" "loop_end")
5796 (set (attr "length")
5797 (if_then_else (ne (symbol_ref "LABEL_P (prev_nonnote_insn (insn))")
5799 (const_int 4) (const_int 0)))]
5802 ; This pattern is generated by arc_reorg when there is no recognizable
5804 (define_insn "*doloop_fallback"
5805 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5807 (label_ref (match_operand 1 "" ""))
5809 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5810 ; avoid fooling the loop optimizer into assuming this is a special insn.
5812 "*return get_attr_length (insn) == 8
5813 ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5814 : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5815 [(set (attr "length")
5816 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
5817 (le (minus (match_dup 1) (pc)) (const_int 244)))
5818 (const_int 8) (const_int 12)))
5819 (set_attr "type" "brcc_no_delay_slot")
5820 (set_attr "cond" "nocond")]
5823 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5824 (define_insn "doloop_fallback_m"
5825 [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5827 (label_ref (match_operand 1 "" ""))
5829 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5830 (set (match_operand:SI 2 "memory_operand" "=m")
5831 (plus:SI (match_dup 0) (const_int -1)))]
5832 ; avoid fooling the loop optimizer into assuming this is a special insn.
5834 "*return get_attr_length (insn) == 12
5835 ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5836 : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5837 [(set (attr "length")
5838 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5839 (le (minus (match_dup 1) (pc)) (const_int 244)))
5840 (const_int 12) (const_int 16)))
5841 (set_attr "type" "brcc_no_delay_slot")
5842 (set_attr "cond" "nocond")]
5845 (define_expand "movmemsi"
5846 [(match_operand:BLK 0 "" "")
5847 (match_operand:BLK 1 "" "")
5848 (match_operand:SI 2 "nonmemory_operand" "")
5849 (match_operand 3 "immediate_operand" "")]
5851 "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5853 ;; See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 why we can't
5854 ;; get rid of this bogosity.
5855 (define_expand "cmpsf"
5857 (compare:CC (match_operand:SF 0 "general_operand" "")
5858 (match_operand:SF 1 "general_operand" "")))]
5862 arc_compare_op0 = operands[0];
5863 arc_compare_op1 = operands[1];
5867 (define_expand "cmpdf"
5869 (compare:CC (match_operand:DF 0 "general_operand" "")
5870 (match_operand:DF 1 "general_operand" "")))]
5871 "TARGET_OPTFPE && !TARGET_DPFP"
5874 arc_compare_op0 = operands[0];
5875 arc_compare_op1 = operands[1];
5879 (define_expand "cmp_float"
5880 [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5881 (clobber (reg:SI 31))
5882 (clobber (reg:SI 12))])]
5886 (define_insn "*cmpsf_eq"
5887 [(set (reg:CC_Z 61) (compare:CC_Z (reg:SF 0) (reg:SF 1)))
5888 (clobber (reg:SI 31))
5889 (clobber (reg:SI 12))]
5890 "TARGET_OPTFPE && !TARGET_SPFP"
5891 "*return arc_output_libcall (\"__eqsf2\");"
5892 [(set_attr "is_sfunc" "yes")]
5895 (define_insn "*cmpdf_eq"
5896 [(set (reg:CC_Z 61) (compare:CC_Z (reg:DF 0) (reg:DF 2)))
5897 (clobber (reg:SI 31))
5898 (clobber (reg:SI 12))]
5899 "TARGET_OPTFPE && !TARGET_DPFP"
5900 "*return arc_output_libcall (\"__eqdf2\");"
5901 [(set_attr "is_sfunc" "yes")]
5904 (define_insn "*cmpsf_gt"
5905 [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:SF 0) (reg:SF 1)))
5906 (clobber (reg:SI 31))
5907 (clobber (reg:SI 12))]
5908 "TARGET_OPTFPE && !TARGET_SPFP"
5909 "*return arc_output_libcall (\"__gtsf2\");"
5910 [(set_attr "is_sfunc" "yes")]
5913 (define_insn "*cmpdf_gt"
5914 [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:DF 0) (reg:DF 2)))
5915 (clobber (reg:SI 31))
5916 (clobber (reg:SI 12))]
5917 "TARGET_OPTFPE && !TARGET_DPFP"
5918 "*return arc_output_libcall (\"__gtdf2\");"
5919 [(set_attr "is_sfunc" "yes")]
5922 (define_insn "*cmpsf_ge"
5923 [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:SF 0) (reg:SF 1)))
5924 (clobber (reg:SI 31))
5925 (clobber (reg:SI 12))]
5926 "TARGET_OPTFPE && !TARGET_SPFP"
5927 "*return arc_output_libcall (\"__gesf2\");"
5928 [(set_attr "is_sfunc" "yes")]
5931 (define_insn "*cmpdf_ge"
5932 [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:DF 0) (reg:DF 2)))
5933 (clobber (reg:SI 31))
5934 (clobber (reg:SI 12))]
5935 "TARGET_OPTFPE && !TARGET_DPFP"
5936 "*return arc_output_libcall (\"__gedf2\");"
5937 [(set_attr "is_sfunc" "yes")]
5940 (define_insn "*cmpsf_uneq"
5941 [(set (reg:CC_FP_UNEQ 61) (compare:CC_FP_UNEQ (reg:SF 0) (reg:SF 1)))
5942 (clobber (reg:SI 31))
5943 (clobber (reg:SI 12))]
5944 "TARGET_OPTFPE && !TARGET_SPFP"
5945 "*return arc_output_libcall (\"__uneqsf2\");"
5946 [(set_attr "is_sfunc" "yes")]
5949 (define_insn "*cmpdf_uneq"
5950 [(set (reg:CC_FP_UNEQ 61) (compare:CC_FP_UNEQ (reg:DF 0) (reg:DF 2)))
5951 (clobber (reg:SI 31))
5952 (clobber (reg:SI 12))]
5953 "TARGET_OPTFPE && !TARGET_DPFP"
5954 "*return arc_output_libcall (\"__uneqdf2\");"
5955 [(set_attr "is_sfunc" "yes")]
5958 (define_insn "*cmpsf_ord"
5959 [(set (reg:CC_FP_ORD 61) (compare:CC_FP_ORD (reg:SF 0) (reg:SF 1)))
5960 (clobber (reg:SI 31))
5961 (clobber (reg:SI 12))]
5962 "TARGET_OPTFPE && !TARGET_SPFP"
5963 "*return arc_output_libcall (\"__ordsf2\");"
5964 [(set_attr "is_sfunc" "yes")]
5967 ;; N.B. double precision fpx sets bit 31 for NaNs. We need bit 51 set
5968 ;; for the floating point emulation to recognize the NaN.
5969 (define_insn "*cmpdf_ord"
5970 [(set (reg:CC_FP_ORD 61) (compare:CC_FP_ORD (reg:DF 0) (reg:DF 2)))
5971 (clobber (reg:SI 31))
5972 (clobber (reg:SI 12))]
5973 "TARGET_OPTFPE && !TARGET_DPFP"
5974 "*return arc_output_libcall (\"__orddf2\");"
5975 [(set_attr "is_sfunc" "yes")]
5978 (define_insn "abssf2"
5979 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcq#q,Rcw,w")
5980 (abs:SF (match_operand:SF 1 "register_operand" "0, 0,c")))]
5983 [(set_attr "type" "unary")
5984 (set_attr "iscompact" "maybe,false,false")
5985 (set_attr "length" "2,4,4")
5986 (set_attr "cond" "canuse,canuse,nocond")])
5988 (define_insn "negsf2"
5989 [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5990 (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5993 [(set_attr "type" "unary")
5994 (set_attr "cond" "canuse,nocond")])
5996 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5997 (define_insn "*millicode_thunk_st"
5998 [(match_parallel 0 "millicode_store_operation"
5999 [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
6002 output_asm_insn ("bl%* __st_r13_to_%0",
6003 &SET_SRC (XVECEXP (operands[0], 0,
6004 XVECLEN (operands[0], 0) - 2)));
6007 [(set_attr "type" "call")])
6009 (define_insn "*millicode_thunk_ld"
6010 [(match_parallel 0 "millicode_load_clob_operation"
6011 [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
6014 output_asm_insn ("bl%* __ld_r13_to_%0",
6015 &SET_DEST (XVECEXP (operands[0], 0,
6016 XVECLEN (operands[0], 0) - 2)));
6019 [(set_attr "type" "call")])
6021 (define_insn "*millicode_sibthunk_ld"
6022 [(match_parallel 0 "millicode_load_operation"
6024 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
6025 (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
6028 output_asm_insn ("b%* __ld_r13_to_%0_ret",
6029 &SET_DEST (XVECEXP (operands[0], 0,
6030 XVECLEN (operands[0], 0) - 1)));
6033 [(set_attr "type" "call")
6034 (set_attr "is_SIBCALL" "yes")])
6036 ;; If hardware floating point is available, don't define a negdf pattern;
6037 ;; it would be something like:
6038 ;;(define_insn "negdf2"
6039 ;; [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
6040 ;; (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
6041 ;; (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
6044 ;; bxor%? %H0,%H1,31
6045 ;; bxor %H0,%H1,31 ` mov %L0,%L1
6046 ;; drsubh%F0%F1 0,0,0
6047 ;; drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
6048 ;; [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
6049 ;; (set_attr "iscompact" "false,false,false,false")
6050 ;; (set_attr "length" "4,4,8,12")
6051 ;; (set_attr "cond" "canuse,nocond,nocond,nocond")])
6052 ;; and this suffers from always requiring a long immediate when using
6053 ;; the floating point hardware.
6054 ;; We then want the sub[sd]f patterns to be used, so that we can load the
6055 ;; constant zero efficiently into a register when we want to do the
6056 ;; computation using the floating point hardware. There should be a special
6057 ;; subdf alternative that matches a zero operand 1, which then can allow
6058 ;; to use bxor to flip the high bit of an integer register.
6059 ;; ??? we actually can't use the floating point hardware for neg, because
6060 ;; this would not work right for -0. OTOH optabs.c has already code
6061 ;; to synthesyze nagate by flipping the sign bit.
6064 ;; include the arc-FPX instructions
6067 (include "simdext.md")