Add hppa*-*-hpux* to targets which do not support split DWARF
[official-gcc.git] / gcc / config / arc / arc.md
blob9004b6085a2376de5e51a3b25ef5ae97e8648de4
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2024 Free Software Foundation, Inc.
4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 ;; behalf of Synopsys Inc.
7 ;;    Position Independent Code support added,Code cleaned up,
8 ;;    Comments and Support For ARC700 instructions added by
9 ;;    Saurabh Verma (saurabh.verma@codito.com)
10 ;;    Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 ;;    Performance improvements by
13 ;;    Joern Rennecke (joern.rennecke@embecosm.com)
16 ;; This file is part of GCC.
18 ;; GCC is free software; you can redistribute it and/or modify
19 ;; it under the terms of the GNU General Public License as published by
20 ;; the Free Software Foundation; either version 3, or (at your option)
21 ;; any later version.
23 ;; GCC is distributed in the hope that it will be useful,
24 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 ;; GNU General Public License for more details.
28 ;; You should have received a copy of the GNU General Public License
29 ;; along with GCC; see the file COPYING3.  If not see
30 ;; <http://www.gnu.org/licenses/>.
32 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
34 ;; <op> dest, src         Two operand instruction's syntax
35 ;; <op> dest, src1, src2  Three operand instruction's syntax
37 ;; ARC and ARCompact PREDICATES:
39 ;;   comparison_operator   LT, GT, LE, GE, LTU, GTU, LEU, GEU, EQ, NE
40 ;;   memory_operand        memory                         [m]
41 ;;   immediate_operand     immediate constant             [IKLMNOP]
42 ;;   register_operand      register                       [rq]
43 ;;   general_operand       register, memory, constant     [rqmIKLMNOP]
45 ;;  Note that the predicates are only used when selecting a pattern
46 ;;  to determine if an operand is valid.
48 ;;  The constraints then select which of the possible valid operands
49 ;;  is present (and guide register selection). The actual assembly
50 ;;  instruction is then selected on the basis of the constraints.
52 ;; ARC and ARCompact CONSTRAINTS:
54 ;;   b  stack pointer                           r28
55 ;;   f  frame pointer                           r27
56 ;;   Rgp global pointer                         r26
57 ;;   g  general reg, memory, constant
58 ;;   m  memory
59 ;;   p  memory address
60 ;;   q  registers commonly used in
61 ;;      16-bit insns                            r0-r3, r12-r15
62 ;;   c  core registers                          r0-r60, ap, pcl
63 ;;   r  general registers                       r0-r28, blink, ap, pcl
65 ;;   H  fp 16-bit constant
66 ;;   I signed 12-bit immediate (for ARCompact)
67 ;;   K  unsigned 3-bit immediate (for ARCompact)
68 ;;   L  unsigned 6-bit immediate (for ARCompact)
69 ;;   M  unsinged 5-bit immediate (for ARCompact)
70 ;;   O  unsinged 7-bit immediate (for ARCompact)
71 ;;   P  unsinged 8-bit immediate (for ARCompact)
72 ;;   N  constant '1' (for ARCompact)
75 ;; TODO:
76 ;; -> prefetch instruction
78 ;;  -----------------------------------------------------------------------------
80 ;; Include DFA scheduluers
81 (include ("arc600.md"))
82 (include ("arc700.md"))
83 (include ("arcEM.md"))
84 (include ("arcHS.md"))
85 (include ("arcHS4x.md"))
87 ;; Predicates
89 (include ("predicates.md"))
90 (include ("constraints.md"))
91 ;;  -----------------------------------------------------------------------------
93 ;; UNSPEC Usage:
94 ;; ~~~~~~~~~~~~
95 ;;  -----------------------------------------------------------------------------
96 ;;  Symbolic name  Value              Desc.
97 ;;  -----------------------------------------------------------------------------
98 ;;  UNSPEC_PLT       3        symbol to be referenced through the PLT
99 ;;  UNSPEC_GOT       4        symbol to be rerenced through the GOT
100 ;;  UNSPEC_GOTOFF    5        Local symbol.To be referenced relative to the
101 ;;                            GOTBASE.(Referenced as @GOTOFF)
102 ;;  UNSPEC_GOTOFFPC  6        Local symbol.  To be referenced pc-relative.
103 ;;  ----------------------------------------------------------------------------
105 (define_c_enum "unspec" [
106   DUMMY_0
107   DUMMY_1
108   DUMMY_2
109   ARC_UNSPEC_PLT
110   ARC_UNSPEC_GOT
111   ARC_UNSPEC_GOTOFF
112   ARC_UNSPEC_GOTOFFPC
113   UNSPEC_TLS_GD
114   UNSPEC_TLS_LD
115   UNSPEC_TLS_IE
116   UNSPEC_TLS_OFF
117   UNSPEC_ARC_NORM
118   UNSPEC_ARC_NORMW
119   UNSPEC_ARC_DIVAW
120   UNSPEC_ARC_DIRECT
121   UNSPEC_ARC_LP
122   UNSPEC_ARC_CASESI
123   UNSPEC_ARC_FFS
124   UNSPEC_ARC_FLS
125   UNSPEC_ARC_MEMBAR
126   UNSPEC_ARC_DMACH
127   UNSPEC_ARC_DMACHU
128   UNSPEC_ARC_DMACWH
129   UNSPEC_ARC_DMACWHU
130   UNSPEC_ARC_DMPYWH
131   UNSPEC_ARC_QMACH
132   UNSPEC_ARC_QMACHU
133   UNSPEC_ARC_QMPYH
134   UNSPEC_ARC_QMPYHU
135   UNSPEC_ARC_VMAC2H
136   UNSPEC_ARC_VMAC2HU
137   UNSPEC_ARC_VMPY2H
138   UNSPEC_ARC_VMPY2HU
139   UNSPEC_ARC_CC_NEZ
141   VUNSPEC_ARC_RTIE
142   VUNSPEC_ARC_SYNC
143   VUNSPEC_ARC_BRK
144   VUNSPEC_ARC_FLAG
145   VUNSPEC_ARC_SLEEP
146   VUNSPEC_ARC_SWI
147   VUNSPEC_ARC_CORE_READ
148   VUNSPEC_ARC_CORE_WRITE
149   VUNSPEC_ARC_LR
150   VUNSPEC_ARC_SR
151   VUNSPEC_ARC_TRAP_S
152   VUNSPEC_ARC_UNIMP_S
153   VUNSPEC_ARC_KFLAG
154   VUNSPEC_ARC_CLRI
155   VUNSPEC_ARC_SETI
156   VUNSPEC_ARC_NOP
157   VUNSPEC_ARC_STACK_IRQ
158   VUNSPEC_ARC_DEXCL
159   VUNSPEC_ARC_DEXCL_NORES
160   VUNSPEC_ARC_LR_HIGH
161   VUNSPEC_ARC_EX
162   VUNSPEC_ARC_CAS
163   VUNSPEC_ARC_SC
164   VUNSPEC_ARC_LL
165   VUNSPEC_ARC_BLOCKAGE
166   VUNSPEC_ARC_EH_RETURN
167   VUNSPEC_ARC_ARC600_RTIE
168   VUNSPEC_ARC_ARC600_STALL
169   VUNSPEC_ARC_LDDI
170   VUNSPEC_ARC_STDI
171   ])
173 (define_constants
174   [(R0_REG 0)
175    (R1_REG 1)
176    (R2_REG 2)
177    (R3_REG 3)
178    (R4_REG 4)
180    (R9_REG 9)
181    (R10_REG 10)
183    (R12_REG 12)
185    (R15_REG 15)
186    (R16_REG 16)
188    (R25_REG 25)
189    (SP_REG 28)
190    (ILINK1_REG 29)
191    (ILINK2_REG 30)
192    (R30_REG 30)
193    (RETURN_ADDR_REGNUM 31)
194    (R32_REG 32)
195    (R33_REG 33)
196    (R34_REG 34)
197    (R35_REG 35)
198    (R36_REG 36)
199    (R37_REG 37)
200    (R38_REG 38)
201    (R39_REG 39)
202    (R40_REG 40)
203    (R41_REG 41)
204    (R42_REG 42)
205    (R43_REG 43)
206    (R44_REG 44)
207    (R45_REG 45)
208    (R46_REG 46)
209    (R47_REG 47)
210    (R48_REG 48)
211    (R49_REG 49)
212    (R50_REG 50)
213    (R51_REG 51)
214    (R52_REG 52)
215    (R53_REG 53)
216    (R54_REG 54)
217    (R55_REG 55)
218    (R56_REG 56)
219    (R57_REG 57)
220    (R58_REG 58)
221    (R59_REG 59)
223    (MUL64_OUT_REG 58)
224    (MUL32x16_REG 56)
225    (ARCV2_ACC 58)
226    (LP_COUNT 60)
227    (CC_REG 61)
228    (PCL_REG 63)
229   ]
232 ;; What is the insn_cost for this insn?  The target hook can still override
233 ;; this.  For optimizing for size the "length" attribute is used instead.
234 (define_attr "cost" "" (const_int 0))
236 (define_attr "is_sfunc" "no,yes" (const_string "no"))
238 ;; Insn type.  Used to default other attribute values.
239 ; While the attribute is_sfunc is set for any call of a special function,
240 ; the instruction type sfunc is used only for the special call sequence
241 ; that loads the (pc-relative) function address into r12 and then calls
242 ; via r12.
244 (define_attr "type"
245   "add,sub,bxor,move,load,store,cmove,unary,binary,compare,shift,uncond_branch,
246    jump,branch,brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
247    multi,umulti,
248    two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
249    misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith, simd_vload,
250    simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
251    simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
252    simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
253    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
254    simd_valign, simd_valign_with_acc, simd_vcontrol,
255    simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
256    fpu, fpu_fuse, fpu_sdiv, fpu_ddiv, fpu_cvt, block"
257   (cond [(eq_attr "is_sfunc" "yes")
258          (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
259                 (match_test "flag_pic") (const_string "sfunc")]
260                (const_string "call_no_delay_slot"))]
261         (const_string "binary")))
263 ;; The following three attributes are mixed case so that they can be
264 ;; used conveniently with the CALL_ATTR macro.
265 (define_attr "is_CALL" "no,yes"
266   (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
267          (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
268         (const_string "no")))
270 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
272 (define_attr "is_NON_SIBCALL" "no,yes"
273   (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
274          (eq_attr "is_CALL" "yes") (const_string "yes")]
275         (const_string "no")))
277 ;; true for compact instructions (those with _s suffix)
278 ;; "maybe" means compact unless we conditionalize the insn.
279 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
280   (cond [(eq_attr "type" "sfunc")
281          (const_string "maybe")]
282         (const_string "false")))
285 ; Is there an instruction that we are actually putting into the delay slot?
286 (define_attr "delay_slot_filled" "no,yes"
287   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
288          (const_string "no")
289          (match_test "!TARGET_AT_DBR_CONDEXEC
290                       && JUMP_P (insn)
291                       && INSN_ANNULLED_BRANCH_P (insn)
292                       && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
293          (const_string "no")]
294         (const_string "yes")))
296 ; Is a delay slot present for purposes of shorten_branches?
297 ; We have to take the length of this insn into account for forward branches
298 ; even if we don't put the insn actually into a delay slot.
299 (define_attr "delay_slot_present" "no,yes"
300   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
301          (const_string "no")]
302         (const_string "yes")))
304 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
305 ; length of a different insn with the same uid.
306 (define_attr "delay_slot_length" ""
307   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
308          (const_int 0)]
309         (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
310                      - get_attr_length (insn)")))
312 ; for ARCv2 we need to disable/enable different instruction alternatives
313 (define_attr "cpu_facility" "std,av1,av2,fpx,cd"
314   (const_string "std"))
316 ; We should consider all the instructions enabled until otherwise
317 (define_attr "enabled" "no,yes"
318   (cond [(and (eq_attr "cpu_facility" "av1")
319               (match_test "TARGET_V2"))
320          (const_string "no")
322          (and (eq_attr "cpu_facility" "av2")
323               (not (match_test "TARGET_V2")))
324          (const_string "no")
326          (and (eq_attr "cpu_facility" "fpx")
327               (match_test "TARGET_FP_DP_AX"))
328          (const_string "no")
330          (and (eq_attr "cpu_facility" "cd")
331               (not (and (match_test "TARGET_V2")
332                         (match_test "TARGET_CODE_DENSITY"))))
333          (const_string "no")
334          ]
335         (const_string "yes")))
337 (define_attr "predicable" "no,yes" (const_string "no"))
338 ;; if 'predicable' were not so brain-dead, we would specify:
339 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
340 ;;        (eq_attr "iscompact" "maybe") (const_string "no")]
341 ;;       (const_string "yes"))
342 ;; and then for everything but calls, we could just set the cond attribute.
344 ;; Condition codes: this one is used by final_prescan_insn to speed up
345 ;; conditionalizing instructions.  It saves having to scan the rtl to see if
346 ;; it uses or alters the condition codes.
348 ;; USE: This insn uses the condition codes (eg: a conditional branch).
349 ;; CANUSE: This insn can use the condition codes (for conditional execution).
350 ;; SET: All condition codes are set by this insn.
351 ;; SET_ZN: the Z and N flags are set by this insn.
352 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
353 ;; CLOB: The condition codes are set to unknown values by this insn.
354 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
356 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
357   (cond
358     [(and (eq_attr "predicable" "yes")
359           (eq_attr "is_sfunc" "no")
360           (eq_attr "delay_slot_filled" "no"))
361      (const_string "canuse")
363      (eq_attr "type" "call")
364      (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
365             (match_test "!flag_pic") (const_string "canuse_limm")]
366            (const_string "nocond"))
368      (eq_attr "iscompact" "maybe,false")
369      (cond [ (and (eq_attr "type" "move")
370                   (match_operand 1 "immediate_operand" ""))
371              (if_then_else
372                 (ior (match_operand 1 "u6_immediate_operand" "")
373                      (match_operand 1 "long_immediate_operand" ""))
374                 (const_string "canuse")
375                 (const_string "canuse_limm"))
377              (eq_attr "type" "binary")
378              (cond [(ne (symbol_ref "REGNO (operands[0])")
379                         (symbol_ref "REGNO (operands[1])"))
380                     (const_string "nocond")
381                     (match_operand 2 "register_operand" "")
382                     (const_string "canuse")
383                     (match_operand 2 "u6_immediate_operand" "")
384                     (const_string "canuse")
385                     (match_operand 2 "long_immediate_operand" "")
386                     (const_string "canuse")
387                     (match_operand 2 "const_int_operand" "")
388                     (const_string "canuse_limm")]
389                    (const_string "nocond"))
391              (eq_attr "type" "compare")
392              (const_string "set")
394              (eq_attr "type" "cmove,branch")
395              (const_string "use")
397              (eq_attr "is_sfunc" "yes")
398              (cond [(match_test "(TARGET_MEDIUM_CALLS
399                                   && !TARGET_LONG_CALLS_SET
400                                   && flag_pic)")
401                     (const_string "canuse_limm_add")
402                     (match_test "(TARGET_MEDIUM_CALLS
403                                   && !TARGET_LONG_CALLS_SET)")
404                     (const_string "canuse_limm")]
405                    (const_string "canuse"))
407             ]
409             (const_string "nocond"))]
411       (cond [(eq_attr "type" "compare")
412              (const_string "set")
414              (eq_attr "type" "cmove,branch")
415              (const_string "use")
417             ]
419             (const_string "nocond"))))
421 /* ??? Having all these patterns gives ifcvt more freedom to generate
422    inefficient code.  It seem to operate on the premise that
423    register-register copies and registers are free.  I see better code
424    with -fno-if-convert now than without.  */
425 (define_cond_exec
426   [(match_operator 0 "proper_comparison_operator"
427      [(reg CC_REG) (const_int 0)])]
428   "true"
429   "")
431 ;; Length (in # of bytes, long immediate constants counted too).
432 ;; ??? There's a nasty interaction between the conditional execution fsm
433 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
434 (define_attr "length" ""
435   (cond
436     [(eq_attr "iscompact" "true")
437       (const_int 2)
439      (eq_attr "iscompact" "maybe")
440      (cond
441        [(eq_attr "type" "sfunc")
442         (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
443                (const_int 12)]
444               (const_int 10))
445         (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)
446         (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (1))")
447         (const_int 4)]
448       (const_int 2))
450     (eq_attr "iscompact" "true_limm")
451     (const_int 6)
453     (eq_attr "iscompact" "maybe_limm")
454     (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
455           (const_int 6))
457     (eq_attr "type" "load")
458     (if_then_else
459        (match_operand 1 "long_immediate_loadstore_operand" "")
460        (const_int 8) (const_int 4))
462     (eq_attr "type" "store")
463     (if_then_else
464       (ior (match_operand 0 "long_immediate_loadstore_operand" "")
465            (match_operand 1 "immediate_operand" ""))
466       (const_int 8) (const_int 4))
468     (eq_attr "type" "move,unary")
469     (cond
470       [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
471        (match_operand 1 "register_operand" "") (const_int 4)
472        (match_operand 1 "long_immediate_operand" "") (const_int 8)
473        (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
474       (const_int 4))
476     (and (eq_attr "type" "shift")
477          (match_operand 1 "immediate_operand"))
478                  (const_int 8)
479     (eq_attr "type" "binary,shift")
480     (if_then_else
481        (ior (match_operand 2 "long_immediate_operand" "")
482             (and (ne (symbol_ref "REGNO (operands[0])")
483                      (symbol_ref "REGNO (operands[1])"))
484                  (eq (match_operand 2 "u6_immediate_operand" "")
485                      (const_int 0))))
487        (const_int 8) (const_int 4))
489     (eq_attr "type" "cmove")
490        (if_then_else (match_operand 1 "register_operand" "")
491                      (const_int 4) (const_int 8))
493     (eq_attr "type" "call_no_delay_slot") (const_int 8)
494    ]
496    (const_int 4))
499 ;; The length here is the length of a single asm.  Unfortunately it might be
500 ;; 4 or 8 so we must allow for 8.  That's ok though.  How often will users
501 ;; lament asm's not being put in delay slots?
503 (define_asm_attributes
504   [(set_attr "length" "8")
505    (set_attr "type" "multi")
506    (set_attr "cond" "clob") ])
508 ;; Delay slots.
509 ;; The first two cond clauses and the default are necessary for correctness;
510 ;; the remaining cond clause is mainly an optimization, as otherwise nops
511 ;; would be inserted; however, if we didn't do this optimization, we would
512 ;; have to be more conservative in our length calculations.
514 (define_attr "in_delay_slot" "false,true"
515   (cond [(eq_attr "type" "uncond_branch,jump,branch,
516                           call,sfunc,call_no_delay_slot,
517                           brcc, brcc_no_delay_slot,loop_setup,loop_end")
518          (const_string "false")
519          (match_test "arc_write_ext_corereg (insn)")
520          (const_string "false")
521          (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
522                                       next_active_insn (insn))")
523              (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
524                            + arc_hazard (insn, next_active_insn (insn)))"))
525          (const_string "false")
526          (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
527          (const_string "false")
528          (eq_attr "iscompact" "maybe") (const_string "true")
529          ]
531          (if_then_else (eq_attr "length" "2,4")
532                        (const_string "true")
533                        (const_string "false"))))
535 ; must not put an insn inside that refers to blink.
536 (define_attr "in_call_delay_slot" "false,true"
537   (cond [(eq_attr "in_delay_slot" "false")
538          (const_string "false")
539          (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
540          (const_string "false")]
541         (const_string "true")))
543 (define_attr "in_sfunc_delay_slot" "false,true"
544   (cond [(eq_attr "in_call_delay_slot" "false")
545          (const_string "false")
546          (match_test "arc_regno_use_in (12, PATTERN (insn))")
547          (const_string "false")]
548         (const_string "true")))
550 (define_attr "in_ret_delay_slot" "no,yes"
551   (cond [(eq_attr "in_delay_slot" "false")
552          (const_string "no")
553          (match_test "regno_clobbered_p
554                         (RETURN_ADDR_REGNUM, insn, SImode, 1)")
555          (const_string "no")]
556         (const_string "yes")))
558 ;; Delay slot definition for ARCompact ISA
559 ;; ??? FIXME:
560 ;; When outputting an annul-true insn elegible for cond-exec
561 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
562 ;; for ARC600; we could also use this for ARC700 if the branch can't be
563 ;; unaligned and is at least somewhat likely (add parameter for this).
565 (define_delay (eq_attr "type" "call")
566   [(eq_attr "in_call_delay_slot" "true")
567    (eq_attr "in_call_delay_slot" "true")
568    (nil)])
570 (define_delay (eq_attr "type" "brcc")
571   [(eq_attr "in_delay_slot" "true")
572    (nil)
573    (nil)])
575 (define_delay
576   (eq_attr "type" "return")
577   [(eq_attr "in_ret_delay_slot" "yes")
578    (nil)
579    (nil)])
581 (define_delay (eq_attr "type" "loop_end")
582   [(eq_attr "in_delay_slot" "true")
583    (nil)
584    (nil)])
586 ;; The only meaningful way to have an annull-true
587 ;; filled delay slot is to conditionalize the delay slot insn.
588 (define_delay (and (eq_attr "type" "branch,uncond_branch,jump")
589                    (match_test "!optimize_size"))
590   [(eq_attr "in_delay_slot" "true")
591    (nil)
592    (nil)])
594 ;; -mlongcall -fpic sfuncs use r12 to load the function address
595 (define_delay (eq_attr "type" "sfunc")
596   [(eq_attr "in_sfunc_delay_slot" "true")
597    (nil)
598    (nil)])
599 ;; ??? need to use a working strategy for canuse_limm:
600 ;; - either canuse_limm is not eligible for delay slots, and has no
601 ;;   delay slots, or arc_reorg has to treat them as nocond, or it has to
602 ;;   somehow modify them to become inelegible for delay slots if a decision
603 ;;   is made that makes conditional execution required.
605 (define_attr "tune" "none,arc600,arc7xx,arc700_4_2_std,arc700_4_2_xmac, \
606 archs4x, archs4xd"
607   (const
608    (cond [(symbol_ref "arc_tune == ARC_TUNE_ARC600")
609           (const_string "arc600")
610           (symbol_ref "arc_tune == ARC_TUNE_ARC7XX")
611           (const_string "arc7xx")
612           (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_STD")
613           (const_string "arc700_4_2_std")
614           (symbol_ref "arc_tune == ARC_TUNE_ARC700_4_2_XMAC")
615           (const_string "arc700_4_2_xmac")
616           (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
617                (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A"))
618           (const_string "archs4x")
619           (ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD")
620                (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW"))
621           (const_string "archs4xd")]
622          (const_string "none"))))
624 (define_attr "tune_arc700" "false,true"
625   (if_then_else (eq_attr "tune" "arc7xx, arc700_4_2_std, arc700_4_2_xmac")
626                 (const_string "true")
627                 (const_string "false")))
629 (define_attr "tune_dspmpy" "none, slow, fast"
630   (const
631   (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
632               (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
633          (const_string "fast")
634          (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD_SLOW")
635          (const_string "slow")]
636         (const_string "none"))))
638 (define_attr "tune_store" "none, normal, rel31a"
639   (const
640   (cond [(ior (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X")
641               (symbol_ref "arc_tune == ARC_TUNE_ARCHS4XD"))
642          (const_string "normal")
643          (symbol_ref "arc_tune == ARC_TUNE_ARCHS4X_REL31A")
644          (const_string "rel31a")]
645         (const_string "none"))))
647 ;; Move instructions.
648 (define_expand "movqi"
649   [(set (match_operand:QI 0 "move_dest_operand" "")
650         (match_operand:QI 1 "general_operand" ""))]
651   ""
652   "if (prepare_move_operands (operands, QImode)) DONE;")
654 ; In order to allow the ccfsm machinery to do its work, the leading compact
655 ; alternatives say 'canuse' - there is another alternative that will match
656 ; when the condition codes are used.
657 ; Likewise, the length of an alternative that might be shifted to conditional
658 ; execution must reflect this, lest out-of-range branches are created.
659 ; The iscompact attribute allows the epilogue expander to know for which
660 ; insns it should lengthen the return insn.
661 (define_insn "*movqi_insn"
662   [(set (match_operand:QI 0 "move_dest_operand" "=q, q,r,q,   h, w, w,???w,h, w,q,S,!*x,  r,r, Ucm,m,???m,  m,Usc")
663         (match_operand:QI 1 "move_src_operand"  "rL,rP,q,P,hCm1,cL, I,?Rac,i,?i,T,q,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
664   "register_operand (operands[0], QImode)
665    || register_operand (operands[1], QImode)
666    || (CONSTANT_P (operands[1])
667        && (!satisfies_constraint_I (operands[1]) || !optimize_size)
668        && satisfies_constraint_Usc (operands[0]))
669    || (satisfies_constraint_Cm3 (operands[1])
670        && memory_operand (operands[0], QImode))"
671   "@
672    mov%?\\t%0,%1
673    mov%?\\t%0,%1
674    mov%?\\t%0,%1
675    mov%?\\t%0,%1
676    mov%?\\t%0,%1
677    mov%?\\t%0,%1
678    mov%?\\t%0,%1
679    mov%?\\t%0,%1
680    mov%?\\t%0,%1
681    mov%?\\t%0,%1
682    ldb%?\\t%0,%1
683    stb%?\\t%1,%0
684    ldb%?\\t%0,%1
685    xldb%U1\\t%0,%1
686    ldb%U1%V1\\t%0,%1
687    xstb%U0\\t%1,%0
688    stb%U0%V0\\t%1,%0
689    stb%U0%V0\\t%1,%0
690    stb%U0%V0\\t%1,%0
691    stb%U0%V0\\t%1,%0"
692   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store,store")
693    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false,false")
694    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no")
695    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
697 (define_expand "movhi"
698   [(set (match_operand:HI 0 "move_dest_operand" "")
699         (match_operand:HI 1 "general_operand" ""))]
700   ""
701   "if (prepare_move_operands (operands, HImode)) DONE;")
703 (define_insn "*movhi_insn"
704   [(set (match_operand:HI 0 "move_dest_operand" "=q, q,r,q,   h, w, w,???w,q,h, w,q,S,  r,r, Ucm,m,???m,  m,VUsc")
705         (match_operand:HI 1 "move_src_operand" " rL,rP,q,P,hCm1,cL, I,?Rac,i,i,?i,T,q,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
706   "register_operand (operands[0], HImode)
707    || register_operand (operands[1], HImode)
708    || (CONSTANT_P (operands[1])
709        /* Don't use a LIMM that we could load with a single insn - we loose
710           delay-slot filling opportunities.  */
711        && !satisfies_constraint_I (operands[1])
712        && satisfies_constraint_Usc (operands[0]))
713    || (satisfies_constraint_Cm3 (operands[1])
714        && memory_operand (operands[0], HImode))"
715   "@
716    mov%?\\t%0,%1
717    mov%?\\t%0,%1
718    mov%?\\t%0,%1
719    mov%?\\t%0,%1
720    mov%?\\t%0,%1
721    mov%?\\t%0,%1
722    mov%?\\t%0,%1
723    mov%?\\t%0,%1
724    mov%?\\t%0,%1
725    mov%?\\t%0,%1
726    mov%?\\t%0,%1
727    ld%_%?\\t%0,%1
728    st%_%?\\t%1,%0
729    xld%_%U1\\t%0,%1
730    ld%_%U1%V1\\t%0,%1
731    xst%_%U0\\t%1,%0
732    st%_%U0%V0\\t%1,%0
733    st%_%U0%V0\\t%1,%0
734    st%_%U0%V0\\t%1,%0
735    st%_%U0%V0\\t%1,%0"
736   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
737    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false")
738    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
739    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
741 (define_expand "movsi"
742   [(set (match_operand:SI 0 "move_dest_operand" "")
743         (match_operand:SI 1 "general_operand" ""))]
744   ""
745   "if (prepare_move_operands (operands, SImode)) DONE;")
747 ; In order to allow the ccfsm machinery to do its work, the leading compact
748 ; alternatives say 'canuse' - there is another alternative that will match
749 ; when the condition codes are used.
750 ; The length of an alternative that might be shifted to conditional
751 ; execution must reflect this, lest out-of-range branches are created.
752 ; the iscompact attribute allows the epilogue expander to know for which
753 ; insns it should lengthen the return insn.
754 (define_insn_and_split "*movsi_insn"            ; 0  1 2 3    4   5 6   7   8   9  10  11  12  13  14  15  16    17      18  19  20    21   22 23  24   25 26  27  28
755   [(set (match_operand:SI 0 "move_dest_operand" "=q, q,r,q,   h, rl,r,  r,  r,  r, ?r,  r,  q,  h, rl,  q,  S,   Us<,qRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,  m,VUsc")
756         (match_operand:SI 1 "move_src_operand"  "rL,rP,q,P,hCm1,rLl,I,Clo,Chi,Cbi,Cpc,Clb,Cax,Cal,Cal,Uts,q,qRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  r,!*Rzd,r,Cm3, C32"))]
757   "register_operand (operands[0], SImode)
758    || register_operand (operands[1], SImode)
759    || (CONSTANT_P (operands[1])
760        && (!satisfies_constraint_I (operands[1]) || !optimize_size)
761        && satisfies_constraint_Usc (operands[0]))
762    || (satisfies_constraint_Cm3 (operands[1])
763       && memory_operand (operands[0], SImode))"
764   "@
765    mov%?\\t%0,%1        ;0
766    mov%?\\t%0,%1        ;1
767    mov%?\\t%0,%1        ;2
768    mov%?\\t%0,%1        ;3
769    mov%?\\t%0,%1        ;4
770    mov%?\\t%0,%1        ;5
771    mov%?\\t%0,%1        ;6
772    movl.cl\\t%0,%1      ;7
773    movh.cl\\t%0,%L1>>16 ;8
774    * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl\\t%0,%1 >> %p1,%p1,8;9\" : \"movbi.cl\\t%0,%L1 >> 24,24,8;9\";
775    add\\t%0,%1          ;10
776    add\\t%0,pcl,%1@pcl  ;11
777    #
778    mov%?\\t%0,%j1       ;13
779    mov%?\\t%0,%j1       ;14
780    ld%?\\t%0,%1         ;15
781    st%?\\t%1,%0         ;16
782    * return arc_short_long (insn, \"push%?\\t%1\", \"st%U0\\t%1,%0\");
783    * return arc_short_long (insn, \"pop%?\\t%0\",  \"ld%U1\\t%0,%1\");
784    ld%?\\t%0,%1         ;19
785    xld%U1\\t%0,%1       ;20
786    ld%?\\t%0,%1         ;21
787    ld%?\\t%0,%1         ;22
788    ld%U1%V1\\t%0,%1     ;23
789    xst%U0\\t%1,%0       ;24
790    st%?\\t%1,%0         ;25
791    st%U0%V0\\t%1,%0     ;26
792    st%U0%V0\\t%1,%0     ;37
793    st%U0%V0\\t%1,%0     ;28"
794   "reload_completed
795    && GET_CODE (PATTERN (insn)) != COND_EXEC
796    && register_operand (operands[0], SImode)
797    && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
798    && satisfies_constraint_Cax (operands[1])"
799   [(const_int 0)]
800   "
801    arc_split_mov_const (operands);
802    DONE;
803   "
804    ;                          0     1     2     3    4    5     6     7     8     9     10     11    12   13    14   15    16    17   18   19    20   21   22    23    24    25    26    27   28
805   [(set_attr "type"       "move, move, move,move,move, move, move,shift,shift,shift,binary,binary,multi,move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store")
806    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,false,false, false, false,false,true,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false")
807    (set_attr "length"    "*,*,*,*,*,4,4,4,4,4,8,8,*,6,*,*,*,*,*,*,4,*,4,*,*,*,*,*,8")
808    (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,yes,no,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
809    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,av2,*")])
811 ;; Sometimes generated by the epilogue code.  We don't want to
812 ;; recognize these addresses in general, because the limm is costly,
813 ;; and we can't use them for stores.  */
814 (define_insn "*movsi_pre_mod"
815   [(set (match_operand:SI 0 "register_operand" "=w")
816         (mem:SI (pre_modify
817                   (reg:SI SP_REG)
818                   (plus:SI (reg:SI SP_REG)
819                            (match_operand 1 "immediate_operand" "Cal")))))]
820   "reload_completed"
821   "ld.a\\t%0,[sp,%1]"
822   [(set_attr "type" "load")
823    (set_attr "length" "8")])
825 ;; Store a value to directly to memory.  The location might also be cached.
826 ;; Since the cached copy can cause a write-back at unpredictable times,
827 ;; we first write cached, then we write uncached.
828 (define_insn "store_direct"
829   [(set (match_operand:SI 0 "move_dest_operand" "=m")
830       (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
831        UNSPEC_ARC_DIRECT))]
832   ""
833   "st%U0\\t%1,%0\;st%U0.di\\t%1,%0"
834   [(set_attr "type" "store")])
836 ;; Combiner patterns for compare with zero
837 (define_mode_iterator SQH [QI HI])
838 (define_mode_attr SQH_postfix [(QI "b") (HI "%_")])
840 (define_code_iterator SEZ [sign_extend zero_extend])
841 (define_code_attr SEZ_prefix [(sign_extend "sex") (zero_extend "ext")])
842 ; Optab prefix for sign/zero-extending operations
843 (define_code_attr su_optab [(sign_extend "") (zero_extend "u")])
845 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0_noout"
846   [(set (match_operand 0 "cc_set_register" "")
847         (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
848                        (const_int 0)))]
849   ""
850   "<SEZ_prefix><SQH_postfix>.f\\t0,%1"
851   [(set_attr "type" "compare")
852    (set_attr "cond" "set_zn")])
854 (define_insn "*<SEZ_prefix>xt<SQH_postfix>_cmp0"
855   [(set (match_operand 0 "cc_set_register" "")
856         (compare:CC_ZN (SEZ:SI (match_operand:SQH 1 "register_operand" "r"))
857                        (const_int 0)))
858    (set (match_operand:SI 2 "register_operand" "=r")
859         (SEZ:SI (match_dup 1)))]
860   ""
861   "<SEZ_prefix><SQH_postfix>.f\\t%2,%1"
862   [(set_attr "type" "compare")
863    (set_attr "cond" "set_zn")])
865 (define_insn "*xbfu_cmp0_noout"
866   [(set (match_operand 0 "cc_set_register" "")
867         (compare:CC_Z
868          (zero_extract:SI
869           (match_operand:SI 1 "register_operand"  "  r,r")
870           (match_operand:SI 2 "const_int_operand" "C3p,n")
871           (match_operand:SI 3 "const_int_operand" "  n,n"))
872          (const_int 0)))]
873   "TARGET_HS && TARGET_BARREL_SHIFTER"
874   {
875    int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
876    operands[2] = GEN_INT (assemble_op2);
877    return "xbfu%?.f\\t0,%1,%2";
878   }
879   [(set_attr "type"       "shift")
880    (set_attr "iscompact"  "false")
881    (set_attr "length"     "4,8")
882    (set_attr "predicable" "no")
883    (set_attr "cond"       "set_zn")])
885 (define_insn "*xbfu_cmp0"
886   [(set (match_operand 4 "cc_set_register" "")
887         (compare:CC_Z
888          (zero_extract:SI
889           (match_operand:SI 1 "register_operand"  "0  ,r,0")
890           (match_operand:SI 2 "const_int_operand" "C3p,n,n")
891           (match_operand:SI 3 "const_int_operand" "n  ,n,n"))
892          (const_int 0)))
893    (set (match_operand:SI 0 "register_operand"  "=r,r,r")
894         (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
895   "TARGET_HS && TARGET_BARREL_SHIFTER"
896   {
897    int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
898    operands[2] = GEN_INT (assemble_op2);
899    return "xbfu%?.f\\t%0,%1,%2";
900   }
901   [(set_attr "type"       "shift")
902    (set_attr "iscompact"  "false")
903    (set_attr "length"     "4,8,8")
904    (set_attr "predicable" "yes,no,yes")
905    (set_attr "cond"       "set_zn")])
907 ; splitting to 'tst' allows short insns and combination into brcc.
908 (define_insn_and_split "*movsi_set_cc_insn"
909   [(set (match_operand 2 "cc_set_register" "")
910         (match_operator 3 "zn_compare_operator"
911                         [(match_operand:SI 1 "nonmemory_operand" "rL,rI,Cal")
912                          (const_int 0)]))
913    (set (match_operand:SI 0 "register_operand" "=r,r,r")
914         (match_dup 1))]
915   ""
916   "mov%?.f\\t%0,%1"
917   "reload_completed && operands_match_p (operands[0], operands[1])"
918   [(set (match_dup 2) (match_dup 3))]
919   ""
920   [(set_attr "type" "compare")
921    (set_attr "predicable" "yes,no,yes")
922    (set_attr "cond" "set_zn")
923    (set_attr "length" "4,4,8")])
925 (define_insn "unary_comparison"
926   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
927         (match_operator:CC_ZN 3 "zn_compare_operator"
928           [(match_operator:SI 2 "unary_operator"
929              [(match_operand:SI 1 "register_operand" "c")])
930            (const_int 0)]))]
931   ""
932   "%O2.f 0,%1"
933   [(set_attr "type" "compare")
934    (set_attr "cond" "set_zn")])
937 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
938 (define_insn "*unary_comparison_result_used"
939   [(set (match_operand 2 "cc_register" "")
940         (match_operator 4 "zn_compare_operator"
941           [(match_operator:SI 3 "unary_operator"
942              [(match_operand:SI 1 "register_operand" "c")])
943                (const_int 0)]))
944    (set (match_operand:SI 0 "register_operand" "=w")
945         (match_dup 3))]
946   ""
947   "%O3.f\\t%0,%1"
948   [(set_attr "type" "compare")
949    (set_attr "cond" "set_zn")
950    (set_attr "length" "4")])
952 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
953 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
954 ; even if we don't need the clobber.
955 (define_insn_and_split "*tst_movb"
956   [(set
957      (match_operand 0 "cc_register" "")
958      (match_operator 4 "zn_compare_operator"
959        [(and:SI
960           (match_operand:SI 1 "register_operand"  "%q,  q, c,  c,  c,  c,  q,  q,  c")
961           (match_operand:SI 2 "nonmemory_operand"  "q,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
962         (const_int 0)]))
963    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,1,c"))]
964   "TARGET_NPS_BITOPS"
965   "movb.f.cl %3,%1,%p2,%p2,%x2"
966   "TARGET_NPS_BITOPS && reload_completed
967    && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
968   [(set (match_dup 0) (match_dup 4))])
970 (define_insn "*tst"
971   [(set
972      (match_operand 0 "cc_register" "")
973      (match_operator 3 "zn_compare_operator"
974        [(and:SI
975           (match_operand:SI 1 "register_operand"
976            "%q,  q, c, c, c,  c,  c,  c")
977           (match_operand:SI 2 "nonmemory_operand"
978            " q,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
979         (const_int 0)]))]
980   "reload_completed
981    || !satisfies_constraint_Cbf (operands[2])
982    || satisfies_constraint_C0p (operands[2])
983    || satisfies_constraint_I (operands[2])
984    || satisfies_constraint_C1p (operands[2])
985    || satisfies_constraint_Chs (operands[2])"
986   "*
987     switch (which_alternative)
988     {
989     case 0: case 2: case 3: case 7:
990       return \"tst%?\\t%1,%2\";
991     case 1:
992       return \"btst%?\\t%1,%z2\";
993     case 4:
994       return \"bmsk%?.f\\t0,%1,%Z2\";
995     case 5:
996       return \"bclr%?.f\\t0,%1,%M2\";
997     case 6:
998       return \"asr.f\\t0,%1,%p2\";
999     default:
1000       gcc_unreachable ();
1001     }
1002   "
1003   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
1004    (set_attr "type" "compare,compare,compare,compare,compare,compare,binary,compare")
1005    (set_attr "length" "*,*,4,4,4,4,4,8")
1006    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
1007    (set_attr "cond" "set_zn")])
1009 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
1010 ; combine will do that and not try the AND.
1012 ; It would take 66 constraint combinations to describe the zero_extract
1013 ; constants that are covered by the 12-bit signed constant for tst
1014 ; (excluding the ones that are better done by mov or btst).
1015 ; so we rather use an extra pattern for tst;
1016 ; since this is about constants, reload shouldn't care.
1017 (define_insn "*tst_bitfield_tst"
1018   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1019         (match_operator 4 "zn_compare_operator"
1020           [(zero_extract:SI
1021              (match_operand:SI 1 "register_operand"  "c")
1022              (match_operand:SI 2 "const_int_operand" "n")
1023              (match_operand:SI 3 "const_int_operand" "n"))
1024            (const_int 0)]))]
1025   "INTVAL (operands[2]) > 1
1026    && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
1027        || (INTVAL (operands[3]) <= 11
1028            && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
1029   "tst\\t%1,((1<<%2)-1)<<%3"
1030   [(set_attr "type" "compare")
1031    (set_attr "cond" "set_zn")
1032    (set_attr "length" "4")])
1034 ; Likewise for asr.f.
1035 (define_insn "*tst_bitfield_asr"
1036   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1037         (match_operator 4 "zn_compare_operator"
1038           [(zero_extract:SI
1039              (match_operand:SI 1 "register_operand"  "c")
1040              (match_operand:SI 2 "const_int_operand" "n")
1041              (match_operand:SI 3 "const_int_operand" "n"))
1042            (const_int 0)]))]
1043   "INTVAL (operands[2]) > 1
1044    && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
1045   "asr.f 0,%1,%3"
1046   [(set_attr "type" "shift")
1047    (set_attr "cond" "set_zn")
1048    (set_attr "length" "4")])
1050 (define_insn "*tst_bitfield"
1051   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1052         (match_operator 5 "zn_compare_operator"
1053           [(zero_extract:SI
1054              (match_operand:SI 1 "register_operand" "%q,c,  c,Rrq,c")
1055              (match_operand:SI 2 "const_int_operand" "N,N,  n,Cbn,n")
1056              (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n"))
1057            (const_int 0)]))
1058    (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
1059   ""
1060   "@
1061    btst%?\\t%1,%3
1062    btst\\t%1,%3
1063    bmsk.f\\t0,%1,%2-1
1064    movb.f.cl\\t%4,%1,%3,%3,%2
1065    and.f\\t0,%1,((1<<%2)-1)<<%3"
1066   [(set_attr "iscompact" "maybe,false,false,false,false")
1067    (set_attr "type" "compare,compare,compare,shift,compare")
1068    (set_attr "cond" "set_zn")
1069    (set_attr "length" "*,4,4,4,8")])
1071 ;; The next two patterns are for plos, ior, xor, and, and mult.
1072 (define_insn "*commutative_binary_cmp0_noout"
1073   [(set (match_operand 0 "cc_set_register" "")
1074         (match_operator 4 "zn_compare_operator"
1075           [(match_operator:SI 3 "commutative_operator"
1076              [(match_operand:SI 1 "register_operand" "%r,r")
1077               (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1078            (const_int 0)]))]
1079   ""
1080   "%O3.f\\t0,%1,%2"
1081   [(set_attr "type" "compare")
1082    (set_attr "cond" "set_zn")
1083    (set_attr "length" "4,8")])
1085 (define_insn "*commutative_binary_cmp0"
1086   [(set (match_operand 3 "cc_set_register" "")
1087         (match_operator 5 "zn_compare_operator"
1088           [(match_operator:SI 4 "commutative_operator"
1089              [(match_operand:SI 1 "register_operand"  "%0, 0,r,r")
1090               (match_operand:SI 2 "nonmemory_operand" "rL,rI,r,Cal")])
1091            (const_int 0)]))
1092    (set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1093         (match_dup 4))]
1094   ""
1095   "%O4.f\\t%0,%1,%2"
1096   [(set_attr "type" "compare")
1097    (set_attr "cond" "set_zn")
1098    (set_attr "predicable" "yes,yes,no,no")
1099    (set_attr "length" "4,4,4,8")])
1101 ; for flag setting 'add' instructions like if (a+b) { ...}
1102 ; the combiner needs this pattern
1103 (define_insn "*addsi_compare"
1104   [(set (reg:CC_ZN CC_REG)
1105         (compare:CC_ZN (neg:SI
1106                         (match_operand:SI 0 "register_operand" "r"))
1107                        (match_operand:SI 1 "register_operand"  "r")))]
1108   ""
1109   "add.f\\t0,%0,%1"
1110   [(set_attr "cond" "set")
1111    (set_attr "type" "compare")
1112    (set_attr "length" "4")])
1114 (define_insn "addsi_compare_2"
1115   [(set (reg:CC_C CC_REG)
1116        (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand"   "r,r")
1117                               (match_operand:SI 1 "nonmemory_operand" "rL,Cal"))
1118                      (match_dup 0)))]
1119   ""
1120   "add.f\\t0,%0,%1"
1121   [(set_attr "cond" "set")
1122    (set_attr "type" "compare")
1123    (set_attr "length" "4,8")])
1125 (define_insn "*addsi_compare_3"
1126   [(set (reg:CC_C CC_REG)
1127        (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "r")
1128                               (match_operand:SI 1 "register_operand" "r"))
1129                      (match_dup 1)))]
1130   ""
1131   "add.f\\t0,%0,%1"
1132   [(set_attr "cond" "set")
1133    (set_attr "type" "compare")
1134    (set_attr "length" "4")])
1136 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
1137 (define_insn "*commutative_binary_comparison_result_used"
1138   [(set (match_operand 3 "cc_register" "")
1139         (match_operator 5 "zn_compare_operator"
1140           ; We can accept any commutative operator except mult because
1141           ; our 'w' class below could try to use LP_COUNT.
1142           [(match_operator:SI 4 "commutative_operator_sans_mult"
1143              [(match_operand:SI 1 "register_operand" "c,0,c")
1144               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1145            (const_int 0)]))
1146    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1147         (match_dup 4))]
1148   ""
1149   "%O4.f\\t%0,%1,%2 ; non-mult commutative"
1150   [(set_attr "type" "compare,compare,compare")
1151    (set_attr "cond" "set_zn,set_zn,set_zn")
1152    (set_attr "length" "4,4,8")])
1154 ; a MULT-specific version of this pattern to avoid touching the
1155 ; LP_COUNT register
1156 (define_insn "*commutative_binary_mult_comparison_result_used"
1157   [(set (match_operand 3 "cc_register" "")
1158         (match_operator 5 "zn_compare_operator"
1159           [(match_operator:SI 4 "mult_operator"
1160              [(match_operand:SI 1 "register_operand" "c,0,c")
1161               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1162            (const_int 0)]))
1163         ; Make sure to use the W class to not touch LP_COUNT.
1164    (set (match_operand:SI 0 "register_operand" "=W,W,W")
1165         (match_dup 4))]
1166   "!TARGET_ARC600_FAMILY"
1167   "%O4.f\\t%0,%1,%2 ; mult commutative"
1168   [(set_attr "type" "compare,compare,compare")
1169    (set_attr "cond" "set_zn,set_zn,set_zn")
1170    (set_attr "length" "4,4,8")])
1172 (define_insn "*noncommutative_binary_cmp0"
1173   [(set (match_operand 3 "cc_set_register" "")
1174         (match_operator 5 "zn_compare_operator"
1175           [(match_operator:SI 4 "noncommutative_operator"
1176              [(match_operand:SI 1 "register_operand"   "0,r,0,  0,r")
1177               (match_operand:SI 2 "nonmemory_operand" "rL,r,I,Cal,Cal")])
1178            (const_int 0)]))
1179    (set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
1180         (match_dup 4))]
1181   ""
1182   "%O4%?.f\\t%0,%1,%2"
1183   [(set_attr "type" "compare")
1184    (set_attr "cond" "set_zn")
1185    (set_attr "predicable" "yes,no,no,yes,no")
1186    (set_attr "length" "4,4,4,8,8")])
1188 (define_insn "*noncommutative_binary_cmp0_noout"
1189   [(set (match_operand 0 "cc_set_register" "")
1190         (match_operator 3 "zn_compare_operator"
1191           [(match_operator:SI 4 "noncommutative_operator"
1192              [(match_operand:SI 1 "register_operand"   "r,r")
1193               (match_operand:SI 2 "nonmemory_operand" "rL,Cal")])
1194            (const_int 0)]))]
1195   ""
1196   "%O4.f\\t0,%1,%2"
1197   [(set_attr "type" "compare")
1198    (set_attr "cond" "set_zn")
1199    (set_attr "length" "4,8")])
1201 ;;rsub variants
1202 (define_insn "*rsub_cmp0"
1203   [(set (match_operand 4 "cc_set_register" "")
1204         (match_operator 3 "zn_compare_operator"
1205           [(minus:SI
1206             (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1207             (match_operand:SI 2 "register_operand"   "r,r"))
1208            (const_int 0)]))
1209    (set (match_operand:SI 0 "register_operand" "=r,r")
1210         (minus:SI (match_dup 1) (match_dup 2)))]
1211   ""
1212   "rsub.f\\t%0,%2,%1"
1213   [(set_attr "type" "compare")
1214    (set_attr "cond" "set_zn")
1215    (set_attr "length" "4,8")])
1217 (define_insn "*rsub_cmp0_noout"
1218   [(set (match_operand 0 "cc_set_register" "")
1219         (match_operator 3 "zn_compare_operator"
1220           [(minus:SI
1221             (match_operand:SI 1 "nonmemory_operand" "rL,Cal")
1222             (match_operand:SI 2 "register_operand"   "r,r"))
1223            (const_int 0)]))]
1224   ""
1225   "rsub.f\\t0,%2,%1"
1226   [(set_attr "type" "compare")
1227    (set_attr "cond" "set_zn")
1228    (set_attr "length" "4,8")])
1230 (define_expand "bic_f_zn"
1231   [(parallel
1232      [(set (reg:CC_ZN CC_REG)
1233            (compare:CC_ZN
1234              (and:SI (match_operand:SI 1 "register_operand" "")
1235                      (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1236            (const_int 0)))
1237       (set (match_operand:SI 0 "register_operand" "")
1238            (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1239   "")
1241 (define_insn "*bic_f"
1242   [(set (match_operand 3 "cc_set_register" "")
1243         (match_operator 4 "zn_compare_operator"
1244           [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1245                    (not:SI
1246                      (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1247            (const_int 0)]))
1248    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1249         (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1250   ""
1251   "bic.f\\t%0,%1,%2"
1252   [(set_attr "type" "compare,compare,compare")
1253    (set_attr "cond" "set_zn,set_zn,set_zn")
1254    (set_attr "length" "4,4,8")])
1256 (define_insn "*bic_cmp0_noout"
1257   [(set (match_operand 0 "cc_set_register" "")
1258         (compare:CC_ZN
1259          (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1260                  (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1261          (const_int 0)))]
1262   "register_operand (operands[1], SImode)
1263    || register_operand (operands[2], SImode)"
1264   "bic.f\\t0,%2,%1"
1265   [(set_attr "type" "unary")
1266    (set_attr "cond" "set_zn")
1267    (set_attr "length" "4,8,8")])
1269 (define_insn "*bic_cmp0"
1270   [(set (match_operand 0 "cc_set_register" "")
1271         (compare:CC_ZN
1272          (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Lr,Cal,r"))
1273                  (match_operand:SI 2 "nonmemory_operand" "r,r,Cal"))
1274          (const_int 0)))
1275    (set (match_operand:SI 3 "register_operand" "=r,r,r")
1276         (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
1277   "register_operand (operands[1], SImode)
1278    || register_operand (operands[2], SImode)"
1279   "bic.f\\t%3,%2,%1"
1280   [(set_attr "type" "unary")
1281    (set_attr "cond" "set_zn")
1282    (set_attr "length" "4,8,8")])
1284 (define_expand "movdi"
1285   [(set (match_operand:DI 0 "move_dest_operand" "")
1286         (match_operand:DI 1 "general_operand" ""))]
1287   ""
1288   "
1289   if (prepare_move_operands (operands, DImode))
1290     DONE;
1291   ")
1293 (define_insn_and_split "*movdi_insn"
1294   [(set (match_operand:DI 0 "move_dest_operand"      "=r, r,r,   m")
1295         (match_operand:DI 1 "move_double_src_operand" "r,Hi,m,rCm3"))]
1296   "register_operand (operands[0], DImode)
1297    || register_operand (operands[1], DImode)
1298    || (satisfies_constraint_Cm3 (operands[1])
1299        && memory_operand (operands[0], DImode))"
1300   "@
1301    vadd2\\t%0,%1,0
1302    #
1303    ldd%U1%V1\\t%0,%1
1304    std%U0%V0\\t%1,%0"
1305   "&& reload_completed && arc_split_move_p (operands)"
1306   [(const_int 0)]
1307   {
1308    arc_split_move (operands);
1309    DONE;
1310   }
1311   [(set_attr "type" "move,move,load,store")
1312    (set_attr "length" "8,16,16,16")])
1314 ;; Floating point move insns.
1316 (define_expand "movsf"
1317   [(set (match_operand:SF 0 "move_dest_operand" "")
1318         (match_operand:SF 1 "general_operand" ""))]
1319   ""
1320   "if (prepare_move_operands (operands, SFmode)) DONE;")
1322 (define_insn "*movsf_insn"
1323   [(set (match_operand:SF 0 "move_dest_operand"   "=h,h,   r,r,  q,S,Usc,r,m")
1324         (match_operand:SF 1 "move_src_operand"  "hCfZ,E,rCfZ,E,Uts,q,  E,m,r"))]
1325   "register_operand (operands[0], SFmode)
1326    || register_operand (operands[1], SFmode)
1327    || (CONSTANT_P (operands[1])
1328        && (!satisfies_constraint_I (operands[1]) || !optimize_size)
1329        && satisfies_constraint_Usc (operands[0]))"
1330   "@
1331    mov%?\\t%0,%1
1332    mov%?\\t%0,%1 ; %A1
1333    mov%?\\t%0,%1
1334    mov%?\\t%0,%1 ; %A1
1335    ld%?%U1\\t%0,%1
1336    st%?\\t%1,%0
1337    st%U0%V0\\t%1,%0
1338    ld%U1%V1\\t%0,%1
1339    st%U0%V0\\t%1,%0"
1340   [(set_attr "type" "move,move,move,move,load,store,store,load,store")
1341    (set_attr "predicable" "no,no,yes,yes,no,no,no,no,no")
1342    (set_attr "length" "*,*,4,*,*,*,*,*,*")
1343    (set_attr "iscompact" "true,true_limm,false,false,true,true,false,false,false")])
1345 (define_expand "movdf"
1346   [(set (match_operand:DF 0 "move_dest_operand" "")
1347         (match_operand:DF 1 "general_operand" ""))]
1348   ""
1349   "if (prepare_move_operands (operands, DFmode)) DONE;")
1351 (define_insn_and_split "*movdf_insn"
1352   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,r,r,r,m")
1353         (match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))]
1354   "(register_operand (operands[0], DFmode)
1355     || register_operand (operands[1], DFmode))"
1356   "@
1357    #
1358    #
1359    vadd2\\t%0,%1,0
1360    #
1361    ldd%U1%V1\\t%0,%1
1362    std%U0%V0\\t%1,%0"
1363   "&& reload_completed && arc_split_move_p (operands)"
1364   [(const_int 0)]
1365   {
1366    arc_split_move (operands);
1367    DONE;
1368   }
1369   [(set_attr "type" "move,move,move,move,load,store")
1370    (set_attr "length" "4,16,8,16,16,16")])
1372 (define_insn_and_split "*movdf_insn_nolrsr"
1373   [(set (match_operand:DF 0 "register_operand"       "=r")
1374         (match_operand:DF 1 "arc_double_register_operand" "D"))
1375    (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1376    ]
1377   "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1378   "#"
1379   "&& 1"
1380   [
1381     ; mov r0, 0
1382     (set (match_dup 0) (match_dup 3))
1384     ; daddh?? r1, r0, r0
1385     (parallel [
1386         (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1387         (use (const_int 1))
1388         (use (const_int 1))
1389         (use (match_dup 0)) ; used to block can_combine_p
1390         (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1391     ])
1393     ; We have to do this twice, once to read the value into R0 and
1394     ; second time to put back the contents which the first DEXCLx
1395     ; will have overwritten
1396     ; dexcl2 r0, r1, r0
1397     (parallel [
1398                (set (match_dup 4) ; aka r0result
1399                                   ; aka DF, r1, r0
1400                     (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1401                                         VUNSPEC_ARC_DEXCL))
1402                (clobber (match_dup 1))
1403                ])
1404     ; Generate the second, which makes sure operand5 and operand4 values
1405     ; are put back in the Dx register properly.
1406     (set (match_dup 1) (unspec_volatile:DF
1407                         [(match_dup 5) (match_dup 4)]
1408                         VUNSPEC_ARC_DEXCL_NORES))
1410     ; Note: we cannot use a (clobber (match_scratch)) here because
1411     ; the combine pass will end up replacing uses of it with 0
1412   ]
1413   "operands[3] = CONST0_RTX (DFmode);
1414    operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1415    operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1416   [(set_attr "type" "move")])
1418 ;; Load/Store with update instructions.
1420 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1421 ;; hardware can also do cases where the increment is not the size of the
1422 ;; object.
1424 ;; In all these cases, we use operands 0 and 1 for the register being
1425 ;; incremented because those are the operands that local-alloc will
1426 ;; tie and these are the pair most likely to be tieable (and the ones
1427 ;; that will benefit the most).
1429 ;; We use match_operator here because we need to know whether the memory
1430 ;; object is volatile or not.
1433 ;; Note: loadqi_update has no 16-bit variant
1434 (define_insn "*loadqi_update"
1435   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1436         (match_operator:QI 4 "any_mem_operand"
1437          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1438                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1439    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1440         (plus:SI (match_dup 1) (match_dup 2)))]
1441   ""
1442   "ldb.a%V4 %3,[%0,%2]"
1443   [(set_attr "type" "load,load")
1444    (set_attr "length" "4,8")])
1446 (define_insn "*load_zeroextendqisi_update"
1447   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1448         (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1449                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1450                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1451    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1452         (plus:SI (match_dup 1) (match_dup 2)))]
1453   ""
1454   "ldb.a%V4 %3,[%0,%2]"
1455   [(set_attr "type" "load,load")
1456    (set_attr "length" "4,8")])
1458 (define_insn "*load_signextendqisi_update"
1459   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1460         (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1461                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1462                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1463    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1464         (plus:SI (match_dup 1) (match_dup 2)))]
1465   ""
1466   "ldb.x.a%V4 %3,[%0,%2]"
1467   [(set_attr "type" "load,load")
1468    (set_attr "length" "4,8")])
1470 (define_insn "*storeqi_update"
1471   [(set (match_operator:QI 4 "any_mem_operand"
1472          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1473                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1474         (match_operand:QI 3 "register_operand" "c"))
1475    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1476         (plus:SI (match_dup 1) (match_dup 2)))]
1477   ""
1478   "stb.a%V4 %3,[%0,%2]"
1479   [(set_attr "type" "store")
1480    (set_attr "length" "4")])
1482 ;; ??? pattern may have to be re-written
1483 ;; Note: no 16-bit variant for this pattern
1484 (define_insn "*loadhi_update"
1485   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1486         (match_operator:HI 4 "any_mem_operand"
1487          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1488                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1489    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1490         (plus:SI (match_dup 1) (match_dup 2)))]
1491   ""
1492   "ld%_.a%V4 %3,[%0,%2]"
1493   [(set_attr "type" "load,load")
1494    (set_attr "length" "4,8")])
1496 (define_insn "*load_zeroextendhisi_update"
1497   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1498         (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1499                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1500                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1501    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1502         (plus:SI (match_dup 1) (match_dup 2)))]
1503   ""
1504   "ld%_.a%V4 %3,[%0,%2]"
1505   [(set_attr "type" "load,load")
1506    (set_attr "length" "4,8")])
1508 ;; Note: no 16-bit variant for this instruction
1509 (define_insn "*load_signextendhisi_update"
1510   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1511         (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1512                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1513                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1514    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1515         (plus:SI (match_dup 1) (match_dup 2)))]
1516   ""
1517   "ld%_.x.a%V4 %3,[%0,%2]"
1518   [(set_attr "type" "load,load")
1519    (set_attr "length" "4,8")])
1521 (define_insn "*storehi_update"
1522   [(set (match_operator:HI 4 "any_mem_operand"
1523          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1524                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1525         (match_operand:HI 3 "register_operand" "c"))
1526    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1527         (plus:SI (match_dup 1) (match_dup 2)))]
1528   ""
1529   "st%_.a%V4 %3,[%0,%2]"
1530   [(set_attr "type" "store")
1531    (set_attr "length" "4")])
1533 ;; No 16-bit variant for this instruction pattern
1534 (define_insn "*loadsi_update"
1535   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1536         (match_operator:SI 4 "any_mem_operand"
1537          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1538                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1539    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1540         (plus:SI (match_dup 1) (match_dup 2)))]
1541   ""
1542   "ld.a%V4 %3,[%0,%2]"
1543   [(set_attr "type" "load,load")
1544    (set_attr "length" "4,8")])
1546 (define_insn "*storesi_update"
1547   [(set (match_operator:SI 4 "any_mem_operand"
1548          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1549                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1550         (match_operand:SI 3 "register_operand" "c"))
1551    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1552         (plus:SI (match_dup 1) (match_dup 2)))]
1553   ""
1554   "st.a%V4 %3,[%0,%2]"
1555   [(set_attr "type" "store")
1556    (set_attr "length" "4")])
1558 (define_insn "*loadsf_update"
1559   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1560         (match_operator:SF 4 "any_mem_operand"
1561          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1562                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1563    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1564         (plus:SI (match_dup 1) (match_dup 2)))]
1565   ""
1566   "ld.a%V4 %3,[%0,%2]"
1567   [(set_attr "type" "load,load")
1568    (set_attr "length" "4,8")])
1570 (define_insn "*storesf_update"
1571   [(set (match_operator:SF 4 "any_mem_operand"
1572          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1573                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1574         (match_operand:SF 3 "register_operand" "c"))
1575    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1576         (plus:SI (match_dup 1) (match_dup 2)))]
1577   ""
1578   "st.a%V4 %3,[%0,%2]"
1579   [(set_attr "type" "store")
1580    (set_attr "length" "4")])
1582 ;; Conditional move instructions.
1584 (define_expand "movsicc"
1585   [(set (match_operand:SI 0 "dest_reg_operand" "")
1586         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1587                          (match_operand:SI 2 "nonmemory_operand" "")
1588                          (match_operand:SI 3 "register_operand" "")))]
1589   ""
1590   "
1591   operands[1] = gen_compare_reg (operands[1], VOIDmode);
1592   if (operands[1] == NULL_RTX)
1593     FAIL;
1594   ")
1596 (define_expand "movdicc"
1597   [(set (match_operand:DI 0 "dest_reg_operand" "")
1598         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1599                         (match_operand:DI 2 "nonmemory_operand" "")
1600                         (match_operand:DI 3 "register_operand" "")))]
1601   ""
1602   "
1603   operands[1] = gen_compare_reg (operands[1], VOIDmode);
1604   if (operands[1] == NULL_RTX)
1605     FAIL;
1606   ")
1609 (define_expand "movsfcc"
1610   [(set (match_operand:SF 0 "dest_reg_operand" "")
1611         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1612                       (match_operand:SF 2 "nonmemory_operand" "")
1613                       (match_operand:SF 3 "register_operand" "")))]
1614   ""
1615   "
1616   operands[1] = gen_compare_reg (operands[1], VOIDmode);
1617   if (operands[1] == NULL_RTX)
1618     FAIL;
1619   ")
1621 (define_expand "movdfcc"
1622   [(set (match_operand:DF 0 "dest_reg_operand" "")
1623         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1624                       (match_operand:DF 2 "nonmemory_operand" "")
1625                       (match_operand:DF 3 "register_operand" "")))]
1626   ""
1627   "
1628   operands[1] = gen_compare_reg (operands[1], VOIDmode);
1629   if (operands[1] == NULL_RTX)
1630     FAIL;
1631   ")
1633 (define_insn "*movsicc_insn"
1634   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1635         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1636                        [(match_operand 4 "cc_register" "") (const_int 0)])
1637                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1638                       (match_operand:SI 2 "register_operand" "0,0")))]
1639   ""
1641   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1642       && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11))
1643     return "sub%?.ne\\t%0,%0,%0";
1644   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1645   if ((optimize_size && (!TARGET_ARC600_FAMILY))
1646       && rtx_equal_p (operands[1], constm1_rtx)
1647       && GET_CODE (operands[3]) == LTU)
1648     return "sbc.cs\\t%0,%0,%0";
1649   return "mov.%d3\\t%0,%1";
1651   [(set_attr "type" "cmove,cmove")
1652    (set_attr "length" "4,8")])
1654 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1655 ;; if the single bit is the sign bit, then GCC likes to convert this
1656 ;; into a sign extend and a compare less than, or greater to zero.
1657 ;; This is usually fine, except for the NXP400 where we have access to
1658 ;; a bit test instruction, along with a special short load instruction
1659 ;; (from CMEM), that doesn't support sign-extension on load.
1661 ;; This peephole optimisation attempts to restore the use of bit-test
1662 ;; in those cases where it is useful to do so.
1663 (define_peephole2
1664   [(set (match_operand:SI 0 "register_operand" "")
1665                 (sign_extend:SI
1666                 (match_operand:QI 1 "any_mem_operand" "")))
1667    (set (reg:CC_ZN CC_REG)
1668         (compare:CC_ZN (match_dup 0)
1669                        (const_int 0)))
1670    (set (pc)
1671         (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1672                        [(reg:CC_ZN CC_REG) (const_int 0)])
1673                       (match_operand 3 "" "")
1674                       (match_operand 4 "" "")))]
1675   "TARGET_NPS_CMEM
1676    && cmem_address (XEXP (operands[1], 0), SImode)
1677    && peep2_reg_dead_p (2, operands[0])
1678    && peep2_regno_dead_p (3, CC_REG)"
1679   [(set (match_dup 0)
1680         (zero_extend:SI
1681         (match_dup 1)))
1682    (set (reg:CC_ZN CC_REG)
1683         (compare:CC_ZN (zero_extract:SI
1684                          (match_dup 0)
1685                          (const_int 1)
1686                          (const_int 7))
1687                        (const_int 0)))
1688    (set (pc)
1689         (if_then_else (match_dup 2)
1690                       (match_dup 3)
1691                       (match_dup 4)))]
1692   "if (GET_CODE (operands[2]) == GE)
1693      operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1694    else
1695      operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1697 ; Try to generate more short moves, and/or less limms, by substituting a
1698 ; conditional move with a conditional sub.
1699 (define_peephole2
1700   [(set (match_operand:SI 0 "compact_register_operand")
1701         (match_operand:SI 1 "const_int_operand"))
1702    (set (match_dup 0)
1703         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1704                            [(match_operand 4 "cc_register" "") (const_int 0)])
1705                             (match_operand:SI 2 "const_int_operand" "")
1706                       (match_dup 0)))]
1707   "!satisfies_constraint_P (operands[1])
1708    && satisfies_constraint_P (operands[2])
1709    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1710   [(set (match_dup 0) (match_dup 2))
1711    (cond_exec
1712      (match_dup 3)
1713      (set (match_dup 0)
1714           (plus:SI (match_dup 0) (match_dup 1))))]
1715   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1716                                                     GET_MODE (operands[4])),
1717                                  VOIDmode, operands[4], const0_rtx);
1718    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1720 (define_insn "*movdicc_insn"
1721   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1722         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1723                         [(match_operand 4 "cc_register" "") (const_int 0)])
1724                       (match_operand:DI 1 "nonmemory_operand" "c,i")
1725                       (match_operand:DI 2 "register_operand" "0,0")))]
1726    ""
1727    "*
1729    switch (which_alternative)
1730      {
1731      default:
1732      case 0 :
1733        /* We normally copy the low-numbered register first.  However, if
1734          the first register operand 0 is the same as the second register of
1735          operand 1, we must copy in the opposite order.  */
1736        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1737         return \"mov.%d3\\t%R0,%R1\;mov.%d3\\t%0,%1\";
1738        else
1739         return \"mov.%d3\\t%0,%1\;mov.%d3\\t%R0,%R1\";
1740      case 1 :
1741         return \"mov.%d3\\t%L0,%L1\;mov.%d3\\t%H0,%H1\";
1744      }
1746   [(set_attr "type" "cmove,cmove")
1747    (set_attr "length" "8,16")])
1750 (define_insn "*movsfcc_insn"
1751   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1752         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1753                        [(match_operand 4 "cc_register" "") (const_int 0)])
1754                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1755                       (match_operand:SF 2 "register_operand" "0,0")))]
1756   ""
1757   "@
1758    mov.%d3\\t%0,%1
1759    mov.%d3\\t%0,%1 ; %A1"
1760   [(set_attr "type" "cmove,cmove")])
1762 (define_insn "*movdfcc_insn"
1763   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1764         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1765                  [(match_operand 4 "cc_register" "") (const_int 0)])
1766                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1767                       (match_operand:DF 3 "register_operand" "0,0")))]
1768   ""
1769   "*
1771   switch (which_alternative)
1772     {
1773     default:
1774     case 0 :
1775       /* We normally copy the low-numbered register first.  However, if
1776          the first register operand 0 is the same as the second register of
1777          operand 1, we must copy in the opposite order.  */
1778       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1779         return \"mov.%d1\\t%R0,%R2\;mov.%d1\\t%0,%2\";
1780       else
1781         return \"mov.%d1\\t%0,%2\;mov.%d1\\t%R0,%R2\";
1782     case 1 :
1783       return \"mov.%d1\\t%L0,%L2\;mov.%d1\\t%H0,%H2; %A2\";
1784     }
1786   [(set_attr "type" "cmove,cmove")
1787    (set_attr "length" "8,16")])
1789 ;; -------------------------------------------------------------------
1790 ;; Sign/Zero extension
1791 ;; -------------------------------------------------------------------
1793 (define_insn "*zero_extendqihi2_i"
1794   [(set (match_operand:HI 0 "dest_reg_operand" "=q,q,r,r,r,r")
1795         (zero_extend:HI
1796          (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,Ucm,m")))]
1797   ""
1798   "@
1799    extb%?\\t%0,%1
1800    extb%?\\t%0,%1
1801    bmsk%?\\t%0,%1,7
1802    extb\\t%0,%1
1803    xldb%U1\\t%0,%1
1804    ldb%U1\\t%0,%1"
1805   [(set_attr "type" "unary,unary,unary,unary,load,load")
1806    (set_attr "iscompact" "maybe,true,false,false,false,false")
1807    (set_attr "predicable" "no,no,yes,no,no,no")])
1809 (define_expand "zero_extendqihi2"
1810   [(set (match_operand:HI 0 "dest_reg_operand" "")
1811         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1812   ""
1813   ""
1816 (define_insn "*zero_extendqisi2_ac"
1817   [(set (match_operand:SI 0 "dest_reg_operand"    "=q,q,r,r,q,!*x,r,r")
1818         (zero_extend:SI
1819          (match_operand:QI 1 "nonvol_nonimm_operand" "0,q,0,r,T,Usd,Ucm,m")))]
1820   ""
1821   "@
1822    extb%?\\t%0,%1
1823    extb%?\\t%0,%1
1824    bmsk%?\\t%0,%1,7
1825    extb\\t%0,%1
1826    ldb%?\\t%0,%1
1827    ldb%?\\t%0,%1
1828    xldb%U1\\t%0,%1
1829    ldb%U1\\t%0,%1"
1830   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1831    (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1832    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1834 (define_expand "zero_extendqisi2"
1835   [(set (match_operand:SI 0 "dest_reg_operand" "")
1836         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1837   ""
1838   ""
1841 (define_insn "*zero_extendhisi2_i"
1842   [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r,!x,q,r,r")
1843         (zero_extend:SI
1844          (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,r,Usd,T,Ucm,m")))]
1845   ""
1846   "@
1847    ext%_%?\\t%0,%1
1848    ext%_%?\\t%0,%1
1849    bmsk%?\\t%0,%1,15
1850    ext%_\\t%0,%1
1851    ld%_%?\\t%0,%1
1852    ld%_%?\\t%0,%1
1853    xldw%U1\\t%0,%1
1854    ld%_%U1%V1\\t%0,%1"
1855   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1856    (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1857    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1859 (define_expand "zero_extendhisi2"
1860   [(set (match_operand:SI 0 "dest_reg_operand" "")
1861         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1862   ""
1863   ""
1866 ;; Sign extension instructions.
1868 (define_insn "*extendqihi2_i"
1869   [(set (match_operand:HI 0 "dest_reg_operand" "=q,r,r,r")
1870         (sign_extend:HI
1871          (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1872   ""
1873   "@
1874    sexb%?\\t%0,%1
1875    sexb\\t%0,%1
1876    ldb.x%U1\\t%0,%1
1877    ldb.x%U1\\t%0,%1"
1878   [(set_attr "type" "unary,unary,load,load")
1879    (set_attr "iscompact" "true,false,false,false")
1880    (set_attr "length" "*,*,*,8")])
1882 (define_expand "extendqihi2"
1883   [(set (match_operand:HI 0 "dest_reg_operand" "")
1884         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1885   ""
1886   ""
1889 (define_insn "*extendqisi2_ac"
1890   [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r")
1891         (sign_extend:SI
1892          (match_operand:QI 1 "nonvol_nonimm_operand" "q,r,Uex,m")))]
1893   ""
1894   "@
1895    sexb%?\\t%0,%1
1896    sexb\\t%0,%1
1897    ldb.x%U1\\t%0,%1
1898    ldb.x%U1\\t%0,%1"
1899   [(set_attr "type" "unary,unary,load,load")
1900    (set_attr "iscompact" "true,false,false,false")
1901    (set_attr "length" "*,*,*,8")])
1903 (define_expand "extendqisi2"
1904   [(set (match_operand:SI 0 "dest_reg_operand" "")
1905         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1906   ""
1907   ""
1910 (define_insn "*extendhisi2_i"
1911   [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,q,r,r")
1912         (sign_extend:SI
1913          (match_operand:HI 1 "nonvol_nonimm_operand" "q,r,Ucd,Uex,m")))]
1914   ""
1915   "@
1916    sex%_%?\\t%0,%1
1917    sex%_\\t%0,%1
1918    ldh%?.x\\t%0,%1
1919    ld%_.x%U1%V1\\t%0,%1
1920    ld%_.x%U1%V1\\t%0,%1"
1921   [(set_attr "type" "unary,unary,load,load,load")
1922    (set_attr "iscompact" "true,false,true,false,false")
1923    (set_attr "length" "*,*,*,4,8")])
1925 (define_expand "extendhisi2"
1926   [(set (match_operand:SI 0 "dest_reg_operand" "")
1927         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1928   ""
1929   ""
1932 ;; Unary arithmetic insns
1934 ;; We allow constant operands to enable late constant propagation, but it is
1935 ;; not worth while to have more than one dedicated alternative to output them -
1936 ;; if we are really worried about getting these the maximum benefit of all
1937 ;; the available alternatives, we should add an extra pass to fold such
1938 ;; operations to movsi.
1940 ;; Absolute instructions
1942 (define_insn "abssi2"
1943   [(set (match_operand:SI 0 "dest_reg_operand" "=q,w,w")
1944         (abs:SI (match_operand:SI 1 "nonmemory_operand" "q,cL,Cal")))]
1945   ""
1946   "abs%?\\t%0,%1"
1947   [(set_attr "type" "two_cycle_core")
1948    (set_attr "length" "*,4,8")
1949    (set_attr "iscompact" "true,false,false")])
1951 ;; Maximum and minimum insns
1953 (define_insn "smaxsi3"
1954    [(set (match_operand:SI 0 "dest_reg_operand"           "=r, r,  r")
1955          (smax:SI (match_operand:SI 1 "register_operand"  "%0, r,  r")
1956                   (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1957   ""
1958   "max%?\\t%0,%1,%2"
1959   [(set_attr "type" "two_cycle_core")
1960    (set_attr "length" "4,4,8")
1961    (set_attr "predicable" "yes,no,no")]
1964 (define_insn "sminsi3"
1965    [(set (match_operand:SI 0 "dest_reg_operand"           "=r, r,  r")
1966          (smin:SI (match_operand:SI 1 "register_operand"  "%0, r,  r")
1967                   (match_operand:SI 2 "nonmemory_operand" "rL,rL,Cal")))]
1968   ""
1969   "min%?\\t%0,%1,%2"
1970   [(set_attr "type" "two_cycle_core")
1971    (set_attr "length" "4,4,8")
1972    (set_attr "predicable" "yes,no,no")]
1975 ;; Arithmetic instructions.
1977 ; The alternatives in the constraints still serve three purposes:
1978 ; - estimate insn size assuming conditional execution
1979 ; - guide reload to re-order the second and third operand to get a better fit.
1980 ; - give tentative insn type to guide scheduling
1981 ;   N.B. "%" for commutativity doesn't help when there is another matching
1982 ;   (but longer) alternative.
1983 (define_insn "*addsi3_mixed"
1984   ;;                                                      0    1     2   3   4   5  6  7  8  9   a   b   c   d   e   f  10
1985   [(set (match_operand:SI 0 "register_operand"           "=q,  h,!*Rsd,Rcb,Rcb,  q, q, q, r,r,   r,  r,  r,  r,  q,  r,  r")
1986         (plus:SI (match_operand:SI 1 "register_operand"  "%0,  0,    q,  0,  0,Rcb, q, 0, 0,r,   r,  r,  0,  r,  0,  0,  r")
1987                  (match_operand:SI 2 "nonmemory_operand" "hL,Cm1,    L,CP4,CM4,CM4,qK, O,rL,0,rC6u,C6n,CIs,C4p,Cal,Cal,Cal")))]
1988   ""
1989   "@
1990   add_s\\t%0,%1,%2   ;b,b,h
1991   add_s\\t%0,%1,%2   ;h,h,s3
1992   add_s\\t%0,%1,%2   ;R0/R1,b,u6
1993   sub_s\\t%0,%1,%n2  ;sp,sp,u7
1994   add_s\\t%0,%1,%2   ;sp,sp,u7
1995   add_s\\t%0,%1,%2   ;b,sp,u7
1996   add_s\\t%0,%1,%2   ;a,b,c/u3
1997   add_s\\t%0,%1,%2   ;b,b,u7
1998   add%?\\t%0,%1,%2   ;(p)b,b,c/u6
1999   add%?\\t%0,%2,%1   ;(p)b,b,c
2000   add%s2\\t%0,%1,%S2 ;a,b,c/u6
2001   sub%s2\\t%0,%1,%N2 ;a,b,u6
2002   add%s2\\t%0,%1,%S2 ;b,b,s12
2003   bxor\\t%0,%1,31
2004   add_s\\t%0,%1,%2   ;b,b,limm
2005   add%?\\t%0,%1,%2   ;(p)b,b,limm
2006   add\\t%0,%1,%2     ;a,b,limm"
2007   [(set_attr "type"       "add,add,add,sub,add,add,add,add,add,add,add,sub,add,bxor,add,add,add")
2008    (set_attr "iscompact"  "true,true,true,true,true,true,true,true,false,false,false,false,false,false,true_limm,false,false")
2009    (set_attr "length"     "2,2,2,2,2,2,2,2,4,4,4,4,4,4,6,8,8")
2010    (set_attr "predicable" "no,no,no,no,no,no,no,no,yes,yes,no,no,no,no,no,yes,no")
2013 ;; ARCv2 MPYW and MPYUW
2014 (define_expand "mulhisi3"
2015   [(set (match_operand:SI 0 "register_operand"                           "")
2016         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  ""))
2017                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
2018   "TARGET_MPYW"
2019   "{
2020     if (CONSTANT_P (operands[2]))
2021     {
2022       emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
2023       DONE;
2024     }
2025    }"
2028 (define_insn "mulhisi3_imm"
2029   [(set (match_operand:SI 0 "register_operand"                         "=r,r,r,  r,  r")
2030         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0,  0,  r"))
2031                  (match_operand:HI 2 "short_const_int_operand"          "L,L,I,C16,C16")))]
2032   "TARGET_MPYW"
2033   "mpyw%?\\t%0,%1,%2"
2034   [(set_attr "length" "4,4,4,8,8")
2035    (set_attr "iscompact" "false")
2036    (set_attr "type" "mul16_em")
2037    (set_attr "predicable" "yes,no,no,yes,no")
2038    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2039    ])
2041 (define_insn "mulhisi3_reg"
2042   [(set (match_operand:SI 0 "register_operand"                          "=q,r,r")
2043         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  "0,0,r"))
2044                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "q,r,r"))))]
2045   "TARGET_MPYW"
2046   "mpyw%?\\t%0,%1,%2"
2047   [(set_attr "length" "*,4,4")
2048    (set_attr "iscompact" "maybe,false,false")
2049    (set_attr "type" "mul16_em")
2050    (set_attr "predicable" "yes,yes,no")
2051    (set_attr "cond" "canuse,canuse,nocond")
2052    ])
2054 (define_expand "umulhisi3"
2055   [(set (match_operand:SI 0 "register_operand"                           "")
2056         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand"  ""))
2057                  (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
2058   "TARGET_MPYW"
2059   "{
2060     if (CONSTANT_P (operands[2]))
2061     {
2062       emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
2063       DONE;
2064     }
2065   }"
2068 (define_insn "umulhisi3_imm"
2069   [(set (match_operand:SI 0 "register_operand"                          "=r, r,  r,  r,  r")
2070         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r,  0,  0,  r"))
2071                  (match_operand:HI 2 "short_unsigned_const_operand"     " L, L,J12,J16,J16")))]
2072   "TARGET_MPYW"
2073   "mpyuw%?\\t%0,%1,%2"
2074   [(set_attr "length" "4,4,4,8,8")
2075    (set_attr "iscompact" "false")
2076    (set_attr "type" "mul16_em")
2077    (set_attr "predicable" "yes,no,no,yes,no")
2078    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
2079    ])
2081 (define_insn "umulhisi3_reg"
2082   [(set (match_operand:SI 0 "register_operand"                          "=q, r, r")
2083         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, 0, r"))
2084                  (zero_extend:SI (match_operand:HI 2 "register_operand"  "q, r, r"))))]
2085   "TARGET_MPYW"
2086   "mpyuw%?\\t%0,%1,%2"
2087   [(set_attr "length" "*,4,4")
2088    (set_attr "iscompact" "maybe,false,false")
2089    (set_attr "type" "mul16_em")
2090    (set_attr "predicable" "yes,yes,no")
2091    (set_attr "cond" "canuse,canuse,nocond")
2092    ])
2094 ;; ARC700/ARC600/V2 multiply
2095 ;; SI <- SI * SI
2097 (define_expand "mulsi3"
2098  [(set (match_operand:SI 0 "register_operand"            "")
2099         (mult:SI (match_operand:SI 1 "register_operand"  "")
2100                  (match_operand:SI 2 "nonmemory_operand" "")))]
2101   "TARGET_ANY_MPY"
2103   if (TARGET_MUL64_SET)
2104     {
2105      emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2]));
2106      DONE;
2107     }
2108   else if (TARGET_MULMAC_32BY16_SET)
2109     {
2110      emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2]));
2111      DONE;
2112     }
2115 (define_insn_and_split "mulsi32x16"
2116  [(set (match_operand:SI 0 "register_operand"            "=w")
2117         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
2118                  (match_operand:SI 2 "nonmemory_operand" "ci")))
2119   (clobber (reg:DI MUL32x16_REG))]
2120  "TARGET_MULMAC_32BY16_SET"
2121  "#"
2122  "TARGET_MULMAC_32BY16_SET && reload_completed"
2123  [(const_int 0)]
2125   if (immediate_operand (operands[2], SImode)
2126     && INTVAL (operands[2]) >= 0
2127     && INTVAL (operands[2]) <= 65535)
2128      {
2129       emit_insn (gen_umul_600 (operands[1], operands[2],
2130                                        gen_acc2 (), gen_acc1 ()));
2131       emit_move_insn (operands[0], gen_acc2 ());
2132       DONE;
2133      }
2134    emit_insn (gen_umul_600 (operands[1], operands[2],
2135                                    gen_acc2 (), gen_acc1 ()));
2136    emit_insn (gen_mac_600 (operands[1], operands[2],
2137                                    gen_acc2 (), gen_acc1 ()));
2138    emit_move_insn (operands[0], gen_acc2 ());
2139    DONE;
2140   }
2141  [(set_attr "type" "multi")
2142   (set_attr "length" "8")])
2144 ; mululw conditional execution without a LIMM clobbers an input register;
2145 ; we'd need a different pattern to describe this.
2146 ; To make the conditional execution valid for the LIMM alternative, we
2147 ; have to emit the LIMM before the register operand.
2148 (define_insn "umul_600"
2149   [(set (match_operand:SI 2 "acc2_operand" "")
2150         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
2151                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2152                                                          "c,L,Cal")
2153                                   (const_int 16)
2154                                   (const_int 0))))
2155    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2156   "TARGET_MULMAC_32BY16_SET"
2157   "mululw\\t0,%0,%1"
2158   [(set_attr "length" "4,4,8")
2159    (set_attr "type" "mulmac_600")
2160    (set_attr "predicable" "no")
2161    (set_attr "cond" "nocond")])
2163 (define_insn "mac_600"
2164   [(set (match_operand:SI 2 "acc2_operand" "")
2165         (plus:SI
2166           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2167                    (ashift:SI
2168                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2169                                       (const_int 16)
2170                                       (const_int 16))
2171                      (const_int 16)))
2172           (match_dup 2)))
2173    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2174   "TARGET_MULMAC_32BY16_SET"
2175   "machlw%?\\t0,%0,%1"
2176   [(set_attr "length" "4,4,8")
2177    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2178    (set_attr "predicable" "no, no, yes")
2179    (set_attr "cond" "nocond, canuse_limm, canuse")])
2181 ; The gcc-internal representation may differ from the hardware
2182 ; register number in order to allow the generic code to correctly
2183 ; split the concatenation of mhi and mlo.
2184 (define_insn_and_split "mulsi64"
2185  [(set (match_operand:SI 0 "register_operand"            "=w")
2186         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
2187                  (match_operand:SI 2 "nonmemory_operand" "ci")))
2188   (clobber (reg:DI MUL64_OUT_REG))]
2189  "TARGET_MUL64_SET"
2190  "#"
2191  "TARGET_MUL64_SET && reload_completed"
2192   [(const_int 0)]
2193   {
2194    rtx mhi = gen_rtx_REG (SImode, R59_REG);
2195    rtx mlo = gen_rtx_REG (SImode, R58_REG);
2196    emit_insn (gen_mulsi_600 (operands[1], operands[2], mlo, mhi));
2197    emit_move_insn (operands[0], mlo);
2198    DONE;
2199   }
2200   [(set_attr "type" "multi")
2201    (set_attr "length" "8")])
2203 (define_insn "mulsi_600"
2204   [(set (match_operand:SI 2 "mlo_operand" "")
2205         (mult:SI (match_operand:SI 0 "register_operand" "%q,c,c,c")
2206                  (match_operand:SI 1 "nonmemory_operand" "q,cL,I,Cal")))
2207    (clobber (match_operand:SI 3 "mhi_operand" ""))]
2208   "TARGET_MUL64_SET"
2209   "mul64%?\\t0,%0,%1"
2210   [(set_attr "length" "*,4,4,8")
2211    (set_attr "iscompact" "maybe,false,false,false")
2212    (set_attr "type" "multi,multi,multi,multi")
2213    (set_attr "predicable" "yes,yes,no,yes")
2214    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2216 (define_insn_and_split "mulsidi_600"
2217   [(set (match_operand:DI 0 "register_operand"                           "=r,r,  r")
2218         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "%r,r,  r"))
2219                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "rL,L,C32"))))
2220    (clobber (reg:DI R58_REG))]
2221   "TARGET_MUL64_SET"
2222   "#"
2223   "TARGET_MUL64_SET && reload_completed"
2224   [(const_int 0)]
2226    int hi = !TARGET_BIG_ENDIAN;
2227    int lo = !hi;
2228    rtx lr = operand_subword (operands[0], lo, 0, DImode);
2229    rtx hr = operand_subword (operands[0], hi, 0, DImode);
2230    emit_insn (gen_mul64 (operands[1], operands[2]));
2231    emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2232    emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2233    DONE;
2235   [(set_attr "type" "multi")
2236    (set_attr "length" "4,4,8")])
2238 (define_insn "mul64"
2239   [(set (reg:DI MUL64_OUT_REG)
2240         (mult:DI
2241          (sign_extend:DI (match_operand:SI 0 "register_operand" "%q, c,c,  c"))
2242          (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "q,cL,L,C32"))))]
2243   "TARGET_MUL64_SET"
2244   "mul64%?\\t0,%0,%1"
2245   [(set_attr "length" "*,4,4,8")
2246    (set_attr "iscompact" "maybe,false,false,false")
2247    (set_attr "type" "multi,multi,multi,multi")
2248    (set_attr "predicable" "yes,yes,no,yes")
2249    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2251 (define_insn_and_split "umulsidi_600"
2252   [(set (match_operand:DI 0 "register_operand"                            "=r,r, r")
2253         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"   "%r,r, r"))
2254                  (zero_extend:DI (match_operand:SI 2 "nonmemory_operand"  "rL,L,C32"))))
2255    (clobber (reg:DI R58_REG))]
2256   "TARGET_MUL64_SET"
2257   "#"
2258   "TARGET_MUL64_SET && reload_completed"
2259   [(const_int 0)]
2261    int hi = !TARGET_BIG_ENDIAN;
2262    int lo = !hi;
2263    rtx lr = operand_subword (operands[0], lo, 0, DImode);
2264    rtx hr = operand_subword (operands[0], hi, 0, DImode);
2265    emit_insn (gen_mulu64 (operands[1], operands[2]));
2266    emit_move_insn (lr, gen_rtx_REG (SImode, R58_REG));
2267    emit_move_insn (hr, gen_rtx_REG (SImode, R59_REG));
2268    DONE;
2270   [(set_attr "type" "umulti")
2271    (set_attr "length" "4,4,8")])
2273 (define_insn "mulu64"
2274   [(set (reg:DI MUL64_OUT_REG)
2275         (mult:DI
2276          (zero_extend:DI (match_operand:SI 0 "register_operand"  "%c,c,c"))
2277          (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2278   "TARGET_MUL64_SET"
2279   "mulu64%?\\t0,%0,%1"
2280   [(set_attr "length" "4,4,8")
2281    (set_attr "iscompact" "false")
2282    (set_attr "type" "umulti")
2283    (set_attr "predicable" "yes,no,yes")
2284    (set_attr "cond" "canuse,canuse_limm,canuse")])
2286 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2287 ; may not be used as destination constraint.
2289 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2290 ; but mpyu is faster for the standard multiplier.
2291 ; Note: we must make sure LP_COUNT is not one of the destination
2292 ; registers, since it cannot be the destination of a multi-cycle insn
2293 ; like MPY or MPYU.
2294 (define_insn "mulsi3_700"
2295  [(set (match_operand:SI 0 "register_operand"            "=r, r,r,  r,r")
2296         (mult:SI (match_operand:SI 1 "register_operand"  "%0, r,0,  0,r")
2297                  (match_operand:SI 2 "nonmemory_operand" "rL,rL,I,Cal,Cal")))]
2298  "TARGET_ARC700_MPY"
2299   "mpyu%?\\t%0,%1,%2"
2300   [(set_attr "length" "4,4,4,8,8")
2301    (set_attr "type" "umulti")
2302    (set_attr "predicable" "yes,no,no,yes,no")
2303    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2305 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2306 ; short variant. LP_COUNT constraints are still valid.
2307 (define_insn "mulsi3_v2"
2308  [(set (match_operand:SI 0 "register_operand"            "=q,q, r, r,r,  r,  r")
2309         (mult:SI (match_operand:SI 1 "register_operand"  "%0,q, 0, r,0,  0,  r")
2310                  (match_operand:SI 2 "nonmemory_operand"  "q,0,rL,rL,I,Cal,Cal")))]
2311  "TARGET_MULTI"
2312  "@
2313   mpy%?\\t%0,%1,%2
2314   mpy%?\\t%0,%2,%1
2315   mpy%?\\t%0,%1,%2
2316   mpy%?\\t%0,%1,%2
2317   mpy%?\\t%0,%1,%2
2318   mpy%?\\t%0,%1,%2
2319   mpy%?\\t%0,%1,%2"
2320  [(set_attr "length" "*,*,4,4,4,8,8")
2321   (set_attr "iscompact" "maybe,maybe,false,false,false,false,false")
2322   (set_attr "type" "umulti")
2323   (set_attr "predicable" "no,no,yes,no,no,yes,no")
2324   (set_attr "cond" "nocond,nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2326 (define_expand "mulsidi3"
2327   [(set (match_operand:DI 0 "register_operand" "")
2328         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2329                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2330   "TARGET_ANY_MPY"
2331   {
2332   if (TARGET_PLUS_MACD)
2333     {
2334      if (CONST_INT_P (operands[2]))
2335        {
2336         emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2337        }
2338      else
2339        {
2340         emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2341        }
2342      DONE;
2343     }
2344   if (TARGET_MPY)
2345     {
2346       operands[2] = force_reg (SImode, operands[2]);
2347       if (!register_operand (operands[0], DImode))
2348         {
2349           rtx result = gen_reg_rtx (DImode);
2351           operands[2] = force_reg (SImode, operands[2]);
2352           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2353           emit_move_insn (operands[0], result);
2354           DONE;
2355         }
2356     }
2357   else if (TARGET_MUL64_SET)
2358     {
2359       emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2360       DONE;
2361     }
2362   else if (TARGET_MULMAC_32BY16_SET)
2363     {
2364       operands[2] = force_reg (SImode, operands[2]);
2365       emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2366       DONE;
2367     }
2368   operands[2] = force_reg (SImode, operands[2]);
2369   })
2371 (define_insn_and_split "mulsidi64"
2372   [(set (match_operand:DI 0 "register_operand" "=w")
2373         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2374                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2375    (clobber (reg:DI MUL32x16_REG))]
2376   "TARGET_MULMAC_32BY16_SET"
2377   "#"
2378   "TARGET_MULMAC_32BY16_SET && reload_completed"
2379   [(const_int 0)]
2380   {
2381    rtx result_hi = gen_highpart (SImode, operands[0]);
2382    rtx result_low = gen_lowpart (SImode, operands[0]);
2384    emit_insn (gen_mul64_600 (operands[1], operands[2]));
2385    emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2386    emit_move_insn (result_low, gen_acc2 ());
2387    DONE;
2388   }
2389   [(set_attr "type" "multi")
2390    (set_attr "length" "8")])
2393 (define_insn "mul64_600"
2394   [(set (reg:DI MUL32x16_REG)
2395         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2396                                   "c,c,c"))
2397                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2398                                   "c,L,Cal")
2399                                   (const_int 16)
2400                                   (const_int 0))))
2401   ]
2402   "TARGET_MULMAC_32BY16_SET"
2403   "mullw%?\\t0,%0,%1"
2404   [(set_attr "length" "4,4,8")
2405    (set_attr "type" "mulmac_600")
2406    (set_attr "predicable" "no,no,yes")
2407    (set_attr "cond" "nocond, canuse_limm, canuse")])
2410 ;; ??? check if this is canonical rtl
2411 (define_insn "mac64_600"
2412   [(set (reg:DI MUL32x16_REG)
2413         (plus:DI
2414           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2415                    (ashift:DI
2416                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2417                                       (const_int 16) (const_int 16))
2418                      (const_int 16)))
2419           (reg:DI MUL32x16_REG)))
2420    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2421         (zero_extract:SI
2422           (plus:DI
2423             (mult:DI (sign_extend:DI (match_dup 1))
2424                      (ashift:DI
2425                        (sign_extract:DI (match_dup 2)
2426                                         (const_int 16) (const_int 16))
2427                           (const_int 16)))
2428             (reg:DI MUL32x16_REG))
2429           (const_int 32) (const_int 32)))]
2430   "TARGET_MULMAC_32BY16_SET"
2431   "machlw%?\\t%0,%1,%2"
2432   [(set_attr "length" "4,4,8")
2433    (set_attr "type" "mulmac_600")
2434    (set_attr "predicable" "no,no,yes")
2435    (set_attr "cond" "nocond, canuse_limm, canuse")])
2438 ;; DI <- DI(signed SI) * DI(signed SI)
2439 (define_insn_and_split "mulsidi3_700"
2440   [(set (match_operand:DI 0 "register_operand" "=&r")
2441         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2442                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2443   "TARGET_MPY && !TARGET_PLUS_MACD"
2444   "#"
2445   "&& reload_completed"
2446   [(const_int 0)]
2448   int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2449   int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2450   rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2451   rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2452   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2453   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2454   DONE;
2456   [(set_attr "type" "multi")
2457    (set_attr "length" "8")])
2459 (define_insn "mulsi3_highpart"
2460   [(set (match_operand:SI 0 "register_operand"                    "=r,r,r,r")
2461         (truncate:SI
2462          (lshiftrt:DI
2463           (mult:DI
2464            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2465            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "r,r,i,i")))
2466           (const_int 32))))]
2467   "TARGET_MPY"
2468   "mpy%+%?\\t%0,%1,%2"
2469   [(set_attr "length" "4,4,8,8")
2470    (set_attr "type" "multi")
2471    (set_attr "predicable" "yes,no,yes,no")
2472    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2474 ; Note that mpyhu has the same latency as mpy / mpyh,
2475 ; thus we use the type multi.
2476 (define_insn "*umulsi3_highpart_i"
2477   [(set (match_operand:SI 0 "register_operand"                    "=r,r,r,r")
2478         (truncate:SI
2479          (lshiftrt:DI
2480           (mult:DI
2481            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,0,r"))
2482            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "r,r,i,i")))
2483           (const_int 32))))]
2484   "TARGET_MPY"
2485   "mpy%+u%?\\t%0,%1,%2"
2486   [(set_attr "length" "4,4,8,8")
2487    (set_attr "type" "multi")
2488    (set_attr "predicable" "yes,no,yes,no")
2489    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2491 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2492 ;; need a separate pattern for immediates
2493 ;; ??? This is fine for combine, but not for reload.
2494 (define_insn "umulsi3_highpart_int"
2495   [(set (match_operand:SI 0 "register_operand"            "=r, r, r,r,  r")
2496         (truncate:SI
2497          (lshiftrt:DI
2498           (mult:DI
2499            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, r, 0,  0,  r"))
2500            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I,Cal,Cal"))
2501           (const_int 32))))]
2502   "TARGET_MPY"
2503   "mpy%+u%?\\t%0,%1,%2"
2504   [(set_attr "length" "4,4,4,8,8")
2505    (set_attr "type" "multi")
2506    (set_attr "predicable" "yes,no,no,yes,no")
2507    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2509 (define_expand "umulsi3_highpart"
2510   [(set (match_operand:SI 0 "general_operand"  "")
2511         (truncate:SI
2512          (lshiftrt:DI
2513           (mult:DI
2514            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2515            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2516           (const_int 32))))]
2517   "TARGET_MPY"
2518   "
2520   rtx target = operands[0];
2522   if (!register_operand (target, SImode))
2523     target = gen_reg_rtx (SImode);
2525   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2526     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2527                                                   operands[2], SImode);
2528   else if (!immediate_operand (operands[2], SImode))
2529     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2530   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2531   if (target != operands[0])
2532     emit_move_insn (operands[0], target);
2533   DONE;
2536 (define_expand "umulsidi3"
2537   [(set (match_operand:DI 0 "register_operand" "")
2538         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2539                  (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2540   "TARGET_ANY_MPY"
2542   if (TARGET_PLUS_MACD)
2543     {
2544      if (CONST_INT_P (operands[2]))
2545        {
2546         emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2547        }
2548      else
2549        {
2550         emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2551        }
2552      DONE;
2553     }
2554   if (TARGET_MPY)
2555     {
2556       operands[2] = force_reg (SImode, operands[2]);
2557       if (!register_operand (operands[0], DImode))
2558         {
2559           rtx result = gen_reg_rtx (DImode);
2561           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2562           emit_move_insn (operands[0], result);
2563           DONE;
2564         }
2565     }
2566   else if (TARGET_MUL64_SET)
2567     {
2568      operands[2] = force_reg (SImode, operands[2]);
2569      emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2570       DONE;
2571     }
2572   else if (TARGET_MULMAC_32BY16_SET)
2573     {
2574      operands[2] = force_reg (SImode, operands[2]);
2575      emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2576       DONE;
2577     }
2578   else
2579   {
2580    gcc_unreachable ();
2581     }
2584 (define_insn_and_split "umulsidi64"
2585   [(set (match_operand:DI 0 "register_operand" "=w")
2586         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2587                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2588    (clobber (reg:DI MUL32x16_REG))]
2589   "TARGET_MULMAC_32BY16_SET"
2590   "#"
2591   "TARGET_MULMAC_32BY16_SET && reload_completed"
2592   [(const_int 0)]
2593   {
2594    rtx result_hi;
2595    rtx result_low;
2597    result_hi = gen_highpart (SImode, operands[0]);
2598    result_low = gen_lowpart (SImode, operands[0]);
2600    emit_insn (gen_umul64_600 (operands[1], operands[2]));
2601    emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2602    emit_move_insn (result_low, gen_acc2 ());
2603    DONE;
2604    }
2605   [(set_attr "type" "multi")
2606    (set_attr "length" "8")])
2608 (define_insn "umul64_600"
2609   [(set (reg:DI MUL32x16_REG)
2610         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2611                                   "c,c,c"))
2612                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2613                                   "c,L,Cal")
2614                                   (const_int 16)
2615                                   (const_int 0))))
2616   ]
2617   "TARGET_MULMAC_32BY16_SET"
2618   "mululw\\t0,%0,%1"
2619   [(set_attr "length" "4,4,8")
2620    (set_attr "type" "mulmac_600")
2621    (set_attr "predicable" "no")
2622    (set_attr "cond" "nocond")])
2625 (define_insn "umac64_600"
2626   [(set (reg:DI MUL32x16_REG)
2627         (plus:DI
2628           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2629                    (ashift:DI
2630                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2631                                       (const_int 16) (const_int 16))
2632                      (const_int 16)))
2633           (reg:DI MUL32x16_REG)))
2634    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2635         (zero_extract:SI
2636           (plus:DI
2637             (mult:DI (zero_extend:DI (match_dup 1))
2638                      (ashift:DI
2639                        (zero_extract:DI (match_dup 2)
2640                                         (const_int 16) (const_int 16))
2641                           (const_int 16)))
2642             (reg:DI MUL32x16_REG))
2643           (const_int 32) (const_int 32)))]
2644   "TARGET_MULMAC_32BY16_SET"
2645   "machulw%?\\t%0,%1,%2"
2646   [(set_attr "length" "4,4,8")
2647    (set_attr "type" "mulmac_600")
2648    (set_attr "predicable" "no,no,yes")
2649    (set_attr "cond" "nocond, canuse_limm, canuse")])
2651 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2652 (define_insn_and_split "umulsidi3_700"
2653   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2654         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2655                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2656   "TARGET_MPY && !TARGET_PLUS_MACD"
2657   "#"
2658   "TARGET_MPY && !TARGET_PLUS_MACD && reload_completed"
2659   [(const_int 0)]
2661   int hi = !TARGET_BIG_ENDIAN;
2662   int lo = !hi;
2663   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2664   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2665   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2666   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2667   DONE;
2669   [(set_attr "type" "umulti")
2670   (set_attr "length" "8")])
2672 (define_expand "addsi3"
2673   [(set (match_operand:SI 0 "dest_reg_operand" "")
2674         (plus:SI (match_operand:SI 1 "register_operand" "")
2675                  (match_operand:SI 2 "nonmemory_operand" "")))]
2676   ""
2678   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2679     operands[2] = force_reg (SImode, operands[2]);
2682 (define_expand "adddi3"
2683   [(parallel
2684       [(set (match_operand:DI 0 "register_operand" "")
2685             (plus:DI (match_operand:DI 1 "register_operand" "")
2686                      (match_operand:DI 2 "nonmemory_operand" "")))
2687        (clobber (reg:CC CC_REG))])])
2689 (define_insn_and_split "*adddi3"
2690   [(set (match_operand:DI 0 "register_operand" "")
2691         (plus:DI (match_operand:DI 1 "register_operand" "")
2692                  (match_operand:DI 2 "nonmemory_operand" "")))
2693    (clobber (reg:CC CC_REG))]
2694   "arc_pre_reload_split ()"
2695   "#"
2696   "&& 1"
2697   [(const_int 0)]
2699   rtx l0 = gen_lowpart (SImode, operands[0]);
2700   rtx h0 = gen_highpart (SImode, operands[0]);
2701   rtx l1 = gen_lowpart (SImode, operands[1]);
2702   rtx h1 = gen_highpart (SImode, operands[1]);
2703   rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2704                                 subreg_lowpart_offset (SImode, DImode));
2705   rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2706                                 subreg_highpart_offset (SImode, DImode));
2708   if (l2 == const0_rtx)
2709     {
2710       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2711         emit_move_insn (l0, l1);
2712       emit_insn (gen_addsi3 (h0, h1, h2));
2713       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2714         emit_move_insn (l0, l1);
2715       DONE;
2716     }
2717   if (rtx_equal_p (l0, h1))
2718     {
2719       if (h2 != const0_rtx)
2720         emit_insn (gen_addsi3 (h0, h1, h2));
2721       else if (!rtx_equal_p (h0, h1))
2722         emit_move_insn (h0, h1);
2723       emit_insn (gen_add_f (l0, l1, l2));
2724       emit_insn
2725         (gen_rtx_COND_EXEC
2726           (VOIDmode,
2727            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2728            gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2729       DONE;
2730     }
2731   emit_insn (gen_add_f (l0, l1, l2));
2732   emit_insn (gen_adc (h0, h1, h2));
2733   DONE;
2735   [(set_attr "length" "8")])
2737 (define_insn "add_f"
2738   [(set (reg:CC_C CC_REG)
2739         (compare:CC_C
2740           (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,L,0,I,Cal,r")
2741                    (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0,  r,rCal"))
2742           (match_dup 1)))
2743    (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2744         (plus:SI (match_dup 1) (match_dup 2)))]
2745   "register_operand (operands[1], SImode)
2746    || register_operand (operands[2], SImode)"
2747   "@
2748   add.f\\t%0,%1,%2
2749   add.f\\t%0,%2,%1
2750   add.f\\t%0,%1,%2
2751   add.f\\t%0,%2,%1
2752   add.f\\t%0,%2,%1
2753   add.f\\t%0,%1,%2"
2754   [(set_attr "cond" "set")
2755    (set_attr "type" "compare")
2756    (set_attr "length" "4,4,4,4,8,8")])
2758 (define_insn "*add_f_2"
2759   [(set (reg:CC_C CC_REG)
2760         (compare:CC_C
2761           (plus:SI (match_operand:SI 1 "register_operand"  "r ,0,r")
2762                    (match_operand:SI 2 "nonmemory_operand" "rL,I,rCal"))
2763           (match_dup 2)))
2764    (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
2765         (plus:SI (match_dup 1) (match_dup 2)))]
2766   ""
2767   "add.f\\t%0,%1,%2"
2768   [(set_attr "cond" "set")
2769    (set_attr "type" "compare")
2770    (set_attr "length" "4,4,8")])
2772 (define_insn "adc"
2773   [(set (match_operand:SI 0 "register_operand"    "=r,  r,r,r,  r,r")
2774         (plus:SI
2775          (plus:SI
2776           (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2777           (match_operand:SI 1 "nonmemory_operand" "%r,  0,r,0,Cal,r"))
2778          (match_operand:SI 2 "nonmemory_operand"   "r,C_0,L,I,  r,Cal")))]
2779   "register_operand (operands[1], SImode)
2780    || register_operand (operands[2], SImode)"
2781   "@
2782     adc\\t%0,%1,%2
2783     add.cs\\t%0,%1,1
2784     adc\\t%0,%1,%2
2785     adc\\t%0,%1,%2
2786     adc\\t%0,%1,%2
2787     adc\\t%0,%1,%2"
2788   [(set_attr "cond" "use")
2789    (set_attr "type" "cc_arith")
2790    (set_attr "length" "4,4,4,4,8,8")])
2792 (define_insn "adc_f"
2793   [(set (reg:CC_C CC_REG)
2794         (compare:CC_C
2795           (zero_extend:DI
2796             (plus:SI
2797               (plus:SI
2798                 (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2799                 (match_operand:SI 1 "register_operand" "%r"))
2800               (match_operand:SI 2 "register_operand" "r")))
2801           (plus:DI
2802             (ltu:DI (reg:CC_C CC_REG) (const_int 0))
2803             (zero_extend:DI (match_dup 1)))))
2804    (set (match_operand:SI 0 "register_operand" "=r")
2805         (plus:SI
2806           (plus:SI
2807             (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2808             (match_dup 1))
2809           (match_dup 2)))]
2810   ""
2811   "adc.f\\t%0,%1,%2"
2812   [(set_attr "cond" "set")
2813    (set_attr "predicable" "no")
2814    (set_attr "type" "cc_arith")
2815    (set_attr "length" "4")])
2817 ; combiner-splitter cmp / scc -> cmp / adc
2818 (define_split
2819   [(set (match_operand:SI 0 "dest_reg_operand" "")
2820         (gtu:SI (match_operand:SI 1 "register_operand" "")
2821                 (match_operand:SI 2 "register_operand" "")))
2822    (clobber (reg CC_REG))]
2823   ""
2824   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2825    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2827 ; combine won't work when an intermediate result is used later...
2828 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2829 (define_peephole2
2830   [(set (match_operand:SI 0 "dest_reg_operand" "")
2831         (plus:SI (match_operand:SI 1 "register_operand" "")
2832                  (match_operand:SI 2 "nonmemory_operand" "")))
2833    (set (reg:CC_C CC_REG)
2834         (compare:CC_C (match_dup 0)
2835                       (match_operand:SI 3 "nonmemory_operand" "")))]
2836   "rtx_equal_p (operands[1], operands[3])
2837    || rtx_equal_p (operands[2], operands[3])"
2838   [(parallel
2839      [(set (reg:CC_C CC_REG)
2840            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2841       (set (match_dup 0)
2842            (plus:SI (match_dup 1) (match_dup 2)))])])
2844 ; ??? need to delve into combine to find out why this is not useful.
2845 ; We'd like to be able to grok various C idioms for carry bit usage.
2846 ;(define_insn "*adc_0"
2847 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2848 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2849 ;                (match_operand:SI 1 "register_operand" "c")))]
2850 ;  ""
2851 ;  "adc\\t%0,%1,0"
2852 ;  [(set_attr "cond" "use")
2853 ;   (set_attr "type" "cc_arith")
2854 ;   (set_attr "length" "4")])
2856 ;(define_split
2857 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2858 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2859 ;                        (match_operand:SI 2 "register_operand" "c"))
2860 ;                (match_operand:SI 3 "register_operand" "c")))
2861 ;   (clobber (reg CC_REG))]
2862 ;  ""
2863 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2864 ;   (set (match_dup 0)
2865 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2866 ;                (match_dup 3)))])
2868 (define_expand "subsi3"
2869   [(set (match_operand:SI 0 "dest_reg_operand" "")
2870         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2871                  (match_operand:SI 2 "nonmemory_operand" "")))]
2872   ""
2873   "
2875   int c = 1;
2877   if (!register_operand (operands[2], SImode))
2878     {
2879       operands[1] = force_reg (SImode, operands[1]);
2880       c = 2;
2881     }
2882   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2883     operands[c] = force_reg (SImode, operands[c]);
2886 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2887 ; combine should make such an insn go away.
2888 (define_insn_and_split "subsi3_insn"
2889   [(set (match_operand:SI 0 "dest_reg_operand"           "=q,q,r, r,r,r,r,  r,  r,  r")
2890         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,q,0,rL,r,L,I,Cal,Cal,  r")
2891                   (match_operand:SI 2 "nonmemory_operand" "q,q,r, 0,r,r,0,  0,  r,Cal")))]
2892   "register_operand (operands[1], SImode)
2893    || register_operand (operands[2], SImode)"
2894   "@
2895     sub%?\\t%0,%1,%2
2896     sub%?\\t%0,%1,%2
2897     sub%?\\t%0,%1,%2
2898     rsub%?\\t%0,%2,%1
2899     sub\\t%0,%1,%2
2900     rsub\\t%0,%2,%1
2901     rsub\\t%0,%2,%1
2902     rsub%?\\t%0,%2,%1
2903     rsub\\t%0,%2,%1
2904     sub\\t%0,%1,%2"
2905   "reload_completed && get_attr_length (insn) == 8
2906    && satisfies_constraint_I (operands[1])
2907    && GET_CODE (PATTERN (insn)) != COND_EXEC"
2908   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2909   "split_subsi (operands);"
2910   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2911   (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2912   (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2913   (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2914   (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2915   ])
2917 (define_expand "subdi3"
2918   [(set (match_operand:DI 0 "register_operand" "")
2919         (minus:DI (match_operand:DI 1 "register_operand" "")
2920                   (match_operand:DI 2 "nonmemory_operand" "")))
2921    (clobber (reg:CC CC_REG))]
2922   ""
2923   "
2924   rtx l0 = gen_lowpart (SImode, operands[0]);
2925   rtx h0 = gen_highpart (SImode, operands[0]);
2926   rtx l1 = gen_lowpart (SImode, operands[1]);
2927   rtx h1 = gen_highpart (SImode, operands[1]);
2928   rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode,
2929                                 subreg_lowpart_offset (SImode, DImode));
2930   rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode,
2931                                 subreg_highpart_offset (SImode, DImode));
2933   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2934     {
2935       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2936       if (!rtx_equal_p (h0, h1))
2937         emit_insn (gen_rtx_SET (h0, h1));
2938       emit_insn (gen_sub_f (l0, l1, l2));
2939       emit_insn
2940         (gen_rtx_COND_EXEC
2941           (VOIDmode,
2942            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2943            gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2944       DONE;
2945     }
2946   emit_insn (gen_sub_f (l0, l1, l2));
2947   emit_insn (gen_sbc (h0, h1, h2));
2948   DONE;
2949   ")
2951 (define_insn "*sbc_0"
2952   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2953         (minus:SI (match_operand:SI 1 "register_operand" "c")
2954                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2955                           (const_int 0))))]
2956   ""
2957   "sbc\\t%0,%1,0"
2958   [(set_attr "cond" "use")
2959    (set_attr "type" "cc_arith")
2960    (set_attr "length" "4")])
2962 (define_insn "sbc"
2963   [(set (match_operand:SI 0 "dest_reg_operand"   "=r,r,r,r,r,r")
2964         (minus:SI
2965          (minus:SI
2966           (match_operand:SI 1 "nonmemory_operand" "r,  0,r,0,  r,Cal")
2967           (ltu:SI (reg:CC_C CC_REG) (const_int 0)))
2968          (match_operand:SI 2 "nonmemory_operand"  "r,C_0,L,I,Cal,r")))]
2969   "register_operand (operands[1], SImode)
2970    || register_operand (operands[2], SImode)"
2971   "@
2972     sbc\\t%0,%1,%2
2973     sub.cs\\t%0,%1,1
2974     sbc\\t%0,%1,%2
2975     sbc\\t%0,%1,%2
2976     sbc\\t%0,%1,%2
2977     sbc\\t%0,%1,%2"
2978   [(set_attr "cond" "use")
2979    (set_attr "type" "cc_arith")
2980    (set_attr "length" "4,4,4,4,8,8")])
2982 (define_insn "sub_f"
2983   [(set (reg:CC CC_REG)
2984         (compare:CC (match_operand:SI 1 "nonmemory_operand" " r,L,0,I,r,Cal")
2985                     (match_operand:SI 2 "nonmemory_operand" "rL,r,I,0,Cal,r")))
2986    (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r,r,r,r")
2987         (minus:SI (match_dup 1) (match_dup 2)))]
2988   "register_operand (operands[1], SImode)
2989    || register_operand (operands[2], SImode)"
2990   "@
2991         sub.f\\t%0,%1,%2
2992         rsub.f\\t%0,%2,%1
2993         sub.f\\t%0,%1,%2
2994         rsub.f\\t%0,%2,%1
2995         sub.f\\t%0,%1,%2
2996         sub.f\\t%0,%1,%2"
2997   [(set_attr "type" "compare")
2998    (set_attr "length" "4,4,4,4,8,8")])
3000 ; combine won't work when an intermediate result is used later...
3001 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3002 (define_peephole2
3003   [(set (reg:CC CC_REG)
3004         (compare:CC (match_operand:SI 1 "register_operand" "")
3005                     (match_operand:SI 2 "nonmemory_operand" "")))
3006    (set (match_operand:SI 0 "dest_reg_operand" "")
3007         (minus:SI (match_dup 1) (match_dup 2)))]
3008   ""
3009   [(parallel
3010      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3011       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3013 (define_peephole2
3014   [(set (reg:CC CC_REG)
3015         (compare:CC (match_operand:SI 1 "register_operand" "")
3016                     (match_operand:SI 2 "nonmemory_operand" "")))
3017    (set (match_operand 3 "" "") (match_operand 4 "" ""))
3018    (set (match_operand:SI 0 "dest_reg_operand" "")
3019         (minus:SI (match_dup 1) (match_dup 2)))]
3020   "!reg_overlap_mentioned_p (operands[3], operands[1])
3021    && !reg_overlap_mentioned_p (operands[3], operands[2])
3022    && !reg_overlap_mentioned_p (operands[0], operands[4])
3023    && !reg_overlap_mentioned_p (operands[0], operands[3])"
3024   [(parallel
3025      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3026       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3027    (set (match_dup 3) (match_dup 4))])
3029 (define_insn "*add_n"
3030   [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
3031         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
3032                           (match_operand:SI 2 "_2_4_8_operand" ""))
3033                  (match_operand:SI 3 "arc_nonmemory_operand" "0,r,Csz")))]
3034   ""
3035   "add%z2%?\\t%0,%3,%1"
3036   [(set_attr "type" "shift")
3037    (set_attr "length" "*,4,8")
3038    (set_attr "predicable" "yes,no,no")
3039    (set_attr "cond" "canuse,nocond,nocond")
3040    (set_attr "iscompact" "maybe,false,false")])
3042 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3043 ;; what synth_mult likes.
3044 (define_insn "*sub_n"
3045   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3046         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3047                   (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
3048                              (match_operand:SI 3 "_1_2_3_operand" ""))))]
3049   ""
3050   "sub%c3%?\\t%0,%1,%2"
3051   [(set_attr "type" "shift")
3052    (set_attr "length" "4,4,8")
3053    (set_attr "predicable" "yes,no,no")
3054    (set_attr "cond" "canuse,nocond,nocond")
3055    (set_attr "iscompact" "false")])
3057 (define_insn "*sub_n"
3058   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3059         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,?Cal")
3060                   (mult:SI (match_operand:SI 2 "register_operand" "r,r,r")
3061                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
3062   ""
3063   "sub%z3%?\\t%0,%1,%2"
3064   [(set_attr "type" "shift")
3065    (set_attr "length" "4,4,8")
3066    (set_attr "predicable" "yes,no,no")
3067    (set_attr "cond" "canuse,nocond,nocond")
3068    (set_attr "iscompact" "false")])
3070 ; ??? check if combine matches this.
3071 (define_insn "*bset"
3072   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3073         (ior:SI (ashift:SI (const_int 1)
3074                            (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3075                 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3076   ""
3077   "bset%?\\t%0,%2,%1"
3078   [(set_attr "length" "4,4,8")
3079    (set_attr "predicable" "yes,no,no")
3080    (set_attr "cond" "canuse,nocond,nocond")]
3083 ; ??? check if combine matches this.
3084 (define_insn "*bxor"
3085   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3086         (xor:SI (ashift:SI (const_int 1)
3087                            (match_operand:SI 1 "nonmemory_operand" "rL,rL,r"))
3088                 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3089   ""
3090   "bxor%?\\t%0,%2,%1"
3091   [(set_attr "length" "4,4,8")
3092    (set_attr "predicable" "yes,no,no")
3093    (set_attr "cond" "canuse,nocond,nocond")]
3096 ; ??? check if combine matches this.
3097 (define_insn "*bclr"
3098   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3099         (and:SI (not:SI (ashift:SI (const_int 1)
3100                                    (match_operand:SI 1 "nonmemory_operand" "rL,rL,r")))
3101                 (match_operand:SI 2 "nonmemory_operand" "0,r,Cal")))]
3102   ""
3103   "bclr%?\\t%0,%2,%1"
3104   [(set_attr "length" "4,4,8")
3105    (set_attr "predicable" "yes,no,no")
3106    (set_attr "cond" "canuse,nocond,nocond")]
3109 ; ??? FIXME: find combine patterns for bmsk.
3111 ;;Following are the define_insns added for the purpose of peephole2's
3113 ; see also iorsi3 for use with constant bit number.
3114 (define_insn "*bset_insn"
3115   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3116         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3117                 (ashift:SI (const_int 1)
3118                            (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3119   ""
3120   "@
3121      bset%?\\t%0,%1,%2 ;;peep2, constr 1
3122      bset\\t%0,%1,%2 ;;peep2, constr 2
3123      bset\\t%0,%1,%2 ;;peep2, constr 3"
3124   [(set_attr "length" "4,4,8")
3125    (set_attr "predicable" "yes,no,no")
3126    (set_attr "cond" "canuse,nocond,nocond")]
3129 ; see also xorsi3 for use with constant bit number.
3130 (define_insn "*bxor_insn"
3131   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3132         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3133                 (ashift:SI (const_int 1)
3134                         (match_operand:SI 2 "nonmemory_operand" "rL,rL,r"))) ) ]
3135   ""
3136   "@
3137      bxor%?\\t%0,%1,%2
3138      bxor\\t%0,%1,%2
3139      bxor\\t%0,%1,%2"
3140   [(set_attr "length" "4,4,8")
3141    (set_attr "predicable" "yes,no,no")
3142    (set_attr "cond" "canuse,nocond,nocond")]
3145 ; see also andsi3 for use with constant bit number.
3146 (define_insn "*bclr_insn"
3147   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3148         (and:SI (not:SI (ashift:SI (const_int 1)
3149                                    (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")))
3150                 (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")))]
3151   ""
3152   "@
3153      bclr%?\\t%0,%1,%2
3154      bclr\\t%0,%1,%2
3155      bclr\\t%0,%1,%2"
3156   [(set_attr "length" "4,4,8")
3157    (set_attr "predicable" "yes,no,no")
3158    (set_attr "cond" "canuse,nocond,nocond")]
3161 ; see also andsi3 for use with constant bit number.
3162 (define_insn "*bmsk_insn"
3163   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
3164         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
3165                 (plus:SI (ashift:SI (const_int 1)
3166                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3167                                              (const_int 1)))
3168                          (const_int -1))))]
3169   ""
3170   "@
3171      bmsk%?\\t%0,%1,%2
3172      bmsk\\t%0,%1,%2
3173      bmsk\\t%0,%1,%2"
3174   [(set_attr "length" "4,4,8")
3175    (set_attr "predicable" "yes,no,no")
3176    (set_attr "cond" "canuse,nocond,nocond")]
3179 ;;Instructions added for peephole2s end
3181 ;; Boolean instructions.
3183 (define_expand "andsi3"
3184   [(set (match_operand:SI 0 "dest_reg_operand" "")
3185         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3186                 (match_operand:SI 2 "nonmemory_operand" "")))]
3187   ""
3188   "if (!satisfies_constraint_Cux (operands[2]))
3189      operands[1] = force_reg (SImode, operands[1]);
3190   ")
3192 (define_insn "andsi3_i"                                     ;0 1   2   3   4  5 6      7   8  9 10 11     12  13  14  15 16 17  18   19
3193   [(set (match_operand:SI 0 "dest_reg_operand"             "=q,q,  q,  q,  q, r,r,     r,  r,  r,r, r,     r,  r,  r,  q,r,  r,  r,  W")
3194         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,q,  0,  0,  q, 0,r,     0,  0,  0,0, r,     r,  r,  r,  q,0,  0,  r,  o")
3195                 (match_operand:SI 2 "nonmemory_operand"     "q,0,C1p,Ccp,Cux,rL,0,C2pC1p,Ccp,CnL,I,rL,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
3196   "(register_operand (operands[1], SImode)
3197     && nonmemory_operand (operands[2], SImode))
3198    || (memory_operand (operands[1], SImode)
3199        && satisfies_constraint_Cux (operands[2]))"
3201   switch (which_alternative)
3202     {
3203     case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3204       return "and%?\\t%0,%1,%2";
3205     case 1: case 6:
3206       return "and%?\\t%0,%2,%1";
3207     case 2:
3208       return "bmsk%?\\t%0,%1,%Z2";
3209     case 7: case 12:
3210      if (satisfies_constraint_C2p (operands[2]))
3211        {
3212         operands[2] = GEN_INT ((~INTVAL (operands[2])));
3213         return "bmskn%?\\t%0,%1,%Z2";
3214        }
3215      else
3216        {
3217         return "bmsk%?\\t%0,%1,%Z2";
3218        }
3219     case 3: case 8: case 13:
3220       return "bclr%?\\t%0,%1,%M2";
3221     case 4:
3222       return (INTVAL (operands[2]) == 0xff
3223               ? "extb%?\\t%0,%1" : "ext%_%?\\t%0,%1");
3224     case 9: case 14: return \"bic%?\\t%0,%1,%n2-1\";
3225     case 15:
3226       return "movb.cl\\t%0,%1,%p2,%p2,%x2";
3228     case 19:
3229       const char *tmpl;
3231       if (satisfies_constraint_Ucm (operands[1]))
3232         tmpl = (INTVAL (operands[2]) == 0xff
3233                 ? "xldb%U1\\t%0,%1" : "xld%_%U1\\t%0,%1");
3234       else
3235         tmpl = INTVAL (operands[2]) == 0xff ? "ldb\\t%0,%1" : "ld%_\\t%0,%1";
3237       if (TARGET_BIG_ENDIAN)
3238         {
3239           rtx xop[2];
3241           xop[0] = operands[0];
3242           xop[1] = adjust_address (operands[1], QImode,
3243                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
3244           output_asm_insn (tmpl, xop);
3245           return "";
3246         }
3247       return tmpl;
3248     default:
3249       gcc_unreachable ();
3250     }
3252   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3253    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3254    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3255    (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3256    (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3258 ; combiner splitter, pattern found in ldtoa.c .
3259 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3260 (define_split
3261   [(set (reg:CC_Z CC_REG)
3262         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3263                               (match_operand 1 "const_int_operand" ""))
3264                       (match_operand 2 "const_int_operand" "")))
3265    (clobber (match_operand:SI 3 "register_operand" ""))]
3266   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3267   [(set (match_dup 3)
3268         (plus:SI (match_dup 0) (match_dup 4)))
3269    (set (reg:CC_Z CC_REG)
3270         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3271                       (const_int 0)))]
3272   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3274 ;;bic define_insn that allows limm to be the first operand
3275 (define_insn "*bicsi3_insn"
3276    [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r,r,r,r,r")
3277         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "q,Lr,I,Cal,Lr,Cal,r"))
3278                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,r,r,Cal")))]
3279   ""
3280   "@
3281    bic%?\\t%0,%2,%1  ;;constraint 0
3282    bic%?\\t%0,%2,%1  ;;constraint 1
3283    bic\\t%0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
3284    bic%?\\t%0,%2,%1  ;;constraint 3, FIXME: will it ever get generated ???
3285    bic\\t%0,%2,%1    ;;constraint 4
3286    bic\\t%0,%2,%1    ;;constraint 5, FIXME: will it ever get generated ???
3287    bic\\t%0,%2,%1    ;;constraint 6"
3288   [(set_attr "length" "*,4,4,8,4,8,8")
3289   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3290   (set_attr "predicable" "no,yes,no,yes,no,no,no")
3291   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3293 (define_insn_and_split "iorsi3"
3294   [(set (match_operand:SI 0 "dest_reg_operand"          "=q,q,  q, r,r,  r,r, r,  r,r,  q,  r,  r")
3295         (ior:SI (match_operand:SI 1 "register_operand"  "%0,q,  0, 0,r,  0,0, r,  r,0,  r,  0,  r")
3296                 (match_operand:SI 2 "nonmemory_operand"  "q,0,C0p,rL,0,C0p,I,rL,C0p,I,C0x,Cal,Cal")))]
3297   ""
3298   "@
3299    or%?\\t%0,%1,%2
3300    or%?\\t%0,%2,%1
3301    bset%?\\t%0,%1,%z2
3302    or%?\\t%0,%1,%2
3303    or%?\\t%0,%2,%1
3304    bset%?\\t%0,%1,%z2
3305    or%?\\t%0,%1,%2
3306    or%?\\t%0,%1,%2
3307    bset%?\\t%0,%1,%z2
3308    or%?\\t%0,%1,%2
3309    #
3310    or%?\\t%0,%1,%2
3311    or%?\\t%0,%1,%2"
3312   "reload_completed
3313    && GET_CODE (PATTERN (insn)) != COND_EXEC
3314    && register_operand (operands[0], SImode)
3315    && IN_RANGE (REGNO (operands[0]) ^ 4, 4, 11)
3316    && satisfies_constraint_C0x (operands[2])"
3317   [(const_int 0)]
3318   "
3319    arc_split_ior (operands);
3320    DONE;
3321   "
3322   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,false")
3323    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,*,8,8")
3324    (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
3325    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,nocond,canuse,nocond")])
3327 (define_insn "xorsi3"
3328   [(set (match_operand:SI 0 "dest_reg_operand"         "=q,q, r,r,  r,r, r,  r,r,  r,  r")
3329         (xor:SI (match_operand:SI 1 "register_operand" "%0,q, 0,r,  0,0, r,  r,0,  0,  r")
3330                 (match_operand:SI 2 "nonmemory_operand" "q,0,rL,0,C0p,I,rL,C0p,I,Cal,Cal")))]
3331   ""
3332   "*
3333   switch (which_alternative)
3334     {
3335     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3336       return \"xor%?\\t%0,%1,%2\";
3337     case 1: case 3:
3338       return \"xor%?\\t%0,%2,%1\";
3339     case 4: case 7:
3340       return \"bxor%?\\t%0,%1,%z2\";
3341     default:
3342       gcc_unreachable ();
3343     }
3344   "
3345   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3346    (set_attr "type" "binary")
3347    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3348    (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3349    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3351 (define_insn "negsi2"
3352   [(set (match_operand:SI 0 "dest_reg_operand" "=q,q,r,r")
3353         (neg:SI (match_operand:SI 1 "register_operand" "0,q,0,r")))]
3354   ""
3355   "neg%?\\t%0,%1"
3356   [(set_attr "type" "unary")
3357    (set_attr "iscompact" "maybe,true,false,false")
3358    (set_attr "predicable" "no,no,yes,no")])
3360 (define_insn "one_cmplsi2"
3361   [(set (match_operand:SI 0 "dest_reg_operand" "=q,w")
3362         (not:SI (match_operand:SI 1 "register_operand" "q,c")))]
3363   ""
3364   "not%?\\t%0,%1"
3365   [(set_attr "type" "unary,unary")
3366    (set_attr "iscompact" "true,false")])
3368 (define_insn_and_split "one_cmpldi2"
3369   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3370         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3371   ""
3372   "#"
3373   "&& reload_completed"
3374   [(set (match_dup 2) (not:SI (match_dup 3)))
3375    (set (match_dup 4) (not:SI (match_dup 5)))]
3377   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3379   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3380   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3381   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3382   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3384   [(set_attr "type" "unary,unary")
3385    (set_attr "cond" "nocond,nocond")
3386    (set_attr "length" "4,8")])
3388 ;; Shift instructions.
3390 (define_code_iterator ANY_ROTATE [rotate rotatert])
3391 (define_code_iterator ANY_SHIFT_ROTATE [ashift ashiftrt lshiftrt
3392                                         rotate rotatert])
3394 (define_code_attr insn [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")
3395                         (rotate "rotl") (rotatert "rotr")])
3397 (define_expand "<insn>si3"
3398   [(set (match_operand:SI 0 "dest_reg_operand" "")
3399         (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand" "")
3400                              (match_operand:SI 2 "nonmemory_operand" "")))]
3401   "")
3403 ; asl, asr, lsr patterns:
3404 ; There is no point in including an 'I' alternative since only the lowest 5
3405 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3406 ; is defined in an external symbol, as we don't have special relocations
3407 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3408 ; provide one alternatice for this, without condexec support.
3409 (define_insn "*ashlsi3_insn"
3410   [(set (match_operand:SI 0 "dest_reg_operand"                 "=q,q, q, r, r,   r")
3411         (ashift:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3412                    (match_operand:SI 2 "nonmemory_operand"      "K,K,qM,rL,rL,rCal")))]
3413   "TARGET_BARREL_SHIFTER
3414    && (register_operand (operands[1], SImode)
3415        || register_operand (operands[2], SImode))"
3416   "asl%?\\t%0,%1,%2"
3417   [(set_attr "type" "shift")
3418    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3419    (set_attr "predicable" "no,no,no,yes,no,no")
3420    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3422 (define_insn "*ashrsi3_insn"
3423   [(set (match_operand:SI 0 "dest_reg_operand"                   "=q,q, q, r, r,   r")
3424         (ashiftrt:SI (match_operand:SI 1 "arc_nonmemory_operand" "!0,q, 0, 0, r,rCsz")
3425                      (match_operand:SI 2 "nonmemory_operand"      "K,K,qM,rL,rL,rCal")))]
3426   "TARGET_BARREL_SHIFTER
3427    && (register_operand (operands[1], SImode)
3428        || register_operand (operands[2], SImode))"
3429   "asr%?\\t%0,%1,%2"
3430   [(set_attr "type" "shift")
3431    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3432    (set_attr "predicable" "no,no,no,yes,no,no")
3433    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3435 (define_insn "*lshrsi3_insn"
3436   [(set (match_operand:SI 0 "dest_reg_operand"               "=q, q, r, r,   r")
3437         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand"  "q, 0, 0, r,rCal")
3438                      (match_operand:SI 2 "nonmemory_operand"  "N,qM,rL,rL,rCal")))]
3439   "TARGET_BARREL_SHIFTER
3440    && (register_operand (operands[1], SImode)
3441        || register_operand (operands[2], SImode))"
3442   "@
3443    lsr_s\\t%0,%1
3444    lsr_s\\t%0,%1,%2
3445    lsr%?\\t%0,%1,%2
3446    lsr%?\\t%0,%1,%2
3447    lsr%?\\t%0,%1,%2"
3448   [(set_attr "type" "shift")
3449    (set_attr "iscompact" "maybe,maybe,false,false,false")
3450    (set_attr "predicable" "no,no,yes,no,no")
3451    (set_attr "cond" "nocond,canuse,canuse,nocond,nocond")])
3453 (define_insn "<insn>si2_cnt16"
3454   [(set (match_operand:SI 0 "register_operand" "=r")
3455         (ANY_ROTATE:SI (match_operand:SI 1 "register_operand" "r")
3456                        (const_int 16)))]
3457   "TARGET_SWAP"
3458   "swap\\t%0,%1"
3459   [(set_attr "length" "4")
3460    (set_attr "type" "two_cycle_core")])
3462 (define_insn "ashlsi2_cnt16"
3463   [(set (match_operand:SI 0 "register_operand"             "=r")
3464         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
3465                    (const_int 16)))]
3466   "TARGET_SWAP && TARGET_V2"
3467   "lsl16\\t%0,%1"
3468   [(set_attr "type" "shift")
3469    (set_attr "iscompact" "false")
3470    (set_attr "length" "4")
3471    (set_attr "predicable" "no")])
3473 (define_insn "lshrsi2_cnt16"
3474   [(set (match_operand:SI 0 "register_operand"               "=r")
3475         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "rL")
3476                      (const_int 16)))]
3477   "TARGET_SWAP && TARGET_V2"
3478   "lsr16\\t%0,%1"
3479   [(set_attr "type" "shift")
3480    (set_attr "iscompact" "false")
3481    (set_attr "length" "4")
3482    (set_attr "predicable" "no")])
3484 ;; Split asl dst,1,src into bset dst,0,src.
3485 (define_insn_and_split "*ashlsi3_1"
3486   [(set (match_operand:SI 0 "dest_reg_operand")
3487         (ashift:SI (const_int 1)
3488                    (match_operand:SI 1 "nonmemory_operand")))]
3489   "!TARGET_BARREL_SHIFTER
3490    && arc_pre_reload_split ()"
3491   "#"
3492   "&& 1"
3493   [(set (match_dup 0)
3494         (ior:SI (ashift:SI (const_int 1) (match_dup 1))
3495                 (const_int 0)))]
3496   ""
3497   [(set_attr "type" "shift")
3498    (set_attr "length" "8")])
3500 (define_insn_and_split "*<insn>si3_nobs"
3501   [(set (match_operand:SI 0 "dest_reg_operand")
3502         (ANY_SHIFT_ROTATE:SI (match_operand:SI 1 "register_operand")
3503                              (match_operand:SI 2 "nonmemory_operand")))]
3504   "!TARGET_BARREL_SHIFTER
3505    && operands[2] != const1_rtx
3506    && arc_pre_reload_split ()"
3507   "#"
3508   "&& 1"
3509   [(const_int 0)]
3511   arc_split_<insn> (operands);
3512   DONE;
3515 ;; <ANY_SHIFT_ROTATE>si3_loop appears after <ANY_SHIFT_ROTATE>si3_nobs
3516 (define_insn "<insn>si3_loop"
3517   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3518         (ANY_SHIFT_ROTATE:SI 
3519           (match_operand:SI 1 "register_operand" "0,0")
3520           (match_operand:SI 2 "nonmemory_operand" "rn,Cal")))
3521    (clobber (reg:SI LP_COUNT))
3522    (clobber (reg:CC CC_REG))
3523   ]
3524   "!TARGET_BARREL_SHIFTER
3525    && operands[2] != const1_rtx"
3526   "* return output_shift_loop (<CODE>, operands);"
3527   [(set_attr "type" "shift")
3528    (set_attr "length" "16,20")])
3530 ;; DImode shifts
3532 (define_expand "ashldi3"
3533   [(parallel
3534       [(set (match_operand:DI 0 "register_operand")
3535             (ashift:DI (match_operand:DI 1 "register_operand")
3536                        (match_operand:QI 2 "const_int_operand")))
3537        (clobber (reg:CC CC_REG))])]
3538   ""
3540   if (operands[2] != const1_rtx)
3541     FAIL;
3544 (define_insn_and_split "*ashldi3_cnt1"
3545   [(set (match_operand:DI 0 "register_operand")
3546         (ashift:DI (match_operand:DI 1 "register_operand")
3547                    (const_int 1)))
3548    (clobber (reg:CC CC_REG))]
3549   "arc_pre_reload_split ()"
3550   "#"
3551   "&& 1"
3552   [(parallel [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 1)))
3553               (clobber (reg:CC CC_REG))])]
3554   ""
3555   [(set_attr "length" "8")])
3557 (define_expand "ashrdi3"
3558   [(parallel
3559       [(set (match_operand:DI 0 "register_operand")
3560             (ashiftrt:DI (match_operand:DI 1 "register_operand")
3561                          (match_operand:QI 2 "const_int_operand")))
3562        (clobber (reg:CC CC_REG))])]
3563   ""
3565   if (operands[2] != const1_rtx)
3566     FAIL;
3569 ;; Split into asr.f hi; rrc lo
3570 (define_insn_and_split "*ashrdi3_cnt1"
3571   [(set (match_operand:DI 0 "register_operand")
3572         (ashiftrt:DI (match_operand:DI 1 "register_operand")
3573                      (const_int 1)))
3574    (clobber (reg:CC CC_REG))]
3575   "arc_pre_reload_split ()"
3576   "#"
3577   "&& 1"
3578   [(const_int 0)]
3580   emit_insn (gen_ashrsi3_cnt1_carry (gen_highpart (SImode, operands[0]),
3581                                      gen_highpart (SImode, operands[1])));
3582   emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]),
3583                          gen_lowpart (SImode, operands[1])));
3584   DONE;
3586   [(set_attr "length" "8")])
3588 (define_expand "lshrdi3"
3589   [(parallel
3590       [(set (match_operand:DI 0 "register_operand")
3591             (lshiftrt:DI (match_operand:DI 1 "register_operand")
3592                          (match_operand:QI 2 "const_int_operand")))
3593        (clobber (reg:CC CC_REG))])]
3594   ""
3596   if (operands[2] != const1_rtx)
3597     FAIL;
3600 ;; Split into lsr.f hi; rrc lo
3601 (define_insn_and_split "*lshrdi3_cnt1"
3602   [(set (match_operand:DI 0 "register_operand")
3603         (lshiftrt:DI (match_operand:DI 1 "register_operand")
3604                      (const_int 1)))
3605    (clobber (reg:CC CC_REG))]
3606   "arc_pre_reload_split ()"
3607   "#"
3608   "&& 1"
3609   [(const_int 0)]
3611   emit_insn (gen_lshrsi3_cnt1_carry (gen_highpart (SImode, operands[0]),
3612                                      gen_highpart (SImode, operands[1])));
3613   emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]),
3614                          gen_lowpart (SImode, operands[1])));
3615   DONE;
3617   [(set_attr "length" "8")])
3619 ;; Rotate instructions.
3621 (define_insn "rotrsi3_insn"
3622   [(set (match_operand:SI 0 "dest_reg_operand"                    "=r, r,   r")
3623         (rotatert:SI (match_operand:SI 1 "arc_nonmemory_operand"  " 0,rL,rCsz")
3624                      (match_operand:SI 2 "nonmemory_operand"      "rL,rL,rCal")))]
3625   "TARGET_BARREL_SHIFTER"
3626   "ror%?\\t%0,%1,%2"
3627   [(set_attr "type" "shift,shift,shift")
3628    (set_attr "predicable" "yes,no,no")
3629    (set_attr "length" "4,4,8")])
3631 (define_insn_and_split "*rotlsi3"
3632   [(set (match_operand:SI 0 "dest_reg_operand")
3633         (rotate:SI (match_operand:SI 1 "register_operand")
3634                    (match_operand:SI 2 "nonmemory_operand")))]
3635   "TARGET_BARREL_SHIFTER
3636    && arc_pre_reload_split ()"
3637   "#"
3638   "&& 1"
3639   [(set (match_dup 0) (rotatert:SI (match_dup 1) (match_dup 3)))]
3641   if (CONST_INT_P (operands[2]))
3642     {
3643       int n = INTVAL (operands[2]) & 31;
3644       if (n == 0)
3645         {
3646           emit_move_insn (operands[0], operands[1]);
3647           DONE;
3648         }
3649       else operands[3] = GEN_INT (32 - n);
3650     }
3651   else
3652     {
3653       if (!register_operand (operands[2], SImode))
3654         operands[2] = force_reg (SImode, operands[2]);
3655       operands[3] = gen_reg_rtx (SImode);
3656       emit_insn (gen_negsi2 (operands[3], operands[2]));
3657     }
3660 ;; Rotate through carry flag
3662 (define_insn "rrcsi2"
3663   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3664         (plus:SI
3665           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
3666                        (const_int 1))
3667           (ashift:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
3668                      (const_int 31))))]
3669   ""
3670   "rrc\\t%0,%1"
3671   [(set_attr "type" "shift")
3672    (set_attr "predicable" "no")
3673    (set_attr "length" "4")])
3675 (define_insn "rrcsi2_carry"
3676   [(set (reg:CC_C CC_REG)
3677         (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
3678                               (const_int 1))] UNSPEC_ARC_CC_NEZ))
3679    (set (match_operand:SI 0 "dest_reg_operand" "=r")
3680         (plus:SI
3681           (lshiftrt:SI (match_dup 1) (const_int 1))
3682           (ashift:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
3683                      (const_int 31))))]
3684   ""
3685   "rrc.f\\t%0,%1"
3686   [(set_attr "type" "shift")
3687    (set_attr "predicable" "no")
3688    (set_attr "length" "4")])
3690 ;; DImode Rotate instructions
3692 (define_expand "rotldi3"
3693   [(parallel
3694       [(set (match_operand:DI 0 "register_operand")
3695             (rotate:DI (match_operand:DI 1 "register_operand")
3696                        (match_operand:QI 2 "const_int_operand")))
3697        (clobber (reg:CC CC_REG))])]
3698   ""
3700   if (operands[2] != const1_rtx)
3701     FAIL;
3704 ;; split into add.f lo; adc.f hi; adc lo
3705 (define_insn_and_split "*rotldi3_cnt1"
3706   [(set (match_operand:DI 0 "register_operand")
3707         (rotate:DI (match_operand:DI 1 "register_operand")
3708                    (const_int 1)))
3709    (clobber (reg:CC CC_REG))]
3710   "arc_pre_reload_split ()"
3711   "#"
3712   "&& 1"
3713   [(const_int 0)]
3715   rtx lo0 = gen_lowpart (SImode, operands[0]);
3716   rtx lo1 = gen_lowpart (SImode, operands[1]);
3717   rtx hi1 = gen_highpart (SImode, operands[1]);
3718   emit_insn (gen_add_f (lo0, lo1, lo1));
3719   emit_insn (gen_adc_f (gen_highpart (SImode, operands[0]), hi1, hi1));
3720   emit_insn (gen_adc (lo0, lo0, const0_rtx));
3721   DONE;
3723   [(set_attr "length" "12")])
3725 (define_expand "rotrdi3"
3726   [(parallel
3727       [(set (match_operand:DI 0 "register_operand")
3728             (rotatert:DI (match_operand:DI 1 "register_operand")
3729                          (match_operand:QI 2 "const_int_operand")))
3730        (clobber (reg:CC CC_REG))])]
3731   ""
3733   if (operands[2] != const1_rtx)
3734     FAIL;
3737 ;; split into asr.f lo; rrc.f hi; rrc lo
3738 (define_insn_and_split "*rotrdi3_cnt1"
3739   [(set (match_operand:DI 0 "register_operand")
3740         (rotatert:DI (match_operand:DI 1 "register_operand")
3741                      (const_int 1)))
3742    (clobber (reg:CC CC_REG))]
3743   "arc_pre_reload_split ()"
3744   "#"
3745   "&& 1"
3746   [(const_int 0)]
3748   rtx lo = gen_lowpart (SImode, operands[1]);
3749   emit_insn (gen_btst_0_carry (lo));
3750   emit_insn (gen_rrcsi2_carry (gen_highpart (SImode, operands[0]),
3751                                gen_highpart (SImode, operands[1])));
3752   emit_insn (gen_rrcsi2 (gen_lowpart (SImode, operands[0]), lo));
3753   DONE;
3755   [(set_attr "length" "12")])
3757 ;; Compare / branch instructions.
3759 (define_expand "cbranchsi4"
3760   [(set (reg:CC CC_REG)
3761         (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3762                     (match_operand:SI 2 "nonmemory_operand" "")))
3763    (set (pc)
3764         (if_then_else
3765               (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3766                                                                (const_int 0)])
3767               (label_ref (match_operand 3 "" ""))
3768               (pc)))]
3769   ""
3771   gcc_assert (XEXP (operands[0], 0) == operands[1]);
3772   gcc_assert (XEXP (operands[0], 1) == operands[2]);
3773   operands[0] = gen_compare_reg (operands[0], VOIDmode);
3774   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3775   DONE;
3778 ;; ??? Could add a peephole to generate compare with swapped operands and
3779 ;; modifed cc user if second, but not first operand is a compact register.
3780 (define_insn "cmpsi_cc_insn_mixed"
3781   [(set (reg:CC CC_REG)
3782         (compare:CC (match_operand:SI 0 "register_operand"   "q, q,  h, c, c,  q,c")
3783                     (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,cL,Cal,Cal")))]
3784   ""
3785   "cmp%?\\t%0,%B1"
3786   [(set_attr "type" "compare")
3787    (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3788    (set_attr "predicable" "no,no,no,no,yes,no,yes")
3789    (set_attr "cond" "set")
3790    (set_attr "length" "*,*,*,4,4,*,8")
3791    (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3793 (define_insn "*cmpsi_cc_zn_insn"
3794   [(set (reg:CC_ZN CC_REG)
3795         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "q,c")
3796                        (const_int 0)))]
3797   ""
3798   "tst%?\\t%0,%0"
3799   [(set_attr "type" "compare,compare")
3800    (set_attr "iscompact" "true,false")
3801    (set_attr "predicable" "no,yes")
3802    (set_attr "cond" "set_zn")
3803    (set_attr "length" "*,4")])
3805 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3806 (define_insn "*btst"
3807   [(set (reg:CC_ZN CC_REG)
3808         (compare:CC_ZN
3809           (zero_extract:SI (match_operand:SI 0 "register_operand" "q,c")
3810                            (const_int 1)
3811                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3812           (const_int 0)))]
3813   ""
3814   "btst%?\\t%0,%1"
3815   [(set_attr "iscompact" "true,false")
3816    (set_attr "predicable" "no,yes")
3817    (set_attr "cond" "set")
3818    (set_attr "type" "compare")
3819    (set_attr "length" "*,4")])
3821 (define_insn "*cmpsi_cc_z_insn"
3822   [(set (reg:CC_Z CC_REG)
3823         (compare:CC_Z (match_operand:SI 0 "register_operand"  "q,c")
3824                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3825   ""
3826   "@
3827         cmp%?\\t%0,%1
3828         bxor.f\\t0,%0,%z1"
3829   [(set_attr "type" "compare,compare")
3830    (set_attr "iscompact" "true,false")
3831    (set_attr "cond" "set,set_zn")
3832    (set_attr "length" "*,4")])
3834 (define_insn "*cmpsi_cc_c_insn"
3835   [(set (reg:CC_C CC_REG)
3836         (compare:CC_C (match_operand:SI 0 "register_operand"   "q, q,  h, c,  q,  c")
3837                       (match_operand:SI 1 "nonmemory_operand" "cO,hO,Cm1,cI,Cal,Cal")))]
3838   ""
3839   "cmp%?\\t%0,%1"
3840   [(set_attr "type" "compare")
3841    (set_attr "iscompact" "true,true,true,false,true_limm,false")
3842    (set_attr "cond" "set")
3843    (set_attr "length" "*,*,*,4,*,8")
3844    (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3846 ;; Next come the scc insns.
3848 (define_expand "cstoresi4"
3849   [(set (match_operand:SI 0 "dest_reg_operand" "")
3850         (match_operator:SI 1 "ordered_comparison_operator"
3851                            [(match_operand:SI 2 "nonmemory_operand" "")
3852                             (match_operand:SI 3 "nonmemory_operand" "")]))]
3853   ""
3855   if (!TARGET_CODE_DENSITY)
3856   {
3857    gcc_assert (XEXP (operands[1], 0) == operands[2]);
3858    gcc_assert (XEXP (operands[1], 1) == operands[3]);
3859    operands[1] = gen_compare_reg (operands[1], SImode);
3860    emit_insn (gen_scc_insn (operands[0], operands[1]));
3861    DONE;
3862   }
3863   if (!register_operand (operands[2], SImode))
3864     operands[2] = force_reg (SImode, operands[2]);
3868 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3869                            (DF "TARGET_FP_DP_BASE || TARGET_OPTFPE")])
3871 (define_expand "cstore<mode>4"
3872   [(set (reg:CC CC_REG)
3873         (compare:CC (match_operand:SDF 2 "register_operand" "")
3874                     (match_operand:SDF 3 "register_operand" "")))
3875    (set (match_operand:SI 0 "dest_reg_operand" "")
3876         (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3877                                                     (const_int 0)]))]
3879   "TARGET_HARD_FLOAT || TARGET_OPTFPE"
3881   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3882   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3883   operands[1] = gen_compare_reg (operands[1], SImode);
3884   emit_insn (gen_scc_insn (operands[0], operands[1]));
3885   DONE;
3888 ; We need a separate expander for this lest we loose the mode of CC_REG
3889 ; when match_operator substitutes the literal operand into the comparison.
3890 (define_expand "scc_insn"
3891   [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3893 (define_mode_iterator CC_ltu [CC_C CC])
3895 (define_insn "scc_ltu_<mode>"
3896   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3897         (ltu:SI (reg:CC_ltu CC_REG) (const_int 0)))]
3898   ""
3899   "rlc\\t%0,0"
3900   [(set_attr "type" "shift")
3901    (set_attr "predicable" "no")
3902    (set_attr "length" "4")])
3904 (define_insn_and_split "*scc_insn"
3905   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3906         (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3907   ""
3908   "#"
3909   "reload_completed
3910    && GET_CODE (operands[1]) != LTU"
3911   [(set (match_dup 0) (const_int 1))
3912    (cond_exec
3913      (match_dup 1)
3914      (set (match_dup 0) (const_int 0)))]
3916   operands[1]
3917     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3918                                          GET_MODE (XEXP (operands[1], 0))),
3919                       VOIDmode,
3920                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3922   [(set_attr "type" "unary")])
3924 ; cond_exec patterns
3925 (define_insn "*movsi_ne"
3926   [(cond_exec
3927     (ne (match_operand:CC_Z 2 "cc_use_register"  "Rcc,Rcc,Rcc,Rcc,Rcc") (const_int 0))
3928     (set (match_operand:SI 0 "dest_reg_operand"   "=q,  q,  r,  q,  r")
3929          (match_operand:SI 1 "nonmemory_operand" "C_0,  h, Lr,Cal,Cal")))]
3930   ""
3931   "@
3932         * current_insn_predicate = 0; return \"sub%?.ne\\t%0,%0,%0\";
3933         * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3934         mov.ne\\t%0,%1
3935         * current_insn_predicate = 0; return \"mov%?.ne\\t%0,%1\";
3936         mov.ne\\t%0,%1"
3937   [(set_attr "type" "cmove")
3938    (set_attr "iscompact" "true,true,false,true_limm,false")
3939    (set_attr "length" "2,2,4,6,8")
3940    (set_attr "cpu_facility" "*,av2,*,av2,*")])
3942 (define_insn "*movsi_cond_exec"
3943   [(cond_exec
3944      (match_operator 3 "proper_comparison_operator"
3945        [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3946      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3947           (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3948   ""
3949   "mov.%d3\\t%0,%1"
3950   [(set_attr "type" "cmove")
3951    (set_attr "length" "4,8")])
3953 (define_insn "*commutative_cond_exec"
3954   [(cond_exec
3955      (match_operator 5 "proper_comparison_operator"
3956        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3957      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3958           (match_operator:SI 3 "commutative_operator"
3959             [(match_operand:SI 1 "register_operand" "%0,0")
3960              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3961   ""
3963   arc_output_commutative_cond_exec (operands, true);
3964   return "";
3966   [(set_attr "cond" "use")
3967    (set_attr "type" "cmove")
3968    (set_attr_alternative "length"
3969      [(const_int 4)
3970       (cond
3971         [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3972              (const_int 4))
3973          (const_int 4)]
3974         (const_int 8))])])
3976 (define_insn "*sub_cond_exec"
3977   [(cond_exec
3978      (match_operator 4 "proper_comparison_operator"
3979        [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3980      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3981           (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3982                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3983   ""
3984   "@
3985         sub.%d4\\t%0,%1,%2
3986         rsub.%d4\\t%0,%2,%1
3987         rsub.%d4\\t%0,%2,%1"
3988   [(set_attr "cond" "use")
3989    (set_attr "type" "cmove")
3990    (set_attr "length" "4,4,8")])
3992 (define_insn "*noncommutative_cond_exec"
3993   [(cond_exec
3994      (match_operator 5 "proper_comparison_operator"
3995        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3996      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3997           (match_operator:SI 3 "noncommutative_operator"
3998             [(match_operand:SI 1 "register_operand" "0,0")
3999              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
4000   ""
4001   "%O3.%d5\\t%0,%1,%2"
4002   [(set_attr "cond" "use")
4003    (set_attr "type" "cmove")
4004    (set_attr "length" "4,8")])
4006 ;; These control RTL generation for conditional jump insns
4007 ;; Match both normal and inverted jump.
4009 ; We need a separate expander for this lest we loose the mode of CC_REG
4010 ; when match_operator substitutes the literal operand into the comparison.
4011 (define_expand "branch_insn"
4012   [(set (pc)
4013         (if_then_else (match_operand 1 "" "")
4014                       (label_ref (match_operand 0 "" ""))
4015                       (pc)))])
4017 ; When estimating sizes during arc_reorg, when optimizing for speed, there
4018 ; are three reasons why we need to consider branches to be length 6:
4019 ; - annull-false delay slot insns are implemented using conditional execution,
4020 ;   thus preventing short insn formation where used.
4021 ; - for ARC600: annull-true delay slot isnns are implemented where possile
4022 ;   using conditional execution, preventing short insn formation where used.
4023 ; - for ARC700: likely or somewhat likely taken branches are made long and
4024 ;   unaligned if possible to avoid branch penalty.
4025 (define_insn "*branch_insn"
4026   [(set (pc)
4027         (if_then_else (match_operator 1 "proper_comparison_operator"
4028                                       [(reg CC_REG) (const_int 0)])
4029                       (label_ref (match_operand 0 "" ""))
4030                       (pc)))]
4031   ""
4032   "*
4034       if (get_attr_length (insn) == 2)
4035          return \"b%d1%?\\t%l0\";
4036       else
4037          return \"b%d1%*\\t%l0\";
4039   [(set_attr "type" "branch")
4040    (set
4041      (attr "length")
4042      (cond [
4043        (eq_attr "delay_slot_filled" "yes")
4044        (const_int 4)
4046        (ne
4047          (if_then_else
4048            (match_operand 1 "equality_comparison_operator" "")
4049            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4050                 (gt (minus (match_dup 0) (pc))
4051                     (minus (const_int 506)
4052                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4053            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
4054                 (lt (minus (match_dup 0) (pc)) (const_int -64))
4055                 (gt (minus (match_dup 0) (pc))
4056                     (minus (const_int 58)
4057                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
4058          (const_int 0))
4059        (const_int 4)]
4060       (const_int 2)))
4062    (set (attr "iscompact")
4063         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
4064               (const_string "false")))])
4066 (define_insn "*rev_branch_insn"
4067   [(set (pc)
4068         (if_then_else (match_operator 1 "proper_comparison_operator"
4069                                       [(reg CC_REG) (const_int 0)])
4070                       (pc)
4071                       (label_ref (match_operand 0 "" ""))))]
4072   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
4073   "b%D1%?\\t%l0"
4074   [(set_attr "type" "branch")
4075    (set
4076      (attr "length")
4077      (cond [
4078        (eq_attr "delay_slot_filled" "yes")
4079        (const_int 4)
4081        (ne
4082          (if_then_else
4083            (match_operand 1 "equality_comparison_operator" "")
4084            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4085                 (gt (minus (match_dup 0) (pc))
4086                     (minus (const_int 506)
4087                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
4088            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
4089                 (lt (minus (match_dup 0) (pc)) (const_int -64))
4090                 (gt (minus (match_dup 0) (pc))
4091                     (minus (const_int 58)
4092                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
4093          (const_int 0))
4094        (const_int 4)]
4095       (const_int 2)))
4097    (set (attr "iscompact")
4098         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
4099               (const_string "false")))])
4101 ;; Unconditional and other jump instructions.
4103 (define_expand "jump"
4104   [(set (pc) (label_ref (match_operand 0 "" "")))]
4105   ""
4106   "")
4108 (define_insn "jump_i"
4109   [(set (pc) (label_ref (match_operand 0 "" "")))]
4110   "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
4111   "b%!%*\\t%l0"
4112   [(set_attr "type" "uncond_branch")
4113    (set (attr "iscompact")
4114         (if_then_else (match_test "get_attr_length (insn) == 2")
4115                       (const_string "true") (const_string "false")))
4116    (set_attr "cond" "canuse")
4117    (set (attr "length")
4118         (cond [
4119           ; In arc_reorg we just guesstimate; might be more or less than 4.
4120           (match_test "arc_branch_size_unknown_p ()")
4121           (const_int 4)
4123           (eq_attr "delay_slot_filled" "yes")
4124           (const_int 4)
4126           (match_test "CROSSING_JUMP_P (insn)")
4127           (const_int 4)
4129           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
4130                (gt (minus (match_dup 0) (pc))
4131                    (minus (const_int 506)
4132                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
4133           (const_int 4)]
4134          (const_int 2)))])
4136 (define_insn "indirect_jump"
4137   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,q,r"))]
4138   ""
4139   "@
4140    j%!%*\\t%0
4141    j%!%*\\t%0
4142    j%!%*\\t%0
4143    j%!%*\\t[%0]
4144    j%!%*\\t[%0]"
4145   [(set_attr "type" "jump")
4146    (set_attr "iscompact" "false,false,false,maybe,false")
4147    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
4149 ;; Implement a switch statement.
4150 (define_expand "casesi"
4151   [(match_operand:SI 0 "register_operand" "")   ; Index
4152    (match_operand:SI 1 "const_int_operand" "")  ; Lower bound
4153    (match_operand:SI 2 "const_int_operand" "")  ; Total range
4154    (match_operand:SI 3 "" "")           ; Table label
4155    (match_operand:SI 4 "" "")]          ; Out of range label
4156   ""
4158   if (operands[1] != const0_rtx)
4159     {
4160       rtx reg = gen_reg_rtx (SImode);
4161       emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
4162       operands[0] = reg;
4163     }
4164   emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, operands[0],
4165                                                operands[2]),
4166                                   operands[0], operands[2], operands[4]));
4167   if (TARGET_BI_BIH)
4168     emit_jump_insn (gen_casesi_dispatch (operands[0], operands[3]));
4169   else
4170     {
4171       rtx reg = gen_reg_rtx (SImode);
4172       rtx lbl = operands[3];
4173       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4174       if (flag_pic)
4175         operands[3] = force_reg (Pmode, operands[3]);
4176       emit_insn (gen_casesi_load (reg,
4177                                   operands[3], operands[0], lbl));
4178       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4179         emit_insn (gen_addsi3 (reg, reg, operands[3]));
4180       emit_jump_insn (gen_casesi_jump (reg, lbl));
4181     }
4182   DONE;
4185 (define_insn "casesi_dispatch"
4186   [(set (pc)
4187         (unspec:SI [(match_operand:SI 0 "register_operand" "r")
4188                     (label_ref (match_operand 1 "" ""))]
4189                    UNSPEC_ARC_CASESI))]
4190   "TARGET_BI_BIH"
4192   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4193   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4194   switch (GET_MODE (diff_vec))
4195     {
4196     case E_SImode:
4197       return \"bi\\t[%0]\";
4198     case E_HImode:
4199     case E_QImode:
4200       return \"bih\\t[%0]\";
4201     default: gcc_unreachable ();
4202     }
4204   [(set_attr "type" "brcc_no_delay_slot")
4205    (set_attr "iscompact" "false")
4206    (set_attr "length" "4")])
4208 (define_insn "casesi_load"
4209   [(set (match_operand:SI 0 "register_operand"             "=q,r,r")
4210         (mem:SI (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "q,r,Cal")
4211                             (match_operand:SI 2 "register_operand"  "q,r,r")]
4212                            UNSPEC_ARC_CASESI)))
4213    (use (label_ref (match_operand 3 "" "")))]
4214   ""
4215   "*
4217   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4219   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4220     {
4221       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4222       gcc_assert (GET_MODE (diff_vec) == SImode);
4223       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4224     }
4226   switch (GET_MODE (diff_vec))
4227     {
4228     case E_SImode:
4229       return \"ld.as\\t%0,[%1,%2]\";
4230     case E_HImode:
4231       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4232         return \"ld%_.as\\t%0,[%1,%2]\";
4233       return \"ld%_.x.as\\t%0,[%1,%2]\";
4234     case E_QImode:
4235       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4236         return \"ldb%?\\t%0,[%1,%2]\";
4237       return \"ldb.x\\t%0,[%1,%2]\";
4238     default:
4239       gcc_unreachable ();
4240     }
4242   [(set_attr "type" "load")
4243    (set_attr_alternative "iscompact"
4244      [(cond
4245         [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4246                                                (as_a<rtx_insn *> (operands[3]))))")
4247              (symbol_ref "QImode"))
4248          (const_string "false")
4249          (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4250                                                        (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4251          (const_string "false")]
4252         (const_string "true"))
4253       (const_string "false")
4254       (const_string "false")])
4255    (set_attr_alternative "length"
4256      [(cond
4257         [(eq_attr "iscompact" "false") (const_int 4)
4258         ; We have to mention (match_dup 3) to convince genattrtab.cc that this
4259         ; is a varying length insn.
4260          (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4261          (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4262         (const_int 2))
4263       (const_int 4)
4264       (const_int 8)])])
4266 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4267 ; even for CASE_VECTOR_PC_RELATIVE.
4268 (define_insn "casesi_jump"
4269   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,q,c"))
4270    (use (label_ref (match_operand 1 "" "")))]
4271   ""
4272   "j%!%* [%0]"
4273   [(set_attr "type" "jump")
4274    (set_attr "iscompact" "false,maybe,false")
4275    (set_attr "cond" "canuse")])
4277 (define_expand "call"
4278   ;; operands[1] is stack_size_rtx
4279   ;; operands[2] is next_arg_register
4280   [(parallel [(call (match_operand:SI 0 "call_operand" "")
4281                     (match_operand 1 "" ""))
4282              (clobber (reg:SI 31))])]
4283   ""
4284   "{
4285     rtx callee;
4287     gcc_assert (MEM_P (operands[0]));
4288     callee  = XEXP (operands[0], 0);
4289     /* This is to decide if we should generate indirect calls by loading the
4290        32 bit address of the callee into a register before performing the
4291        branch and link - this exposes cse opportunities.
4292        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
4293     if (GET_CODE (callee) != REG
4294         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4295       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4296   }
4299 ; At instruction output time, if it doesn't match and we end up with
4300 ; alternative 1 ("q"), that means that we can't use the short form.
4301 (define_insn "*call_i"
4302   [(call (mem:SI (match_operand:SI 0
4303                   "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4304          (match_operand 1 "" ""))
4305    (clobber (reg:SI 31))]
4306   ""
4307   "@
4308    jl%!%*\\t[%0]
4309    jl%!%*\\t[%0]
4310    jli_s\\t%J0
4311    sjli\\t%J0
4312    bl%!%*\\t%P0
4313    bl%!%*\\t%P0
4314    jl%!%*\\t%0
4315    jl%*\\t%0
4316    jl%!\\t%0"
4317   [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4318    (set_attr "iscompact" "maybe,*,true,*,*,*,*,*,*")
4319    (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4320    (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4322 (define_expand "call_value"
4323   ;; operand 2 is stack_size_rtx
4324   ;; operand 3 is next_arg_register
4325   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4326                    (call (match_operand:SI 1 "call_operand" "")
4327                          (match_operand 2 "" "")))
4328              (clobber (reg:SI 31))])]
4329   ""
4330   "
4331   {
4332     rtx callee;
4334     gcc_assert (MEM_P (operands[1]));
4335     callee = XEXP (operands[1], 0);
4336      /* See the comment in define_expand \"call\".  */
4337     if (GET_CODE (callee) != REG
4338         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4339       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4340   }")
4342 ; At instruction output time, if it doesn't match and we end up with
4343 ; alternative 1 ("q"), that means that we can't use the short form.
4344 (define_insn "*call_value_i"
4345   [(set (match_operand 0 "dest_reg_operand"  "=q,w,  w,  w,  w,  w,w,w,  w")
4346         (call (mem:SI (match_operand:SI 1
4347                        "call_address_operand" "q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
4348               (match_operand 2 "" "")))
4349    (clobber (reg:SI 31))]
4350   ""
4351   "@
4352    jl%!%*\\t[%1]
4353    jl%!%*\\t[%1]
4354    jli_s\\t%J1
4355    sjli\\t%J1
4356    bl%!%*\\t%P1;1
4357    bl%!%*\\t%P1;1
4358    jl%!%*\\t%1
4359    jl%*\\t%1
4360    jl%!\\t%1"
4361   [(set_attr "type" "call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
4362    (set_attr "iscompact" "maybe,*,true,false,*,*,*,*,*")
4363    (set_attr "predicable" "no,yes,no,no,yes,no,yes,no,yes")
4364    (set_attr "length" "*,4,2,4,4,4,4,4,8")])
4366 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4367 ; use it for lack of inter-procedural branch shortening.
4368 ; Link-time relaxation would help...
4370 (define_insn "trap"
4371   [(trap_if (const_int 1) (const_int 0))]
4372   "!TARGET_ARC600_FAMILY"
4373   "trap_s\\t5"
4374   [(set_attr "type" "misc")
4375    (set_attr "length" "2")])
4377 (define_insn "nop"
4378   [(const_int 0)]
4379   ""
4380   "nop%?"
4381   [(set_attr "type" "misc")
4382    (set_attr "iscompact" "true")
4383    (set_attr "cond" "canuse")
4384    (set_attr "length" "2")])
4386 (define_insn "nopv"
4387   [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4388   ""
4389   "nop%?"
4390   [(set_attr "type" "misc")
4391    (set_attr "iscompact" "maybe")
4392    (set_attr "length" "*")])
4394 (define_insn "blockage"
4395   [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)]
4396   ""
4397   ""
4398   [(set_attr "length" "0")
4399    (set_attr "type" "block")]
4402 (define_insn "arc600_stall"
4403   [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_ARC600_STALL)]
4404   "TARGET_MUL64_SET"
4405   "mov\\t0,mlo\t;wait until multiply complete."
4406   [(set_attr "length" "4")
4407    (set_attr "type" "move")]
4410 ;; Split up troublesome insns for better scheduling.
4412 ;; Peepholes go at the end.
4413 ;;asl followed by add can be replaced by an add{1,2,3}
4414 ;; Three define_peepholes have been added for this optimization
4415 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
4416 ;; can be generated by combine.  Check if these peepholes still provide
4417 ;; any benefit.
4419 ;; -------------------------------------------------------------
4420 ;; Pattern 1 : r0 = r1 << {i}
4421 ;;             r3 = r4/INT + r0     ;;and commutative
4422 ;;                 ||
4423 ;;                 \/
4424 ;;             add{i} r3,r4/INT,r1
4425 ;; -------------------------------------------------------------
4426 ;; ??? This should be covered by combine, alas, at times combine gets
4427 ;; too clever for it's own good: when the shifted input is known to be
4428 ;; either 0 or 1, the operation will be made into an if-then-else, and
4429 ;; thus fail to match the add_n pattern.  Example: _mktm_r, line 85 in
4430 ;; newlib/libc/time/mktm_r.c .
4432 (define_peephole2
4433   [(set (match_operand:SI 0 "dest_reg_operand" "")
4434         (ashift:SI (match_operand:SI 1 "register_operand" "")
4435                    (match_operand:SI 2 "_1_2_3_operand" "")))
4436   (set (match_operand:SI 3 "dest_reg_operand" "")
4437        (plus:SI (match_operand:SI 4 "arc_nonmemory_operand" "")
4438                 (match_operand:SI 5 "arc_nonmemory_operand" "")))]
4439   "(true_regnum (operands[4]) == true_regnum (operands[0])
4440        || true_regnum (operands[5]) == true_regnum (operands[0]))
4441    && (peep2_reg_dead_p (2, operands[0])
4442        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4443  ;; the preparation statements take care to put proper operand in
4444  ;; operands[4] operands[4] will always contain the correct
4445  ;; operand. This is added to satisfy commutativity
4446   [(set (match_dup 3)
4447         (plus:SI (mult:SI (match_dup 1)
4448                           (match_dup 2))
4449                  (match_dup 4)))]
4450   "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4451       operands[4] = operands[5];
4452    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4455 ;; -------------------------------------------------------------
4456 ;; Pattern 1 : r0 = r1 << {i}
4457 ;;             r3 = r4 - r0
4458 ;;                 ||
4459 ;;                 \/
4460 ;;             sub{i} r3,r4,r1
4461 ;; -------------------------------------------------------------
4462 ;; ??? This should be covered by combine, alas, at times combine gets
4463 ;; too clever for it's own good: when the shifted input is known to be
4464 ;; either 0 or 1, the operation will be made into an if-then-else, and
4465 ;; thus fail to match the sub_n pattern.  Example: __ieee754_yn, line 239 in
4466 ;; newlib/libm/math/e_jn.c .
4468 (define_peephole2
4469   [(set (match_operand:SI 0 "dest_reg_operand" "")
4470         (ashift:SI (match_operand:SI 1 "register_operand" "")
4471                    (match_operand:SI 2 "const_int_operand" "")))
4472    (set (match_operand:SI 3 "dest_reg_operand" "")
4473         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4474                   (match_dup 0)))]
4475   "(INTVAL (operands[2]) == 1
4476     || INTVAL (operands[2]) == 2
4477     || INTVAL (operands[2]) == 3)
4478    && (peep2_reg_dead_p (2, operands[0])
4479        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4480   [(set (match_dup 3)
4481         (minus:SI (match_dup 4)
4482                   (mult:SI (match_dup 1)
4483                            (match_dup 2))))]
4484   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4489 ; When using the high single bit, the result of a multiply is either
4490 ; the original number or zero.  But MPY costs 4 cycles, which we
4491 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4492 (define_peephole2
4493   [(set (match_operand:SI 0 "dest_reg_operand" "")
4494         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4495                      (const_int 31)))
4496    (set (match_operand:SI 4 "register_operand" "")
4497         (mult:SI (match_operand:SI 2 "register_operand")
4498                  (match_operand:SI 3 "nonmemory_operand" "")))]
4499   "TARGET_ARC700_MPY
4500    && (rtx_equal_p (operands[0], operands[2])
4501        || rtx_equal_p (operands[0], operands[3]))
4502    && peep2_regno_dead_p (0, CC_REG)
4503    && (rtx_equal_p (operands[0], operands[4])
4504        || (peep2_reg_dead_p (2, operands[0])
4505           && peep2_reg_dead_p (1, operands[4])))"
4506   [(parallel [(set (reg:CC_Z CC_REG)
4507                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4508                                  (const_int 0)))
4509               (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4510    (cond_exec
4511      (ne (reg:CC_Z CC_REG) (const_int 0))
4512      (set (match_dup 4) (match_dup 5)))]
4514   if (!rtx_equal_p (operands[0], operands[2]))
4515     operands[5] = operands[2];
4516   else if (!rtx_equal_p (operands[0], operands[3]))
4517     operands[5] = operands[3];
4518   else
4519     operands[5] = operands[4]; /* Actually a no-op... presumably rare.  */
4522 (define_peephole2
4523   [(set (match_operand:SI 0 "dest_reg_operand" "")
4524         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4525                      (const_int 31)))
4526    (set (match_operand:SI 4 "register_operand" "")
4527         (mult:SI (match_operand:SI 2 "register_operand")
4528                  (match_operand:SI 3 "nonmemory_operand" "")))]
4529   "TARGET_ARC700_MPY
4530    && (rtx_equal_p (operands[0], operands[2])
4531        || rtx_equal_p (operands[0], operands[3]))
4532    && peep2_regno_dead_p (2, CC_REG)"
4533   [(parallel [(set (reg:CC_Z CC_REG)
4534                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4535                                  (const_int 0)))
4536               (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4537    (set (match_dup 4) (match_dup 5))
4538    (cond_exec
4539      (eq (reg:CC_Z CC_REG) (const_int 0))
4540      (set (match_dup 4) (const_int 0)))]
4541  "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4543 ;; Instructions generated through builtins
4545 (define_insn "clrsbsi2"
4546   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4547         (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))]
4548   "TARGET_NORM"
4549   "norm\\t%0,%1"
4550   [(set_attr "length" "4,8")
4551    (set_attr "type" "two_cycle_core,two_cycle_core")])
4553 (define_insn "norm_f"
4554   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4555         (clrsb:SI (match_operand:SI 1 "general_operand" "rL,Cal")))
4556    (set (reg:CC_ZN CC_REG)
4557         (compare:CC_ZN (match_dup 1) (const_int 0)))]
4558   "TARGET_NORM"
4559   "norm.f\\t%0,%1"
4560   [(set_attr "length" "4,8")
4561    (set_attr "type" "two_cycle_core,two_cycle_core")])
4563 (define_insn_and_split "clrsbhi2"
4564   [(set (match_operand:HI  0 "dest_reg_operand" "=w,w")
4565         (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4566   "TARGET_NORM"
4567   "#"
4568   "reload_completed"
4569   [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4570   "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4572 (define_insn "normw"
4573   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4574         (zero_extend:SI
4575           (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4576   "TARGET_NORM"
4577   "@
4578    norm%_\\t%0,%1
4579    norm%_\\t%0,%1"
4580   [(set_attr "length" "4,8")
4581    (set_attr "type" "two_cycle_core,two_cycle_core")])
4583 (define_expand "clzsi2"
4584   [(parallel
4585     [(set (match_operand:SI 0 "register_operand" "")
4586           (clz:SI (match_operand:SI 1 "register_operand" "")))
4587      (clobber (match_dup 2))])]
4588   "TARGET_NORM"
4589   "
4590    if (TARGET_V2)
4591     {
4592       /* ARCv2's FLS is a bit more optimal than using norm.  */
4593       rtx tmp = gen_reg_rtx (SImode);
4594       emit_insn (gen_fls (tmp, operands[1]));
4595       emit_insn (gen_subsi3 (operands[0], GEN_INT (31), tmp));
4596       DONE;
4597     }
4598    operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);
4599   ")
4601 (define_insn_and_split "*arc_clzsi2"
4602   [(set (match_operand:SI 0 "register_operand" "=r")
4603         (clz:SI (match_operand:SI 1 "register_operand" "r")))
4604    (clobber (reg:CC_ZN CC_REG))]
4605   "TARGET_NORM"
4606   "#"
4607   "reload_completed"
4608   [(const_int 0)]
4610   emit_insn (gen_norm_f (operands[0], operands[1]));
4611   emit_insn
4612     (gen_rtx_COND_EXEC
4613       (VOIDmode,
4614        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4615        gen_rtx_SET (operands[0], const0_rtx)));
4616   emit_insn
4617     (gen_rtx_COND_EXEC
4618       (VOIDmode,
4619        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4620        gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4621   DONE;
4623 [(set_attr "type" "unary")
4624  (set_attr "length" "12")])
4626 (define_expand "ctzsi2"
4627   [(match_operand:SI 0 "register_operand" "")
4628    (match_operand:SI 1 "register_operand" "")]
4629   "TARGET_NORM"
4630   "
4631    if (TARGET_V2)
4632     {
4633       emit_insn (gen_ffs (operands[0], operands[1]));
4634       DONE;
4635     }
4636    emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4637    DONE;
4640 (define_insn_and_split "arc_ctzsi2"
4641   [(set (match_operand:SI 0 "register_operand" "=r")
4642         (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4643    (clobber (reg:CC_ZN CC_REG))
4644    (clobber (match_scratch:SI 2 "=&r"))]
4645   "TARGET_NORM"
4646   "#"
4647   "reload_completed"
4648   [(const_int 0)]
4650   rtx temp = operands[0];
4652   if (reg_overlap_mentioned_p (temp, operands[1])
4653       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4654           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4655                                  REGNO (temp))))
4656     temp = operands[2];
4657   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4658   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4659   emit_insn (gen_clrsbsi2 (operands[0], temp));
4660   emit_insn
4661     (gen_rtx_COND_EXEC
4662       (VOIDmode,
4663        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4664        gen_rtx_SET (operands[0], GEN_INT (32))));
4665   emit_insn
4666     (gen_rtx_COND_EXEC
4667       (VOIDmode,
4668        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4669        gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4670                                                 operands[0]))));
4671   DONE;
4673 [(set_attr "type" "unary")
4674  (set_attr "length" "20")])
4676 (define_insn "divaw"
4677   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4678                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4679                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4680                                            UNSPEC_ARC_DIVAW))]
4681   "TARGET_ARC700 || TARGET_EA_SET"
4682   "@
4683    divaw\\t%0,%1,%2
4684    divaw\\t%0,%1,%2
4685    divaw\\t%0,%1,%2"
4686   [(set_attr "length" "4,8,8")
4687    (set_attr "type" "divaw,divaw,divaw")])
4689 (define_insn "flag"
4690   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4691                    VUNSPEC_ARC_FLAG)]
4692   ""
4693   "@
4694     flag%?\\t%0
4695     flag\\t%0
4696     flag%?\\t%0"
4697   [(set_attr "length" "4,4,8")
4698    (set_attr "type" "misc,misc,misc")
4699    (set_attr "predicable" "yes,no,yes")
4700    (set_attr "cond" "clob,clob,clob")])
4702 (define_insn "brk"
4703   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4704                    VUNSPEC_ARC_BRK)]
4705   ""
4706   "brk"
4707   [(set_attr "length" "4")
4708   (set_attr "type" "misc")])
4710 (define_insn "rtie"
4711   [(return)
4712    (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)]
4713   "!TARGET_ARC600_FAMILY"
4714   "rtie"
4715   [(set_attr "length" "4")
4716    (set_attr "type" "rtie")
4717    (set_attr "cond" "clob")])
4719 (define_insn "sync"
4720   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4721                    VUNSPEC_ARC_SYNC)]
4722   ""
4723   "sync"
4724   [(set_attr "length" "4")
4725   (set_attr "type" "misc")])
4727 (define_insn "swi"
4728   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4729                    VUNSPEC_ARC_SWI)]
4730   ""
4731   "*
4733     if(TARGET_ARC700)
4734         return \"trap0\";
4735     else
4736         return \"swi\";
4738   [(set_attr "length" "4")
4739   (set_attr "type" "misc")])
4742 (define_insn "sleep"
4743   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "Lr")]
4744                    VUNSPEC_ARC_SLEEP)]
4745   ""
4746   "sleep\\t%0"
4747   [(set_attr "length" "4")
4748   (set_attr "type" "misc")])
4750 (define_insn "core_read"
4751   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4752         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4753                             VUNSPEC_ARC_CORE_READ))]
4754   ""
4755   "*
4756     if (check_if_valid_regno_const (operands, 1))
4757       return \"mov \t%0, r%1\";
4758     return \"mov \t%0, r%1\";
4759   "
4760   [(set_attr "length" "4")
4761    (set_attr "type" "unary")])
4763 (define_insn "core_write"
4764   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4765                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4766                    VUNSPEC_ARC_CORE_WRITE)]
4767   ""
4768   "*
4769     if (check_if_valid_regno_const (operands, 1))
4770       return \"mov\\tr%1,%0\";
4771     return \"mov\\tr%1,%0\";
4772   "
4773   [(set_attr "length" "4")
4774    (set_attr "type" "unary")])
4776 (define_insn "lr"
4777   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4778         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4779                             VUNSPEC_ARC_LR))]
4780   ""
4781   "lr\t%0, [%1]"
4782   [(set_attr "length" "4,8,4,8")
4783    (set_attr "type" "lr,lr,lr,lr")])
4785 (define_insn "sr"
4786   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4787                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4788                    VUNSPEC_ARC_SR)]
4789   ""
4790   "sr\t%0, [%1]"
4791   [(set_attr "length" "8,4,8,4")
4792    (set_attr "type" "sr,sr,sr,sr")])
4794 (define_mode_iterator ALLI [QI HI SI (DI "TARGET_LL64")])
4795 (define_mode_attr mALLI [(QI "b") (HI "%_") (SI "") (DI "d")])
4797 (define_insn "lddi<mode>"
4798   [(set (match_operand:ALLI 0 "register_operand" "=r")
4799         (unspec_volatile:ALLI [(match_operand:ALLI 1 "memory_operand" "m")]
4800                               VUNSPEC_ARC_LDDI))]
4801   ""
4802   "ld<mALLI>%U1.di\\t%0,%1"
4803   [(set_attr "type" "load")])
4805 (define_insn "stdi<mode>"
4806   [(unspec_volatile [(match_operand:ALLI 0 "memory_operand"    "m,m,Usc")
4807                      (match_operand:ALLI 1 "nonmemory_operand" "r,Cm3,i")]
4808                     VUNSPEC_ARC_STDI)]
4809   ""
4810   "st<mALLI>%U0.di\\t%1,%0"
4811   [(set_attr "length" "*,*,8")
4812    (set_attr "type" "store")])
4814 (define_insn_and_split "*stdidi_split"
4815   [(unspec_volatile [(match_operand:DI 0 "memory_operand"   "m")
4816                      (match_operand:DI 1 "register_operand" "r")]
4817                     VUNSPEC_ARC_STDI)]
4818   "!TARGET_LL64"
4819   "#"
4820   "&& reload_completed"
4821   [(unspec_volatile:SI [(match_dup 2) (match_dup 3)] VUNSPEC_ARC_STDI)
4822    (unspec_volatile:SI [(match_dup 4) (match_dup 5)] VUNSPEC_ARC_STDI)]
4823   "
4824   {
4825    operands[3] = gen_lowpart (SImode, operands[1]);
4826    operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
4827    operands[2] = gen_lowpart (SImode, operands[0]);
4828    operands[4] = gen_highpart (SImode, operands[0]);
4829   }
4830   "
4831   )
4833 (define_insn_and_split "*lddidi_split"
4834   [(set (match_operand:DI 0 "register_operand" "=r")
4835         (unspec_volatile:DI [(match_operand:DI 1 "memory_operand" "m")]
4836                             VUNSPEC_ARC_LDDI))]
4837   "!TARGET_LL64"
4838   "#"
4839   "&& reload_completed"
4840   [(set (match_dup 2) (unspec_volatile:SI [(match_dup 3)] VUNSPEC_ARC_LDDI))
4841    (set (match_dup 4) (unspec_volatile:SI [(match_dup 5)] VUNSPEC_ARC_LDDI))]
4842   "
4843   {
4844    operands[3] = gen_lowpart (SImode, operands[1]);
4845    operands[5] = gen_highpart (SImode, operands[1]);
4846    operands[2] = gen_lowpart (SImode, operands[0]);
4847    operands[4] = gen_highpart (SImode, operands[0]);
4848   }
4849   "
4850   )
4852 (define_insn "trap_s"
4853   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4854                    VUNSPEC_ARC_TRAP_S)]
4855   "!TARGET_ARC600_FAMILY"
4857   if (which_alternative == 0)
4858     {
4859       return \"trap_s\\t%0\";
4860     }
4862   /* Keep this message in sync with the one in arc.cc:arc_expand_builtin,
4863      because *.md files do not get scanned by exgettext.  */
4864   fatal_error (input_location,
4865                \"operand to %<trap_s%> should be an unsigned 6-bit value\");
4867   [(set_attr "length" "2")
4868   (set_attr "type" "misc")])
4870 (define_insn "unimp_s"
4871   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4872                    VUNSPEC_ARC_UNIMP_S)]
4873   "!TARGET_ARC600_FAMILY"
4874   "unimp_s"
4875   [(set_attr "length" "4")
4876   (set_attr "type" "misc")])
4878 ;; End of instructions generated through builtins
4880 ; Since the demise of REG_N_SETS as reliable data readily available to the
4881 ; target, it is no longer possible to find out
4882 ; in the prologue / epilogue expanders how many times blink is set.
4883 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4884 ; any explicit use of blink will cause it to be saved; hence we cannot
4885 ; represent the blink use in return / sibcall instructions themselves, and
4886 ; instead have to show it in EPILOGUE_USES and must explicitly
4887 ; forbid instructions that change blink in the return / sibcall delay slot.
4888 (define_expand "sibcall"
4889   [(parallel [(call (match_operand 0 "memory_operand" "")
4890                     (match_operand 1 "general_operand" ""))
4891               (simple_return)
4892               (use (match_operand 2 "" ""))])]
4893   ""
4894   "
4895   {
4896     rtx callee = XEXP (operands[0], 0);
4898     if (operands[2] == NULL_RTX)
4899       operands[2] = const0_rtx;
4900     if (GET_CODE (callee) != REG
4901         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4902       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4903   }"
4906 (define_expand "sibcall_value"
4907   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4908                    (call (match_operand 1 "memory_operand" "")
4909                          (match_operand 2 "general_operand" "")))
4910               (simple_return)
4911               (use (match_operand 3 "" ""))])]
4912   ""
4913   "
4914   {
4915     rtx callee = XEXP (operands[1], 0);
4917     if (operands[3] == NULL_RTX)
4918       operands[3] = const0_rtx;
4919     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4920       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4921   }"
4924 (define_insn "*sibcall_insn"
4925  [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4926                  "Cbp,Cbr,!Rcd,Rsc,Cal"))
4927         (match_operand 1 "" ""))
4928   (simple_return)
4929   (use (match_operand 2 "" ""))]
4930   ""
4931   "@
4932    b%!%*\\t%P0
4933    b%!%*\\t%P0
4934    j%!%*\\t[%0]
4935    j%!%*\\t[%0]
4936    j%!\\t%P0"
4937   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4938    (set_attr "predicable" "yes,no,no,yes,yes")
4939    (set_attr "iscompact" "false,false,maybe,false,false")
4940    (set_attr "is_SIBCALL" "yes")]
4943 (define_insn "*sibcall_value_insn"
4944  [(set (match_operand 0 "dest_reg_operand" "")
4945        (call (mem:SI (match_operand:SI 1 "call_address_operand"
4946               "Cbp,Cbr,!Rcd,Rsc,Cal"))
4947              (match_operand 2 "" "")))
4948   (simple_return)
4949   (use (match_operand 3 "" ""))]
4950   ""
4951   "@
4952    b%!%*\\t%P1
4953    b%!%*\\t%P1
4954    j%!%*\\t[%1]
4955    j%!%*\\t[%1]
4956    j%!\\t%P1"
4957   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4958    (set_attr "predicable" "yes,no,no,yes,yes")
4959    (set_attr "iscompact" "false,false,maybe,false,false")
4960    (set_attr "is_SIBCALL" "yes")]
4963 (define_expand "prologue"
4964   [(pc)]
4965   ""
4967   arc_expand_prologue ();
4968   DONE;
4971 (define_expand "epilogue"
4972   [(pc)]
4973   ""
4975   arc_expand_epilogue (0);
4976   DONE;
4979 (define_expand "sibcall_epilogue"
4980   [(pc)]
4981   ""
4983   arc_expand_epilogue (1);
4984   DONE;
4987 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4988 ; in the prologue / epilogue expanders how many times blink is set.
4989 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4990 ; any explicit use of blink will cause it to be saved; hence we cannot
4991 ; represent the blink use in return / sibcall instructions themselves, and
4992 ; instead have to show it in EPILOGUE_USES and must explicitly
4993 ; forbid instructions that change blink in the return / sibcall delay slot.
4994 (define_insn "simple_return"
4995   [(simple_return)]
4996   ""
4997   "j%!%*\\t[blink]"
4998   [(set_attr "type" "return")
4999    (set_attr "cond" "canuse")
5000    (set_attr "iscompact" "maybe")
5001    (set_attr "length" "*")])
5003 (define_insn "arc600_rtie"
5004   [(return)
5005    (unspec_volatile [(match_operand 0 "pmode_register_operand" "")]
5006                     VUNSPEC_ARC_ARC600_RTIE)]
5007   "TARGET_ARC600_FAMILY"
5008   "j.f\\t[%0]"
5009   [(set_attr "length" "4")
5010    (set_attr "type" "rtie")
5011    (set_attr "cond" "clob")])
5013 (define_insn "p_return_i"
5014   [(set (pc)
5015         (if_then_else (match_operator 0 "proper_comparison_operator"
5016                                       [(reg CC_REG) (const_int 0)])
5017                       (simple_return) (pc)))]
5018   "reload_completed"
5019   "j%d0%!%*\\t[blink]"
5020   [(set_attr "type" "return")
5021    (set_attr "cond" "use")
5022    (set_attr "iscompact" "maybe" )
5023    (set (attr "length")
5024         (cond [(not (match_operand 0 "equality_comparison_operator" ""))
5025                (const_int 4)
5026                (eq_attr "delay_slot_filled" "yes")
5027                (const_int 4)]
5028               (const_int 2)))])
5030 ;; Return nonzero if this function is known to have a null epilogue.
5031 ;; This allows the optimizer to omit jumps to jumps if no stack
5032 ;; was created.
5033 (define_expand "return"
5034   [(return)]
5035   "arc_can_use_return_insn ()"
5036   "")
5038  ;; Comment in final.cc (insn_current_reference_address) says
5039  ;; forward branch addresses are calculated from the next insn after branch
5040  ;; and for backward branches, it is calculated from the branch insn start.
5041  ;; The shortening logic here is tuned to accomodate this behavior
5042 ;; ??? This should be grokked by the ccfsm machinery.
5043 (define_insn "cbranchsi4_scratch"
5044   [(set (pc)
5045         (if_then_else (match_operator 0 "proper_comparison_operator"
5046                         [(match_operand:SI 1 "register_operand" "c,c, c")
5047                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
5048                       (label_ref (match_operand 3 "" ""))
5049                       (pc)))
5050    (clobber (match_operand 4 "cc_register" ""))]
5051    "(reload_completed
5052      || (TARGET_EARLY_CBRANCHSI
5053          && brcc_nolimm_operator (operands[0], VOIDmode)))
5054     && !CROSSING_JUMP_P (insn)"
5055    "*
5056      switch (get_attr_length (insn))
5057      {
5058        case 2: return \"br%d0%?\\t%1,%2,%l3\";
5059        case 4: return \"br%d0%*\\t%1,%B2,%l3\";
5060        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
5061                  return \"br%d0%*\\t%1,%B2,%l3\";
5062        /* FALLTHRU */
5063        case 6: case 10:
5064        case 12:return \"cmp%?\\t%1,%B2\\n\\tb%d0%*\\t%l3 ;br%d0 out of range\";
5065        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
5066      }
5067    "
5068   [(set_attr "cond" "clob, clob, clob")
5069    (set (attr "type")
5070         (if_then_else
5071           (match_test "valid_brcc_with_delay_p (operands)")
5072           (const_string "brcc")
5073           (const_string "brcc_no_delay_slot")))
5074    ; For forward branches, we need to account not only for the distance to
5075    ; the target, but also the difference between pcl and pc, the instruction
5076    ; length, and any delay insn, if present.
5077    (set
5078      (attr "length")
5079      (cond ; the outer cond does a test independent of branch shortening.
5080        [(match_operand 0 "brcc_nolimm_operator" "")
5081         (cond
5082           [(and (match_operand:CC_Z 4 "cc_register")
5083                 (eq_attr "delay_slot_filled" "no")
5084                 (ge (minus (match_dup 3) (pc)) (const_int -128))
5085                 (le (minus (match_dup 3) (pc))
5086                     (minus (const_int 122)
5087                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5088            (const_int 2)
5089            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5090                 (le (minus (match_dup 3) (pc))
5091                     (minus (const_int 244)
5092                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5093            (const_int 4)
5094            (and (match_operand:SI 1 "compact_register_operand" "")
5095                 (match_operand:SI 2 "compact_hreg_operand" ""))
5096            (const_int 6)]
5097           (const_int 8))]
5098          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5099                      (le (minus (match_dup 3) (pc)) (const_int 244)))
5100                 (const_int 8)
5101                 (and (match_operand:SI 1 "compact_register_operand" "")
5102                      (match_operand:SI 2 "compact_hreg_operand" ""))
5103                 (const_int 10)]
5104                (const_int 12))))
5105    (set (attr "iscompact")
5106         (if_then_else (match_test "get_attr_length (insn) & 2")
5107                       (const_string "true") (const_string "false")))])
5109 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5110 (define_insn "*bbit"
5111   [(set (pc)
5112         (if_then_else
5113           (match_operator 3 "equality_comparison_operator"
5114             [(zero_extract:SI (match_operand:SI 1 "register_operand"  "q,c")
5115                               (const_int 1)
5116                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5117              (const_int 0)])
5118           (label_ref (match_operand 0 "" ""))
5119           (pc)))
5120    (clobber (reg:CC_ZN CC_REG))]
5121   "!CROSSING_JUMP_P (insn)"
5123   switch (get_attr_length (insn))
5124     {
5125       case 4: return (GET_CODE (operands[3]) == EQ
5126                       ? \"bbit0%*\\t%1,%2,%0\" : \"bbit1%*\\t%1,%2,%0\");
5127       case 6:
5128       case 8: return \"btst%?\\t%1,%2\n\tb%d3%*\\t%0; bbit out of range\";
5129       default: gcc_unreachable ();
5130     }
5132   [(set_attr "type" "brcc")
5133    (set_attr "cond" "clob")
5134    (set (attr "length")
5135         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5136                     (le (minus (match_dup 0) (pc))
5137                     (minus (const_int 248)
5138                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5139                (const_int 4)
5140                (eq (symbol_ref "which_alternative") (const_int 0))
5141                (const_int 6)]
5142               (const_int 8)))
5143    (set (attr "iscompact")
5144         (if_then_else (match_test "get_attr_length (insn) == 6")
5145                       (const_string "true") (const_string "false")))])
5147 ;; -------------------------------------------------------------------
5148 ;; Hardware loop
5149 ;; -------------------------------------------------------------------
5151 ; operand 0 is the loop count pseudo register
5152 ; operand 1 is the label to jump to at the top of the loop
5153 (define_expand "doloop_end"
5154   [(parallel [(set (pc)
5155                    (if_then_else
5156                     (ne (match_operand 0 "nonimmediate_operand")
5157                         (const_int 1))
5158                     (label_ref (match_operand 1 "" ""))
5159                     (pc)))
5160               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5161               (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5162               (clobber (match_dup 2))])]
5163   ""
5165  if (GET_MODE (operands[0]) != SImode)
5166    FAIL;
5167  operands[2] = gen_rtx_SCRATCH (SImode);
5170 (define_insn "arc_lp"
5171   [(unspec:SI [(reg:SI LP_COUNT)]
5172               UNSPEC_ARC_LP)
5173    (use (label_ref (match_operand 0 "" "")))
5174    (use (label_ref (match_operand 1 "" "")))]
5175   ""
5176   "lp\\t@%l1\\t; lp_count:@%l0->@%l1"
5177   [(set_attr "type" "loop_setup")
5178    (set_attr "length" "4")])
5180 ;; if by any chance the lp_count is not used, then use an 'r'
5181 ;; register, instead of going to memory.
5182 ;; split pattern for the very slim chance when the loop register is
5183 ;; memory.
5184 (define_insn_and_split "loop_end"
5185   [(set (pc)
5186         (if_then_else (ne (match_operand:SI 0 "nonimmediate_operand" "+r,!m")
5187                           (const_int 1))
5188                       (label_ref (match_operand 1 "" ""))
5189                       (pc)))
5190    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5191    (unspec:SI [(const_int 0)] UNSPEC_ARC_LP)
5192    (clobber (match_scratch:SI 2 "=X,&r"))]
5193   ""
5194   "@
5195    ; ZOL_END, begins @%l1
5196    #"
5197   "reload_completed && memory_operand (operands[0], Pmode)"
5198   [(set (match_dup 2) (match_dup 0))
5199    (parallel
5200     [(set (reg:CC_ZN CC_REG)
5201           (compare:CC_ZN (plus:SI (match_dup 2) (const_int -1))
5202                          (const_int 0)))
5203      (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
5204    (set (match_dup 0) (match_dup 2))
5205    (set (pc)
5206         (if_then_else (ne (reg:CC_ZN CC_REG)
5207                           (const_int 0))
5208                       (label_ref (match_dup 1))
5209                       (pc)))]
5210   ""
5211   [(set_attr "length" "0,24")
5212    (set_attr "predicable" "no")
5213    (set_attr "type" "loop_end")])
5215 (define_insn "loop_fail"
5216   [(set (reg:SI LP_COUNT)
5217         (plus:SI (reg:SI LP_COUNT) (const_int -1)))
5218    (set (reg:CC_ZN CC_REG)
5219         (compare:CC_ZN (plus:SI (reg:SI LP_COUNT) (const_int -1))
5220                        (const_int 0)))]
5221   ""
5222   "sub.f%?\\tlp_count,lp_count,1"
5223   [(set_attr "iscompact" "false")
5224    (set_attr "type" "compare")
5225    (set_attr "cond" "set_zn")
5226    (set_attr "length" "4")
5227    (set_attr "predicable" "yes")])
5229 (define_insn_and_split "dbnz"
5230   [(set (pc)
5231         (if_then_else
5232          (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m")
5233                       (const_int -1))
5234              (const_int 0))
5235          (label_ref (match_operand 1 "" ""))
5236          (pc)))
5237    (set (match_dup 0)
5238         (plus:SI (match_dup 0)
5239                  (const_int -1)))
5240    (clobber (match_scratch:SI 2 "=X,r"))]
5241   "TARGET_DBNZ"
5242   "@
5243    dbnz%*\\t%0,%l1
5244    #"
5245   "TARGET_DBNZ && reload_completed && memory_operand (operands[0], SImode)"
5246   [(set (match_dup 2) (match_dup 0))
5247    (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5248    (set (reg:CC CC_REG) (compare:CC (match_dup 2) (const_int 0)))
5249    (set (match_dup 0) (match_dup 2))
5250    (set (pc) (if_then_else (ge (reg:CC CC_REG)
5251                                (const_int 0))
5252                            (label_ref (match_dup 1))
5253                            (pc)))]
5254   ""
5255   [(set_attr "iscompact" "false")
5256    (set_attr "type" "loop_end")
5257    (set_attr "length" "4,20")])
5259 (define_expand "cpymemsi"
5260   [(match_operand:BLK 0 "" "")
5261    (match_operand:BLK 1 "" "")
5262    (match_operand:SI 2 "nonmemory_operand" "")
5263    (match_operand 3 "immediate_operand" "")]
5264   ""
5265   "if (arc_expand_cpymem (operands)) DONE; else FAIL;")
5267 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5268 ;; to the point that we can generate cmove instructions.
5269 (define_expand "cbranch<mode>4"
5270   [(set (reg:CC CC_REG)
5271         (compare:CC (match_operand:SDF 1 "register_operand" "")
5272                     (match_operand:SDF 2 "register_operand" "")))
5273    (set (pc)
5274         (if_then_else
5275          (match_operator 0 "comparison_operator" [(reg CC_REG)
5276                                                       (const_int 0)])
5277          (label_ref (match_operand 3 "" ""))
5278          (pc)))]
5280   "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5282   gcc_assert (XEXP (operands[0], 0) == operands[1]);
5283   gcc_assert (XEXP (operands[0], 1) == operands[2]);
5284   operands[0] = gen_compare_reg (operands[0], VOIDmode);
5285   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5286   DONE;
5289 (define_expand "cmp_float"
5290   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5291               (clobber (reg:SI RETURN_ADDR_REGNUM))
5292               (clobber (reg:SI R12_REG))])]
5293   ""
5294   "")
5296 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5297 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5298                        (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5300 (define_insn "*cmpsf_<cmp>"
5301   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5302    (clobber (reg:SI RETURN_ADDR_REGNUM))
5303    (clobber (reg:SI R12_REG))]
5304   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5305    && SFUNC_CHECK_PREDICABLE"
5306   "*return arc_output_libcall (\"__<cmp>sf2\");"
5307   [(set_attr "is_sfunc" "yes")
5308    (set_attr "predicable" "yes")])
5310 ;; N.B. for "*cmpdf_ord":
5311 ;; double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5312 ;; for the floating point emulation to recognize the NaN.
5313 (define_insn "*cmpdf_<cmp>"
5314   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5315    (clobber (reg:SI RETURN_ADDR_REGNUM))
5316    (clobber (reg:SI R12_REG))]
5317   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5318    && SFUNC_CHECK_PREDICABLE"
5319   "*return arc_output_libcall (\"__<cmp>df2\");"
5320   [(set_attr "is_sfunc" "yes")
5321    (set_attr "predicable" "yes")])
5323 (define_insn "abssf2"
5324   [(set (match_operand:SF 0 "dest_reg_operand"    "=q,r,r")
5325         (abs:SF (match_operand:SF 1 "register_operand" "0,0,r")))]
5326   ""
5327   "bclr%?\\t%0,%1,31"
5328   [(set_attr "type" "unary")
5329    (set_attr "iscompact" "maybe,false,false")
5330    (set_attr "length" "2,4,4")
5331    (set_attr "predicable" "no,yes,no")])
5333 (define_insn "negsf2"
5334   [(set (match_operand:SF 0 "dest_reg_operand" "=r,r")
5335         (neg:SF (match_operand:SF 1 "register_operand" "0,r")))]
5336   ""
5337   "bxor%?\\t%0,%1,31"
5338   [(set_attr "type" "unary")
5339    (set_attr "predicable" "yes,no")])
5341 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5342 (define_insn "*millicode_thunk_st"
5343   [(match_parallel 0 "millicode_store_operation"
5344                    [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5345   ""
5347   output_asm_insn ("bl%* __st_r13_to_%0",
5348                    &SET_SRC (XVECEXP (operands[0], 0,
5349                                       XVECLEN (operands[0], 0) - 2)));
5350   return "";
5352   [(set_attr "type" "call")])
5354 (define_insn "*millicode_thunk_ld"
5355   [(match_parallel 0 "millicode_load_clob_operation"
5356                    [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5357   ""
5359   output_asm_insn ("bl%* __ld_r13_to_%0",
5360                    &SET_DEST (XVECEXP (operands[0], 0,
5361                                        XVECLEN (operands[0], 0) - 2)));
5362   return "";
5364   [(set_attr "type" "call")])
5366 ; the sibthunk restores blink, so we use the return rtx.
5367 (define_insn "*millicode_sibthunk_ld"
5368   [(match_parallel 0 "millicode_load_operation"
5369                    [(return)
5370                     (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5371                     (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5372   ""
5374   output_asm_insn ("b%* __ld_r13_to_%0_ret",
5375                    &SET_DEST (XVECEXP (operands[0], 0,
5376                                        XVECLEN (operands[0], 0) - 1)));
5377   return "";
5379   [(set_attr "type" "call")
5380    (set_attr "is_SIBCALL" "yes")])
5382 ;; For thread pointer builtins
5383 (define_expand "get_thread_pointersi"
5384   [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5385  ""
5386  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5388 (define_expand "set_thread_pointersi"
5389   [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5390  ""
5391  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5393 ;; If hardware floating point is available, don't define a negdf pattern;
5394 ;; it would be something like:
5395 ;;(define_insn "negdf2"
5396 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5397 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5398 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5399 ;;  ""
5400 ;;  "@
5401 ;;   bxor%? %H0,%H1,31
5402 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
5403 ;;   drsubh%F0%F1 0,0,0
5404 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5405 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5406 ;;   (set_attr "iscompact" "false,false,false,false")
5407 ;;   (set_attr "length" "4,4,8,12")
5408 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
5409 ;; and this suffers from always requiring a long immediate when using
5410 ;; the floating point hardware.
5411 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5412 ;; constant zero efficiently into a register when we want to do the
5413 ;; computation using the floating point hardware.  There should be a special
5414 ;; subdf alternative that matches a zero operand 1, which then can allow
5415 ;; to use bxor to flip the high bit of an integer register.
5416 ;; ??? we actually can't use the floating point hardware for neg, because
5417 ;; this would not work right for -0.  OTOH optabs.cc has already code
5418 ;; to synthesyze negate by flipping the sign bit.
5420 ;;V2 instructions
5421 (define_insn "bswapsi2"
5422   [(set (match_operand:SI 0 "register_operand"           "= r,r")
5423         (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5424   "TARGET_V2 && TARGET_SWAP"
5425   "swape\\t%0,%1"
5426   [(set_attr "length" "4,8")
5427    (set_attr "type" "two_cycle_core")])
5429 (define_expand "prefetch"
5430   [(prefetch (match_operand:SI 0 "address_operand" "")
5431              (match_operand:SI 1 "const_int_operand" "")
5432              (match_operand:SI 2 "const_int_operand" ""))]
5433   "TARGET_HS"
5434   "")
5436 (define_insn "prefetch_1"
5437   [(prefetch (match_operand:SI 0 "register_operand" "r")
5438              (match_operand:SI 1 "const_int_operand" "n")
5439              (match_operand:SI 2 "const_int_operand" "n"))]
5440   "TARGET_HS"
5441   {
5442    if (INTVAL (operands[1]))
5443       return "prefetchw [%0]";
5444    else
5445       return "prefetch [%0]";
5446   }
5447   [(set_attr "type" "load")
5448    (set_attr "length" "4")])
5450 (define_insn "prefetch_2"
5451   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5452                       (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5453              (match_operand:SI 2 "const_int_operand" "n,n,n")
5454              (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5455   "TARGET_HS"
5456   {
5457    if (INTVAL (operands[2]))
5458       return "prefetchw\\t[%0, %1]";
5459    else
5460       return "prefetch\\t[%0, %1]";
5461   }
5462   [(set_attr "type" "load")
5463    (set_attr "length" "4,4,8")])
5465 (define_insn "prefetch_3"
5466   [(prefetch (match_operand:SI 0 "address_operand" "p")
5467              (match_operand:SI 1 "const_int_operand" "n")
5468              (match_operand:SI 2 "const_int_operand" "n"))]
5469   "TARGET_HS"
5470   {
5471    operands[0] = gen_rtx_MEM (SImode, operands[0]);
5472    if (INTVAL (operands[1]))
5473       return "prefetchw%U0\\t%0";
5474    else
5475       return "prefetch%U0\\t%0";
5476    }
5477   [(set_attr "type" "load")
5478    (set_attr "length" "8")])
5480 (define_insn "divsi3"
5481   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5482         (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5483                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5484   "TARGET_DIVREM"
5485   "div%?\\t%0,%1,%2"
5486   [(set_attr "length" "4,4,8,4,4,4,8,8")
5487    (set_attr "iscompact" "false")
5488    (set_attr "type" "div_rem")
5489    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5490    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5491    ])
5493 (define_insn "udivsi3"
5494   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5495         (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5496                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5497   "TARGET_DIVREM"
5498   "divu%?\\t%0,%1,%2"
5499   [(set_attr "length" "4,4,8,4,4,4,8,8")
5500    (set_attr "iscompact" "false")
5501    (set_attr "type" "div_rem")
5502    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5503    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5504    ])
5506 (define_insn "modsi3"
5507   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5508         (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5509                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5510   "TARGET_DIVREM"
5511   "rem%?\\t%0,%1,%2"
5512   [(set_attr "length" "4,4,8,4,4,4,8,8")
5513    (set_attr "iscompact" "false")
5514    (set_attr "type" "div_rem")
5515    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5516    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5517    ])
5519 (define_insn "umodsi3"
5520   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5521         (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5522                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5523   "TARGET_DIVREM"
5524   "remu%?\\t%0,%1,%2"
5525   [(set_attr "length" "4,4,8,4,4,4,8,8")
5526    (set_attr "iscompact" "false")
5527    (set_attr "type" "div_rem")
5528    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5529    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5530    ])
5532 ;; SETcc instructions
5533 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5535 (define_insn "arcset<code>"
5536   [(set (match_operand:SI 0 "register_operand"                "=r,r,r,r,r,r,r")
5537         (arcCC_cond:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,0,r")
5538                        (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5539   "TARGET_V2 && TARGET_CODE_DENSITY"
5540   "set<code>%?\\t%0,%1,%2"
5541   [(set_attr "length" "4,4,4,4,4,8,8")
5542    (set_attr "iscompact" "false")
5543    (set_attr "type" "compare")
5544    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5545    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5546    ])
5548 (define_insn "arcsetltu"
5549   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5550         (ltu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5551                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5552   "TARGET_V2 && TARGET_CODE_DENSITY"
5553   "setlo%?\\t%0,%1,%2"
5554   [(set_attr "length" "4,4,4,4,4,8,8")
5555    (set_attr "iscompact" "false")
5556    (set_attr "type" "compare")
5557    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5558    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5559    ])
5561 (define_insn "arcsetgeu"
5562   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5563         (geu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5564                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5565   "TARGET_V2 && TARGET_CODE_DENSITY"
5566   "seths%?\\t%0,%1,%2"
5567   [(set_attr "length" "4,4,4,4,4,8,8")
5568    (set_attr "iscompact" "false")
5569    (set_attr "type" "compare")
5570    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5571    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5572    ])
5574 ;; Special cases of SETCC
5575 (define_insn_and_split "arcsethi"
5576   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5577         (gtu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5578                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5579   "TARGET_V2 && TARGET_CODE_DENSITY"
5580   "setlo%?\\t%0,%2,%1"
5581   "reload_completed
5582    && CONST_INT_P (operands[2])
5583    && satisfies_constraint_C62 (operands[2])"
5584   [(const_int 0)]
5585   "{
5586     /* sethi a,b,u6 => seths a,b,u6 + 1.  */
5587     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5588     emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5589     DONE;
5590  }"
5591  [(set_attr "length" "4,4,4,8")
5592    (set_attr "iscompact" "false")
5593    (set_attr "type" "compare")
5594    (set_attr "predicable" "yes,no,no,no")
5595    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5598 (define_insn_and_split "arcsetls"
5599   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5600         (leu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5601                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5602   "TARGET_V2 && TARGET_CODE_DENSITY"
5603   "seths%?\\t%0,%2,%1"
5604   "reload_completed
5605    && CONST_INT_P (operands[2])
5606    && satisfies_constraint_C62 (operands[2])"
5607   [(const_int 0)]
5608   "{
5609     /* setls a,b,u6 => setlo a,b,u6 + 1.  */
5610     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5611     emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5612     DONE;
5613  }"
5614  [(set_attr "length" "4,4,4,8")
5615    (set_attr "iscompact" "false")
5616    (set_attr "type" "compare")
5617    (set_attr "predicable" "yes,no,no,no")
5618    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5621 ; Any mode that needs to be solved by secondary reload
5622 (define_mode_iterator SRI [QI HI])
5624 (define_expand "reload_<mode>_load"
5625   [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5626               (match_operand:SRI 1 "memory_operand" "m")
5627               (match_operand:SI 2 "register_operand" "=&r")])]
5628   ""
5630  arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5631  DONE;
5634 (define_expand "reload_<mode>_store"
5635   [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5636               (match_operand:SRI 1 "register_operand" "r")
5637               (match_operand:SI 2 "register_operand" "=&r")])]
5638   ""
5640  arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5641  DONE;
5644 (define_insn "extzvsi"
5645   [(set (match_operand:SI 0 "register_operand"                  "=r  ,  r,r,r")
5646         (zero_extract:SI (match_operand:SI 1 "register_operand"  "0  ,  r,r,0")
5647                          (match_operand:SI 2 "const_int_operand" "C3p,C3p,n,n")
5648                          (match_operand:SI 3 "const_int_operand" "n  ,  n,n,n")))]
5649   "TARGET_HS && TARGET_BARREL_SHIFTER"
5650   {
5651    int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5652    operands[2] = GEN_INT (assemble_op2);
5653    return "xbfu%?\\t%0,%1,%2";
5654   }
5655   [(set_attr "type"       "shift")
5656    (set_attr "iscompact"  "false")
5657    (set_attr "length"     "4,4,8,8")
5658    (set_attr "predicable" "yes,no,no,yes")
5659    (set_attr "cond"       "canuse,nocond,nocond,canuse_limm")])
5661 (define_insn "kflag"
5662   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5663                    VUNSPEC_ARC_KFLAG)]
5664   "TARGET_V2"
5665   "@
5666     kflag%?\\t%0
5667     kflag\\t%0
5668     kflag%?\\t%0"
5669   [(set_attr "length" "4,4,8")
5670    (set_attr "type" "misc,misc,misc")
5671    (set_attr "predicable" "yes,no,yes")
5672    (set_attr "cond" "clob,clob,clob")])
5674 (define_insn "clri"
5675   [(set (match_operand:SI  0 "dest_reg_operand" "=r")
5676         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5677                             VUNSPEC_ARC_CLRI))]
5678   "TARGET_V2"
5679   "clri\\t%0"
5680   [(set_attr "length" "4")
5681    (set_attr "type" "misc")])
5683 (define_insn "ffs"
5684   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
5685         (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5686                             UNSPEC_ARC_FFS))]
5687   "TARGET_NORM && TARGET_V2"
5688   "ffs\\t%0,%1"
5689   [(set_attr "length" "4,8")
5690    (set_attr "type" "two_cycle_core,two_cycle_core")])
5692 (define_insn "ffs_f"
5693   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
5694         (unspec:SI [(match_operand:SI 1 "general_operand" "rL,Cal")]
5695                             UNSPEC_ARC_FFS))
5696    (set (reg:CC_ZN CC_REG)
5697         (compare:CC_ZN (match_dup 1) (const_int 0)))]
5698   "TARGET_NORM && TARGET_V2"
5699   "ffs.f\\t%0,%1"
5700   [(set_attr "length" "4,8")
5701    (set_attr "type" "two_cycle_core,two_cycle_core")])
5703 (define_expand "ffssi2"
5704   [(parallel [(set (match_dup 2)
5705                    (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5706                               UNSPEC_ARC_FFS))
5707               (set (reg:CC_ZN CC_REG)
5708                    (compare:CC_ZN (match_dup 1) (const_int 0)))])
5709    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5710    (set (match_operand:SI 0 "dest_reg_operand" "")
5711         (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5712                          (const_int 0)
5713                          (match_dup 2)))]
5714   "TARGET_NORM && TARGET_V2"
5715   {
5716    operands[2] = gen_reg_rtx (SImode);
5717    })
5719 (define_insn "fls"
5720   [(set (match_operand:SI  0 "register_operand" "=r,r")
5721         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "rL,Cal")]
5722                             UNSPEC_ARC_FLS))]
5723   "TARGET_NORM && TARGET_V2"
5724   "fls\\t%0,%1"
5725   [(set_attr "length" "4,8")
5726    (set_attr "type" "two_cycle_core,two_cycle_core")])
5728 (define_insn "seti"
5729   [(unspec_volatile:SI [(match_operand:SI 0 "nonmemory_operand" "rL")]
5730                        VUNSPEC_ARC_SETI)]
5731   "TARGET_V2"
5732   "seti\\t%0"
5733   [(set_attr "length" "4")
5734    (set_attr "type" "misc")])
5736 ;; FPU/FPX expands
5738 ;;add
5739 (define_expand "addsf3"
5740   [(set (match_operand:SF 0 "register_operand"           "")
5741         (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5742                  (match_operand:SF 2 "nonmemory_operand" "")))]
5743   "TARGET_FP_SP_BASE || TARGET_SPFP"
5744   "
5745   if (!register_operand (operands[1], SFmode)
5746       && !register_operand (operands[2], SFmode))
5747     operands[1] = force_reg (SFmode, operands[1]);
5748   ")
5750 ;;sub
5751 (define_expand "subsf3"
5752   [(set (match_operand:SF 0 "register_operand"            "")
5753         (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5754                   (match_operand:SF 2 "nonmemory_operand" "")))]
5755   "TARGET_FP_SP_BASE || TARGET_SPFP"
5756   "
5757   if (!register_operand (operands[1], SFmode)
5758       && !register_operand (operands[2], SFmode))
5759     operands[1] = force_reg (SFmode, operands[1]);
5760   ")
5762 ;;mul
5763 (define_expand "mulsf3"
5764   [(set (match_operand:SF 0 "register_operand"           "")
5765         (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5766                  (match_operand:SF 2 "nonmemory_operand" "")))]
5767   "TARGET_FP_SP_BASE || TARGET_SPFP"
5768   "
5769   if (!register_operand (operands[1], SFmode)
5770       && !register_operand (operands[2], SFmode))
5771     operands[1] = force_reg (SFmode, operands[1]);
5772   ")
5774 ;;add
5775 (define_expand "adddf3"
5776   [(set (match_operand:DF 0 "double_register_operand"           "")
5777         (plus:DF (match_operand:DF 1 "double_register_operand"  "")
5778                  (match_operand:DF 2 "nonmemory_operand" "")))]
5779  "TARGET_FP_DP_BASE || TARGET_DPFP"
5781   if (TARGET_DPFP)
5782    {
5783     if (GET_CODE (operands[2]) == CONST_DOUBLE)
5784      {
5785         rtx first, second, tmp;
5786         split_double (operands[2], &first, &second);
5787         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5788         emit_insn (gen_adddf3_insn (operands[0], operands[1],
5789                                     operands[2], tmp, const0_rtx));
5790      }
5791     else
5792      emit_insn (gen_adddf3_insn (operands[0], operands[1],
5793                                  operands[2], const1_rtx, const1_rtx));
5794    DONE;
5795   }
5796  else if (TARGET_FP_DP_BASE)
5797   {
5798    if (!even_register_operand (operands[2], DFmode))
5799       operands[2] = force_reg (DFmode, operands[2]);
5801    if (!even_register_operand (operands[1], DFmode))
5802       operands[1] = force_reg (DFmode, operands[1]);
5803   }
5804  else
5805   gcc_unreachable ();
5806  ")
5808 ;;sub
5809 (define_expand "subdf3"
5810   [(set (match_operand:DF 0 "double_register_operand"            "")
5811         (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5812                   (match_operand:DF 2 "nonmemory_operand" "")))]
5813   "TARGET_FP_DP_BASE || TARGET_DPFP"
5814   "
5815    if (TARGET_DPFP)
5816     {
5817      if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
5818        operands[1] = force_reg (DFmode, operands[1]);
5819      if ((GET_CODE (operands[1]) == CONST_DOUBLE)
5820           || GET_CODE (operands[2]) == CONST_DOUBLE)
5821       {
5822         rtx first, second, tmp;
5823         int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
5824         split_double (operands[const_index], &first, &second);
5825         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5826         emit_insn (gen_subdf3_insn (operands[0], operands[1],
5827                                     operands[2], tmp, const0_rtx));
5828       }
5829     else
5830      emit_insn (gen_subdf3_insn (operands[0], operands[1],
5831                                  operands[2], const1_rtx, const1_rtx));
5832     DONE;
5833    }
5834   else if (TARGET_FP_DP_BASE)
5835    {
5836     if (!even_register_operand (operands[2], DFmode))
5837        operands[2] = force_reg (DFmode, operands[2]);
5839     if (!even_register_operand (operands[1], DFmode))
5840        operands[1] = force_reg (DFmode, operands[1]);
5841    }
5842   else
5843    gcc_unreachable ();
5844   ")
5846 ;;mul
5847 (define_expand "muldf3"
5848   [(set (match_operand:DF 0 "double_register_operand"           "")
5849         (mult:DF (match_operand:DF 1 "double_register_operand"  "")
5850                  (match_operand:DF 2 "nonmemory_operand" "")))]
5851   "TARGET_FP_DP_BASE || TARGET_DPFP"
5852   "
5853    if (TARGET_DPFP)
5854     {
5855      if (GET_CODE (operands[2]) == CONST_DOUBLE)
5856       {
5857         rtx first, second, tmp;
5858         split_double (operands[2], &first, &second);
5859         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5860         emit_insn (gen_muldf3_insn (operands[0], operands[1],
5861                                     operands[2], tmp, const0_rtx));
5862       }
5863      else
5864       emit_insn (gen_muldf3_insn (operands[0], operands[1],
5865                                   operands[2], const1_rtx, const1_rtx));
5866     DONE;
5867    }
5868   else if (TARGET_FP_DP_BASE)
5869    {
5870     if (!even_register_operand (operands[2], DFmode))
5871        operands[2] = force_reg (DFmode, operands[2]);
5873     if (!even_register_operand (operands[1], DFmode))
5874        operands[1] = force_reg (DFmode, operands[1]);
5875    }
5876   else
5877    gcc_unreachable ();
5878  ")
5880 ;;div
5881 (define_expand "divsf3"
5882   [(set (match_operand:SF 0 "register_operand"        "")
5883         (div:SF (match_operand:SF 1 "nonmemory_operand" "")
5884                 (match_operand:SF 2 "nonmemory_operand" "")))]
5885   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5886   "
5887   if (TARGET_FPX_QUARK)
5888    {
5889      operands[1] = force_reg (SFmode, operands[1]);
5890      operands[2] = force_reg (SFmode, operands[2]);
5891    }
5892   else
5893    {
5894      if (!register_operand (operands[1], SFmode)
5895         && !register_operand (operands[2], SFmode))
5896        operands[1] = force_reg (SFmode, operands[1]);
5897    }
5898   ")
5900 ;; Square root
5901 (define_expand "sqrtsf2"
5902   [(set (match_operand:SF 0 "register_operand"           "")
5903         (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
5904   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
5905   "
5906   if (TARGET_FPX_QUARK)
5907    {
5908      operands[1] = force_reg (SFmode, operands[1]);
5909    }
5912 ;; SF->SI (using rounding towards zero)
5913 (define_expand "fix_truncsfsi2"
5914   [(set (match_operand:SI 0 "register_operand"                "")
5915         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
5916   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5917   "")
5919 ;; SI->SF
5920 (define_expand "floatsisf2"
5921   [(set (match_operand:SF 0 "register_operand"            "")
5922         (float:SF (match_operand:SI 1 "register_operand" "")))]
5923   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
5924   "")
5926 (define_expand "extzv"
5927   [(set (match_operand:SI 0 "register_operand" "")
5928         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
5929                          (match_operand:SI 2 "const_int_operand" "")
5930                          (match_operand:SI 3 "const_int_operand" "")))]
5931   "TARGET_NPS_BITOPS")
5933 ; We need a sanity check in the instuction predicate because combine
5934 ; will throw any old rubbish at us and see what sticks.
5935 (define_insn "*extzv_i"
5936   [(set (match_operand:SI 0 "register_operand" "=Rrq")
5937         (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
5938                          (match_operand:SI 2 "const_int_operand" "n")
5939                          (match_operand:SI 3 "const_int_operand" "n")))]
5940   "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
5941   "movb.cl\\t%0,%1,0,%3,%2"
5942   [(set_attr "type" "shift")
5943    (set_attr "length" "4")])
5945 (define_expand "insv"
5946   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
5947                          (match_operand:SI 1 "const_int_operand" "")
5948                          (match_operand:SI 2 "const_int_operand" ""))
5949         (match_operand:SI 3 "nonmemory_operand" ""))]
5950   "TARGET_NPS_BITOPS"
5952   int size = INTVAL (operands[1]);
5954   if (size != 1 && size != 2 && size != 4 && size != 8)
5955     operands[3] = force_reg (SImode, operands[3]);
5958 (define_insn "*insv_i"
5959   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
5960                          (match_operand:SI 1 "const_int_operand" "C18,n")
5961                          (match_operand:SI 2 "const_int_operand" "n,n"))
5962         (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
5963   "TARGET_NPS_BITOPS
5964    && (register_operand (operands[3], SImode)
5965        || satisfies_constraint_C18 (operands[1]))"
5966   "@
5967    movbi\\t%0,%0,%3,%2,%1
5968    movb\\t%0,%0,%3,%2,0,%1"
5969   [(set_attr "type" "shift")
5970    (set_attr "length" "4")])
5972 (define_insn "*movb"
5973   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5974                          (match_operand:SI 1 "const_int_operand" "n")
5975                          (match_operand:SI 2 "const_int_operand" "n"))
5976         (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5977                          (match_dup 1)
5978                          (match_operand:SI 4 "const_int_operand" "n")))]
5979   "TARGET_NPS_BITOPS"
5980   "movb\\t%0,%0,%3,%2,%4,%1"
5981   [(set_attr "type" "shift")
5982    (set_attr "length" "4")])
5984 (define_insn "*movb_signed"
5985   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5986                          (match_operand:SI 1 "const_int_operand" "n")
5987                          (match_operand:SI 2 "const_int_operand" "n"))
5988         (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
5989                          (match_dup 1)
5990                          (match_operand:SI 4 "const_int_operand" "n")))]
5991   "TARGET_NPS_BITOPS"
5992   "movb\\t%0,%0,%3,%2,%4,%1"
5993   [(set_attr "type" "shift")
5994    (set_attr "length" "4")])
5996 (define_insn "*movb_high"
5997   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
5998                          (match_operand:SI 1 "const_int_operand" "n")
5999                          (match_operand:SI 2 "const_int_operand" "n"))
6000         (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6001                      (match_operand:SI 4 "const_int_operand" "n")))]
6002   "TARGET_NPS_BITOPS
6003    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6004   "movb\\t%0,%0,%3,%2,%4,%1"
6005   [(set_attr "type" "shift")
6006    (set_attr "length" "4")])
6008 ; N.B.: when processing signed bitfields that fit in the top half of
6009 ; a word, gcc will use a narrow sign extending load, and in this case
6010 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6011 (define_insn "*movb_high_signed"
6012   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6013                          (match_operand:SI 1 "const_int_operand" "n")
6014                          (match_operand:SI 2 "const_int_operand" "n"))
6015         (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6016                      (match_operand:SI 4 "const_int_operand" "n")))]
6017   "TARGET_NPS_BITOPS
6018    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6019   "movb\\t%0,%0,%3,%2,%4,%1"
6020   [(set_attr "type" "shift")
6021    (set_attr "length" "4")])
6023 (define_split
6024   [(set (match_operand:SI 0 "register_operand" "")
6025         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6026                            (match_operand:SI 2 "const_int_operand" ""))
6027                 (subreg:SI (match_operand 3 "") 0)))]
6028   "TARGET_NPS_BITOPS
6029    && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6030    && !reg_overlap_mentioned_p (operands[0], operands[1])"
6031   [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6032    (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6033         (match_dup 1))]
6034   "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6036 (define_insn "*mrgb"
6037   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6038                          (match_operand:SI 1 "const_int_operand" "n")
6039                          (match_operand:SI 2 "const_int_operand" "n"))
6040         (zero_extract:SI (match_dup 0) (match_dup 1)
6041                          (match_operand:SI 3 "const_int_operand" "n")))
6042    (set (zero_extract:SI (match_dup 0)
6043                          (match_operand:SI 4 "const_int_operand" "n")
6044                          (match_operand:SI 5 "const_int_operand" "n"))
6045         (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6046                          (match_dup 4)
6047                          (match_operand:SI 7 "const_int_operand" "n")))]
6048   "TARGET_NPS_BITOPS"
6050   output_asm_insn ("mrgb\\t%0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6051   /* The ;%? updates the known unalignment.  */
6052   return arc_short_long (insn, ";%?", "nop_s");
6054   [(set_attr "type" "shift")
6055    (set_attr "length" "6")
6056    (set_attr "iscompact" "true")])
6058 ;; combine fumbles combination of two movb patterns, and then the
6059 ;; combination is rejected by combinable_i3pat.
6060 ;; Thus, we can only use a peephole2 to combine two such insns.
6062 (define_peephole2
6063   [(set (match_operand:SI 0 "register_operand" "")
6064         (match_operand:SI 1 "register_operand" ""))
6065    (set (zero_extract:SI (match_dup 0)
6066                          (match_operand:SI 2 "const_int_operand" "")
6067                          (match_operand:SI 3 "const_int_operand" ""))
6068         (zero_extract:SI (match_dup 1)
6069                          (match_dup 2)
6070                          (match_operand:SI 4 "const_int_operand" "")))
6071    (match_operand 9) ; unrelated insn scheduled here
6072    (set (zero_extract:SI (match_dup 0)
6073                          (match_operand:SI 5 "const_int_operand" "")
6074                          (match_operand:SI 6 "const_int_operand" ""))
6075         (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6076                          (match_dup 5)
6077                          (match_operand:SI 8 "const_int_operand" "")))]
6078   "TARGET_NPS_BITOPS
6079    // Check that the second movb doesn't clobber an input of the extra insn.
6080    && !reg_overlap_mentioned_p (operands[0], operands[9])
6081    // And vice versa.
6082    && !reg_set_p (operands[0], operands[9])
6083    && !reg_set_p (operands[7], operands[9])"
6084   [(set (match_dup 0) (match_dup 1))
6085    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6086                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6087               (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6088                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6089    (match_dup 9)])
6091 (define_peephole2
6092   [(set (match_operand:SI 0 "register_operand" "")
6093         (match_operand:SI 1 "register_operand" ""))
6094    (set (zero_extract:SI (match_dup 0)
6095                          (match_operand:SI 2 "const_int_operand" "")
6096                          (match_operand:SI 3 "const_int_operand" ""))
6097         (zero_extract:SI (match_dup 1)
6098                          (match_dup 2)
6099                          (match_operand:SI 4 "const_int_operand" "")))
6100    (set (match_dup 1) (match_operand 8))
6101    (set (zero_extract:SI (match_dup 0)
6102                          (match_operand:SI 5 "const_int_operand" "")
6103                          (match_operand:SI 6 "const_int_operand" ""))
6104         (zero_extract:SI (match_dup 1) (match_dup 5)
6105                          (match_operand:SI 7 "const_int_operand" "")))]
6106   "TARGET_NPS_BITOPS
6107    && !reg_overlap_mentioned_p (operands[0], operands[8])"
6108   [(set (match_dup 0) (match_dup 1))
6109    (set (match_dup 1) (match_dup 8))
6110    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6111                    (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6112               (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6113                    (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6114    (match_dup 1)])
6116 ;; Split sign-extension of single least significant bit as and x,$1;neg x
6117 (define_insn_and_split "*extvsi_1_0"
6118   [(set (match_operand:SI 0 "register_operand" "=r")
6119         (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
6120                          (const_int 1)
6121                          (const_int 0)))]
6122   "!TARGET_BARREL_SHIFTER"
6123   "#"
6124   "&& 1"
6125   [(set (match_dup 0) (and:SI (match_dup 1) (const_int 1)))
6126    (set (match_dup 0) (neg:SI (match_dup 0)))]
6127   ""
6128   [(set_attr "length" "8")])
6130 (define_insn_and_split "*extvsi_n_0"
6131   [(set (match_operand:SI 0 "register_operand" "=r")
6132         (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
6133                          (match_operand:QI 2 "const_int_operand")
6134                          (const_int 0)))]
6135   "!TARGET_BARREL_SHIFTER
6136    && IN_RANGE (INTVAL (operands[2]), 2,
6137                 (optimize_insn_for_size_p () ? 28 : 30))"
6138   "#"
6139   "&& 1"
6140 [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 3)))
6141  (set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))
6142  (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 4)))]
6144   int tmp = INTVAL (operands[2]);
6145   operands[3] = GEN_INT (~(HOST_WIDE_INT_M1U << tmp));
6146   operands[4] = GEN_INT (HOST_WIDE_INT_1U << (tmp - 1));
6148   [(set_attr "length" "14")])
6150 (define_insn_and_split "rotlsi3_cnt1"
6151   [(set (match_operand:SI 0 "dest_reg_operand"            "=r")
6152         (rotate:SI (match_operand:SI 1 "register_operand" "r")
6153                    (const_int 1)))]
6154   "!TARGET_BARREL_SHIFTER"
6155   "#"
6156   "&& 1"
6157   [(const_int 0)]
6159   emit_insn (gen_add_f (operands[0], operands[1], operands[1]));
6160   emit_insn (gen_adc (operands[0], operands[0], const0_rtx));
6161   DONE;
6164 (define_insn "rotrsi3_cnt1"
6165   [(set (match_operand:SI 0 "dest_reg_operand"              "=r")
6166         (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6167                      (const_int 1)))]
6168   ""
6169   "ror\\t%0,%1"
6170   [(set_attr "type" "shift")
6171    (set_attr "predicable" "no")
6172    (set_attr "length" "4")])
6174 (define_insn "*rotrsi3_cnt8"
6175   [(set (match_operand:SI 0 "register_operand"             "=r")
6176         (rotatert:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6177                      (const_int 8)))]
6178   "TARGET_BARREL_SHIFTER && TARGET_V2"
6179   "ror8\\t%0,%1"
6180   [(set_attr "type" "shift")
6181    (set_attr "predicable" "no")
6182    (set_attr "length" "4")])
6184 (define_insn "ashlsi3_cnt1"
6185   [(set (match_operand:SI 0 "dest_reg_operand"           "=q,w")
6186         (ashift:SI (match_operand:SI 1 "register_operand" "q,c")
6187                    (const_int 1)))]
6188   ""
6189   "asl%?\\t%0,%1"
6190   [(set_attr "type" "unary")
6191    (set_attr "iscompact" "maybe,false")
6192    (set_attr "length" "*,4")
6193    (set_attr "predicable" "no,no")])
6195 (define_insn "*ashlsi2_cnt8"
6196   [(set (match_operand:SI 0 "register_operand"            "=r")
6197         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "rL")
6198                    (const_int 8)))]
6199   "TARGET_BARREL_SHIFTER && TARGET_V2"
6200   "lsl8\\t%0,%1"
6201   [(set_attr "type" "shift")
6202    (set_attr "iscompact" "false")
6203    (set_attr "length" "4")
6204    (set_attr "predicable" "no")])
6206 (define_insn "lshrsi3_cnt1"
6207   [(set (match_operand:SI 0 "dest_reg_operand"             "=q,w")
6208         (lshiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6209                      (const_int 1)))]
6210   ""
6211   "lsr%?\\t%0,%1"
6212   [(set_attr "type" "unary")
6213    (set_attr "iscompact" "maybe,false")
6214    (set_attr "predicable" "no,no")])
6216 (define_insn "lshrsi3_cnt1_carry"
6217   [(set (reg:CC_C CC_REG)
6218         (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
6219                               (const_int 1))] UNSPEC_ARC_CC_NEZ))
6220    (set (match_operand:SI 0 "dest_reg_operand" "=r")
6221         (lshiftrt:SI (match_dup 1) (const_int 1)))]
6222   ""
6223   "lsr.f\\t%0,%1"
6224   [(set_attr "type" "unary")
6225    (set_attr "length" "4")
6226    (set_attr "predicable" "no")])
6228 (define_insn "ashrsi3_cnt1"
6229   [(set (match_operand:SI 0 "dest_reg_operand"             "=q,w")
6230         (ashiftrt:SI (match_operand:SI 1 "register_operand" "q,c")
6231                      (const_int 1)))]
6232   ""
6233   "asr%?\\t%0,%1"
6234   [(set_attr "type" "unary")
6235    (set_attr "iscompact" "maybe,false")
6236    (set_attr "predicable" "no,no")])
6238 (define_insn "ashrsi3_cnt1_carry"
6239   [(set (reg:CC_C CC_REG)
6240         (unspec:CC_C [(and:SI (match_operand:SI 1 "register_operand" "r")
6241                               (const_int 1))] UNSPEC_ARC_CC_NEZ))
6242    (set (match_operand:SI 0 "dest_reg_operand" "=r")
6243         (ashiftrt:SI (match_dup 1) (const_int 1)))]
6244   ""
6245   "asr.f\\t%0,%1"
6246   [(set_attr "type" "unary")
6247    (set_attr "length" "4")
6248    (set_attr "predicable" "no")])
6250 (define_insn "btst_0_carry"
6251   [(set (reg:CC_C CC_REG)
6252         (unspec:CC_C [(and:SI (match_operand:SI 0 "register_operand" "r")
6253                               (const_int 1))] UNSPEC_ARC_CC_NEZ))]
6254   ""
6255   "asr.f\\t0,%0"
6256   [(set_attr "type" "unary")
6257    (set_attr "length" "4")
6258    (set_attr "predicable" "no")])
6260 (define_peephole2
6261   [(set (match_operand:SI 0 "register_operand" "")
6262         (zero_extract:SI (match_dup 0)
6263                          (match_operand:SI 1 "const_int_operand" "")
6264                          (match_operand:SI 2 "const_int_operand" "")))
6265    (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6266                          (match_dup 1)
6267                          (match_dup 2))
6268         (match_dup 0))]
6269   "TARGET_NPS_BITOPS
6270    && !reg_overlap_mentioned_p (operands[0], operands[3])"
6271   [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6272         (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6274 ;; Dummy pattern used as a place holder for automatically saved
6275 ;; registers.
6276 (define_insn "stack_irq_dwarf"
6277   [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6278   ""
6279   ""
6280   [(set_attr "length" "0")])
6282 ;; MAC and DMPY instructions
6284 ; Use VMAC2H(U) instruction to emulate scalar 16bit mac.
6285 (define_expand "maddhisi4"
6286   [(match_operand:SI 0 "register_operand" "")
6287    (match_operand:HI 1 "register_operand" "")
6288    (match_operand:HI 2 "register_operand" "")
6289    (match_operand:SI 3 "register_operand" "")]
6290   "TARGET_PLUS_MACD"
6291   "{
6292    rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6294    emit_move_insn (acc_reg, operands[3]);
6295    emit_insn (gen_machi (operands[0], operands[1], operands[2], acc_reg));
6296    DONE;
6297   }")
6299 (define_insn "machi"
6300   [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6301         (plus:SI
6302          (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6303                   (sign_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6304          (match_operand:SI 3 "accl_operand" "")))
6305    (clobber (reg:DI ARCV2_ACC))]
6306   "TARGET_PLUS_MACD"
6307   "dmach\\t%0,%1,%2"
6308   [(set_attr "length" "4")
6309    (set_attr "type" "multi")
6310    (set_attr "predicable" "no")
6311    (set_attr "cond" "nocond")])
6313 ; The same for the unsigned variant, but using VMAC2HU instruction.
6314 (define_expand "umaddhisi4"
6315   [(match_operand:SI 0 "register_operand" "")
6316    (match_operand:HI 1 "register_operand" "")
6317    (match_operand:HI 2 "register_operand" "")
6318    (match_operand:SI 3 "register_operand" "")]
6319   "TARGET_PLUS_MACD"
6320   "{
6321    rtx acc_reg = gen_rtx_REG (SImode, ACCL_REGNO);
6323    emit_move_insn (acc_reg, operands[3]);
6324    emit_insn (gen_umachi (operands[0], operands[1], operands[2], acc_reg));
6325    DONE;
6326   }")
6328 (define_insn "umachi"
6329   [(set (match_operand:SI 0 "register_operand" "=Ral,r")
6330         (plus:SI
6331          (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r,r"))
6332                   (zero_extend:SI (match_operand:HI 2 "register_operand" "r,r")))
6333          (match_operand:SI 3 "accl_operand" "")))
6334    (clobber (reg:DI ARCV2_ACC))]
6335   "TARGET_PLUS_MACD"
6336   "dmachu\\t%0,%1,%2"
6337   [(set_attr "length" "4")
6338    (set_attr "type" "multi")
6339    (set_attr "predicable" "no")
6340    (set_attr "cond" "nocond")])
6342 (define_expand "maddsidi4"
6343   [(match_operand:DI 0 "register_operand" "")
6344    (match_operand:SI 1 "register_operand" "")
6345    (match_operand:SI 2 "extend_operand"   "")
6346    (match_operand:DI 3 "register_operand" "")]
6347   "TARGET_PLUS_DMPY"
6348   "{
6349    emit_insn (gen_maddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6350    DONE;
6351   }")
6353 (define_insn_and_split "maddsidi4_split"
6354   [(set (match_operand:DI 0 "register_operand" "=r")
6355         (plus:DI
6356          (mult:DI
6357           (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6358           (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6359          (match_operand:DI 3 "register_operand" "r")))
6360    (clobber (reg:DI ARCV2_ACC))]
6361   "TARGET_PLUS_DMPY"
6362   "#"
6363   "TARGET_PLUS_DMPY && reload_completed"
6364   [(const_int 0)]
6365   "{
6366    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6367    emit_move_insn (acc_reg, operands[3]);
6368    if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6369        && REGNO (operands[0]) != ACC_REG_FIRST)
6370       emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6371    else
6372      {
6373       emit_insn (gen_mac (operands[1], operands[2]));
6374       if (REGNO (operands[0]) != ACC_REG_FIRST)
6375         emit_move_insn (operands[0], acc_reg);
6376      }
6377    DONE;
6378    }"
6379   [(set_attr "type" "multi")
6380    (set_attr "length" "36")])
6382 (define_insn "macd"
6383   [(set (match_operand:DI 0 "even_register_operand"     "=r,r,r")
6384         (plus:DI
6385          (mult:DI
6386           (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6387           (sign_extend:DI (match_operand:SI 2 "extend_operand"    "r,rI,Cal")))
6388          (reg:DI ARCV2_ACC)))
6389    (set (reg:DI ARCV2_ACC)
6390         (plus:DI
6391          (mult:DI (sign_extend:DI (match_dup 1))
6392                   (sign_extend:DI (match_dup 2)))
6393          (reg:DI ARCV2_ACC)))]
6394  "TARGET_PLUS_MACD"
6395  "macd\\t%0,%1,%2"
6396   [(set_attr "length" "4,4,8")
6397    (set_attr "type" "multi")
6398    (set_attr "predicable" "yes,no,no")
6399    (set_attr "cond" "canuse,nocond,nocond")])
6401 (define_insn "mac"
6402   [(set (reg:DI ARCV2_ACC)
6403         (plus:DI
6404          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6405                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6406          (reg:DI ARCV2_ACC)))]
6407  "TARGET_PLUS_DMPY"
6408  "mac 0,%0,%1"
6409   [(set_attr "length" "4,8")
6410    (set_attr "type" "multi")
6411    (set_attr "predicable" "no")
6412    (set_attr "cond" "nocond")])
6414 (define_peephole2
6415   [(set (reg:DI ARCV2_ACC)
6416         (plus:DI
6417          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6418                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6419          (reg:DI ARCV2_ACC)))
6420    (set (match_operand:SI 2 "register_operand" "")
6421         (match_operand:SI 3 "accl_operand" ""))]
6422  "TARGET_PLUS_DMPY"
6423  [(const_int 0)]
6425   emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6426   DONE;
6427  })
6429 (define_insn "mac_r"
6430   [(set (match_operand:SI 0 "register_operand" "=r,r")
6431         (truncate:SI
6432          (plus:DI
6433           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6434                    (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6435           (reg:DI ARCV2_ACC))))
6436    (clobber (reg:DI ARCV2_ACC))]
6437  "TARGET_PLUS_DMPY"
6438  "mac\\t%0,%1,%2"
6439   [(set_attr "length" "4,8")
6440    (set_attr "type" "multi")
6441    (set_attr "predicable" "no")
6442    (set_attr "cond" "nocond")])
6444 (define_expand "umaddsidi4"
6445   [(match_operand:DI 0 "register_operand" "")
6446    (match_operand:SI 1 "register_operand" "")
6447    (match_operand:SI 2 "extend_operand"   "")
6448    (match_operand:DI 3 "register_operand" "")]
6449   "TARGET_PLUS_DMPY"
6450   "{
6451    emit_insn (gen_umaddsidi4_split (operands[0], operands[1], operands[2], operands[3]));
6452    DONE;
6453   }")
6455 (define_insn_and_split "umaddsidi4_split"
6456   [(set (match_operand:DI 0 "register_operand" "=r")
6457         (plus:DI
6458          (mult:DI
6459           (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6460           (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6461          (match_operand:DI 3 "register_operand" "r")))
6462    (clobber (reg:DI ARCV2_ACC))]
6463   "TARGET_PLUS_DMPY"
6464   "#"
6465   "TARGET_PLUS_DMPY && reload_completed"
6466   [(const_int 0)]
6467   "{
6468    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6469    emit_move_insn (acc_reg, operands[3]);
6470    if (TARGET_PLUS_MACD && even_register_operand (operands[0], DImode)
6471        && REGNO (operands[0]) != ACC_REG_FIRST)
6472       emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6473    else
6474      {
6475       emit_insn (gen_macu (operands[1], operands[2]));
6476       if (REGNO (operands[0]) != ACC_REG_FIRST)
6477         emit_move_insn (operands[0], acc_reg);
6478      }
6479    DONE;
6480    }"
6481   [(set_attr "type" "multi")
6482    (set_attr "length" "36")])
6484 (define_insn "macdu"
6485   [(set (match_operand:DI 0 "even_register_operand"     "=r,r,r")
6486         (plus:DI
6487          (mult:DI
6488           (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,r,r"))
6489           (zero_extend:DI (match_operand:SI 2 "extend_operand"    "r,rI,i")))
6490          (reg:DI ARCV2_ACC)))
6491    (set (reg:DI ARCV2_ACC)
6492         (plus:DI
6493          (mult:DI (zero_extend:DI (match_dup 1))
6494                   (zero_extend:DI (match_dup 2)))
6495          (reg:DI ARCV2_ACC)))]
6496  "TARGET_PLUS_MACD"
6497  "macdu\\t%0,%1,%2"
6498   [(set_attr "length" "4,4,8")
6499    (set_attr "type" "multi")
6500    (set_attr "predicable" "yes,no,no")
6501    (set_attr "cond" "canuse,nocond,nocond")])
6503 (define_insn "macu"
6504   [(set (reg:DI ARCV2_ACC)
6505         (plus:DI
6506          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6507                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6508          (reg:DI ARCV2_ACC)))]
6509  "TARGET_PLUS_DMPY"
6510  "macu 0,%0,%1"
6511   [(set_attr "length" "4,8")
6512    (set_attr "type" "multi")
6513    (set_attr "predicable" "no")
6514    (set_attr "cond" "nocond")])
6516 (define_peephole2
6517   [(set (reg:DI ARCV2_ACC)
6518         (plus:DI
6519          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6520                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6521          (reg:DI ARCV2_ACC)))
6522    (set (match_operand:SI 2 "register_operand" "")
6523         (match_operand:SI 3 "accl_operand" ""))]
6524  "TARGET_PLUS_DMPY"
6525  [(const_int 0)]
6527   emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6528   DONE;
6529  })
6531 (define_insn "macu_r"
6532   [(set (match_operand:SI 0 "register_operand" "=r,r")
6533         (truncate:SI
6534          (plus:DI
6535           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6536                    (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6537           (reg:DI ARCV2_ACC))))
6538    (clobber (reg:DI ARCV2_ACC))]
6539  "TARGET_PLUS_DMPY"
6540  "macu\\t%0,%1,%2"
6541   [(set_attr "length" "4,8")
6542    (set_attr "type" "multi")
6543    (set_attr "predicable" "no")
6544    (set_attr "cond" "nocond")])
6546 (define_insn "mpyd<su_optab>_arcv2hs"
6547   [(set (match_operand:DI 0 "even_register_operand"            "=r")
6548         (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand" "r"))
6549                  (SEZ:DI (match_operand:SI 2 "register_operand" "r"))))
6550    (set (reg:DI ARCV2_ACC)
6551         (mult:DI
6552           (SEZ:DI (match_dup 1))
6553           (SEZ:DI (match_dup 2))))]
6554   "TARGET_PLUS_MACD"
6555   "mpyd<su_optab>%?\\t%0,%1,%2"
6556   [(set_attr "length" "4")
6557    (set_attr "iscompact" "false")
6558    (set_attr "type" "multi")
6559    (set_attr "predicable" "no")])
6561 (define_insn "*pmpyd<su_optab>_arcv2hs"
6562   [(set (match_operand:DI 0 "even_register_operand"          "=r")
6563         (mult:DI
6564          (SEZ:DI (match_operand:SI 1 "even_register_operand" "%0"))
6565          (SEZ:DI (match_operand:SI 2 "register_operand"      "r"))))
6566    (set (reg:DI ARCV2_ACC)
6567         (mult:DI
6568           (SEZ:DI (match_dup 1))
6569           (SEZ:DI (match_dup 2))))]
6570   "TARGET_PLUS_MACD"
6571   "mpyd<su_optab>%?\\t%0,%1,%2"
6572   [(set_attr "length" "4")
6573    (set_attr "iscompact" "false")
6574    (set_attr "type" "multi")
6575    (set_attr "predicable" "yes")])
6577 (define_insn "mpyd<su_optab>_imm_arcv2hs"
6578   [(set (match_operand:DI 0 "even_register_operand"             "=r,r,  r")
6579         (mult:DI (SEZ:DI (match_operand:SI 1 "register_operand"  "r,0,  r"))
6580                  (match_operand 2            "immediate_operand" "L,I,Cal")))
6581    (set (reg:DI ARCV2_ACC)
6582         (mult:DI (SEZ:DI (match_dup 1))
6583                  (match_dup 2)))]
6584   "TARGET_PLUS_MACD"
6585   "mpyd<su_optab>%?\\t%0,%1,%2"
6586   [(set_attr "length" "4,4,8")
6587    (set_attr "iscompact" "false")
6588    (set_attr "type" "multi")
6589    (set_attr "predicable" "no")])
6591 (define_insn "*pmpyd<su_optab>_imm_arcv2hs"
6592   [(set (match_operand:DI 0 "even_register_operand"         "=r,r")
6593         (mult:DI
6594          (SEZ:DI (match_operand:SI 1 "even_register_operand" "0,0"))
6595          (match_operand 2            "immediate_operand"     "L,Cal")))
6596    (set (reg:DI ARCV2_ACC)
6597         (mult:DI (SEZ:DI (match_dup 1))
6598                  (match_dup 2)))]
6599   "TARGET_PLUS_MACD"
6600   "mpyd<su_optab>%?\\t%0,%1,%2"
6601   [(set_attr "length" "4,8")
6602    (set_attr "iscompact" "false")
6603    (set_attr "type" "multi")
6604    (set_attr "predicable" "yes")])
6606 (define_insn "add_shift"
6607   [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6608         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
6609                             (match_operand:SI 2 "_1_2_3_operand" ""))
6610                  (match_operand:SI 3 "arc_nonmemory_operand"  "0,r,Csz")))]
6611   ""
6612   "add%2%?\\t%0,%3,%1"
6613   [(set_attr "length" "*,4,8")
6614    (set_attr "predicable" "yes,no,no")
6615    (set_attr "iscompact" "maybe,false,false")
6616    (set_attr "cond" "canuse,nocond,nocond")])
6618 (define_insn "*add_shift2"
6619   [(set (match_operand:SI 0 "register_operand" "=q,r,r")
6620         (plus:SI (match_operand:SI 1 "nonmemory_operand"  "0,r,Cal")
6621                  (ashift:SI (match_operand:SI 2 "register_operand" "q,r,r")
6622                             (match_operand:SI 3 "_1_2_3_operand" ""))))]
6623   ""
6624   "add%3%?\\t%0,%1,%2"
6625   [(set_attr "length" "*,4,8")
6626    (set_attr "predicable" "yes,no,no")
6627    (set_attr "iscompact" "maybe,false,false")
6628    (set_attr "cond" "canuse,nocond,nocond")])
6630 (define_insn "*sub_shift"
6631   [(set (match_operand:SI 0"register_operand" "=r,r,r")
6632          (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal")
6633                    (ashift:SI (match_operand:SI 2 "register_operand" "r,r,r")
6634                               (match_operand:SI 3 "_1_2_3_operand" ""))))]
6635   ""
6636   "sub%3\\t%0,%1,%2"
6637   [(set_attr "length" "4,4,8")
6638    (set_attr "cond" "canuse,nocond,nocond")
6639    (set_attr "predicable" "yes,no,no")])
6641 (define_insn "*sub_shift_cmp0_noout"
6642   [(set (match_operand 0 "cc_set_register" "")
6643         (compare:CC
6644          (minus:SI (match_operand:SI 1 "register_operand" "r")
6645                    (ashift:SI (match_operand:SI 2 "register_operand" "r")
6646                               (match_operand:SI 3 "_1_2_3_operand" "")))
6647          (const_int 0)))]
6648   ""
6649   "sub%3.f\\t0,%1,%2"
6650   [(set_attr "length" "4")])
6652 (define_insn "*compare_si_ashiftsi"
6653   [(set (match_operand 0 "cc_set_register" "")
6654         (compare:CC (match_operand:SI 1 "register_operand" "r")
6655                     (ashift:SI (match_operand:SI 2 "register_operand" "r")
6656                                (match_operand:SI 3 "_1_2_3_operand" ""))))]
6657   ""
6658   "sub%3.f\\t0,%1,%2"
6659   [(set_attr "length" "4")])
6661 ;; Convert the sequence
6662 ;;  asl rd,rn,_1_2_3
6663 ;;  cmp ra,rd
6664 ;; into
6665 ;;  sub{123}.f 0,ra,rn
6666 (define_peephole2
6667   [(set (match_operand:SI 0 "register_operand" "")
6668         (ashift:SI (match_operand:SI 1 "register_operand" "")
6669                    (match_operand:SI 2 "_1_2_3_operand" "")))
6670    (set (reg:CC CC_REG)
6671         (compare:CC (match_operand:SI 3 "register_operand" "")
6672                     (match_dup 0)))]
6673   "peep2_reg_dead_p (2, operands[0])"
6674   [(set (reg:CC CC_REG) (compare:CC (match_dup 3)
6675                                     (ashift:SI (match_dup 1) (match_dup 2))))])
6677 (define_peephole2 ; std
6678   [(set (match_operand:SI 2 "memory_operand" "")
6679         (match_operand:SI 0 "register_operand" ""))
6680    (set (match_operand:SI 3 "memory_operand" "")
6681         (match_operand:SI 1 "register_operand" ""))]
6682   "TARGET_LL64"
6683   [(const_int 0)]
6685   if (!gen_operands_ldd_std (operands, false, false))
6686     FAIL;
6687   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6688   operands[2] = adjust_address (operands[2], DImode, 0);
6689   emit_insn (gen_rtx_SET (operands[2], operands[0]));
6690   DONE;
6693 (define_peephole2 ; ldd
6694   [(set (match_operand:SI 0 "register_operand" "")
6695         (match_operand:SI 2 "memory_operand" ""))
6696    (set (match_operand:SI 1 "register_operand" "")
6697         (match_operand:SI 3 "memory_operand" ""))]
6698   "TARGET_LL64"
6699   [(const_int 0)]
6701   if (!gen_operands_ldd_std (operands, true, false))
6702     FAIL;
6703   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6704   operands[2] = adjust_address (operands[2], DImode, 0);
6705   emit_insn (gen_rtx_SET (operands[0], operands[2]));
6706   DONE;
6709 ;; We require consecutive registers for LDD instruction.  Check if we
6710 ;; can reorder them and use an LDD.
6712 (define_peephole2 ; swap the destination registers of two loads
6713                   ; before a commutative operation.
6714   [(set (match_operand:SI 0 "register_operand" "")
6715         (match_operand:SI 2 "memory_operand" ""))
6716    (set (match_operand:SI 1 "register_operand" "")
6717         (match_operand:SI 3 "memory_operand" ""))
6718    (set (match_operand:SI 4 "register_operand" "")
6719         (match_operator:SI 5 "commutative_operator"
6720                            [(match_operand 6 "register_operand" "")
6721                             (match_operand 7 "register_operand" "") ]))]
6722   "TARGET_LL64
6723    && (((rtx_equal_p (operands[0], operands[6]))
6724          && (rtx_equal_p (operands[1], operands[7])))
6725         || ((rtx_equal_p (operands[0], operands[7]))
6726              && (rtx_equal_p (operands[1], operands[6]))))
6727    && (peep2_reg_dead_p (3, operands[0])
6728        || rtx_equal_p (operands[0], operands[4]))
6729    && (peep2_reg_dead_p (3, operands[1])
6730        || rtx_equal_p (operands[1], operands[4]))"
6731   [(set (match_dup 0) (match_dup 2))
6732    (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]
6733   {
6734     if (!gen_operands_ldd_std (operands, true, true))
6735      {
6736         FAIL;
6737      }
6738     else
6739      {
6740         operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6741         operands[2] = adjust_address (operands[2], DImode, 0);
6742      }
6743    }
6746 (define_insn "*push_multi_fp"
6747   [(match_parallel 0 "push_multi_operand"
6748                    [(set (reg:SI SP_REG)
6749                          (plus:SI (reg:SI SP_REG)
6750                                   (match_operand 1 "immediate_operand" "")))
6751                     (set (mem:SI (plus:SI (reg:SI SP_REG)
6752                                           (match_operand 2 "immediate_operand"
6753                                                          "")))
6754                          (reg:SI 13))])]
6755   "TARGET_CODE_DENSITY"
6756   {
6757    int len = XVECLEN (operands[0], 0);
6758    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6759    if (MEM_P (XEXP (tmp, 0)))
6760      {
6761       operands[3] = XEXP (tmp, 1);
6762       return "enter_s\\t{r13-%3} ; sp=sp+(%1)";
6763      }
6764    else
6765      {
6766       tmp = XVECEXP (operands[0], 0, len - 3);
6767       operands[3] = XEXP (tmp, 1);
6768       return "enter_s\\t{r13-%3, fp} ; sp=sp+(%1)";
6769      }
6770   }
6771   [(set_attr "type" "call_no_delay_slot")
6772    (set_attr "length" "2")])
6774 (define_insn "*push_multi_fp_blink"
6775   [(match_parallel 0 "push_multi_operand"
6776                    [(set (reg:SI SP_REG)
6777                          (plus:SI (reg:SI SP_REG)
6778                                   (match_operand 1 "immediate_operand" "")))
6779                     (set (mem:SI (plus:SI (reg:SI SP_REG)
6780                                           (match_operand 2 "immediate_operand"
6781                                                          "")))
6782                          (reg:SI RETURN_ADDR_REGNUM))])]
6783   "TARGET_CODE_DENSITY"
6784   {
6785    int len = XVECLEN (operands[0], 0);
6786    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6787    if (MEM_P (XEXP (tmp, 0)))
6788      {
6789       operands[3] = XEXP (tmp, 1);
6790       return "enter_s\\t{r13-%3, blink} ; sp=sp+(%1)";
6791      }
6792    else
6793      {
6794       tmp = XVECEXP (operands[0], 0, len - 3);
6795       operands[3] = XEXP (tmp, 1);
6796       return "enter_s\\t{r13-%3, fp, blink} ; sp=sp+(%1)";
6797      }
6798   }
6799   [(set_attr "type" "call_no_delay_slot")
6800    (set_attr "length" "2")])
6802 (define_insn "*pop_multi_fp"
6803   [(match_parallel 0 "pop_multi_operand"
6804                    [(set (reg:SI SP_REG)
6805                          (plus:SI (reg:SI SP_REG)
6806                                   (match_operand 1 "immediate_operand" "")))
6807                     (set (reg:SI 13)
6808                          (mem:SI
6809                           (plus:SI
6810                            (reg:SI SP_REG)
6811                            (match_operand 2 "immediate_operand" ""))))])]
6812   "TARGET_CODE_DENSITY"
6813   {
6814    int len = XVECLEN (operands[0], 0);
6815    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6816    if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6817      {
6818       operands[3] = XEXP (tmp, 0);
6819       gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6820       return "leave_s\\t{r13-%3} ; sp=sp+%1";
6821      }
6822    else
6823      {
6824       tmp = XVECEXP (operands[0], 0, len - 2);
6825       operands[3] = XEXP (tmp, 0);
6826       return "leave_s\\t{r13-%3, fp} ; sp=sp+%1";
6827      }
6828   }
6829   [(set_attr "type" "call_no_delay_slot")
6830    (set_attr "length" "2")])
6832 (define_insn "*pop_multi_fp_blink"
6833   [(match_parallel 0 "pop_multi_operand"
6834                    [(set (reg:SI SP_REG)
6835                          (plus:SI (reg:SI SP_REG)
6836                                   (match_operand 1 "immediate_operand" "")))
6837                     (set (reg:SI RETURN_ADDR_REGNUM)
6838                          (mem:SI
6839                           (plus:SI
6840                            (reg:SI SP_REG)
6841                            (match_operand 2 "immediate_operand" ""))))])]
6842   "TARGET_CODE_DENSITY"
6843   {
6844    int len = XVECLEN (operands[0], 0);
6845    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6846    if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6847      {
6848       operands[3] = XEXP (tmp, 0);
6849       gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6850       return "leave_s\\t{r13-%3, blink} ; sp=sp+%1";
6851      }
6852    else
6853      {
6854       tmp = XVECEXP (operands[0], 0, len - 2);
6855       operands[3] = XEXP (tmp, 0);
6856       return "leave_s\\t{r13-%3, fp, blink} ; sp=sp+%1";
6857      }
6858   }
6859   [(set_attr "type" "call_no_delay_slot")
6860    (set_attr "length" "2")])
6862 (define_insn "*pop_multi_fp_ret"
6863   [(match_parallel 0 "pop_multi_operand"
6864                    [(return)
6865                     (set (reg:SI SP_REG)
6866                          (plus:SI (reg:SI SP_REG)
6867                                   (match_operand 1 "immediate_operand" "")))
6868                     (set (reg:SI 13)
6869                          (mem:SI
6870                           (plus:SI
6871                            (reg:SI SP_REG)
6872                            (match_operand 2 "immediate_operand" ""))))])]
6873   "TARGET_CODE_DENSITY"
6874   {
6875    int len = XVECLEN (operands[0], 0);
6876    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6877    if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6878      {
6879       operands[3] = XEXP (tmp, 0);
6880       gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6881       return "leave_s\\t{r13-%3, pcl} ; sp=sp+%1";
6882      }
6883    else
6884      {
6885       tmp = XVECEXP (operands[0], 0, len - 2);
6886       operands[3] = XEXP (tmp, 0);
6887       return "leave_s\\t{r13-%3, fp, pcl} ; sp=sp+%1";
6888      }
6889   }
6890   [(set_attr "type" "call_no_delay_slot")
6891    (set_attr "length" "2")])
6893 (define_insn "*pop_multi_fp_blink_ret"
6894   [(match_parallel 0 "pop_multi_operand"
6895                    [(return)
6896                     (set (reg:SI SP_REG)
6897                          (plus:SI (reg:SI SP_REG)
6898                                   (match_operand 1 "immediate_operand" "")))
6899                     (set (reg:SI RETURN_ADDR_REGNUM)
6900                          (mem:SI
6901                           (plus:SI
6902                            (reg:SI SP_REG)
6903                            (match_operand 2 "immediate_operand" ""))))])]
6904   "TARGET_CODE_DENSITY"
6905   {
6906    int len = XVECLEN (operands[0], 0);
6907    rtx tmp = XVECEXP (operands[0], 0, len - 1);
6908    if (XEXP (tmp, 0) != hard_frame_pointer_rtx)
6909      {
6910       operands[3] = XEXP (tmp, 0);
6911       gcc_assert (INTVAL (operands[1]) == INTVAL (operands[2]));
6912       return "leave_s\\t{r13-%3, blink, pcl} ; sp=sp+%1";
6913      }
6914    else
6915      {
6916       tmp = XVECEXP (operands[0], 0, len - 2);
6917       operands[3] = XEXP (tmp, 0);
6918       return "leave_s\\t{r13-%3, fp, blink, pcl} ; sp=sp+%1";
6919      }
6920   }
6921   [(set_attr "type" "call_no_delay_slot")
6922    (set_attr "length" "2")])
6924 ;; Patterns for exception handling
6925 (define_insn_and_split "eh_return"
6926   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
6927                     VUNSPEC_ARC_EH_RETURN)]
6928   ""
6929   "#"
6930   "reload_completed"
6931   [(const_int 0)]
6932   "
6933   {
6934     arc_eh_return_address_location (operands[0]);
6935     DONE;
6936   }"
6937   [(set_attr "length" "8")]
6938   )
6940 ;; include the arc-FPX instructions
6941 (include "fpx.md")
6943 ;; include the arc-FPU instructions
6944 (include "fpu.md")
6946 (include "simdext.md")
6948 ;; include atomic extensions
6949 (include "atomic.md")