[2/77] Add an E_ prefix to case statements
[official-gcc.git] / gcc / config / arc / arc.md
blob566c560ef6164f6a9cd42ce2ef13275e8958c989
1 ;; Machine description of the Synopsys DesignWare ARC cpu for GNU C compiler
2 ;; Copyright (C) 1994-2017 Free Software Foundation, Inc.
4 ;; Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 ;; behalf of Synopsys Inc.
7 ;;    Position Independent Code support added,Code cleaned up,
8 ;;    Comments and Support For ARC700 instructions added by
9 ;;    Saurabh Verma (saurabh.verma@codito.com)
10 ;;    Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 ;;    Performance improvements by
13 ;;    Joern Rennecke (joern.rennecke@embecosm.com)
16 ;; This file is part of GCC.
18 ;; GCC is free software; you can redistribute it and/or modify
19 ;; it under the terms of the GNU General Public License as published by
20 ;; the Free Software Foundation; either version 3, or (at your option)
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"))
86 ;; Predicates
88 (include ("predicates.md"))
89 (include ("constraints.md"))
90 ;;  -----------------------------------------------------------------------------
92 ;; UNSPEC Usage:
93 ;; ~~~~~~~~~~~~
94 ;;  -----------------------------------------------------------------------------
95 ;;  Symbolic name  Value              Desc.
96 ;;  -----------------------------------------------------------------------------
97 ;;  UNSPEC_PLT       3        symbol to be referenced through the PLT
98 ;;  UNSPEC_GOT       4        symbol to be rerenced through the GOT
99 ;;  UNSPEC_GOTOFF    5        Local symbol.To be referenced relative to the
100 ;;                            GOTBASE.(Referenced as @GOTOFF)
101 ;;  UNSPEC_GOTOFFPC  6        Local symbol.  To be referenced pc-relative.
102 ;;  ----------------------------------------------------------------------------
104 (define_c_enum "unspec" [
105   DUMMY_0
106   DUMMY_1
107   DUMMY_2
108   ARC_UNSPEC_PLT
109   ARC_UNSPEC_GOT
110   ARC_UNSPEC_GOTOFF
111   ARC_UNSPEC_GOTOFFPC
112   UNSPEC_TLS_GD
113   UNSPEC_TLS_LD
114   UNSPEC_TLS_IE
115   UNSPEC_TLS_OFF
116   UNSPEC_ARC_NORM
117   UNSPEC_ARC_NORMW
118   UNSPEC_ARC_SWAP
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_QMACH
131   UNSPEC_ARC_QMACHU
132   UNSPEC_ARC_QMPYH
133   UNSPEC_ARC_QMPYHU
134   UNSPEC_ARC_VMAC2H
135   UNSPEC_ARC_VMAC2HU
136   UNSPEC_ARC_VMPY2H
137   UNSPEC_ARC_VMPY2HU
138   UNSPEC_ARC_STKTIE
139   ])
141 (define_c_enum "vunspec" [
142   VUNSPEC_ARC_RTIE
143   VUNSPEC_ARC_SYNC
144   VUNSPEC_ARC_BRK
145   VUNSPEC_ARC_FLAG
146   VUNSPEC_ARC_SLEEP
147   VUNSPEC_ARC_SWI
148   VUNSPEC_ARC_CORE_READ
149   VUNSPEC_ARC_CORE_WRITE
150   VUNSPEC_ARC_LR
151   VUNSPEC_ARC_SR
152   VUNSPEC_ARC_TRAP_S
153   VUNSPEC_ARC_UNIMP_S
154   VUNSPEC_ARC_KFLAG
155   VUNSPEC_ARC_CLRI
156   VUNSPEC_ARC_SETI
157   VUNSPEC_ARC_NOP
158   VUNSPEC_ARC_STACK_IRQ
159   VUNSPEC_ARC_DEXCL
160   VUNSPEC_ARC_DEXCL_NORES
161   VUNSPEC_ARC_LR_HIGH
162   VUNSPEC_ARC_EX
163   VUNSPEC_ARC_CAS
164   VUNSPEC_ARC_SC
165   VUNSPEC_ARC_LL
166   ])
168 (define_constants
169   [(R0_REG 0)
170    (R1_REG 1)
171    (R2_REG 2)
172    (R3_REG 3)
173    (R10_REG 10)
174    (R12_REG 12)
175    (SP_REG 28)
176    (ILINK1_REGNUM 29)
177    (ILINK2_REGNUM 30)
178    (RETURN_ADDR_REGNUM 31)
179    (MUL64_OUT_REG 58)
180    (MUL32x16_REG 56)
181    (ARCV2_ACC 58)
183    (LP_COUNT 60)
184    (CC_REG 61)
185    (LP_START 144)
186    (LP_END 145)
187   ]
190 (define_attr "is_sfunc" "no,yes" (const_string "no"))
192 ;; Insn type.  Used to default other attribute values.
193 ; While the attribute is_sfunc is set for any call of a special function,
194 ; the instruction type sfunc is used only for the special call sequence
195 ; that loads the (pc-relative) function address into r12 and then calls
196 ; via r12.
198 (define_attr "type"
199   "move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
200    brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
201    multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
202    misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
203    simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
204    simd_vmove_with_acc, simd_varith_1cycle, simd_varith_2cycle,
205    simd_varith_with_acc, simd_vlogic, simd_vlogic_with_acc,
206    simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc,
207    simd_valign, simd_valign_with_acc, simd_vcontrol,
208    simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem,
209    fpu, block"
210   (cond [(eq_attr "is_sfunc" "yes")
211          (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call")
212                 (match_test "flag_pic") (const_string "sfunc")]
213                (const_string "call_no_delay_slot"))]
214         (const_string "binary")))
216 ;; The following three attributes are mixed case so that they can be
217 ;; used conveniently with the CALL_ATTR macro.
218 (define_attr "is_CALL" "no,yes"
219   (cond [(eq_attr "is_sfunc" "yes") (const_string "yes")
220          (eq_attr "type" "call,call_no_delay_slot") (const_string "yes")]
221         (const_string "no")))
223 (define_attr "is_SIBCALL" "no,yes" (const_string "no"))
225 (define_attr "is_NON_SIBCALL" "no,yes"
226   (cond [(eq_attr "is_SIBCALL" "yes") (const_string "no")
227          (eq_attr "is_CALL" "yes") (const_string "yes")]
228         (const_string "no")))
230 ;; true for compact instructions (those with _s suffix)
231 ;; "maybe" means compact unless we conditionalize the insn.
232 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
233   (cond [(eq_attr "type" "sfunc")
234          (const_string "maybe")]
235         (const_string "false")))
238 ; Is there an instruction that we are actually putting into the delay slot?
239 (define_attr "delay_slot_filled" "no,yes"
240   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
241          (const_string "no")
242          (match_test "!TARGET_AT_DBR_CONDEXEC
243                       && JUMP_P (insn)
244                       && INSN_ANNULLED_BRANCH_P (insn)
245                       && !INSN_FROM_TARGET_P (NEXT_INSN (insn))")
246          (const_string "no")]
247         (const_string "yes")))
249 ; Is a delay slot present for purposes of shorten_branches?
250 ; We have to take the length of this insn into account for forward branches
251 ; even if we don't put the insn actually into a delay slot.
252 (define_attr "delay_slot_present" "no,yes"
253   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
254          (const_string "no")]
255         (const_string "yes")))
257 ; We can't use get_attr_length (NEXT_INSN (insn)) because this gives the
258 ; length of a different insn with the same uid.
259 (define_attr "delay_slot_length" ""
260   (cond [(match_test "NEXT_INSN (PREV_INSN (insn)) == insn")
261          (const_int 0)]
262         (symbol_ref "get_attr_length (NEXT_INSN (PREV_INSN (insn)))
263                      - get_attr_length (insn)")))
265 ; for ARCv2 we need to disable/enable different instruction alternatives
266 (define_attr "cpu_facility" "std,av1,av2,fpx,cd"
267   (const_string "std"))
269 ; We should consider all the instructions enabled until otherwise
270 (define_attr "enabled" "no,yes"
271   (cond [(and (eq_attr "cpu_facility" "av1")
272               (match_test "TARGET_V2"))
273          (const_string "no")
275          (and (eq_attr "cpu_facility" "av2")
276               (not (match_test "TARGET_V2")))
277          (const_string "no")
279          (and (eq_attr "cpu_facility" "fpx")
280               (match_test "TARGET_FP_DP_AX"))
281          (const_string "no")
283          (and (eq_attr "cpu_facility" "cd")
284               (not (and (match_test "TARGET_V2")
285                         (match_test "TARGET_CODE_DENSITY"))))
286          (const_string "no")
287          ]
288         (const_string "yes")))
290 (define_attr "predicable" "no,yes" (const_string "no"))
291 ;; if 'predicable' were not so brain-dead, we would specify:
292 ;; (cond [(eq_attr "cond" "!canuse") (const_string "no")
293 ;;        (eq_attr "iscompact" "maybe") (const_string "no")]
294 ;;       (const_string "yes"))
295 ;; and then for everything but calls, we could just set the cond attribute.
297 ;; Condition codes: this one is used by final_prescan_insn to speed up
298 ;; conditionalizing instructions.  It saves having to scan the rtl to see if
299 ;; it uses or alters the condition codes.
301 ;; USE: This insn uses the condition codes (eg: a conditional branch).
302 ;; CANUSE: This insn can use the condition codes (for conditional execution).
303 ;; SET: All condition codes are set by this insn.
304 ;; SET_ZN: the Z and N flags are set by this insn.
305 ;; SET_ZNC: the Z, N, and C flags are set by this insn.
306 ;; CLOB: The condition codes are set to unknown values by this insn.
307 ;; NOCOND: This insn can't use and doesn't affect the condition codes.
309 (define_attr "cond" "use,canuse,canuse_limm,canuse_limm_add,set,set_zn,clob,nocond"
310   (cond
311     [(and (eq_attr "predicable" "yes")
312           (eq_attr "is_sfunc" "no")
313           (eq_attr "delay_slot_filled" "no"))
314      (const_string "canuse")
316      (eq_attr "type" "call")
317      (cond [(eq_attr "delay_slot_filled" "yes") (const_string "nocond")
318             (match_test "!flag_pic") (const_string "canuse_limm")]
319            (const_string "nocond"))
321      (eq_attr "iscompact" "maybe,false")
322      (cond [ (and (eq_attr "type" "move")
323                   (match_operand 1 "immediate_operand" ""))
324              (if_then_else
325                 (ior (match_operand 1 "u6_immediate_operand" "")
326                      (match_operand 1 "long_immediate_operand" ""))
327                 (const_string "canuse")
328                 (const_string "canuse_limm"))
330              (eq_attr "type" "binary")
331              (cond [(ne (symbol_ref "REGNO (operands[0])")
332                         (symbol_ref "REGNO (operands[1])"))
333                     (const_string "nocond")
334                     (match_operand 2 "register_operand" "")
335                     (const_string "canuse")
336                     (match_operand 2 "u6_immediate_operand" "")
337                     (const_string "canuse")
338                     (match_operand 2 "long_immediate_operand" "")
339                     (const_string "canuse")
340                     (match_operand 2 "const_int_operand" "")
341                     (const_string "canuse_limm")]
342                    (const_string "nocond"))
344              (eq_attr "type" "compare")
345              (const_string "set")
347              (eq_attr "type" "cmove,branch")
348              (const_string "use")
350              (eq_attr "is_sfunc" "yes")
351              (cond [(match_test "(TARGET_MEDIUM_CALLS
352                                   && !TARGET_LONG_CALLS_SET
353                                   && flag_pic)")
354                     (const_string "canuse_limm_add")
355                     (match_test "(TARGET_MEDIUM_CALLS
356                                   && !TARGET_LONG_CALLS_SET)")
357                     (const_string "canuse_limm")]
358                    (const_string "canuse"))
360             ]
362             (const_string "nocond"))]
364       (cond [(eq_attr "type" "compare")
365              (const_string "set")
367              (eq_attr "type" "cmove,branch")
368              (const_string "use")
370             ]
372             (const_string "nocond"))))
374 /* ??? Having all these patterns gives ifcvt more freedom to generate
375    inefficient code.  It seem to operate on the premise that
376    register-register copies and registers are free.  I see better code
377    with -fno-if-convert now than without.  */
378 (define_cond_exec
379   [(match_operator 0 "proper_comparison_operator"
380      [(reg CC_REG) (const_int 0)])]
381   "true"
382   "")
384 ;; Length (in # of bytes, long immediate constants counted too).
385 ;; ??? There's a nasty interaction between the conditional execution fsm
386 ;; and insn lengths: insns with shimm values cannot be conditionally executed.
387 (define_attr "length" ""
388   (cond
389     [(eq_attr "iscompact" "true,maybe")
390      (cond
391        [(eq_attr "type" "sfunc")
392         (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC")
393                (const_int 12)]
394               (const_int 10))
395         (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 4)]
396       (const_int 2))
398     (eq_attr "iscompact" "true_limm")
399     (const_int 6)
401     (eq_attr "iscompact" "maybe_limm")
402     (cond [(match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
403           (const_int 6))
405     (eq_attr "type" "load")
406     (if_then_else
407        (match_operand 1 "long_immediate_loadstore_operand" "")
408        (const_int 8) (const_int 4))
410     (eq_attr "type" "store")
411     (if_then_else
412       (ior (match_operand 0 "long_immediate_loadstore_operand" "")
413            (match_operand 1 "immediate_operand" ""))
414       (const_int 8) (const_int 4))
416     (eq_attr "type" "move,unary")
417     (cond
418       [(match_operand 1 "u6_immediate_operand" "") (const_int 4)
419        (match_operand 1 "register_operand" "") (const_int 4)
420        (match_operand 1 "long_immediate_operand" "") (const_int 8)
421        (match_test "GET_CODE (PATTERN (insn)) == COND_EXEC") (const_int 8)]
422       (const_int 4))
424     (and (eq_attr "type" "shift")
425          (match_operand 1 "immediate_operand"))
426                  (const_int 8)
427     (eq_attr "type" "binary,shift")
428     (if_then_else
429        (ior (match_operand 2 "long_immediate_operand" "")
430             (and (ne (symbol_ref "REGNO (operands[0])")
431                      (symbol_ref "REGNO (operands[1])"))
432                  (eq (match_operand 2 "u6_immediate_operand" "")
433                      (const_int 0))))
435        (const_int 8) (const_int 4))
437     (eq_attr "type" "cmove")
438        (if_then_else (match_operand 1 "register_operand" "")
439                      (const_int 4) (const_int 8))
441     (eq_attr "type" "call_no_delay_slot") (const_int 8)
442    ]
444    (const_int 4))
447 ;; The length here is the length of a single asm.  Unfortunately it might be
448 ;; 4 or 8 so we must allow for 8.  That's ok though.  How often will users
449 ;; lament asm's not being put in delay slots?
451 (define_asm_attributes
452   [(set_attr "length" "8")
453    (set_attr "type" "multi")
454    (set_attr "cond" "clob") ])
456 ;; Delay slots.
457 ;; The first two cond clauses and the default are necessary for correctness;
458 ;; the remaining cond clause is mainly an optimization, as otherwise nops
459 ;; would be inserted; however, if we didn't do this optimization, we would
460 ;; have to be more conservative in our length calculations.
462 (define_attr "in_delay_slot" "false,true"
463   (cond [(eq_attr "type" "uncond_branch,jump,branch,
464                           call,sfunc,call_no_delay_slot,
465                           brcc, brcc_no_delay_slot,loop_setup,loop_end")
466          (const_string "false")
467          (match_test "arc_write_ext_corereg (insn)")
468          (const_string "false")
469          (gt (symbol_ref "arc_hazard (prev_active_insn (insn),
470                                       next_active_insn (insn))")
471              (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
472                            + arc_hazard (insn, next_active_insn (insn)))"))
473          (const_string "false")
474          (eq_attr "iscompact" "maybe") (const_string "true")
475          ]
477          (if_then_else (eq_attr "length" "2,4")
478                        (const_string "true")
479                        (const_string "false"))))
481 ; must not put an insn inside that refers to blink.
482 (define_attr "in_call_delay_slot" "false,true"
483   (cond [(eq_attr "in_delay_slot" "false")
484          (const_string "false")
485          (match_test "arc_regno_use_in (RETURN_ADDR_REGNUM, PATTERN (insn))")
486          (const_string "false")]
487         (const_string "true")))
489 (define_attr "in_sfunc_delay_slot" "false,true"
490   (cond [(eq_attr "in_call_delay_slot" "false")
491          (const_string "false")
492          (match_test "arc_regno_use_in (12, PATTERN (insn))")
493          (const_string "false")]
494         (const_string "true")))
496 ;; Instructions that we can put into a delay slot and conditionalize.
497 (define_attr "cond_delay_insn" "no,yes"
498   (cond [(eq_attr "cond" "!canuse") (const_string "no")
499          (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
500          (const_string "no")
501          (eq_attr "length" "2,4") (const_string "yes")]
502         (const_string "no")))
504 (define_attr "in_ret_delay_slot" "no,yes"
505   (cond [(eq_attr "in_delay_slot" "false")
506          (const_string "no")
507          (match_test "regno_clobbered_p
508                         (arc_return_address_register
509                           (arc_compute_function_type (cfun)),
510                          insn, SImode, 1)")
511          (const_string "no")]
512         (const_string "yes")))
514 (define_attr "cond_ret_delay_insn" "no,yes"
515   (cond [(eq_attr "in_ret_delay_slot" "no") (const_string "no")
516          (eq_attr "cond_delay_insn" "no") (const_string "no")]
517         (const_string "yes")))
519 (define_attr "annul_ret_delay_insn" "no,yes"
520   (cond [(eq_attr "cond_ret_delay_insn" "yes") (const_string "yes")
521          (match_test "TARGET_AT_DBR_CONDEXEC") (const_string "no")
522          (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
523            (const_string "yes")]
524    (const_string "no")))
527 ;; Delay slot definition for ARCompact ISA
528 ;; ??? FIXME:
529 ;; When outputting an annul-true insn elegible for cond-exec
530 ;; in a cbranch delay slot, unless optimizing for size, we use cond-exec
531 ;; for ARC600; we could also use this for ARC700 if the branch can't be
532 ;; unaligned and is at least somewhat likely (add parameter for this).
534 (define_delay (eq_attr "type" "call")
535   [(eq_attr "in_call_delay_slot" "true")
536    (eq_attr "in_call_delay_slot" "true")
537    (nil)])
539 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
540                    (eq_attr "type" "brcc"))
541   [(eq_attr "in_delay_slot" "true")
542    (eq_attr "in_delay_slot" "true")
543    (nil)])
545 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
546                    (eq_attr "type" "brcc"))
547   [(eq_attr "in_delay_slot" "true")
548    (nil)
549    (nil)])
551 (define_delay
552   (eq_attr "type" "return")
553   [(eq_attr "in_ret_delay_slot" "yes")
554    (eq_attr "annul_ret_delay_insn" "yes")
555    (eq_attr "cond_ret_delay_insn" "yes")])
557 ;; For ARC600, unexposing the delay sloy incurs a penalty also in the
558 ;; non-taken case, so the only meaningful way to have an annull-true
559 ;; filled delay slot is to conditionalize the delay slot insn.
560 (define_delay (and (match_test "TARGET_AT_DBR_CONDEXEC")
561                    (eq_attr "type" "branch,uncond_branch,jump")
562                    (match_test "!optimize_size"))
563   [(eq_attr "in_delay_slot" "true")
564    (eq_attr "cond_delay_insn" "yes")
565    (eq_attr "cond_delay_insn" "yes")])
567 ;; For ARC700, anything goes for annulled-true insns, since there is no
568 ;; penalty for the unexposed delay slot when the branch is not taken,
569 ;; however, we must avoid things that have a delay slot themselvese to
570 ;; avoid confusing gcc.
571 (define_delay (and (match_test "!TARGET_AT_DBR_CONDEXEC")
572                    (eq_attr "type" "branch,uncond_branch,jump")
573                    (match_test "!optimize_size"))
574   [(eq_attr "in_delay_slot" "true")
575    (eq_attr "type" "!call,branch,uncond_branch,jump,brcc,return,sfunc")
576    (eq_attr "cond_delay_insn" "yes")])
578 ;; -mlongcall -fpic sfuncs use r12 to load the function address
579 (define_delay (eq_attr "type" "sfunc")
580   [(eq_attr "in_sfunc_delay_slot" "true")
581    (eq_attr "in_sfunc_delay_slot" "true")
582    (nil)])
583 ;; ??? need to use a working strategy for canuse_limm:
584 ;; - either canuse_limm is not eligible for delay slots, and has no
585 ;;   delay slots, or arc_reorg has to treat them as nocond, or it has to
586 ;;   somehow modify them to become inelegible for delay slots if a decision
587 ;;   is made that makes conditional execution required.
589 (define_attr "tune" "none,arc600,arc700_4_2_std,arc700_4_2_xmac"
590   (const
591    (cond [(symbol_ref "arc_tune == TUNE_ARC600")
592           (const_string "arc600")
593           (symbol_ref "arc_tune == TUNE_ARC700_4_2_STD")
594           (const_string "arc700_4_2_std")
595           (symbol_ref "arc_tune == TUNE_ARC700_4_2_XMAC")
596           (const_string "arc700_4_2_xmac")]
597          (const_string "none"))))
599 (define_attr "tune_arc700" "false,true"
600   (if_then_else (eq_attr "tune" "arc700_4_2_std, arc700_4_2_xmac")
601                 (const_string "true")
602                 (const_string "false")))
604 ;; Move instructions.
605 (define_expand "movqi"
606   [(set (match_operand:QI 0 "move_dest_operand" "")
607         (match_operand:QI 1 "general_operand" ""))]
608   ""
609   "if (prepare_move_operands (operands, QImode)) DONE;")
611 ; In order to allow the ccfsm machinery to do its work, the leading compact
612 ; alternatives say 'canuse' - there is another alternative that will match
613 ; when the condition codes are used.
614 ; Rcq won't match if the condition is actually used; to avoid a spurious match
615 ; via q, q is inactivated as constraint there.
616 ; Likewise, the length of an alternative that might be shifted to conditional
617 ; execution must reflect this, lest out-of-range branches are created.
618 ; The iscompact attribute allows the epilogue expander to know for which
619 ; insns it should lengthen the return insn.
620 (define_insn "*movqi_insn"
621   [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,Usc")
622         (match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3"))]
623   "register_operand (operands[0], QImode)
624    || register_operand (operands[1], QImode)"
625   "@
626    mov%? %0,%1%&
627    mov%? %0,%1%&
628    mov%? %0,%1%&
629    mov%? %0,%1%&
630    mov%? %0,%1%&
631    mov%? %0,%1
632    mov%? %0,%1
633    mov%? %0,%1
634    mov%? %0,%1
635    mov%? %0,%S1
636    ldb%? %0,%1%&
637    stb%? %1,%0%&
638    ldb%? %0,%1%&
639    xldb%U1 %0,%1
640    ldb%U1%V1 %0,%1
641    xstb%U0 %1,%0
642    stb%U0%V0 %1,%0
643    stb%U0%V0 %1,%0
644    stb%U0%V0 %1,%0"
645   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store")
646    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false")
647    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no")
648    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
650 (define_expand "movhi"
651   [(set (match_operand:HI 0 "move_dest_operand" "")
652         (match_operand:HI 1 "general_operand" ""))]
653   ""
654   "if (prepare_move_operands (operands, HImode)) DONE;")
656 (define_insn "*movhi_insn"
657   [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,VUsc,VUsc")
658         (match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1,cL,I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))]
659   "register_operand (operands[0], HImode)
660    || register_operand (operands[1], HImode)
661    || (CONSTANT_P (operands[1])
662        /* Don't use a LIMM that we could load with a single insn - we loose
663           delay-slot filling opportunities.  */
664        && !satisfies_constraint_I (operands[1])
665        && satisfies_constraint_Usc (operands[0]))"
666   "@
667    mov%? %0,%1%&
668    mov%? %0,%1%&
669    mov%? %0,%1%&
670    mov%? %0,%1%&
671    mov%? %0,%1%&
672    mov%? %0,%1
673    mov%? %0,%1
674    mov%? %0,%1
675    mov%? %0,%S1%&
676    mov%? %0,%S1
677    mov%? %0,%S1
678    ld%_%? %0,%1%&
679    st%_%? %1,%0%&
680    xld%_%U1 %0,%1
681    ld%_%U1%V1 %0,%1
682    xst%_%U0 %1,%0
683    st%_%U0%V0 %1,%0
684    st%_%U0%V0 %1,%0
685    st%_%U0%V0 %S1,%0
686    st%_%U0%V0 %S1,%0"
687   [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
688    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false")
689    (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
690    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")])
692 (define_expand "movsi"
693   [(set (match_operand:SI 0 "move_dest_operand" "")
694         (match_operand:SI 1 "general_operand" ""))]
695   ""
696   "if (prepare_move_operands (operands, SImode)) DONE;")
698 ; In order to allow the ccfsm machinery to do its work, the leading compact
699 ; alternatives say 'canuse' - there is another alternative that will match
700 ; when the condition codes are used.
701 ; Rcq won't match if the condition is actually used; to avoid a spurious match
702 ; via q, q is inactivated as constraint there.
703 ; Likewise, the length of an alternative that might be shifted to conditional
704 ; execution must reflect this, lest out-of-range branches are created.
705 ; the iscompact attribute allows the epilogue expander to know for which
706 ; insns it should lengthen the return insn.
707 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
708 (define_insn "*movsi_insn"                      ;   0     1     2     3    4  5 6   7   8   9   10  11  12  13    14  15   16  17  18     19     20  21  22    23    24 25 26    27 28  29   30   31
709   [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   h, w,w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,   w,Rcq,  S,   Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,VUsc,VUsc")
710         (match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,  T,Rcq,RcqRck,   Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac, Cm3, C32"))]
711   "register_operand (operands[0], SImode)
712    || register_operand (operands[1], SImode)
713    || (CONSTANT_P (operands[1])
714        /* Don't use a LIMM that we could load with a single insn - we loose
715           delay-slot filling opportunities.  */
716        && !satisfies_constraint_I (operands[1])
717        && satisfies_constraint_Usc (operands[0]))"
718   "@
719    mov%? %0,%1%&        ;0
720    mov%? %0,%1%&        ;1
721    mov%? %0,%1%&        ;2
722    mov%? %0,%1%&        ;3
723    mov%? %0,%1%&        ;4
724    mov%? %0,%1          ;5
725    mov%? %0,%1          ;6
726    ror %0,((%1*2+1) & 0x3f) ;7
727    movl.cl %0,%1        ;8
728    movh.cl %0,%L1>>16   ;9
729    * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
730    mov%? %0,%1          ;11
731    add %0,%S1           ;12
732    add %0,pcl,%1@pcl    ;13
733    mov%? %0,%S1%&       ;14
734    mov%? %0,%S1         ;15
735    mov%? %0,%S1         ;16
736    ld%? %0,%1%&         ;17
737    st%? %1,%0%&         ;18
738    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
739    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
740    ld%? %0,%1%&         ;21
741    xld%U1 %0,%1         ;22
742    ld%? %0,%1%&         ;23
743    ld%? %0,%1%&         ;24
744    ld%U1%V1 %0,%1       ;25
745    xst%U0 %1,%0         ;26
746    st%? %1,%0%&         ;27
747    st%U0%V0 %1,%0       ;28
748    st%U0%V0 %1,%0       ;29
749    st%U0%V0 %1,%0       ;30
750    st%U0%V0 %S1,%0      ;31"
751    ;                         0     1     2     3    4    5      6       7           8     9    10     11    12    13           14        15    16   17    18    19   20    21    22   23  24    25    26    27    28    29   30   31
752   [(set_attr "type"       "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary,      move,      move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store")
753    (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,         false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false,false")
754    ; Use default length for iscompact to allow for COND_EXEC.  But set length
755    ; of Crr to 4.
756    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8")
757    (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no")
758    (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")])
760 ;; Sometimes generated by the epilogue code.  We don't want to
761 ;; recognize these addresses in general, because the limm is costly,
762 ;; and we can't use them for stores.  */
763 (define_insn "*movsi_pre_mod"
764   [(set (match_operand:SI 0 "register_operand" "=w")
765         (mem:SI (pre_modify
766                   (reg:SI SP_REG)
767                   (plus:SI (reg:SI SP_REG)
768                            (match_operand 1 "immediate_operand" "Cal")))))]
769   "reload_completed"
770   "ld.a %0,[sp,%1]"
771   [(set_attr "type" "load")
772    (set_attr "length" "8")])
774 ;; Store a value to directly to memory.  The location might also be cached.
775 ;; Since the cached copy can cause a write-back at unpredictable times,
776 ;; we first write cached, then we write uncached.
777 (define_insn "store_direct"
778   [(set (match_operand:SI 0 "move_dest_operand" "=m")
779       (unspec:SI [(match_operand:SI 1 "register_operand" "c")]
780        UNSPEC_ARC_DIRECT))]
781   ""
782   "st%U0 %1,%0\;st%U0.di %1,%0"
783   [(set_attr "type" "store")])
785 (define_insn_and_split "*movsi_set_cc_insn"
786   [(set (match_operand:CC_ZN 2 "cc_set_register" "")
787         (match_operator:CC_ZN 3 "zn_compare_operator"
788           [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)]))
789    (set (match_operand:SI 0 "register_operand" "=w,w,w")
790         (match_dup 1))]
791   ""
792   "mov%?.f %0,%S1"
793   ; splitting to 'tst' allows short insns and combination into brcc.
794   "reload_completed && operands_match_p (operands[0], operands[1])"
795   [(set (match_dup 2) (match_dup 3))]
796   ""
797   [(set_attr "type" "compare")
798    (set_attr "predicable" "no,yes,yes")
799    (set_attr "cond" "set_zn")
800    (set_attr "length" "4,4,8")])
802 (define_insn "unary_comparison"
803   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
804         (match_operator:CC_ZN 3 "zn_compare_operator"
805           [(match_operator:SI 2 "unary_operator"
806              [(match_operand:SI 1 "register_operand" "c")])
807            (const_int 0)]))]
808   ""
809   "%O2.f 0,%1"
810   [(set_attr "type" "compare")
811    (set_attr "cond" "set_zn")])
814 ; this pattern is needed by combiner for cases like if (c=(~b)) { ... }
815 (define_insn "*unary_comparison_result_used"
816   [(set (match_operand 2 "cc_register" "")
817         (match_operator 4 "zn_compare_operator"
818           [(match_operator:SI 3 "unary_operator"
819              [(match_operand:SI 1 "register_operand" "c")])
820                (const_int 0)]))
821    (set (match_operand:SI 0 "register_operand" "=w")
822         (match_dup 3))]
823   ""
824   "%O3.f %0,%1"
825   [(set_attr "type" "compare")
826    (set_attr "cond" "set_zn")
827    (set_attr "length" "4")])
829 ; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
830 ; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
831 ; even if we don't need the clobber.
832 (define_insn_and_split "*tst_movb"
833   [(set
834      (match_operand 0 "cc_register" "")
835      (match_operator 4 "zn_compare_operator"
836        [(and:SI
837           (match_operand:SI 1 "register_operand"  "%Rcq,Rcq, c,  c,  c,  c,Rrq,  3,  c")
838           (match_operand:SI 2 "nonmemory_operand"  "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
839         (const_int 0)]))
840    (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
841   "TARGET_NPS_BITOPS"
842   "movb.f.cl %3,%1,%p2,%p2,%s2"
843   "TARGET_NPS_BITOPS && reload_completed
844    && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
845   [(set (match_dup 0) (match_dup 4))])
847 (define_insn "*tst"
848   [(set
849      (match_operand 0 "cc_register" "")
850      (match_operator 3 "zn_compare_operator"
851        [(and:SI
852           (match_operand:SI 1 "register_operand"
853            "%Rcq,Rcq, c, c, c,  c,  c,  c")
854           (match_operand:SI 2 "nonmemory_operand"
855            " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
856         (const_int 0)]))]
857   "reload_completed
858    || !satisfies_constraint_Cbf (operands[2])
859    || satisfies_constraint_C0p (operands[2])
860    || satisfies_constraint_I (operands[2])
861    || satisfies_constraint_C1p (operands[2])
862    || satisfies_constraint_Chs (operands[2])"
863   "*
864     switch (which_alternative)
865     {
866     case 0: case 2: case 3: case 7:
867       return \"tst%? %1,%2\";
868     case 1:
869       return \"btst%? %1,%z2\";
870     case 4:
871       return \"bmsk%?.f 0,%1,%Z2%&\";
872     case 5:
873       return \"bclr%?.f 0,%1,%M2%&\";
874     case 6:
875       return \"asr.f 0,%1,%p2\";
876     default:
877       gcc_unreachable ();
878     }
879   "
880   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
881    (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
882    (set_attr "length" "*,*,4,4,4,4,4,8")
883    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
884    (set_attr "cond" "set_zn")])
886 ; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
887 ; combine will do that and not try the AND.
889 ; It would take 66 constraint combinations to describe the zero_extract
890 ; constants that are covered by the 12-bit signed constant for tst
891 ; (excluding the ones that are better done by mov or btst).
892 ; so we rather use an extra pattern for tst;
893 ; since this is about constants, reload shouldn't care.
894 (define_insn "*tst_bitfield_tst"
895   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
896         (match_operator 4 "zn_compare_operator"
897           [(zero_extract:SI
898              (match_operand:SI 1 "register_operand"  "c")
899              (match_operand:SI 2 "const_int_operand" "n")
900              (match_operand:SI 3 "const_int_operand" "n"))
901            (const_int 0)]))]
902   "INTVAL (operands[2]) > 1
903    && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
904        || (INTVAL (operands[3]) <= 11
905            && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
906   "tst %1,((1<<%2)-1)<<%3"
907   [(set_attr "type" "compare")
908    (set_attr "cond" "set_zn")
909    (set_attr "length" "4")])
911 ; Likewise for asr.f.
912 (define_insn "*tst_bitfield_asr"
913   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
914         (match_operator 4 "zn_compare_operator"
915           [(zero_extract:SI
916              (match_operand:SI 1 "register_operand"  "c")
917              (match_operand:SI 2 "const_int_operand" "n")
918              (match_operand:SI 3 "const_int_operand" "n"))
919            (const_int 0)]))]
920   "INTVAL (operands[2]) > 1
921    && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
922   "asr.f 0,%1,%3"
923   [(set_attr "type" "shift")
924    (set_attr "cond" "set_zn")
925    (set_attr "length" "4")])
927 (define_insn "*tst_bitfield"
928   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
929         (match_operator 5 "zn_compare_operator"
930           [(zero_extract:SI
931              (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
932              (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
933              (match_operand:SI 3 "const_int_operand"    "n,n,C_0,Cbn,n"))
934            (const_int 0)]))
935    (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
936   ""
937   "@
938    btst%? %1,%3
939    btst %1,%3
940    bmsk.f 0,%1,%2-1
941    movb.f.cl %4,%1,%3,%3,%2
942    and.f 0,%1,((1<<%2)-1)<<%3"
943   [(set_attr "iscompact" "maybe,false,false,false,false")
944    (set_attr "type" "compare,compare,compare,shift,compare")
945    (set_attr "cond" "set_zn")
946    (set_attr "length" "*,4,4,4,8")])
948 (define_insn "*commutative_binary_comparison"
949   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
950         (match_operator:CC_ZN 5 "zn_compare_operator"
951           [(match_operator:SI 4 "commutative_operator"
952              [(match_operand:SI 1 "register_operand" "%c,c")
953               (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
954            (const_int 0)]))
955    (clobber (match_scratch:SI 3 "=X,X"))]
956   ""
957   "%O4.f 0,%1,%2"
958   [(set_attr "type" "compare")
959    (set_attr "cond" "set_zn")
960    (set_attr "length" "4,8")])
962 ; for flag setting 'add' instructions like if (a+b) { ...}
963 ; the combiner needs this pattern
964 (define_insn "*addsi_compare"
965   [(set (reg:CC_ZN CC_REG)
966         (compare:CC_ZN (match_operand:SI 0 "register_operand" "c")
967                        (neg:SI (match_operand:SI 1 "register_operand" "c"))))]
968   ""
969   "add.f 0,%0,%1"
970   [(set_attr "cond" "set")
971    (set_attr "type" "compare")
972    (set_attr "length" "4")])
974 ; for flag setting 'add' instructions like if (a+b < a) { ...}
975 ; the combiner needs this pattern
976 (define_insn "addsi_compare_2"
977   [(set (reg:CC_C CC_REG)
978         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c,c")
979                                (match_operand:SI 1 "nonmemory_operand" "cL,Cal"))
980                       (match_dup 0)))]
981   ""
982   "add.f 0,%0,%1"
983   [(set_attr "cond" "set")
984    (set_attr "type" "compare")
985    (set_attr "length" "4,8")])
987 (define_insn "*addsi_compare_3"
988   [(set (reg:CC_C CC_REG)
989         (compare:CC_C (plus:SI (match_operand:SI 0 "register_operand" "c")
990                                (match_operand:SI 1 "register_operand" "c"))
991                       (match_dup 1)))]
992   ""
993   "add.f 0,%0,%1"
994   [(set_attr "cond" "set")
995    (set_attr "type" "compare")
996    (set_attr "length" "4")])
998 ; this pattern is needed by combiner for cases like if (c=a+b) { ... }
999 (define_insn "*commutative_binary_comparison_result_used"
1000   [(set (match_operand 3 "cc_register" "")
1001         (match_operator 5 "zn_compare_operator"
1002           ; We can accept any commutative operator except mult because
1003           ; our 'w' class below could try to use LP_COUNT.
1004           [(match_operator:SI 4 "commutative_operator_sans_mult"
1005              [(match_operand:SI 1 "register_operand" "c,0,c")
1006               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1007            (const_int 0)]))
1008    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1009         (match_dup 4))]
1010   ""
1011   "%O4.f %0,%1,%2 ; non-mult commutative"
1012   [(set_attr "type" "compare,compare,compare")
1013    (set_attr "cond" "set_zn,set_zn,set_zn")
1014    (set_attr "length" "4,4,8")])
1016 ; a MULT-specific version of this pattern to avoid touching the
1017 ; LP_COUNT register
1018 (define_insn "*commutative_binary_mult_comparison_result_used"
1019   [(set (match_operand 3 "cc_register" "")
1020         (match_operator 5 "zn_compare_operator"
1021           [(match_operator:SI 4 "mult_operator"
1022              [(match_operand:SI 1 "register_operand" "c,0,c")
1023               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1024            (const_int 0)]))
1025         ; Make sure to use the W class to not touch LP_COUNT.
1026    (set (match_operand:SI 0 "register_operand" "=W,W,W")
1027         (match_dup 4))]
1028   "!TARGET_ARC600_FAMILY"
1029   "%O4.f %0,%1,%2 ; mult commutative"
1030   [(set_attr "type" "compare,compare,compare")
1031    (set_attr "cond" "set_zn,set_zn,set_zn")
1032    (set_attr "length" "4,4,8")])
1034 ; this pattern is needed by combiner for cases like if (c=a<<b) { ... }
1035 (define_insn "*noncommutative_binary_comparison_result_used"
1036   [(set (match_operand 3 "cc_register" "")
1037         (match_operator 5 "zn_compare_operator"
1038           [(match_operator:SI 4 "noncommutative_operator"
1039              [(match_operand:SI 1 "register_operand" "c,0,c")
1040               (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")])
1041                (const_int 0)]))
1042    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1043         (match_dup 4 ))]
1044   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1045   "%O4.f %0,%1,%2"
1046   [(set_attr "type" "compare,compare,compare")
1047    (set_attr "cond" "set_zn,set_zn,set_zn")
1048    (set_attr "length" "4,4,8")])
1050 (define_insn "*noncommutative_binary_comparison"
1051   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
1052         (match_operator:CC_ZN 5 "zn_compare_operator"
1053           [(match_operator:SI 4 "noncommutative_operator"
1054              [(match_operand:SI 1 "register_operand" "c,c")
1055               (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])
1056            (const_int 0)]))
1057    (clobber (match_scratch:SI 3 "=X,X"))]
1058   "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS"
1059   "%O4.f 0,%1,%2"
1060   [(set_attr "type" "compare")
1061    (set_attr "cond" "set_zn")
1062    (set_attr "length" "4,8")])
1064 (define_expand "bic_f_zn"
1065   [(parallel
1066      [(set (reg:CC_ZN CC_REG)
1067            (compare:CC_ZN
1068              (and:SI (match_operand:SI 1 "register_operand" "")
1069                      (not:SI (match_operand:SI 2 "nonmemory_operand" "")))
1070            (const_int 0)))
1071       (set (match_operand:SI 0 "register_operand" "")
1072            (and:SI (match_dup 1) (not:SI (match_dup 2))))])]
1073   "")
1075 (define_insn "*bic_f"
1076   [(set (match_operand 3 "cc_register" "=Rcc,Rcc,Rcc")
1077         (match_operator 4 "zn_compare_operator"
1078           [(and:SI (match_operand:SI 1 "register_operand" "c,0,c")
1079                    (not:SI
1080                      (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")))
1081            (const_int 0)]))
1082    (set (match_operand:SI 0 "register_operand" "=w,w,w")
1083         (and:SI (match_dup 1) (not:SI (match_dup 2))))]
1084   ""
1085   "bic.f %0,%1,%2"
1086   [(set_attr "type" "compare,compare,compare")
1087    (set_attr "cond" "set_zn,set_zn,set_zn")
1088    (set_attr "length" "4,4,8")])
1090 (define_expand "movdi"
1091   [(set (match_operand:DI 0 "move_dest_operand" "")
1092         (match_operand:DI 1 "general_operand" ""))]
1093   ""
1094   "
1095   if (prepare_move_operands (operands, DImode))
1096     DONE;
1097   ")
1099 (define_insn_and_split "*movdi_insn"
1100   [(set (match_operand:DI 0 "move_dest_operand"      "=w, w,r,m")
1101         (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,c"))]
1102   "register_operand (operands[0], DImode)
1103    || register_operand (operands[1], DImode)"
1104   "*
1106   switch (which_alternative)
1107     {
1108     default:
1109       return \"#\";
1111     case 2:
1112     if (TARGET_LL64
1113         && ((even_register_operand (operands[0], DImode)
1114              && memory_operand (operands[1], DImode))
1115             || (memory_operand (operands[0], DImode)
1116                 && even_register_operand (operands[1], DImode))))
1117       return \"ldd%U1%V1 %0,%1%&\";
1118     return \"#\";
1120     case 3:
1121     if (TARGET_LL64
1122         && ((even_register_operand (operands[0], DImode)
1123              && memory_operand (operands[1], DImode))
1124             || (memory_operand (operands[0], DImode)
1125                 && even_register_operand (operands[1], DImode))))
1126      return \"std%U0%V0 %1,%0\";
1127     return \"#\";
1128     }
1130   "reload_completed"
1131   [(const_int 0)]
1132   {
1133    arc_split_move (operands);
1134    DONE;
1135   }
1136   [(set_attr "type" "move,move,load,store")
1137    ;; ??? The ld/st values could be 4 if it's [reg,bignum].
1138    (set_attr "length" "8,16,*,*")])
1141 ;; Floating point move insns.
1143 (define_expand "movsf"
1144   [(set (match_operand:SF 0 "move_dest_operand" "")
1145         (match_operand:SF 1 "general_operand" ""))]
1146   ""
1147   "if (prepare_move_operands (operands, SFmode)) DONE;")
1149 (define_insn "*movsf_insn"
1150   [(set (match_operand:SF 0 "move_dest_operand"    "=h,w,w,r,m")
1151         (match_operand:SF 1 "move_src_operand"   "hCm1,c,E,m,c"))]
1152   "register_operand (operands[0], SFmode)
1153    || register_operand (operands[1], SFmode)"
1154   "@
1155    mov%? %0,%1
1156    mov%? %0,%1
1157    mov%? %0,%1 ; %A1
1158    ld%U1%V1 %0,%1
1159    st%U0%V0 %1,%0"
1160   [(set_attr "type" "move,move,move,load,store")
1161    (set_attr "predicable" "no,yes,yes,no,no")
1162    (set_attr "iscompact" "true,false,false,false,false")])
1164 (define_expand "movdf"
1165   [(set (match_operand:DF 0 "move_dest_operand" "")
1166         (match_operand:DF 1 "general_operand" ""))]
1167   ""
1168   "if (prepare_move_operands (operands, DFmode)) DONE;")
1170 (define_insn_and_split "*movdf_insn"
1171   [(set (match_operand:DF 0 "move_dest_operand"      "=D,r,c,c,r,m")
1172         (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
1173   "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
1174   "*
1176  switch (which_alternative)
1177    {
1178     default:
1179       return \"#\";
1180     case 4:
1181     if (TARGET_LL64
1182         && ((even_register_operand (operands[0], DFmode)
1183              && memory_operand (operands[1], DFmode))
1184             || (memory_operand (operands[0], DFmode)
1185                 && even_register_operand (operands[1], DFmode))))
1186       return \"ldd%U1%V1 %0,%1%&\";
1187     return \"#\";
1189     case 5:
1190     if (TARGET_LL64
1191         && ((even_register_operand (operands[0], DFmode)
1192              && memory_operand (operands[1], DFmode))
1193             || (memory_operand (operands[0], DFmode)
1194                 && even_register_operand (operands[1], DFmode))))
1195      return \"std%U0%V0 %1,%0\";
1196     return \"#\";
1197    }
1199   "reload_completed"
1200   [(const_int 0)]
1201   {
1202    arc_split_move (operands);
1203    DONE;
1204   }
1205   [(set_attr "type" "move,move,move,move,load,store")
1206    (set_attr "predicable" "no,no,yes,yes,no,no")
1207    ;; ??? The ld/st values could be 16 if it's [reg,bignum].
1208    (set_attr "length" "4,16,8,16,16,16")])
1210 (define_insn_and_split "*movdf_insn_nolrsr"
1211   [(set (match_operand:DF 0 "register_operand"       "=r")
1212         (match_operand:DF 1 "arc_double_register_operand" "D"))
1213    (use (match_operand:SI 2 "" "N")) ; aka const1_rtx
1214    ]
1215   "TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR"
1216   "#"
1217   "&& 1"
1218   [
1219     ; mov r0, 0
1220     (set (match_dup 0) (match_dup 3))
1222     ; daddh?? r1, r0, r0
1223     (parallel [
1224         (set (match_dup 1) (plus:DF (match_dup 1) (match_dup 0)))
1225         (use (const_int 1))
1226         (use (const_int 1))
1227         (use (match_dup 0)) ; used to block can_combine_p
1228         (set (match_dup 0) (plus:DF (match_dup 1) (match_dup 0))) ; r1 in op 0
1229     ])
1231     ; We have to do this twice, once to read the value into R0 and
1232     ; second time to put back the contents which the first DEXCLx
1233     ; will have overwritten
1234     ; dexcl2 r0, r1, r0
1235     (parallel [
1236                (set (match_dup 4) ; aka r0result
1237                                   ; aka DF, r1, r0
1238                     (unspec_volatile:SI [(match_dup 5) (match_dup 4)]
1239                                         VUNSPEC_ARC_DEXCL))
1240                (clobber (match_dup 1))
1241                ])
1242     ; Generate the second, which makes sure operand5 and operand4 values
1243     ; are put back in the Dx register properly.
1244     (set (match_dup 1) (unspec_volatile:DF
1245                         [(match_dup 5) (match_dup 4)]
1246                         VUNSPEC_ARC_DEXCL_NORES))
1248     ; Note: we cannot use a (clobber (match_scratch)) here because
1249     ; the combine pass will end up replacing uses of it with 0
1250   ]
1251   "operands[3] = CONST0_RTX (DFmode);
1252    operands[4] = simplify_gen_subreg (SImode, operands[0], DFmode, 0);
1253    operands[5] = simplify_gen_subreg (SImode, operands[0], DFmode, 4);"
1254   [(set_attr "type" "move")])
1256 ;; Load/Store with update instructions.
1258 ;; Some of these we can get by using pre-decrement or pre-increment, but the
1259 ;; hardware can also do cases where the increment is not the size of the
1260 ;; object.
1262 ;; In all these cases, we use operands 0 and 1 for the register being
1263 ;; incremented because those are the operands that local-alloc will
1264 ;; tie and these are the pair most likely to be tieable (and the ones
1265 ;; that will benefit the most).
1267 ;; We use match_operator here because we need to know whether the memory
1268 ;; object is volatile or not.
1271 ;; Note: loadqi_update has no 16-bit variant
1272 (define_insn "*loadqi_update"
1273   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
1274         (match_operator:QI 4 "any_mem_operand"
1275          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1276                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1277    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1278         (plus:SI (match_dup 1) (match_dup 2)))]
1279   ""
1280   "ldb.a%V4 %3,[%0,%S2]"
1281   [(set_attr "type" "load,load")
1282    (set_attr "length" "4,8")])
1284 (define_insn "*load_zeroextendqisi_update"
1285   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1286         (zero_extend:SI (match_operator:QI 4 "any_mem_operand"
1287                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1288                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1289    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1290         (plus:SI (match_dup 1) (match_dup 2)))]
1291   ""
1292   "ldb.a%V4 %3,[%0,%S2]"
1293   [(set_attr "type" "load,load")
1294    (set_attr "length" "4,8")])
1296 (define_insn "*load_signextendqisi_update"
1297   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1298         (sign_extend:SI (match_operator:QI 4 "any_mem_operand"
1299                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1300                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1301    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1302         (plus:SI (match_dup 1) (match_dup 2)))]
1303   ""
1304   "ldb.x.a%V4 %3,[%0,%S2]"
1305   [(set_attr "type" "load,load")
1306    (set_attr "length" "4,8")])
1308 (define_insn "*storeqi_update"
1309   [(set (match_operator:QI 4 "any_mem_operand"
1310          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1311                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1312         (match_operand:QI 3 "register_operand" "c"))
1313    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1314         (plus:SI (match_dup 1) (match_dup 2)))]
1315   ""
1316   "stb.a%V4 %3,[%0,%2]"
1317   [(set_attr "type" "store")
1318    (set_attr "length" "4")])
1320 ;; ??? pattern may have to be re-written
1321 ;; Note: no 16-bit variant for this pattern
1322 (define_insn "*loadhi_update"
1323   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
1324         (match_operator:HI 4 "any_mem_operand"
1325          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1326                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1327    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1328         (plus:SI (match_dup 1) (match_dup 2)))]
1329   ""
1330   "ld%_.a%V4 %3,[%0,%S2]"
1331   [(set_attr "type" "load,load")
1332    (set_attr "length" "4,8")])
1334 (define_insn "*load_zeroextendhisi_update"
1335   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1336         (zero_extend:SI (match_operator:HI 4 "any_mem_operand"
1337                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1338                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1339    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
1340         (plus:SI (match_dup 1) (match_dup 2)))]
1341   ""
1342   "ld%_.a%V4 %3,[%0,%S2]"
1343   [(set_attr "type" "load,load")
1344    (set_attr "length" "4,8")])
1346 ;; Note: no 16-bit variant for this instruction
1347 (define_insn "*load_signextendhisi_update"
1348   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1349         (sign_extend:SI (match_operator:HI 4 "any_mem_operand"
1350                          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1351                                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
1352    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1353         (plus:SI (match_dup 1) (match_dup 2)))]
1354   ""
1355   "ld%_.x.a%V4 %3,[%0,%S2]"
1356   [(set_attr "type" "load,load")
1357    (set_attr "length" "4,8")])
1359 (define_insn "*storehi_update"
1360   [(set (match_operator:HI 4 "any_mem_operand"
1361          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1362                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1363         (match_operand:HI 3 "register_operand" "c"))
1364    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1365         (plus:SI (match_dup 1) (match_dup 2)))]
1366   ""
1367   "st%_.a%V4 %3,[%0,%2]"
1368   [(set_attr "type" "store")
1369    (set_attr "length" "4")])
1371 ;; No 16-bit variant for this instruction pattern
1372 (define_insn "*loadsi_update"
1373   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
1374         (match_operator:SI 4 "any_mem_operand"
1375          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1376                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1377    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1378         (plus:SI (match_dup 1) (match_dup 2)))]
1379   ""
1380   "ld.a%V4 %3,[%0,%S2]"
1381   [(set_attr "type" "load,load")
1382    (set_attr "length" "4,8")])
1384 (define_insn "*storesi_update"
1385   [(set (match_operator:SI 4 "any_mem_operand"
1386          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1387                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1388         (match_operand:SI 3 "register_operand" "c"))
1389    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1390         (plus:SI (match_dup 1) (match_dup 2)))]
1391   ""
1392   "st.a%V4 %3,[%0,%2]"
1393   [(set_attr "type" "store")
1394    (set_attr "length" "4")])
1396 (define_insn "*loadsf_update"
1397   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
1398         (match_operator:SF 4 "any_mem_operand"
1399          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
1400                    (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
1401    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1402         (plus:SI (match_dup 1) (match_dup 2)))]
1403   ""
1404   "ld.a%V4 %3,[%0,%S2]"
1405   [(set_attr "type" "load,load")
1406    (set_attr "length" "4,8")])
1408 (define_insn "*storesf_update"
1409   [(set (match_operator:SF 4 "any_mem_operand"
1410          [(plus:SI (match_operand:SI 1 "register_operand" "0")
1411                    (match_operand:SI 2 "short_immediate_operand" "I"))])
1412         (match_operand:SF 3 "register_operand" "c"))
1413    (set (match_operand:SI 0 "dest_reg_operand" "=w")
1414         (plus:SI (match_dup 1) (match_dup 2)))]
1415   ""
1416   "st.a%V4 %3,[%0,%2]"
1417   [(set_attr "type" "store")
1418    (set_attr "length" "4")])
1420 ;; Conditional move instructions.
1422 (define_expand "movsicc"
1423   [(set (match_operand:SI 0 "dest_reg_operand" "")
1424         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1425                          (match_operand:SI 2 "nonmemory_operand" "")
1426                          (match_operand:SI 3 "register_operand" "")))]
1427   ""
1428   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1431 (define_expand "movdicc"
1432   [(set (match_operand:DI 0 "dest_reg_operand" "")
1433         (if_then_else:DI(match_operand 1 "comparison_operator" "")
1434                         (match_operand:DI 2 "nonmemory_operand" "")
1435                         (match_operand:DI 3 "register_operand" "")))]
1436   ""
1437   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1440 (define_expand "movsfcc"
1441   [(set (match_operand:SF 0 "dest_reg_operand" "")
1442         (if_then_else:SF (match_operand 1 "comparison_operator" "")
1443                       (match_operand:SF 2 "nonmemory_operand" "")
1444                       (match_operand:SF 3 "register_operand" "")))]
1445   ""
1446   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1448 (define_expand "movdfcc"
1449   [(set (match_operand:DF 0 "dest_reg_operand" "")
1450         (if_then_else:DF (match_operand 1 "comparison_operator" "")
1451                       (match_operand:DF 2 "nonmemory_operand" "")
1452                       (match_operand:DF 3 "register_operand" "")))]
1453   ""
1454   "operands[1] = gen_compare_reg (operands[1], VOIDmode);")
1456 (define_insn "*movsicc_insn"
1457   [(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
1458         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1459                        [(match_operand 4 "cc_register" "") (const_int 0)])
1460                       (match_operand:SI 1 "nonmemory_operand" "cL,Cal")
1461                       (match_operand:SI 2 "register_operand" "0,0")))]
1462   ""
1464   if (rtx_equal_p (operands[1], const0_rtx) && GET_CODE (operands[3]) == NE
1465       && satisfies_constraint_Rcq (operands[0]))
1466     return "sub%?.ne %0,%0,%0";
1467   /* ??? might be good for speed on ARC600 too, *if* properly scheduled.  */
1468   if ((optimize_size && (!TARGET_ARC600_FAMILY))
1469       && rtx_equal_p (operands[1], constm1_rtx)
1470       && GET_CODE (operands[3]) == LTU)
1471     return "sbc.cs %0,%0,%0";
1472   return "mov.%d3 %0,%S1";
1474   [(set_attr "type" "cmove,cmove")
1475    (set_attr "length" "4,8")])
1477 ;; When there's a mask of a single bit, and then a compare to 0 or 1,
1478 ;; if the single bit is the sign bit, then GCC likes to convert this
1479 ;; into a sign extend and a compare less than, or greater to zero.
1480 ;; This is usually fine, except for the NXP400 where we have access to
1481 ;; a bit test instruction, along with a special short load instruction
1482 ;; (from CMEM), that doesn't support sign-extension on load.
1484 ;; This peephole optimisation attempts to restore the use of bit-test
1485 ;; in those cases where it is useful to do so.
1486 (define_peephole2
1487   [(set (match_operand:SI 0 "register_operand" "")
1488                 (sign_extend:SI
1489                 (match_operand:QI 1 "any_mem_operand" "")))
1490    (set (reg:CC_ZN CC_REG)
1491         (compare:CC_ZN (match_dup 0)
1492                        (const_int 0)))
1493    (set (pc)
1494         (if_then_else (match_operator 2 "ge_lt_comparison_operator"
1495                        [(reg:CC_ZN CC_REG) (const_int 0)])
1496                       (match_operand 3 "" "")
1497                       (match_operand 4 "" "")))]
1498   "TARGET_NPS_CMEM
1499    && cmem_address (XEXP (operands[1], 0), SImode)
1500    && peep2_reg_dead_p (2, operands[0])
1501    && peep2_regno_dead_p (3, CC_REG)"
1502   [(set (match_dup 0)
1503         (zero_extend:SI
1504         (match_dup 1)))
1505    (set (reg:CC_ZN CC_REG)
1506         (compare:CC_ZN (zero_extract:SI
1507                          (match_dup 0)
1508                          (const_int 1)
1509                          (const_int 7))
1510                        (const_int 0)))
1511    (set (pc)
1512         (if_then_else (match_dup 2)
1513                       (match_dup 3)
1514                       (match_dup 4)))]
1515   "if (GET_CODE (operands[2]) == GE)
1516      operands[2] = gen_rtx_EQ (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);
1517    else
1518      operands[2] = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, 61), const0_rtx);")
1520 ; Try to generate more short moves, and/or less limms, by substituting a
1521 ; conditional move with a conditional sub.
1522 (define_peephole2
1523   [(set (match_operand:SI 0 "compact_register_operand")
1524         (match_operand:SI 1 "const_int_operand"))
1525    (set (match_dup 0)
1526         (if_then_else:SI (match_operator 3 "proper_comparison_operator"
1527                            [(match_operand 4 "cc_register" "") (const_int 0)])
1528                             (match_operand:SI 2 "const_int_operand" "")
1529                       (match_dup 0)))]
1530   "!satisfies_constraint_P (operands[1])
1531    && satisfies_constraint_P (operands[2])
1532    && UNSIGNED_INT6 (INTVAL (operands[2]) - INTVAL (operands[1]))"
1533   [(set (match_dup 0) (match_dup 2))
1534    (cond_exec
1535      (match_dup 3)
1536      (set (match_dup 0)
1537           (plus:SI (match_dup 0) (match_dup 1))))]
1538   "operands[3] = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[3]),
1539                                                     GET_MODE (operands[4])),
1540                                  VOIDmode, operands[4], const0_rtx);
1541    operands[1] = GEN_INT (INTVAL (operands[1]) - INTVAL (operands[2]));")
1543 (define_insn "*movdicc_insn"
1544   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w")
1545         (if_then_else:DI (match_operator 3 "proper_comparison_operator"
1546                         [(match_operand 4 "cc_register" "") (const_int 0)])
1547                       (match_operand:DI 1 "nonmemory_operand" "c,i")
1548                       (match_operand:DI 2 "register_operand" "0,0")))]
1549    ""
1550    "*
1552    switch (which_alternative)
1553      {
1554      default:
1555      case 0 :
1556        /* We normally copy the low-numbered register first.  However, if
1557          the first register operand 0 is the same as the second register of
1558          operand 1, we must copy in the opposite order.  */
1559        if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
1560         return \"mov.%d3 %R0,%R1\;mov.%d3 %0,%1\";
1561        else
1562         return \"mov.%d3 %0,%1\;mov.%d3 %R0,%R1\";
1563      case 1 :
1564         return \"mov.%d3 %L0,%L1\;mov.%d3 %H0,%H1\";
1567      }
1569   [(set_attr "type" "cmove,cmove")
1570    (set_attr "length" "8,16")])
1573 (define_insn "*movsfcc_insn"
1574   [(set (match_operand:SF 0 "dest_reg_operand" "=w,w")
1575         (if_then_else:SF (match_operator 3 "proper_comparison_operator"
1576                        [(match_operand 4 "cc_register" "") (const_int 0)])
1577                       (match_operand:SF 1 "nonmemory_operand" "c,E")
1578                       (match_operand:SF 2 "register_operand" "0,0")))]
1579   ""
1580   "@
1581    mov.%d3 %0,%1
1582    mov.%d3 %0,%1 ; %A1"
1583   [(set_attr "type" "cmove,cmove")])
1585 (define_insn "*movdfcc_insn"
1586   [(set (match_operand:DF 0 "dest_reg_operand" "=w,w")
1587         (if_then_else:DF (match_operator 1 "proper_comparison_operator"
1588                  [(match_operand 4 "cc_register" "") (const_int 0)])
1589                       (match_operand:DF 2 "nonmemory_operand" "c,E")
1590                       (match_operand:DF 3 "register_operand" "0,0")))]
1591   ""
1592   "*
1594   switch (which_alternative)
1595     {
1596     default:
1597     case 0 :
1598       /* We normally copy the low-numbered register first.  However, if
1599          the first register operand 0 is the same as the second register of
1600          operand 1, we must copy in the opposite order.  */
1601       if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
1602         return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
1603       else
1604         return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
1605     case 1 :
1606               return \"mov.%d1 %L0,%L2\;mov.%d1 %H0,%H2; %A2 \";
1608     }
1610   [(set_attr "type" "cmove,cmove")
1611    (set_attr "length" "8,16")])
1614 (define_insn "*zero_extendqihi2_i"
1615   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
1616         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
1617   ""
1618   "@
1619    extb%? %0,%1%&
1620    extb%? %0,%1%&
1621    bmsk%? %0,%1,7
1622    extb %0,%1
1623    xldb%U1 %0,%1
1624    ldb%U1 %0,%1"
1625   [(set_attr "type" "unary,unary,unary,unary,load,load")
1626    (set_attr "iscompact" "maybe,true,false,false,false,false")
1627    (set_attr "predicable" "no,no,yes,no,no,no")])
1629 (define_expand "zero_extendqihi2"
1630   [(set (match_operand:HI 0 "dest_reg_operand" "")
1631         (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1632   ""
1633   "if (prepare_extend_operands (operands, ZERO_EXTEND, HImode)) DONE;"
1636 (define_insn "*zero_extendqisi2_ac"
1637   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
1638         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
1639   ""
1640   "@
1641    extb%? %0,%1%&
1642    extb%? %0,%1%&
1643    bmsk%? %0,%1,7
1644    extb %0,%1
1645    ldb%? %0,%1%&
1646    ldb%? %0,%1%&
1647    xldb%U1 %0,%1
1648    ldb%U1 %0,%1"
1649   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1650    (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
1651    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1653 (define_expand "zero_extendqisi2"
1654   [(set (match_operand:SI 0 "dest_reg_operand" "")
1655         (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1656   ""
1657   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1660 (define_insn "*zero_extendhisi2_i"
1661   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
1662         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
1663   ""
1664   "@
1665    ext%_%? %0,%1%&
1666    ext%_%? %0,%1%&
1667    bmsk%? %0,%1,15
1668    ext%_ %0,%1
1669    ld%_%? %0,%1%&
1670    ld%_%U1 %0,%1
1671    * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
1672    ld%_%U1%V1 %0,%1"
1673   [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
1674    (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
1675    (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
1678 (define_expand "zero_extendhisi2"
1679   [(set (match_operand:SI 0 "dest_reg_operand" "")
1680         (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1681   ""
1682   "if (prepare_extend_operands (operands, ZERO_EXTEND, SImode)) DONE;"
1685 ;; Sign extension instructions.
1687 (define_insn "*extendqihi2_i"
1688   [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
1689         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
1690   ""
1691   "@
1692    sexb%? %0,%1%&
1693    sexb %0,%1
1694    ldb.x%U1 %0,%1
1695    ldb.x%U1 %0,%1"
1696   [(set_attr "type" "unary,unary,load,load")
1697    (set_attr "iscompact" "true,false,false,false")
1698    (set_attr "length" "*,*,*,8")])
1701 (define_expand "extendqihi2"
1702   [(set (match_operand:HI 0 "dest_reg_operand" "")
1703         (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1704   ""
1705   "if (prepare_extend_operands (operands, SIGN_EXTEND, HImode)) DONE;"
1708 (define_insn "*extendqisi2_ac"
1709   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
1710         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
1711   ""
1712   "@
1713    sexb%? %0,%1%&
1714    sexb %0,%1
1715    ldb.x%U1 %0,%1
1716    ldb.x%U1 %0,%1"
1717   [(set_attr "type" "unary,unary,load,load")
1718    (set_attr "iscompact" "true,false,false,false")
1719    (set_attr "length" "*,*,*,8")])
1721 (define_expand "extendqisi2"
1722   [(set (match_operand:SI 0 "dest_reg_operand" "")
1723         (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "")))]
1724   ""
1725   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1728 (define_insn "*extendhisi2_i"
1729   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r")
1730         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))]
1731   ""
1732   "@
1733    sex%_%? %0,%1%&
1734    sex%_ %0,%1
1735    ldh%?.x %0,%1%&
1736    ld%_.x%U1%V1 %0,%1
1737    ld%_.x%U1%V1 %0,%1"
1738   [(set_attr "type" "unary,unary,load,load,load")
1739    (set_attr "iscompact" "true,false,true,false,false")
1740    (set_attr "length" "*,*,*,4,8")])
1742 (define_expand "extendhisi2"
1743   [(set (match_operand:SI 0 "dest_reg_operand" "")
1744         (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "")))]
1745   ""
1746   "if (prepare_extend_operands (operands, SIGN_EXTEND, SImode)) DONE;"
1749 ;; Unary arithmetic insns
1751 ;; We allow constant operands to enable late constant propagation, but it is
1752 ;; not worth while to have more than one dedicated alternative to output them -
1753 ;; if we are really worried about getting these the maximum benefit of all
1754 ;; the available alternatives, we should add an extra pass to fold such
1755 ;; operations to movsi.
1757 ;; Absolute instructions
1759 (define_insn "*abssi2_mixed"
1760   [(set (match_operand:SI 0 "compact_register_operand" "=q")
1761         (abs:SI (match_operand:SI 1 "compact_register_operand" "q")))]
1762   "TARGET_MIXED_CODE"
1763   "abs%? %0,%1%&"
1764   [(set_attr "type" "two_cycle_core")
1765    (set_attr "iscompact" "true")])
1767 (define_insn "abssi2"
1768   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w")
1769         (abs:SI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,Cal")))]
1770   ""
1771   "abs%? %0,%1%&"
1772   [(set_attr "type" "two_cycle_core")
1773    (set_attr "length" "*,4,8")
1774    (set_attr "iscompact" "true,false,false")])
1776 ;; Maximum and minimum insns
1778 (define_insn "smaxsi3"
1779    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1780          (smax:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1781                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1782   ""
1783   "max%? %0,%1,%2"
1784   [(set_attr "type" "two_cycle_core")
1785    (set_attr "length" "4,4,8")
1786    (set_attr "predicable" "yes,no,no")]
1789 (define_insn "sminsi3"
1790    [(set (match_operand:SI 0 "dest_reg_operand"         "=Rcw, w,  w")
1791          (smin:SI (match_operand:SI 1 "register_operand"  "%0, c,  c")
1792                   (match_operand:SI 2 "nonmemory_operand" "cL,cL,Cal")))]
1793   ""
1794   "min%? %0,%1,%2"
1795   [(set_attr "type" "two_cycle_core")
1796    (set_attr "length" "4,4,8")
1797    (set_attr "predicable" "yes,no,no")]
1800 ;; Arithmetic instructions.
1802 ; We say an insn can be conditionalized if this doesn't introduce a long
1803 ; immediate.  We set the type such that we still have good scheduling if the
1804 ; insn is conditionalized.
1805 ; ??? It would make sense to allow introduction of long immediates, but
1806 ;     we'd need to communicate to the ccfsm machinery the extra cost.
1807 ; The alternatives in the constraints still serve three purposes:
1808 ; - estimate insn size assuming conditional execution
1809 ; - guide reload to re-order the second and third operand to get a better fit.
1810 ; - give tentative insn type to guide scheduling
1811 ;   N.B. "%" for commutativity doesn't help when there is another matching
1812 ;   (but longer) alternative.
1813 ; We avoid letting this pattern use LP_COUNT as a register by specifying
1814 ;  register class 'W' instead of 'w'.
1815 (define_insn_and_split "*addsi3_mixed"
1816   ;;                                                      0       1    2    3   4   5   6     7    8   9   a    b     c   d e   f  10  11  12
1817   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcq#q,Rcq,   h,!*Rsd,Rcq,Rcb,Rcq, Rcqq,Rcqq,Rcw,Rcw, Rcw,    W,  W,W,  W,Rcqq,Rcw,  W")
1818         (plus:SI (match_operand:SI 1 "register_operand" "%0,      c,   0, Rcqq,  0,  0,Rcb, Rcqq,   0,  0,  c,   0,    c,  c,0,  0,   0,  0,  c")
1819                  (match_operand:SI 2 "nonmemory_operand" "cL,     0, Cm1,    L,CL2,Csp,CM4,RcqqK,  cO, cL,  0,cCca,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))]
1820   ""
1822   arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true);
1823   return "";
1825   "&& reload_completed && get_attr_length (insn) == 8
1826    && satisfies_constraint_I (operands[2])
1827    && GET_CODE (PATTERN (insn)) != COND_EXEC"
1828   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
1829   "split_addsi (operands);"
1830   [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*")
1831    (set (attr "iscompact")
1832         (cond [(match_test "~arc_output_addsi (operands, false, false) & 2")
1833                (const_string "false")
1834                (match_operand 2 "long_immediate_operand" "")
1835                (const_string "maybe_limm")]
1836               (const_string "maybe")))
1837    (set_attr "length"     "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8")
1838    (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no")
1839    (set_attr "cond"       "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond")
1842 ;; ARCv2 MPYW and MPYUW
1843 (define_expand "mulhisi3"
1844   [(set (match_operand:SI 0 "register_operand"                           "")
1845         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  ""))
1846                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))]
1847   "TARGET_MPYW"
1848   "{
1849     if (CONSTANT_P (operands[2]))
1850     {
1851       emit_insn (gen_mulhisi3_imm (operands[0], operands[1], operands[2]));
1852       DONE;
1853     }
1854    }"
1857 (define_insn "mulhisi3_imm"
1858   [(set (match_operand:SI 0 "register_operand"                         "=r,r,r,  r,  r")
1859         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "0,r,0,  0,  r"))
1860                  (match_operand:HI 2 "short_const_int_operand"          "L,L,I,C16,C16")))]
1861   "TARGET_MPYW"
1862   "mpyw%? %0,%1,%2"
1863   [(set_attr "length" "4,4,4,8,8")
1864    (set_attr "iscompact" "false")
1865    (set_attr "type" "mul16_em")
1866    (set_attr "predicable" "yes,no,no,yes,no")
1867    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1868    ])
1870 (define_insn "mulhisi3_reg"
1871   [(set (match_operand:SI 0 "register_operand"                          "=Rcqq,r,r")
1872         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"  "   0,0,r"))
1873                  (sign_extend:SI (match_operand:HI 2 "nonmemory_operand" "Rcqq,r,r"))))]
1874   "TARGET_MPYW"
1875   "mpyw%? %0,%1,%2"
1876   [(set_attr "length" "*,4,4")
1877    (set_attr "iscompact" "maybe,false,false")
1878    (set_attr "type" "mul16_em")
1879    (set_attr "predicable" "yes,yes,no")
1880    (set_attr "cond" "canuse,canuse,nocond")
1881    ])
1883 (define_expand "umulhisi3"
1884   [(set (match_operand:SI 0 "register_operand"                           "")
1885         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand"  ""))
1886                  (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))]
1887   "TARGET_MPYW"
1888   "{
1889     if (CONSTANT_P (operands[2]))
1890     {
1891       emit_insn (gen_umulhisi3_imm (operands[0], operands[1], operands[2]));
1892       DONE;
1893     }
1894   }"
1897 (define_insn "umulhisi3_imm"
1898   [(set (match_operand:SI 0 "register_operand"                          "=r, r,  r,  r,  r")
1899         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r,  0,  0,  r"))
1900                  (match_operand:HI 2 "short_unsigned_const_operand"     " L, L,J12,J16,J16")))]
1901   "TARGET_MPYW"
1902   "mpyuw%? %0,%1,%2"
1903   [(set_attr "length" "4,4,4,8,8")
1904    (set_attr "iscompact" "false")
1905    (set_attr "type" "mul16_em")
1906    (set_attr "predicable" "yes,no,no,yes,no")
1907    (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")
1908    ])
1910 (define_insn "umulhisi3_reg"
1911   [(set (match_operand:SI 0 "register_operand"                          "=Rcqq, r, r")
1912         (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "   %0, 0, r"))
1913                  (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))]
1914   "TARGET_MPYW"
1915   "mpyuw%? %0,%1,%2"
1916   [(set_attr "length" "*,4,4")
1917    (set_attr "iscompact" "maybe,false,false")
1918    (set_attr "type" "mul16_em")
1919    (set_attr "predicable" "yes,yes,no")
1920    (set_attr "cond" "canuse,canuse,nocond")
1921    ])
1923 ;; ARC700/ARC600/V2 multiply
1924 ;; SI <- SI * SI
1926 (define_expand "mulsi3"
1927  [(set (match_operand:SI 0 "nonimmediate_operand"            "")
1928         (mult:SI (match_operand:SI 1 "register_operand"  "")
1929                  (match_operand:SI 2 "nonmemory_operand" "")))]
1930   ""
1932   if (TARGET_MPY)
1933     {
1934       if (!register_operand (operands[0], SImode))
1935         {
1936           rtx result = gen_reg_rtx (SImode);
1938           emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
1939           emit_move_insn (operands[0], result);
1940           DONE;
1941         }
1942     }
1943   else if (TARGET_MUL64_SET)
1944     {
1945      rtx tmp = gen_reg_rtx (SImode);
1946      emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
1947      emit_move_insn (operands[0], tmp);
1948      DONE;
1949     }
1950   else if (TARGET_MULMAC_32BY16_SET)
1951     {
1952      rtx tmp = gen_reg_rtx (SImode);
1953      emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
1954      emit_move_insn (operands[0], tmp);
1955      DONE;
1956     }
1957   else
1958     {
1959       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
1960       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
1961       emit_insn (gen_mulsi3_600_lib ());
1962       emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
1963       DONE;
1964     }
1967 (define_insn_and_split "mulsi32x16"
1968  [(set (match_operand:SI 0 "register_operand"            "=w")
1969         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
1970                  (match_operand:SI 2 "nonmemory_operand" "ci")))
1971   (clobber (reg:DI MUL32x16_REG))]
1972  "TARGET_MULMAC_32BY16_SET"
1973  "#"
1974  "TARGET_MULMAC_32BY16_SET && reload_completed"
1975  [(const_int 0)]
1977   if (immediate_operand (operands[2], SImode)
1978     && INTVAL (operands[2]) >= 0
1979     && INTVAL (operands[2]) <= 65535)
1980      {
1981       emit_insn (gen_umul_600 (operands[1], operands[2],
1982                                        gen_acc2 (), gen_acc1 ()));
1983       emit_move_insn (operands[0], gen_acc2 ());
1984       DONE;
1985      }
1986    emit_insn (gen_umul_600 (operands[1], operands[2],
1987                                    gen_acc2 (), gen_acc1 ()));
1988    emit_insn (gen_mac_600 (operands[1], operands[2],
1989                                    gen_acc2 (), gen_acc1 ()));
1990    emit_move_insn (operands[0], gen_acc2 ());
1991    DONE;
1992   }
1993  [(set_attr "type" "multi")
1994   (set_attr "length" "8")])
1996 ; mululw conditional execution without a LIMM clobbers an input register;
1997 ; we'd need a different pattern to describe this.
1998 ; To make the conditional execution valid for the LIMM alternative, we
1999 ; have to emit the LIMM before the register operand.
2000 (define_insn "umul_600"
2001   [(set (match_operand:SI 2 "acc2_operand" "")
2002         (mult:SI (match_operand:SI 0 "register_operand"  "c,c,c")
2003                  (zero_extract:SI (match_operand:SI 1 "nonmemory_operand"
2004                                                          "c,L,Cal")
2005                                   (const_int 16)
2006                                   (const_int 0))))
2007    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2008   "TARGET_MULMAC_32BY16_SET"
2009   "mululw 0, %0, %1"
2010   [(set_attr "length" "4,4,8")
2011    (set_attr "type" "mulmac_600")
2012    (set_attr "predicable" "no")
2013    (set_attr "cond" "nocond")])
2015 (define_insn "mac_600"
2016   [(set (match_operand:SI 2 "acc2_operand" "")
2017         (plus:SI
2018           (mult:SI (match_operand:SI 0 "register_operand" "c,c,c")
2019                    (ashift:SI
2020                      (zero_extract:SI (match_operand:SI 1 "nonmemory_operand" "c,L,Cal")
2021                                       (const_int 16)
2022                                       (const_int 16))
2023                      (const_int 16)))
2024           (match_dup 2)))
2025    (clobber (match_operand:SI 3 "acc1_operand" ""))]
2026   "TARGET_MULMAC_32BY16_SET"
2027   "machlw%? 0, %0, %1"
2028   [(set_attr "length" "4,4,8")
2029    (set_attr "type" "mulmac_600, mulmac_600, mulmac_600")
2030    (set_attr "predicable" "no, no, yes")
2031    (set_attr "cond" "nocond, canuse_limm, canuse")])
2033 (define_insn_and_split "mulsi64"
2034  [(set (match_operand:SI 0 "register_operand"            "=w")
2035         (mult:SI (match_operand:SI 1 "register_operand"  "%c")
2036                  (match_operand:SI 2 "nonmemory_operand" "ci")))
2037   (clobber (reg:DI MUL64_OUT_REG))]
2038  "TARGET_MUL64_SET"
2039  "#"
2040  "TARGET_MUL64_SET && reload_completed"
2041   [(const_int 0)]
2043   emit_insn (gen_mulsi_600 (operands[1], operands[2],
2044                         gen_mlo (), gen_mhi ()));
2045   emit_move_insn (operands[0], gen_mlo ());
2046   DONE;
2048   [(set_attr "type" "multi")
2049    (set_attr "length" "8")])
2051 (define_insn "mulsi_600"
2052   [(set (match_operand:SI 2 "mlo_operand" "")
2053         (mult:SI (match_operand:SI 0 "register_operand"  "%Rcq#q,c,c,c")
2054                  (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,I,Cal")))
2055    (clobber (match_operand:SI 3 "mhi_operand" ""))]
2056   "TARGET_MUL64_SET"
2057 ; The assembler mis-assembles mul64 / mulu64 with "I" constraint constants,
2058 ; using a machine code pattern that only allows "L" constraint constants.
2059 ;  "mul64%? \t0, %0, %1%&"
2061   if (satisfies_constraint_I (operands[1])
2062       && !satisfies_constraint_L (operands[1]))
2063     {
2064       /* MUL64 <0,>b,s12 00101bbb10000100 0BBBssssssSSSSSS  */
2065       int n = true_regnum (operands[0]);
2066       int i = INTVAL (operands[1]);
2067       asm_fprintf (asm_out_file, "\t.short %d`", 0x2884 + ((n & 7) << 8));
2068       asm_fprintf (asm_out_file, "\t.short %d`",
2069                    ((i & 0x3f) << 6) + ((i >> 6) & 0x3f) + ((n & 070) << 9));
2070       return "; mul64%? \t0, %0, %1%&";
2071     }
2072   return "mul64%? \t0, %0, %1%&";
2074   [(set_attr "length" "*,4,4,8")
2075    (set_attr "iscompact" "maybe,false,false,false")
2076    (set_attr "type" "multi,multi,multi,multi")
2077    (set_attr "predicable" "yes,yes,no,yes")
2078    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2080 ; If we compile without an mul option enabled, but link with libraries
2081 ; for a mul option, we'll see clobbers of multiplier output registers.
2082 ; There is also an implementation using norm that clobbers the loop registers.
2083 (define_insn "mulsi3_600_lib"
2084   [(set (reg:SI R0_REG)
2085         (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
2086    (clobber (reg:SI RETURN_ADDR_REGNUM))
2087    (clobber (reg:SI R1_REG))
2088    (clobber (reg:SI R2_REG))
2089    (clobber (reg:SI R3_REG))
2090    (clobber (reg:DI MUL64_OUT_REG))
2091    (clobber (reg:SI LP_COUNT))
2092    (clobber (reg:SI LP_START))
2093    (clobber (reg:SI LP_END))
2094    (clobber (reg:CC CC_REG))]
2095   "!TARGET_ANY_MPY
2096    && SFUNC_CHECK_PREDICABLE"
2097   "*return arc_output_libcall (\"__mulsi3\");"
2098   [(set_attr "is_sfunc" "yes")
2099    (set_attr "predicable" "yes")])
2101 (define_insn_and_split "mulsidi_600"
2102   [(set (match_operand:DI 0 "register_operand"                               "=c, c,c,  c")
2103         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "%Rcq#q, c,c,  c"))
2104                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand"  "Rcq#q,cL,L,C32"))))
2105    (clobber (reg:DI MUL64_OUT_REG))]
2106   "TARGET_MUL64_SET"
2107   "#"
2108   "TARGET_MUL64_SET"
2109   [(const_int 0)]
2110   "emit_insn (gen_mul64 (operands[1], operands[2]));
2111    emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2112    DONE;"
2113   [(set_attr "type" "multi")
2114    (set_attr "length" "8")])
2116 (define_insn "mul64"
2117   [(set (reg:DI MUL64_OUT_REG)
2118         (mult:DI
2119          (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c,  c"))
2120          (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))]
2121   "TARGET_MUL64_SET"
2122   "mul64%? \t0, %0, %1%&"
2123   [(set_attr "length" "*,4,4,8")
2124    (set_attr "iscompact" "maybe,false,false,false")
2125    (set_attr "type" "multi,multi,multi,multi")
2126    (set_attr "predicable" "yes,yes,no,yes")
2127    (set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
2129 (define_insn_and_split "umulsidi_600"
2130   [(set (match_operand:DI 0 "register_operand"                            "=c,c, c")
2131         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"   "%c,c, c"))
2132                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand"  "cL,L,C32"))))
2133    (clobber (reg:DI MUL64_OUT_REG))]
2134   "TARGET_MUL64_SET"
2135   "#"
2136   "TARGET_MUL64_SET"
2137   [(const_int 0)]
2138   "emit_insn (gen_mulu64 (operands[1], operands[2]));
2139    emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG));
2140    DONE;"
2141   [(set_attr "type" "umulti")
2142    (set_attr "length" "8")])
2144 (define_insn "mulu64"
2145   [(set (reg:DI MUL64_OUT_REG)
2146         (mult:DI
2147          (zero_extend:DI (match_operand:SI 0 "register_operand"  "%c,c,c"))
2148          (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))]
2149   "TARGET_MUL64_SET"
2150   "mulu64%? \t0, %0, %1%&"
2151   [(set_attr "length" "4,4,8")
2152    (set_attr "iscompact" "false")
2153    (set_attr "type" "umulti")
2154    (set_attr "predicable" "yes,no,yes")
2155    (set_attr "cond" "canuse,canuse_limm,canuse")])
2157 ; ARC700 mpy* instructions: This is a multi-cycle extension, and thus 'w'
2158 ; may not be used as destination constraint.
2160 ; The result of mpy and mpyu is the same except for flag setting (if enabled),
2161 ; but mpyu is faster for the standard multiplier.
2162 ; Note: we must make sure LP_COUNT is not one of the destination
2163 ; registers, since it cannot be the destination of a multi-cycle insn
2164 ; like MPY or MPYU.
2165 (define_insn "mulsi3_700"
2166  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcr,r,r,Rcr,r")
2167         (mult:SI (match_operand:SI 1 "register_operand"  "%0,c,0,0,c")
2168                  (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))]
2169  "TARGET_ARC700_MPY"
2170   "mpyu%? %0,%1,%2"
2171   [(set_attr "length" "4,4,4,8,8")
2172    (set_attr "type" "umulti")
2173    (set_attr "predicable" "yes,no,no,yes,no")
2174    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2176 ; ARCv2 has no penalties between mpy and mpyu. So, we use mpy because of its
2177 ; short variant. LP_COUNT constraints are still valid.
2178 (define_insn "mulsi3_v2"
2179  [(set (match_operand:SI 0 "mpy_dest_reg_operand"        "=Rcqq,Rcr, r,r,Rcr,  r")
2180         (mult:SI (match_operand:SI 1 "register_operand"     "%0,  0, c,0,  0,  c")
2181                  (match_operand:SI 2 "nonmemory_operand" " Rcqq, cL,cL,I,Cal,Cal")))]
2182  "TARGET_MULTI"
2183  "mpy%? %0,%1,%2"
2184  [(set_attr "length" "*,4,4,4,8,8")
2185   (set_attr "iscompact" "maybe,false,false,false,false,false")
2186   (set_attr "type" "umulti")
2187   (set_attr "predicable" "no,yes,no,no,yes,no")
2188   (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")])
2190 (define_expand "mulsidi3"
2191   [(set (match_operand:DI 0 "register_operand" "")
2192         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
2193                  (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2194   "TARGET_ANY_MPY"
2195   {
2196   if (TARGET_PLUS_MACD)
2197     {
2198      if (CONST_INT_P (operands[2]))
2199        {
2200         emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2]));
2201        }
2202      else
2203        {
2204         emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2]));
2205        }
2206      DONE;
2207     }
2208   if (TARGET_MPY)
2209     {
2210       operands[2] = force_reg (SImode, operands[2]);
2211       if (!register_operand (operands[0], DImode))
2212         {
2213           rtx result = gen_reg_rtx (DImode);
2215           operands[2] = force_reg (SImode, operands[2]);
2216           emit_insn (gen_mulsidi3 (result, operands[1], operands[2]));
2217           emit_move_insn (operands[0], result);
2218           DONE;
2219         }
2220     }
2221   else if (TARGET_MUL64_SET)
2222     {
2223       emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2]));
2224       DONE;
2225     }
2226   else if (TARGET_MULMAC_32BY16_SET)
2227     {
2228       operands[2] = force_reg (SImode, operands[2]);
2229       emit_insn (gen_mulsidi64 (operands[0], operands[1], operands[2]));
2230       DONE;
2231     }
2232   operands[2] = force_reg (SImode, operands[2]);
2233   })
2235 (define_insn_and_split "mulsidi64"
2236   [(set (match_operand:DI 0 "register_operand" "=w")
2237         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2238                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2239    (clobber (reg:DI MUL32x16_REG))]
2240   "TARGET_MULMAC_32BY16_SET"
2241   "#"
2242   "TARGET_MULMAC_32BY16_SET && reload_completed"
2243   [(const_int 0)]
2244   {
2245    rtx result_hi = gen_highpart (SImode, operands[0]);
2246    rtx result_low = gen_lowpart (SImode, operands[0]);
2248    emit_insn (gen_mul64_600 (operands[1], operands[2]));
2249    emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2]));
2250    emit_move_insn (result_low, gen_acc2 ());
2251    DONE;
2252   }
2253   [(set_attr "type" "multi")
2254    (set_attr "length" "8")])
2257 (define_insn "mul64_600"
2258   [(set (reg:DI MUL32x16_REG)
2259         (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand"
2260                                   "c,c,c"))
2261                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2262                                   "c,L,Cal")
2263                                   (const_int 16)
2264                                   (const_int 0))))
2265   ]
2266   "TARGET_MULMAC_32BY16_SET"
2267   "mullw%? 0, %0, %1"
2268   [(set_attr "length" "4,4,8")
2269    (set_attr "type" "mulmac_600")
2270    (set_attr "predicable" "no,no,yes")
2271    (set_attr "cond" "nocond, canuse_limm, canuse")])
2274 ;; ??? check if this is canonical rtl
2275 (define_insn "mac64_600"
2276   [(set (reg:DI MUL32x16_REG)
2277         (plus:DI
2278           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2279                    (ashift:DI
2280                      (sign_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2281                                       (const_int 16) (const_int 16))
2282                      (const_int 16)))
2283           (reg:DI MUL32x16_REG)))
2284    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2285         (zero_extract:SI
2286           (plus:DI
2287             (mult:DI (sign_extend:DI (match_dup 1))
2288                      (ashift:DI
2289                        (sign_extract:DI (match_dup 2)
2290                                         (const_int 16) (const_int 16))
2291                           (const_int 16)))
2292             (reg:DI MUL32x16_REG))
2293           (const_int 32) (const_int 32)))]
2294   "TARGET_MULMAC_32BY16_SET"
2295   "machlw%? %0, %1, %2"
2296   [(set_attr "length" "4,4,8")
2297    (set_attr "type" "mulmac_600")
2298    (set_attr "predicable" "no,no,yes")
2299    (set_attr "cond" "nocond, canuse_limm, canuse")])
2302 ;; DI <- DI(signed SI) * DI(signed SI)
2303 (define_insn_and_split "mulsidi3_700"
2304   [(set (match_operand:DI 0 "register_operand" "=&r")
2305         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2306                  (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2307   "TARGET_MPY && !TARGET_PLUS_MACD"
2308   "#"
2309   "&& reload_completed"
2310   [(const_int 0)]
2312   int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
2313   int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
2314   rtx l0 = simplify_gen_subreg (word_mode, operands[0], DImode, lo);
2315   rtx h0 = simplify_gen_subreg (word_mode, operands[0], DImode, hi);
2316   emit_insn (gen_mulsi3_highpart (h0, operands[1], operands[2]));
2317   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2318   DONE;
2320   [(set_attr "type" "multi")
2321    (set_attr "length" "8")])
2323 (define_insn "mulsi3_highpart"
2324   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2325         (truncate:SI
2326          (lshiftrt:DI
2327           (mult:DI
2328            (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2329            (sign_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
2330           (const_int 32))))]
2331   "TARGET_MPY"
2332   "mpy%+%? %0,%1,%2"
2333   [(set_attr "length" "4,4,8,8")
2334    (set_attr "type" "multi")
2335    (set_attr "predicable" "yes,no,yes,no")
2336    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2338 ; Note that mpyhu has the same latency as mpy / mpyh,
2339 ; thus we use the type multi.
2340 (define_insn "*umulsi3_highpart_i"
2341   [(set (match_operand:SI 0 "register_operand"                  "=Rcr,r,Rcr,r")
2342         (truncate:SI
2343          (lshiftrt:DI
2344           (mult:DI
2345            (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,  0,c"))
2346            (zero_extend:DI (match_operand:SI 2 "extend_operand"    "c,c,  i,i")))
2347           (const_int 32))))]
2348   "TARGET_MPY"
2349   "mpy%+u%? %0,%1,%2"
2350   [(set_attr "length" "4,4,8,8")
2351    (set_attr "type" "multi")
2352    (set_attr "predicable" "yes,no,yes,no")
2353    (set_attr "cond" "canuse,nocond,canuse,nocond")])
2355 ; Implementations include additional labels for umulsidi3, so we got all
2356 ; the same clobbers - plus one for the result low part.  */
2357 (define_insn "umulsi3_highpart_600_lib_le"
2358   [(set (reg:SI R1_REG)
2359         (truncate:SI
2360          (lshiftrt:DI
2361           (mult:DI (zero_extend:DI (reg:SI R0_REG))
2362                    (zero_extend:DI (reg:SI R1_REG)))
2363           (const_int 32))))
2364    (clobber (reg:SI RETURN_ADDR_REGNUM))
2365    (clobber (reg:SI R0_REG))
2366    (clobber (reg:DI R2_REG))
2367    (clobber (reg:SI R12_REG))
2368    (clobber (reg:DI MUL64_OUT_REG))
2369    (clobber (reg:CC CC_REG))]
2370   "!TARGET_BIG_ENDIAN
2371    && !TARGET_ANY_MPY
2372    && SFUNC_CHECK_PREDICABLE"
2373   "*return arc_output_libcall (\"__umulsi3_highpart\");"
2374   [(set_attr "is_sfunc" "yes")
2375    (set_attr "predicable" "yes")])
2377 (define_insn "umulsi3_highpart_600_lib_be"
2378   [(set (reg:SI R0_REG)
2379         (truncate:SI
2380          (lshiftrt:DI
2381           (mult:DI (zero_extend:DI (reg:SI R0_REG))
2382                    (zero_extend:DI (reg:SI R1_REG)))
2383           (const_int 32))))
2384    (clobber (reg:SI RETURN_ADDR_REGNUM))
2385    (clobber (reg:SI R1_REG))
2386    (clobber (reg:DI R2_REG))
2387    (clobber (reg:SI R12_REG))
2388    (clobber (reg:DI MUL64_OUT_REG))
2389    (clobber (reg:CC CC_REG))]
2390   "TARGET_BIG_ENDIAN
2391    && !TARGET_ANY_MPY
2392    && SFUNC_CHECK_PREDICABLE"
2393   "*return arc_output_libcall (\"__umulsi3_highpart\");"
2394   [(set_attr "is_sfunc" "yes")
2395    (set_attr "predicable" "yes")])
2397 ;; (zero_extend:DI (const_int)) leads to internal errors in combine, so we
2398 ;; need a separate pattern for immediates
2399 ;; ??? This is fine for combine, but not for reload.
2400 (define_insn "umulsi3_highpart_int"
2401   [(set (match_operand:SI 0 "register_operand"            "=Rcr, r, r,Rcr,  r")
2402         (truncate:SI
2403          (lshiftrt:DI
2404           (mult:DI
2405            (zero_extend:DI (match_operand:SI 1 "register_operand"  " 0, c, 0,  0,  c"))
2406            (match_operand:DI 2 "immediate_usidi_operand" "L, L, I, Cal, Cal"))
2407           (const_int 32))))]
2408   "TARGET_MPY"
2409   "mpy%+u%? %0,%1,%2"
2410   [(set_attr "length" "4,4,4,8,8")
2411    (set_attr "type" "multi")
2412    (set_attr "predicable" "yes,no,no,yes,no")
2413    (set_attr "cond" "canuse,nocond,canuse_limm,canuse,nocond")])
2415 (define_expand "umulsi3_highpart"
2416   [(set (match_operand:SI 0 "general_operand"  "")
2417         (truncate:SI
2418          (lshiftrt:DI
2419           (mult:DI
2420            (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2421            (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" "")))
2422           (const_int 32))))]
2423   "!TARGET_MUL64_SET && !TARGET_MULMAC_32BY16_SET"
2424   "
2426   rtx target = operands[0];
2428   if (!TARGET_MPY)
2429     {
2430       emit_move_insn (gen_rtx_REG (SImode, 0), operands[1]);
2431       emit_move_insn (gen_rtx_REG (SImode, 1), operands[2]);
2432       if (TARGET_BIG_ENDIAN)
2433         emit_insn (gen_umulsi3_highpart_600_lib_be ());
2434       else
2435         emit_insn (gen_umulsi3_highpart_600_lib_le ());
2436       emit_move_insn (target, gen_rtx_REG (SImode, 0));
2437       DONE;
2438     }
2440   if (!register_operand (target, SImode))
2441     target = gen_reg_rtx (SImode);
2443   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
2444     operands[2] = simplify_const_unary_operation (ZERO_EXTEND, DImode,
2445                                                   operands[2], SImode);
2446   else if (!immediate_operand (operands[2], SImode))
2447     operands[2] = gen_rtx_ZERO_EXTEND (DImode, operands[2]);
2448   emit_insn (gen_umulsi3_highpart_int (target, operands[1], operands[2]));
2449   if (target != operands[0])
2450     emit_move_insn (operands[0], target);
2451   DONE;
2454 (define_expand "umulsidi3"
2455   [(set (match_operand:DI 0 "register_operand" "")
2456         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
2457                  (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))]
2458   ""
2460   if (TARGET_PLUS_MACD)
2461     {
2462      if (CONST_INT_P (operands[2]))
2463        {
2464         emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2]));
2465        }
2466      else
2467        {
2468         emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2]));
2469        }
2470      DONE;
2471     }
2472   if (TARGET_MPY)
2473     {
2474       operands[2] = force_reg (SImode, operands[2]);
2475       if (!register_operand (operands[0], DImode))
2476         {
2477           rtx result = gen_reg_rtx (DImode);
2479           emit_insn (gen_umulsidi3 (result, operands[1], operands[2]));
2480           emit_move_insn (operands[0], result);
2481           DONE;
2482         }
2483     }
2484   else if (TARGET_MUL64_SET)
2485     {
2486      operands[2] = force_reg (SImode, operands[2]);
2487      emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2]));
2488       DONE;
2489     }
2490   else if (TARGET_MULMAC_32BY16_SET)
2491     {
2492      operands[2] = force_reg (SImode, operands[2]);
2493      emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2]));
2494       DONE;
2495     }
2496   else
2497     {
2498       emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
2499       emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
2500       emit_insn (gen_umulsidi3_600_lib ());
2501       emit_move_insn (operands[0], gen_rtx_REG (DImode, R0_REG));
2502       DONE;
2503     }
2506 (define_insn_and_split "umulsidi64"
2507   [(set (match_operand:DI 0 "register_operand" "=w")
2508         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2509                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))
2510    (clobber (reg:DI MUL32x16_REG))]
2511   "TARGET_MULMAC_32BY16_SET"
2512   "#"
2513   "TARGET_MULMAC_32BY16_SET && reload_completed"
2514   [(const_int 0)]
2515   {
2516    rtx result_hi;
2517    rtx result_low;
2519    result_hi = gen_highpart (SImode, operands[0]);
2520    result_low = gen_lowpart (SImode, operands[0]);
2522    emit_insn (gen_umul64_600 (operands[1], operands[2]));
2523    emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2]));
2524    emit_move_insn (result_low, gen_acc2 ());
2525    DONE;
2526    }
2527   [(set_attr "type" "multi")
2528    (set_attr "length" "8")])
2530 (define_insn "umul64_600"
2531   [(set (reg:DI MUL32x16_REG)
2532         (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand"
2533                                   "c,c,c"))
2534                  (zero_extract:DI (match_operand:SI 1 "nonmemory_operand"
2535                                   "c,L,Cal")
2536                                   (const_int 16)
2537                                   (const_int 0))))
2538   ]
2539   "TARGET_MULMAC_32BY16_SET"
2540   "mululw 0, %0, %1"
2541   [(set_attr "length" "4,4,8")
2542    (set_attr "type" "mulmac_600")
2543    (set_attr "predicable" "no")
2544    (set_attr "cond" "nocond")])
2547 (define_insn "umac64_600"
2548   [(set (reg:DI MUL32x16_REG)
2549         (plus:DI
2550           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "c,c,c"))
2551                    (ashift:DI
2552                      (zero_extract:DI (match_operand:SI 2 "nonmemory_operand" "c,L,Cal")
2553                                       (const_int 16) (const_int 16))
2554                      (const_int 16)))
2555           (reg:DI MUL32x16_REG)))
2556    (set (match_operand:SI 0 "register_operand" "=w,w,w")
2557         (zero_extract:SI
2558           (plus:DI
2559             (mult:DI (zero_extend:DI (match_dup 1))
2560                      (ashift:DI
2561                        (zero_extract:DI (match_dup 2)
2562                                         (const_int 16) (const_int 16))
2563                           (const_int 16)))
2564             (reg:DI MUL32x16_REG))
2565           (const_int 32) (const_int 32)))]
2566   "TARGET_MULMAC_32BY16_SET"
2567   "machulw%? %0, %1, %2"
2568   [(set_attr "length" "4,4,8")
2569    (set_attr "type" "mulmac_600")
2570    (set_attr "predicable" "no,no,yes")
2571    (set_attr "cond" "nocond, canuse_limm, canuse")])
2573 ;; DI <- DI(unsigned SI) * DI(unsigned SI)
2574 (define_insn_and_split "umulsidi3_700"
2575   [(set (match_operand:DI 0 "dest_reg_operand" "=&r")
2576         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c"))
2577                  (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))]
2578   "TARGET_MPY && !TARGET_PLUS_MACD"
2579   "#"
2580   "reload_completed"
2581   [(const_int 0)]
2583   int hi = !TARGET_BIG_ENDIAN;
2584   int lo = !hi;
2585   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2586   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2587   emit_insn (gen_umulsi3_highpart (h0, operands[1], operands[2]));
2588   emit_insn (gen_mulsi3 (l0, operands[1], operands[2]));
2589   DONE;
2591   [(set_attr "type" "umulti")
2592   (set_attr "length" "8")])
2594 (define_insn "umulsidi3_600_lib"
2595   [(set (reg:DI R0_REG)
2596         (mult:DI (zero_extend:DI (reg:SI R0_REG))
2597                  (zero_extend:DI (reg:SI R1_REG))))
2598    (clobber (reg:SI RETURN_ADDR_REGNUM))
2599    (clobber (reg:DI R2_REG))
2600    (clobber (reg:SI R12_REG))
2601    (clobber (reg:DI MUL64_OUT_REG))
2602    (clobber (reg:CC CC_REG))]
2603    "!TARGET_ANY_MPY
2604    && SFUNC_CHECK_PREDICABLE"
2605   "*return arc_output_libcall (\"__umulsidi3\");"
2606   [(set_attr "is_sfunc" "yes")
2607    (set_attr "predicable" "yes")])
2609 (define_peephole2
2610   [(parallel
2611      [(set (reg:DI R0_REG)
2612            (mult:DI (zero_extend:DI (reg:SI R0_REG))
2613                     (zero_extend:DI (reg:SI R1_REG))))
2614       (clobber (reg:SI RETURN_ADDR_REGNUM))
2615       (clobber (reg:DI R2_REG))
2616       (clobber (reg:SI R12_REG))
2617       (clobber (reg:DI MUL64_OUT_REG))
2618       (clobber (reg:CC CC_REG))])]
2619   "!TARGET_ANY_MPY
2620    && peep2_regno_dead_p (1, TARGET_BIG_ENDIAN ? R1_REG : R0_REG)"
2621   [(pc)]
2623   if (TARGET_BIG_ENDIAN)
2624     emit_insn (gen_umulsi3_highpart_600_lib_be ());
2625   else
2626     emit_insn (gen_umulsi3_highpart_600_lib_le ());
2627   DONE;
2630 (define_expand "addsi3"
2631   [(set (match_operand:SI 0 "dest_reg_operand" "")
2632         (plus:SI (match_operand:SI 1 "register_operand" "")
2633                  (match_operand:SI 2 "nonmemory_operand" "")))]
2634   ""
2635   "if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[2], false))
2636      {
2637        operands[2]=force_reg(SImode, operands[2]);
2638      }
2639   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[2], Pmode))
2640    {
2641       operands[2] = force_reg (SImode, arc_rewrite_small_data (operands[2]));
2642    }
2644   ")
2646 (define_expand "adddi3"
2647   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2648                    (plus:DI (match_operand:DI 1 "register_operand" "")
2649                             (match_operand:DI 2 "nonmemory_operand" "")))
2650               (clobber (reg:CC CC_REG))])]
2651   ""
2654 ; This assumes that there can be no strictly partial overlap between
2655 ; operands[1] and operands[2].
2656 (define_insn_and_split "*adddi3_i"
2657   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w")
2658         (plus:DI (match_operand:DI 1 "register_operand" "%c,0,c")
2659                  (match_operand:DI 2 "nonmemory_operand" "ci,ci,!i")))
2660    (clobber (reg:CC CC_REG))]
2661   ""
2662   "#"
2663   "reload_completed"
2664   [(const_int 0)]
2666   int hi = !TARGET_BIG_ENDIAN;
2667   int lo = !hi;
2668   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2669   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2670   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2671   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2672   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2673   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2676   if (l2 == const0_rtx)
2677     {
2678       if (!rtx_equal_p (l0, l1) && !rtx_equal_p (l0, h1))
2679         emit_move_insn (l0, l1);
2680       emit_insn (gen_addsi3 (h0, h1, h2));
2681       if (!rtx_equal_p (l0, l1) && rtx_equal_p (l0, h1))
2682         emit_move_insn (l0, l1);
2683       DONE;
2684     }
2685   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0
2686       && INTVAL (operands[2]) >= -0x7fffffff)
2687     {
2688       emit_insn (gen_subdi3_i (operands[0], operands[1],
2689                  GEN_INT (-INTVAL (operands[2]))));
2690       DONE;
2691     }
2692   if (rtx_equal_p (l0, h1))
2693     {
2694       if (h2 != const0_rtx)
2695         emit_insn (gen_addsi3 (h0, h1, h2));
2696       else if (!rtx_equal_p (h0, h1))
2697         emit_move_insn (h0, h1);
2698       emit_insn (gen_add_f (l0, l1, l2));
2699       emit_insn
2700         (gen_rtx_COND_EXEC
2701           (VOIDmode,
2702            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2703            gen_rtx_SET (h0, plus_constant (SImode, h0, 1))));
2704       DONE;
2705     }
2706   emit_insn (gen_add_f (l0, l1, l2));
2707   emit_insn (gen_adc (h0, h1, h2));
2708   DONE;
2710   [(set_attr "cond" "clob")
2711    (set_attr "type" "binary")
2712    (set_attr "length" "16,16,20")])
2714 (define_insn "add_f"
2715   [(set (reg:CC_C CC_REG)
2716         (compare:CC_C
2717           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2718                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2719           (match_dup 1)))
2720    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2721         (plus:SI (match_dup 1) (match_dup 2)))]
2722   ""
2723   "add.f %0,%1,%2"
2724   [(set_attr "cond" "set")
2725    (set_attr "type" "compare")
2726    (set_attr "length" "4,4,8")])
2728 (define_insn "*add_f_2"
2729   [(set (reg:CC_C CC_REG)
2730         (compare:CC_C
2731           (plus:SI (match_operand:SI 1 "register_operand" "c,0,c")
2732                    (match_operand:SI 2 "nonmemory_operand" "cL,I,cCal"))
2733           (match_dup 2)))
2734    (set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w")
2735         (plus:SI (match_dup 1) (match_dup 2)))]
2736   ""
2737   "add.f %0,%1,%2"
2738   [(set_attr "cond" "set")
2739    (set_attr "type" "compare")
2740    (set_attr "length" "4,4,8")])
2742 ; w/c/c comes first (rather than w/0/C_0) to prevent the middle-end
2743 ; needlessly prioritizing the matching constraint.
2744 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional
2745 ; execution is used where possible.
2746 (define_insn_and_split "adc"
2747   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2748         (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2749                           (match_operand:SI 1 "nonmemory_operand"
2750                                                          "%c,0,c,0,cCal"))
2751                  (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2752   "register_operand (operands[1], SImode)
2753    || register_operand (operands[2], SImode)"
2754   "@
2755         adc %0,%1,%2
2756         add.cs %0,%1,1
2757         adc %0,%1,%2
2758         adc %0,%1,%2
2759         adc %0,%1,%2"
2760   ; if we have a bad schedule after sched2, split.
2761   "reload_completed
2762    && !optimize_size && (!TARGET_ARC600_FAMILY)
2763    && arc_scheduling_not_expected ()
2764    && arc_sets_cc_p (prev_nonnote_insn (insn))
2765    /* If next comes a return or other insn that needs a delay slot,
2766       expect the adc to get into the delay slot.  */
2767    && next_nonnote_insn (insn)
2768    && !arc_need_delay (next_nonnote_insn (insn))
2769    /* Restore operands before emitting.  */
2770    && (extract_insn_cached (insn), 1)"
2771   [(set (match_dup 0) (match_dup 3))
2772    (cond_exec
2773      (ltu (reg:CC_C CC_REG) (const_int 0))
2774      (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))))]
2775   "operands[3] = simplify_gen_binary (PLUS, SImode, operands[1], operands[2]);"
2776   [(set_attr "cond" "use")
2777    (set_attr "type" "cc_arith")
2778    (set_attr "length" "4,4,4,4,8")])
2780 ; combiner-splitter cmp / scc -> cmp / adc
2781 (define_split
2782   [(set (match_operand:SI 0 "dest_reg_operand" "")
2783         (gtu:SI (match_operand:SI 1 "register_operand" "")
2784                 (match_operand:SI 2 "register_operand" "")))
2785    (clobber (reg CC_REG))]
2786   ""
2787   [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2788    (set (match_dup 0) (ltu:SI (reg:CC_C CC_REG) (const_int 0)))])
2790 ; combine won't work when an intermediate result is used later...
2791 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
2792 (define_peephole2
2793   [(set (match_operand:SI 0 "dest_reg_operand" "")
2794         (plus:SI (match_operand:SI 1 "register_operand" "")
2795                  (match_operand:SI 2 "nonmemory_operand" "")))
2796    (set (reg:CC_C CC_REG)
2797         (compare:CC_C (match_dup 0)
2798                       (match_operand:SI 3 "nonmemory_operand" "")))]
2799   "rtx_equal_p (operands[1], operands[3])
2800    || rtx_equal_p (operands[2], operands[3])"
2801   [(parallel
2802      [(set (reg:CC_C CC_REG)
2803            (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))
2804       (set (match_dup 0)
2805            (plus:SI (match_dup 1) (match_dup 2)))])])
2807 ; ??? need to delve into combine to find out why this is not useful.
2808 ; We'd like to be able to grok various C idioms for carry bit usage.
2809 ;(define_insn "*adc_0"
2810 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2811 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2812 ;                (match_operand:SI 1 "register_operand" "c")))]
2813 ;  ""
2814 ;  "adc %0,%1,0"
2815 ;  [(set_attr "cond" "use")
2816 ;   (set_attr "type" "cc_arith")
2817 ;   (set_attr "length" "4")])
2819 ;(define_split
2820 ;  [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2821 ;       (plus:SI (gtu:SI (match_operand:SI 1 "register_operand" "c")
2822 ;                        (match_operand:SI 2 "register_operand" "c"))
2823 ;                (match_operand:SI 3 "register_operand" "c")))
2824 ;   (clobber (reg CC_REG))]
2825 ;  ""
2826 ;  [(set (reg:CC_C CC_REG) (compare:CC_C (match_dup 2) (match_dup 1)))
2827 ;   (set (match_dup 0)
2828 ;       (plus:SI (ltu:SI (reg:CC_C CC_REG) (const_int 0))
2829 ;                (match_dup 3)))])
2831 (define_expand "subsi3"
2832   [(set (match_operand:SI 0 "dest_reg_operand" "")
2833         (minus:SI (match_operand:SI 1 "nonmemory_operand" "")
2834                  (match_operand:SI 2 "nonmemory_operand" "")))]
2835   ""
2836   "
2838   int c = 1;
2840   if (!register_operand (operands[2], SImode))
2841     {
2842       operands[1] = force_reg (SImode, operands[1]);
2843       c = 2;
2844     }
2845   if (flag_pic && arc_raw_symbolic_reference_mentioned_p (operands[c], false))
2846     operands[c] = force_reg (SImode, operands[c]);
2847   else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[c], Pmode))
2848       operands[c] = force_reg (SImode, arc_rewrite_small_data (operands[c]));
2851 ; the casesi expander might generate a sub of zero, so we have to recognize it.
2852 ; combine should make such an insn go away.
2853 (define_insn_and_split "subsi3_insn"
2854   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcqq,Rcqq,Rcw,Rcw,w,w,w,  w,  w,  w")
2855         (minus:SI (match_operand:SI 1 "nonmemory_operand"    "0,Rcqq,  0, cL,c,L,I,Cal,Cal,  c")
2856                   (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq,  c,  0,c,c,0,  0,  c,Cal")))]
2857   "register_operand (operands[1], SImode)
2858    || register_operand (operands[2], SImode)"
2859   "@
2860     sub%? %0,%1,%2%&
2861     sub%? %0,%1,%2%&
2862     sub%? %0,%1,%2
2863     rsub%? %0,%2,%1
2864     sub %0,%1,%2
2865     rsub %0,%2,%1
2866     rsub %0,%2,%1
2867     rsub%? %0,%2,%1
2868     rsub %0,%2,%1
2869     sub %0,%1,%2"
2870   "reload_completed && get_attr_length (insn) == 8
2871    && satisfies_constraint_I (operands[1])
2872    && GET_CODE (PATTERN (insn)) != COND_EXEC"
2873   [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))]
2874   "split_subsi (operands);"
2875   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false")
2876   (set_attr "length" "*,*,4,4,4,4,4,8,8,8")
2877   (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no")
2878   (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")
2879   (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*")
2880   ])
2882 (define_expand "subdi3"
2883   [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "")
2884                    (minus:DI (match_operand:DI 1 "nonmemory_operand" "")
2885                              (match_operand:DI 2 "nonmemory_operand" "")))
2886               (clobber (reg:CC CC_REG))])]
2887   ""
2889   if (!register_operand (operands[2], DImode))
2890     operands[1] = force_reg (DImode, operands[1]);
2893 (define_insn_and_split "subdi3_i"
2894   [(set (match_operand:DI 0 "dest_reg_operand" "=&w,w,w,w,w")
2895         (minus:DI (match_operand:DI 1 "nonmemory_operand" "ci,0,ci,c,!i")
2896                   (match_operand:DI 2 "nonmemory_operand" "ci,ci,0,!i,c")))
2897    (clobber (reg:CC CC_REG))]
2898   "register_operand (operands[1], DImode)
2899    || register_operand (operands[2], DImode)"
2900   "#"
2901   "reload_completed"
2902   [(const_int 0)]
2904   int hi = !TARGET_BIG_ENDIAN;
2905   int lo = !hi;
2906   rtx l0 = operand_subword (operands[0], lo, 0, DImode);
2907   rtx h0 = operand_subword (operands[0], hi, 0, DImode);
2908   rtx l1 = operand_subword (operands[1], lo, 0, DImode);
2909   rtx h1 = operand_subword (operands[1], hi, 0, DImode);
2910   rtx l2 = operand_subword (operands[2], lo, 0, DImode);
2911   rtx h2 = operand_subword (operands[2], hi, 0, DImode);
2913   if (rtx_equal_p (l0, h1) || rtx_equal_p (l0, h2))
2914     {
2915       h1 = simplify_gen_binary (MINUS, SImode, h1, h2);
2916       if (!rtx_equal_p (h0, h1))
2917         emit_insn (gen_rtx_SET (h0, h1));
2918       emit_insn (gen_sub_f (l0, l1, l2));
2919       emit_insn
2920         (gen_rtx_COND_EXEC
2921           (VOIDmode,
2922            gen_rtx_LTU (VOIDmode, gen_rtx_REG (CC_Cmode, CC_REG), GEN_INT (0)),
2923            gen_rtx_SET (h0, plus_constant (SImode, h0, -1))));
2924       DONE;
2925     }
2926   emit_insn (gen_sub_f (l0, l1, l2));
2927   emit_insn (gen_sbc (h0, h1, h2, gen_rtx_REG (CCmode, CC_REG)));
2928   DONE;
2930   [(set_attr "cond" "clob")
2931    (set_attr "length" "16,16,16,20,20")])
2933 (define_insn "*sbc_0"
2934   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
2935         (minus:SI (match_operand:SI 1 "register_operand" "c")
2936                   (ltu:SI (match_operand:CC_C 2 "cc_use_register")
2937                           (const_int 0))))]
2938   ""
2939   "sbc %0,%1,0"
2940   [(set_attr "cond" "use")
2941    (set_attr "type" "cc_arith")
2942    (set_attr "length" "4")])
2944 ; w/c/c comes first (rather than Rcw/0/C_0) to prevent the middle-end
2945 ; needlessly prioritizing the matching constraint.
2946 ; Rcw/0/C_0 comes before w/c/L so that the lower latency conditional execution
2947 ; is used where possible.
2948 (define_insn_and_split "sbc"
2949   [(set (match_operand:SI 0 "dest_reg_operand" "=w,Rcw,w,Rcw,w")
2950         (minus:SI (minus:SI (match_operand:SI 1 "nonmemory_operand"
2951                                                 "c,0,c,0,cCal")
2952                             (ltu:SI (match_operand:CC_C 3 "cc_use_register")
2953                                     (const_int 0)))
2954                   (match_operand:SI 2 "nonmemory_operand" "c,C_0,L,I,cCal")))]
2955   "register_operand (operands[1], SImode)
2956    || register_operand (operands[2], SImode)"
2957   "@
2958         sbc %0,%1,%2
2959         sub.cs %0,%1,1
2960         sbc %0,%1,%2
2961         sbc %0,%1,%2
2962         sbc %0,%1,%2"
2963   ; if we have a bad schedule after sched2, split.
2964   "reload_completed
2965    && !optimize_size && (!TARGET_ARC600_FAMILY)
2966    && arc_scheduling_not_expected ()
2967    && arc_sets_cc_p (prev_nonnote_insn (insn))
2968    /* If next comes a return or other insn that needs a delay slot,
2969       expect the adc to get into the delay slot.  */
2970    && next_nonnote_insn (insn)
2971    && !arc_need_delay (next_nonnote_insn (insn))
2972    /* Restore operands before emitting.  */
2973    && (extract_insn_cached (insn), 1)"
2974   [(set (match_dup 0) (match_dup 4))
2975    (cond_exec
2976      (ltu (reg:CC_C CC_REG) (const_int 0))
2977      (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1))))]
2978   "operands[4] = simplify_gen_binary (MINUS, SImode, operands[1], operands[2]);"
2979   [(set_attr "cond" "use")
2980    (set_attr "type" "cc_arith")
2981    (set_attr "length" "4,4,4,4,8")])
2983 (define_insn "sub_f"
2984   [(set (reg:CC CC_REG)
2985         (compare:CC (match_operand:SI 1 "nonmemory_operand" " c,L,0,I,c,Cal")
2986                     (match_operand:SI 2 "nonmemory_operand" "cL,c,I,0,Cal,c")))
2987    (set (match_operand:SI 0 "dest_reg_operand" "=w,w,Rcw,Rcw,w,w")
2988         (minus:SI (match_dup 1) (match_dup 2)))]
2989   "register_operand (operands[1], SImode)
2990    || register_operand (operands[2], SImode)"
2991   "@
2992         sub.f %0,%1,%2
2993         rsub.f %0,%2,%1
2994         sub.f %0,%1,%2
2995         rsub.f %0,%2,%1
2996         sub.f %0,%1,%2
2997         sub.f %0,%1,%2"
2998   [(set_attr "type" "compare")
2999    (set_attr "length" "4,4,4,4,8,8")])
3001 ; combine won't work when an intermediate result is used later...
3002 ; add %0,%1,%2 ` cmp %0,%[12] -> add.f %0,%1,%2
3003 (define_peephole2
3004   [(set (reg:CC CC_REG)
3005         (compare:CC (match_operand:SI 1 "register_operand" "")
3006                     (match_operand:SI 2 "nonmemory_operand" "")))
3007    (set (match_operand:SI 0 "dest_reg_operand" "")
3008         (minus:SI (match_dup 1) (match_dup 2)))]
3009   ""
3010   [(parallel
3011      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3012       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])])
3014 (define_peephole2
3015   [(set (reg:CC CC_REG)
3016         (compare:CC (match_operand:SI 1 "register_operand" "")
3017                     (match_operand:SI 2 "nonmemory_operand" "")))
3018    (set (match_operand 3 "" "") (match_operand 4 "" ""))
3019    (set (match_operand:SI 0 "dest_reg_operand" "")
3020         (minus:SI (match_dup 1) (match_dup 2)))]
3021   "!reg_overlap_mentioned_p (operands[3], operands[1])
3022    && !reg_overlap_mentioned_p (operands[3], operands[2])
3023    && !reg_overlap_mentioned_p (operands[0], operands[4])
3024    && !reg_overlap_mentioned_p (operands[0], operands[3])"
3025   [(parallel
3026      [(set (reg:CC CC_REG) (compare:CC (match_dup 1) (match_dup 2)))
3027       (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
3028    (set (match_dup 3) (match_dup 4))])
3030 (define_insn "*add_n"
3031   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3032         (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3033                             (match_operand:SI 2 "_1_2_3_operand" ""))
3034                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3035   ""
3036   "add%c2%? %0,%3,%1%&"
3037   [(set_attr "type" "shift")
3038    (set_attr "length" "*,4,4,8,4,8")
3039    (set_attr "predicable" "yes,yes,no,no,no,no")
3040    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3041    (set_attr "iscompact" "maybe,false,false,false,false,false")])
3043 (define_insn "*add_n"
3044   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
3045         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c")
3046                           (match_operand:SI 2 "_2_4_8_operand" ""))
3047                  (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))]
3048   ""
3049   "add%z2%? %0,%3,%1%&"
3050   [(set_attr "type" "shift")
3051    (set_attr "length" "*,4,4,8,4,8")
3052    (set_attr "predicable" "yes,yes,no,no,no,no")
3053    (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
3054    (set_attr "iscompact" "maybe,false,false,false,false,false")])
3056 ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
3057 ;; what synth_mult likes.
3058 (define_insn "*sub_n"
3059   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3060         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3061                   (ashift:SI (match_operand:SI 2 "register_operand" "c,c,c")
3062                              (match_operand:SI 3 "_1_2_3_operand" ""))))]
3063   ""
3064   "sub%c3%? %0,%1,%2"
3065   [(set_attr "type" "shift")
3066    (set_attr "length" "4,4,8")
3067    (set_attr "predicable" "yes,no,no")
3068    (set_attr "cond" "canuse,nocond,nocond")
3069    (set_attr "iscompact" "false")])
3071 (define_insn "*sub_n"
3072   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3073         (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal")
3074                   (mult:SI (match_operand:SI 2 "register_operand" "c,c,c")
3075                            (match_operand:SI 3 "_2_4_8_operand" ""))))]
3076   ""
3077   "sub%z3%? %0,%1,%2"
3078   [(set_attr "type" "shift")
3079    (set_attr "length" "4,4,8")
3080    (set_attr "predicable" "yes,no,no")
3081    (set_attr "cond" "canuse,nocond,nocond")
3082    (set_attr "iscompact" "false")])
3084 ; ??? check if combine matches this.
3085 (define_insn "*bset"
3086   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3087         (ior:SI (ashift:SI (const_int 1)
3088                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3089                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3090   ""
3091   "bset%? %0,%2,%1"
3092   [(set_attr "length" "4,4,8")
3093    (set_attr "predicable" "yes,no,no")
3094    (set_attr "cond" "canuse,nocond,nocond")]
3097 ; ??? check if combine matches this.
3098 (define_insn "*bxor"
3099   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3100         (xor:SI (ashift:SI (const_int 1)
3101                            (match_operand:SI 1 "nonmemory_operand" "cL,cL,c"))
3102                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3103   ""
3104   "bxor%? %0,%2,%1"
3105   [(set_attr "length" "4,4,8")
3106    (set_attr "predicable" "yes,no,no")
3107    (set_attr "cond" "canuse,nocond,nocond")]
3110 ; ??? check if combine matches this.
3111 (define_insn "*bclr"
3112   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3113         (and:SI (not:SI (ashift:SI (const_int 1)
3114                                    (match_operand:SI 1 "nonmemory_operand" "cL,cL,c")))
3115                 (match_operand:SI 2 "nonmemory_operand" "0,c,Cal")))]
3116   ""
3117   "bclr%? %0,%2,%1"
3118   [(set_attr "length" "4,4,8")
3119    (set_attr "predicable" "yes,no,no")
3120    (set_attr "cond" "canuse,nocond,nocond")]
3123 ; ??? FIXME: find combine patterns for bmsk.
3125 ;;Following are the define_insns added for the purpose of peephole2's
3127 ; see also iorsi3 for use with constant bit number.
3128 (define_insn "*bset_insn"
3129   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3130         (ior:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3131                 (ashift:SI (const_int 1)
3132                            (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3133   ""
3134   "@
3135      bset%? %0,%1,%2 ;;peep2, constr 1
3136      bset %0,%1,%2 ;;peep2, constr 2
3137      bset %0,%S1,%2 ;;peep2, constr 3"
3138   [(set_attr "length" "4,4,8")
3139    (set_attr "predicable" "yes,no,no")
3140    (set_attr "cond" "canuse,nocond,nocond")]
3143 ; see also xorsi3 for use with constant bit number.
3144 (define_insn "*bxor_insn"
3145   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3146         (xor:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3147                 (ashift:SI (const_int 1)
3148                         (match_operand:SI 2 "nonmemory_operand" "cL,cL,c"))) ) ]
3149   ""
3150   "@
3151      bxor%? %0,%1,%2
3152      bxor %0,%1,%2
3153      bxor %0,%S1,%2"
3154   [(set_attr "length" "4,4,8")
3155    (set_attr "predicable" "yes,no,no")
3156    (set_attr "cond" "canuse,nocond,nocond")]
3159 ; see also andsi3 for use with constant bit number.
3160 (define_insn "*bclr_insn"
3161   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3162         (and:SI (not:SI (ashift:SI (const_int 1)
3163                                    (match_operand:SI 2 "nonmemory_operand" "cL,rL,r")))
3164                 (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")))]
3165   ""
3166   "@
3167      bclr%? %0,%1,%2
3168      bclr %0,%1,%2
3169      bclr %0,%S1,%2"
3170   [(set_attr "length" "4,4,8")
3171    (set_attr "predicable" "yes,no,no")
3172    (set_attr "cond" "canuse,nocond,nocond")]
3175 ; see also andsi3 for use with constant bit number.
3176 (define_insn "*bmsk_insn"
3177   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w")
3178         (and:SI (match_operand:SI 1 "nonmemory_operand" "0,c,Cal")
3179                 (plus:SI (ashift:SI (const_int 1)
3180                                     (plus:SI (match_operand:SI 2 "nonmemory_operand" "rL,rL,r")
3181                                              (const_int 1)))
3182                          (const_int -1))))]
3183   ""
3184   "@
3185      bmsk%? %0,%S1,%2
3186      bmsk %0,%1,%2
3187      bmsk %0,%S1,%2"
3188   [(set_attr "length" "4,4,8")
3189    (set_attr "predicable" "yes,no,no")
3190    (set_attr "cond" "canuse,nocond,nocond")]
3193 ;;Instructions added for peephole2s end
3195 ;; Boolean instructions.
3197 (define_expand "andsi3"
3198   [(set (match_operand:SI 0 "dest_reg_operand" "")
3199         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
3200                 (match_operand:SI 2 "nonmemory_operand" "")))]
3201   ""
3202   "if (!satisfies_constraint_Cux (operands[2]))
3203      operands[1] = force_reg (SImode, operands[1]);
3204    else if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
3205      operands[1] = arc_rewrite_small_data (operands[1]);")
3207 (define_insn "andsi3_i"
3208   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,   Rcw,Rcw,Rcw,Rcw, w,     w,  w,  w,Rrq,w,Rcw,  w,W")
3209         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,   0,   0,Rcqq,  0,  c,     0,  0,  0,  0, c,     c,  c,  c,Rrq,0,  0,  c,o")
3210                 (match_operand:SI 2 "nonmemory_operand"  "Rcqq,  0, C1p, Ccp, Cux, cL,  0,C2pC1p,Ccp,CnL,  I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
3211   "(register_operand (operands[1], SImode)
3212     && nonmemory_operand (operands[2], SImode))
3213    || (memory_operand (operands[1], SImode)
3214        && satisfies_constraint_Cux (operands[2]))"
3216   switch (which_alternative)
3217     {
3218     case 0: case 5: case 10: case 11: case 16: case 17: case 18:
3219       return "and%? %0,%1,%2%&";
3220     case 1: case 6:
3221       return "and%? %0,%2,%1%&";
3222     case 2:
3223       return "bmsk%? %0,%1,%Z2%&";
3224     case 7: case 12:
3225      if (satisfies_constraint_C2p (operands[2]))
3226        {
3227         operands[2] = GEN_INT ((~INTVAL (operands[2])));
3228         return "bmskn%? %0,%1,%Z2%&";
3229        }
3230      else
3231        {
3232         return "bmsk%? %0,%1,%Z2%&";
3233        }
3234     case 3: case 8: case 13:
3235       return "bclr%? %0,%1,%M2%&";
3236     case 4:
3237       return (INTVAL (operands[2]) == 0xff
3238               ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
3239     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
3240     case 15:
3241       return "movb.cl %0,%1,%p2,%p2,%s2";
3243     case 19:
3244       const char *tmpl;
3246       if (satisfies_constraint_Ucm (operands[1]))
3247         tmpl = (INTVAL (operands[2]) == 0xff
3248                 ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
3249       else
3250         tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
3252       if (TARGET_BIG_ENDIAN)
3253         {
3254           rtx xop[2];
3256           xop[0] = operands[0];
3257           xop[1] = adjust_address (operands[1], QImode,
3258                                    INTVAL (operands[2]) == 0xff ? 3 : 2);
3259           output_asm_insn (tmpl, xop);
3260           return "";
3261         }
3262       return tmpl;
3263     default:
3264       gcc_unreachable ();
3265     }
3267   [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
3268    (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
3269    (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
3270    (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
3271    (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
3273 ; combiner splitter, pattern found in ldtoa.c .
3274 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
3275 (define_split
3276   [(set (reg:CC_Z CC_REG)
3277         (compare:CC_Z (and:SI (match_operand:SI 0 "register_operand" "")
3278                               (match_operand 1 "const_int_operand" ""))
3279                       (match_operand 2 "const_int_operand" "")))
3280    (clobber (match_operand:SI 3 "register_operand" ""))]
3281   "((INTVAL (operands[1]) + 1) & INTVAL (operands[1])) == 0"
3282   [(set (match_dup 3)
3283         (plus:SI (match_dup 0) (match_dup 4)))
3284    (set (reg:CC_Z CC_REG)
3285         (compare:CC_Z (and:SI (match_dup 3) (match_dup 1))
3286                       (const_int 0)))]
3287   "operands[4] = GEN_INT ( -(~INTVAL (operands[1]) | INTVAL (operands[2])));")
3289 ;;bic define_insn that allows limm to be the first operand
3290 (define_insn "*bicsi3_insn"
3291    [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,Rcw,w,w,w")
3292         (and:SI (not:SI (match_operand:SI 1 "nonmemory_operand" "Rcqq,Lc,I,Cal,Lc,Cal,c"))
3293                 (match_operand:SI 2 "nonmemory_operand" "0,0,0,0,c,c,Cal")))]
3294   ""
3295   "@
3296    bic%? %0, %2, %1%& ;;constraint 0
3297    bic%? %0,%2,%1  ;;constraint 1
3298    bic %0,%2,%1    ;;constraint 2, FIXME: will it ever get generated ???
3299    bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
3300    bic %0,%2,%1    ;;constraint 4
3301    bic %0,%2,%S1   ;;constraint 5, FIXME: will it ever get generated ???
3302    bic %0,%S2,%1   ;;constraint 6"
3303   [(set_attr "length" "*,4,4,8,4,8,8")
3304   (set_attr "iscompact" "maybe, false, false, false, false, false, false")
3305   (set_attr "predicable" "no,yes,no,yes,no,no,no")
3306   (set_attr "cond" "canuse,canuse,canuse_limm,canuse,nocond,nocond,nocond")])
3308 (define_insn "iorsi3"
3309   [(set (match_operand:SI 0 "dest_reg_operand"        "=Rcqq,Rcq,Rcqq,Rcw,Rcw,Rcw,Rcw,w,  w,w,Rcw,  w")
3310         (ior:SI (match_operand:SI 1 "nonmemory_operand" "% 0,Rcq,   0,  0,  c,  0, 0, c,  c,0,  0,  c")
3311                 (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C0p, cL,  0,C0p, I,cL,C0p,I,Cal,Cal")))]
3312   ""
3313   "*
3314   switch (which_alternative)
3315     {
3316     case 0: case 3: case 6: case 7: case 9: case 10: case 11:
3317       return \"or%? %0,%1,%2%&\";
3318     case 1: case 4:
3319       return \"or%? %0,%2,%1%&\";
3320     case 2: case 5: case 8:
3321       return \"bset%? %0,%1,%z2%&\";
3322     default:
3323       gcc_unreachable ();
3324     }"
3325   [(set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false")
3326    (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8")
3327    (set_attr "predicable" "no,no,no,yes,yes,yes,no,no,no,no,yes,no")
3328    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3330 (define_insn "xorsi3"
3331   [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcw,Rcw,Rcw,Rcw, w,  w,w,  w,  w")
3332         (xor:SI (match_operand:SI 1 "register_operand"  "%0,   Rcq,  0,  c,  0,  0, c,  c,0,  0,  c")
3333                 (match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, cL,  0,C0p,  I,cL,C0p,I,Cal,Cal")))]
3334   ""
3335   "*
3336   switch (which_alternative)
3337     {
3338     case 0: case 2: case 5: case 6: case 8: case 9: case 10:
3339       return \"xor%? %0,%1,%2%&\";
3340     case 1: case 3:
3341       return \"xor%? %0,%2,%1%&\";
3342     case 4: case 7:
3343       return \"bxor%? %0,%1,%z2\";
3344     default:
3345       gcc_unreachable ();
3346     }
3347   "
3348   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false,false,false")
3349    (set_attr "type" "binary")
3350    (set_attr "length" "*,*,4,4,4,4,4,4,4,8,8")
3351    (set_attr "predicable" "no,no,yes,yes,yes,no,no,no,no,yes,no")
3352    (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,canuse_limm,canuse,nocond")])
3354 (define_insn "negsi2"
3355   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,w")
3356         (neg:SI (match_operand:SI 1 "register_operand" "0,Rcqq,0,c")))]
3357   ""
3358   "neg%? %0,%1%&"
3359   [(set_attr "type" "unary")
3360    (set_attr "iscompact" "maybe,true,false,false")
3361    (set_attr "predicable" "no,no,yes,no")])
3363 (define_insn "one_cmplsi2"
3364   [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w")
3365         (not:SI (match_operand:SI 1 "register_operand" "Rcqq,c")))]
3366   ""
3367   "not%? %0,%1%&"
3368   [(set_attr "type" "unary,unary")
3369    (set_attr "iscompact" "true,false")])
3371 (define_insn_and_split "one_cmpldi2"
3372   [(set (match_operand:DI 0 "dest_reg_operand" "=q,w")
3373         (not:DI (match_operand:DI 1 "register_operand" "q,c")))]
3374   ""
3375   "#"
3376   "&& reload_completed"
3377   [(set (match_dup 2) (not:SI (match_dup 3)))
3378    (set (match_dup 4) (not:SI (match_dup 5)))]
3380   int swap = (true_regnum (operands[0]) == true_regnum (operands[1]) + 1);
3382   operands[2] = operand_subword (operands[0], 0+swap, 0, DImode);
3383   operands[3] = operand_subword (operands[1], 0+swap, 0, DImode);
3384   operands[4] = operand_subword (operands[0], 1-swap, 0, DImode);
3385   operands[5] = operand_subword (operands[1], 1-swap, 0, DImode);
3387   [(set_attr "type" "unary,unary")
3388    (set_attr "cond" "nocond,nocond")
3389    (set_attr "length" "4,8")])
3391 ;; Shift instructions.
3393 (define_expand "ashlsi3"
3394   [(set (match_operand:SI 0 "dest_reg_operand" "")
3395         (ashift:SI (match_operand:SI 1 "register_operand" "")
3396                    (match_operand:SI 2 "nonmemory_operand" "")))]
3397   ""
3398   "
3400   if (!TARGET_BARREL_SHIFTER)
3401     {
3402       emit_shift (ASHIFT, operands[0], operands[1], operands[2]);
3403       DONE;
3404     }
3407 (define_expand "ashrsi3"
3408   [(set (match_operand:SI 0 "dest_reg_operand" "")
3409         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3410                      (match_operand:SI 2 "nonmemory_operand" "")))]
3411   ""
3412   "
3414   if (!TARGET_BARREL_SHIFTER)
3415     {
3416       emit_shift (ASHIFTRT, operands[0], operands[1], operands[2]);
3417       DONE;
3418     }
3421 (define_expand "lshrsi3"
3422   [(set (match_operand:SI 0 "dest_reg_operand" "")
3423         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3424                      (match_operand:SI 2 "nonmemory_operand" "")))]
3425   ""
3426   "
3428   if (!TARGET_BARREL_SHIFTER)
3429     {
3430       emit_shift (LSHIFTRT, operands[0], operands[1], operands[2]);
3431       DONE;
3432     }
3435 (define_insn "shift_si3"
3436   [(set (match_operand:SI 0 "dest_reg_operand" "=r")
3437         (match_operator:SI 3 "shift4_operator"
3438                            [(match_operand:SI 1 "register_operand" "0")
3439                             (match_operand:SI 2 "const_int_operand" "n")]))
3440    (clobber (match_scratch:SI 4 "=&r"))
3441    (clobber (reg:CC CC_REG))
3442   ]
3443   "!TARGET_BARREL_SHIFTER"
3444   "* return output_shift (operands);"
3445   [(set_attr "type" "shift")
3446    (set_attr "length" "16")])
3448 (define_insn "shift_si3_loop"
3449   [(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
3450         (match_operator:SI 3 "shift_operator"
3451                            [(match_operand:SI 1 "register_operand" "0,0")
3452                             (match_operand:SI 2 "nonmemory_operand" "rn,Cal")]))
3453    (clobber (match_scratch:SI 4 "=X,X"))
3454    (clobber (reg:SI LP_COUNT))
3455    (clobber (reg:SI LP_START))
3456    (clobber (reg:SI LP_END))
3457    (clobber (reg:CC CC_REG))
3458   ]
3459   "!TARGET_BARREL_SHIFTER"
3460   "* return output_shift (operands);"
3461   [(set_attr "type" "shift")
3462    (set_attr "length" "16,20")])
3464 ; asl, asr, lsr patterns:
3465 ; There is no point in including an 'I' alternative since only the lowest 5
3466 ; bits are used for the shift.  OTOH Cal can be useful if the shift amount
3467 ; is defined in an external symbol, as we don't have special relocations
3468 ; to truncate a symbol in a u6 immediate; but that's rather exotic, so only
3469 ; provide one alternatice for this, without condexec support.
3470 (define_insn "*ashlsi3_insn"
3471   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3472         (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3473                    (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3474   "TARGET_BARREL_SHIFTER
3475    && (register_operand (operands[1], SImode)
3476        || register_operand (operands[2], SImode))"
3477   "asl%? %0,%1,%2%&"
3478   [(set_attr "type" "shift")
3479    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3480    (set_attr "predicable" "no,no,no,yes,no,no")
3481    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3483 (define_insn "*ashrsi3_insn"
3484   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3485         (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3486                      (match_operand:SI 2 "nonmemory_operand"  "K,  K,RcqqM, cL,cL,cCal")))]
3487   "TARGET_BARREL_SHIFTER
3488    && (register_operand (operands[1], SImode)
3489        || register_operand (operands[2], SImode))"
3490   "asr%? %0,%1,%2%&"
3491   [(set_attr "type" "shift")
3492    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3493    (set_attr "predicable" "no,no,no,yes,no,no")
3494    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3496 (define_insn "*lshrsi3_insn"
3497   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcq,Rcqq,Rcqq,Rcw, w,   w")
3498         (lshiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq,   0,  0, c,cCal")
3499                      (match_operand:SI 2 "nonmemory_operand"  "N,  N,RcqqM, cL,cL,cCal")))]
3500   "TARGET_BARREL_SHIFTER
3501    && (register_operand (operands[1], SImode)
3502        || register_operand (operands[2], SImode))"
3503   "*return (which_alternative <= 1 && !arc_ccfsm_cond_exec_p ()
3504             ?  \"lsr%? %0,%1%&\" : \"lsr%? %0,%1,%2%&\");"
3505   [(set_attr "type" "shift")
3506    (set_attr "iscompact" "maybe,maybe,maybe,false,false,false")
3507    (set_attr "predicable" "no,no,no,yes,no,no")
3508    (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond")])
3510 (define_insn "rotrsi3"
3511   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcw, w,   w")
3512         (rotatert:SI (match_operand:SI 1 "register_operand"  " 0,cL,cCal")
3513                      (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
3514   "TARGET_BARREL_SHIFTER"
3515   "ror%? %0,%1,%2"
3516   [(set_attr "type" "shift,shift,shift")
3517    (set_attr "predicable" "yes,no,no")
3518    (set_attr "length" "4,4,8")])
3520 ;; Compare / branch instructions.
3522 (define_expand "cbranchsi4"
3523   [(set (reg:CC CC_REG)
3524         (compare:CC (match_operand:SI 1 "nonmemory_operand" "")
3525                     (match_operand:SI 2 "nonmemory_operand" "")))
3526    (set (pc)
3527         (if_then_else
3528               (match_operator 0 "ordered_comparison_operator" [(reg CC_REG)
3529                                                                (const_int 0)])
3530               (label_ref (match_operand 3 "" ""))
3531               (pc)))]
3532   ""
3534   gcc_assert (XEXP (operands[0], 0) == operands[1]);
3535   gcc_assert (XEXP (operands[0], 1) == operands[2]);
3536   operands[0] = gen_compare_reg (operands[0], VOIDmode);
3537   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
3538   DONE;
3541 ;; ??? Could add a peephole to generate compare with swapped operands and
3542 ;; modifed cc user if second, but not first operand is a compact register.
3543 (define_insn "cmpsi_cc_insn_mixed"
3544   [(set (reg:CC CC_REG)
3545         (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq,  h, c, c,qRcq,c")
3546                     (match_operand:SI 1 "nonmemory_operand"   "cO,  hO,Cm1,cI,cL, Cal,Cal")))]
3547   ""
3548   "cmp%? %0,%B1%&"
3549   [(set_attr "type" "compare")
3550    (set_attr "iscompact" "true,true,true,false,false,true_limm,false")
3551    (set_attr "predicable" "no,no,no,no,yes,no,yes")
3552    (set_attr "cond" "set")
3553    (set_attr "length" "*,*,*,4,4,*,8")
3554    (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")])
3556 (define_insn "*cmpsi_cc_zn_insn"
3557   [(set (reg:CC_ZN CC_REG)
3558         (compare:CC_ZN (match_operand:SI 0 "register_operand"  "qRcq,c")
3559                        (const_int 0)))]
3560   ""
3561   "tst%? %0,%0%&"
3562   [(set_attr "type" "compare,compare")
3563    (set_attr "iscompact" "true,false")
3564    (set_attr "predicable" "no,yes")
3565    (set_attr "cond" "set_zn")
3566    (set_attr "length" "*,4")])
3568 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
3569 (define_insn "*btst"
3570   [(set (reg:CC_ZN CC_REG)
3571         (compare:CC_ZN
3572           (zero_extract:SI (match_operand:SI 0 "register_operand" "Rcqq,c")
3573                            (const_int 1)
3574                            (match_operand:SI 1 "nonmemory_operand" "L,Lc"))
3575           (const_int 0)))]
3576   ""
3577   "btst%? %0,%1"
3578   [(set_attr "iscompact" "true,false")
3579    (set_attr "predicable" "no,yes")
3580    (set_attr "cond" "set")
3581    (set_attr "type" "compare")
3582    (set_attr "length" "*,4")])
3584 ; combine suffers from 'simplifications' that replace a one-bit zero
3585 ; extract with a shift if it can prove that the upper bits are zero.
3586 ; arc_reorg sees the code after sched2, which can have caused our
3587 ; inputs to be clobbered even if they were not clobbered before.
3588 ; Therefore, add a third way to convert btst / b{eq,ne} to bbit{0,1}
3589 ; OTOH, this is somewhat marginal, and can leat to out-of-range
3590 ; bbit (i.e. bad scheduling) and missed conditional execution,
3591 ; so make this an option.
3592 (define_peephole2
3593   [(set (reg:CC_ZN CC_REG)
3594         (compare:CC_ZN
3595           (zero_extract:SI (match_operand:SI 0 "register_operand" "")
3596                            (const_int 1)
3597                            (match_operand:SI 1 "nonmemory_operand" ""))
3598           (const_int 0)))
3599    (set (pc)
3600         (if_then_else (match_operator 3 "equality_comparison_operator"
3601                                       [(reg:CC_ZN CC_REG) (const_int 0)])
3602                       (label_ref (match_operand 2 "" ""))
3603                       (pc)))]
3604   "TARGET_BBIT_PEEPHOLE && peep2_regno_dead_p (2, CC_REG)"
3605   [(parallel [(set (pc)
3606                    (if_then_else
3607                      (match_op_dup 3
3608                        [(zero_extract:SI (match_dup 0)
3609                                          (const_int 1) (match_dup 1))
3610                         (const_int 0)])
3611                      (label_ref (match_dup 2))
3612                      (pc)))
3613               (clobber (reg:CC_ZN CC_REG))])])
3615 (define_insn "*cmpsi_cc_z_insn"
3616   [(set (reg:CC_Z CC_REG)
3617         (compare:CC_Z (match_operand:SI 0 "register_operand"  "qRcq,c")
3618                       (match_operand:SI 1 "p2_immediate_operand"  "O,n")))]
3619   ""
3620   "@
3621         cmp%? %0,%1%&
3622         bxor.f 0,%0,%z1"
3623   [(set_attr "type" "compare,compare")
3624    (set_attr "iscompact" "true,false")
3625    (set_attr "cond" "set,set_zn")
3626    (set_attr "length" "*,4")])
3628 (define_insn "*cmpsi_cc_c_insn"
3629   [(set (reg:CC_C CC_REG)
3630         (compare:CC_C (match_operand:SI 0 "register_operand"  "Rcqq,Rcqq,  h, c,Rcqq,  c")
3631                       (match_operand:SI 1 "nonmemory_operand"   "cO,  hO,Cm1,cI, Cal,Cal")))]
3632   ""
3633   "cmp%? %0,%S1%&"
3634   [(set_attr "type" "compare")
3635    (set_attr "iscompact" "true,true,true,false,true_limm,false")
3636    (set_attr "cond" "set")
3637    (set_attr "length" "*,*,*,4,*,8")
3638    (set_attr "cpu_facility" "av1,av2,*,*,*,*")])
3640 ;; Next come the scc insns.
3642 (define_expand "cstoresi4"
3643   [(set (match_operand:SI 0 "dest_reg_operand" "")
3644         (match_operator:SI 1 "ordered_comparison_operator"
3645                            [(match_operand:SI 2 "nonmemory_operand" "")
3646                             (match_operand:SI 3 "nonmemory_operand" "")]))]
3647   ""
3649   if (!TARGET_CODE_DENSITY)
3650   {
3651    gcc_assert (XEXP (operands[1], 0) == operands[2]);
3652    gcc_assert (XEXP (operands[1], 1) == operands[3]);
3653    operands[1] = gen_compare_reg (operands[1], SImode);
3654    emit_insn (gen_scc_insn (operands[0], operands[1]));
3655    DONE;
3656   }
3657   if (!register_operand (operands[2], SImode))
3658     operands[2] = force_reg (SImode, operands[2]);
3662 (define_mode_iterator SDF [(SF "TARGET_FP_SP_BASE || TARGET_OPTFPE")
3663                            (DF "TARGET_OPTFPE")])
3665 (define_expand "cstore<mode>4"
3666   [(set (reg:CC CC_REG)
3667         (compare:CC (match_operand:SDF 2 "register_operand" "")
3668                     (match_operand:SDF 3 "register_operand" "")))
3669    (set (match_operand:SI 0 "dest_reg_operand" "")
3670         (match_operator:SI 1 "comparison_operator" [(reg CC_REG)
3671                                                     (const_int 0)]))]
3673   "TARGET_FP_SP_BASE || TARGET_OPTFPE"
3675   gcc_assert (XEXP (operands[1], 0) == operands[2]);
3676   gcc_assert (XEXP (operands[1], 1) == operands[3]);
3677   operands[1] = gen_compare_reg (operands[1], SImode);
3678   emit_insn (gen_scc_insn (operands[0], operands[1]));
3679   DONE;
3682 ; We need a separate expander for this lest we loose the mode of CC_REG
3683 ; when match_operator substitutes the literal operand into the comparison.
3684 (define_expand "scc_insn"
3685   [(set (match_operand:SI 0 "dest_reg_operand" "=w") (match_operand:SI 1 ""))])
3687 (define_insn_and_split "*scc_insn"
3688   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3689         (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))]
3690   ""
3691   "#"
3692   "reload_completed"
3693   [(set (match_dup 0) (const_int 1))
3694    (cond_exec
3695      (match_dup 1)
3696      (set (match_dup 0) (const_int 0)))]
3698   operands[1]
3699     = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (operands[1]),
3700                                          GET_MODE (XEXP (operands[1], 0))),
3701                       VOIDmode,
3702                       XEXP (operands[1], 0), XEXP (operands[1], 1));
3704   [(set_attr "type" "unary")])
3706 ;; ??? At least for ARC600, we should use sbc b,b,s12 if we want a value
3707 ;; that is one lower if the carry flag is set.
3709 ;; ??? Look up negscc insn.  See pa.md for example.
3710 (define_insn "*neg_scc_insn"
3711   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3712         (neg:SI (match_operator:SI 1 "proper_comparison_operator"
3713                  [(reg CC_REG) (const_int 0)])))]
3714   ""
3715   "mov %0,-1\;sub.%D1 %0,%0,%0"
3716   [(set_attr "type" "unary")
3717    (set_attr "length" "8")])
3719 (define_insn "*not_scc_insn"
3720   [(set (match_operand:SI 0 "dest_reg_operand" "=w")
3721         (not:SI (match_operator:SI 1 "proper_comparison_operator"
3722                  [(reg CC_REG) (const_int 0)])))]
3723   ""
3724   "mov %0,1\;sub.%d1 %0,%0,%0"
3725   [(set_attr "type" "unary")
3726    (set_attr "length" "8")])
3728 ; cond_exec patterns
3729 (define_insn "*movsi_ne"
3730   [(cond_exec
3731      (ne (match_operand:CC_Z 2 "cc_use_register"    "Rcc,  Rcc,  Rcc,Rcc,Rcc") (const_int 0))
3732      (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q,  w,w")
3733           (match_operand:SI 1 "nonmemory_operand"   "C_0,    h, ?Cal, Lc,?Cal")))]
3734   ""
3735   "@
3736         * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\";
3737         * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3738         * current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
3739         mov.ne %0,%1
3740         mov.ne %0,%S1"
3741   [(set_attr "type" "cmove")
3742    (set_attr "iscompact" "true,true,true_limm,false,false")
3743    (set_attr "length" "2,2,6,4,8")
3744    (set_attr "cpu_facility" "*,av2,av2,*,*")])
3746 (define_insn "*movsi_cond_exec"
3747   [(cond_exec
3748      (match_operator 3 "proper_comparison_operator"
3749        [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)])
3750      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3751           (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
3752   ""
3753   "mov.%d3 %0,%S1"
3754   [(set_attr "type" "cmove")
3755    (set_attr "length" "4,8")])
3757 (define_insn "*commutative_cond_exec"
3758   [(cond_exec
3759      (match_operator 5 "proper_comparison_operator"
3760        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3761      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3762           (match_operator:SI 3 "commutative_operator"
3763             [(match_operand:SI 1 "register_operand" "%0,0")
3764              (match_operand:SI 2 "nonmemory_operand" "cL,?Cal")])))]
3765   ""
3767   arc_output_commutative_cond_exec (operands, true);
3768   return "";
3770   [(set_attr "cond" "use")
3771    (set_attr "type" "cmove")
3772    (set_attr_alternative "length"
3773      [(const_int 4)
3774       (cond
3775         [(eq (symbol_ref "arc_output_commutative_cond_exec (operands, false)")
3776              (const_int 4))
3777          (const_int 4)]
3778         (const_int 8))])])
3780 (define_insn "*sub_cond_exec"
3781   [(cond_exec
3782      (match_operator 4 "proper_comparison_operator"
3783        [(match_operand 3 "cc_register" "Rcc,Rcc,Rcc") (const_int 0)])
3784      (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
3785           (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,cL,Cal")
3786                     (match_operand:SI 2 "nonmemory_operand" "cL,0,0"))))]
3787   ""
3788   "@
3789         sub.%d4 %0,%1,%2
3790         rsub.%d4 %0,%2,%1
3791         rsub.%d4 %0,%2,%1"
3792   [(set_attr "cond" "use")
3793    (set_attr "type" "cmove")
3794    (set_attr "length" "4,4,8")])
3796 (define_insn "*noncommutative_cond_exec"
3797   [(cond_exec
3798      (match_operator 5 "proper_comparison_operator"
3799        [(match_operand 4 "cc_register" "Rcc,Rcc") (const_int 0)])
3800      (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
3801           (match_operator:SI 3 "noncommutative_operator"
3802             [(match_operand:SI 1 "register_operand" "0,0")
3803              (match_operand:SI 2 "nonmemory_operand" "cL,Cal")])))]
3804   ""
3805   "%O3.%d5 %0,%1,%2"
3806   [(set_attr "cond" "use")
3807    (set_attr "type" "cmove")
3808    (set_attr "length" "4,8")])
3810 ;; These control RTL generation for conditional jump insns
3811 ;; Match both normal and inverted jump.
3813 ; We need a separate expander for this lest we loose the mode of CC_REG
3814 ; when match_operator substitutes the literal operand into the comparison.
3815 (define_expand "branch_insn"
3816   [(set (pc)
3817         (if_then_else (match_operand 1 "" "")
3818                       (label_ref (match_operand 0 "" ""))
3819                       (pc)))])
3821 ; When estimating sizes during arc_reorg, when optimizing for speed, there
3822 ; are three reasons why we need to consider branches to be length 6:
3823 ; - annull-false delay slot insns are implemented using conditional execution,
3824 ;   thus preventing short insn formation where used.
3825 ; - for ARC600: annull-true delay slot isnns are implemented where possile
3826 ;   using conditional execution, preventing short insn formation where used.
3827 ; - for ARC700: likely or somewhat likely taken branches are made long and
3828 ;   unaligned if possible to avoid branch penalty.
3829 (define_insn "*branch_insn"
3830   [(set (pc)
3831         (if_then_else (match_operator 1 "proper_comparison_operator"
3832                                       [(reg CC_REG) (const_int 0)])
3833                       (label_ref (match_operand 0 "" ""))
3834                       (pc)))]
3835   ""
3836   "*
3838   if (arc_ccfsm_branch_deleted_p ())
3839     {
3840       arc_ccfsm_record_branch_deleted ();
3841       return \"; branch deleted, next insns conditionalized\";
3842     }
3843   else
3844     {
3845       arc_ccfsm_record_condition (operands[1], false, insn, 0);
3846       if (get_attr_length (insn) == 2)
3847          return \"b%d1%? %^%l0%&\";
3848       else
3849          return \"b%d1%# %^%l0\";
3850     }
3852   [(set_attr "type" "branch")
3853    (set
3854      (attr "length")
3855      (cond [
3856        (eq_attr "delay_slot_filled" "yes")
3857        (const_int 4)
3859        (ne
3860          (if_then_else
3861            (match_operand 1 "equality_comparison_operator" "")
3862            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3863                 (gt (minus (match_dup 0) (pc))
3864                     (minus (const_int 506)
3865                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3866            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3867                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3868                 (gt (minus (match_dup 0) (pc))
3869                     (minus (const_int 58)
3870                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3871          (const_int 0))
3872        (const_int 4)]
3873       (const_int 2)))
3875    (set (attr "iscompact")
3876         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3877               (const_string "false")))])
3879 (define_insn "*rev_branch_insn"
3880   [(set (pc)
3881         (if_then_else (match_operator 1 "proper_comparison_operator"
3882                                       [(reg CC_REG) (const_int 0)])
3883                       (pc)
3884                       (label_ref (match_operand 0 "" ""))))]
3885   "REVERSIBLE_CC_MODE (GET_MODE (XEXP (operands[1], 0)))"
3886   "*
3888   if (arc_ccfsm_branch_deleted_p ())
3889     {
3890       arc_ccfsm_record_branch_deleted ();
3891       return \"; branch deleted, next insns conditionalized\";
3892     }
3893   else
3894     {
3895       arc_ccfsm_record_condition (operands[1], true, insn, 0);
3896       if (get_attr_length (insn) == 2)
3897          return \"b%D1%? %^%l0\";
3898       else
3899          return \"b%D1%# %^%l0\";
3900     }
3902   [(set_attr "type" "branch")
3903    (set
3904      (attr "length")
3905      (cond [
3906        (eq_attr "delay_slot_filled" "yes")
3907        (const_int 4)
3909        (ne
3910          (if_then_else
3911            (match_operand 1 "equality_comparison_operator" "")
3912            (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3913                 (gt (minus (match_dup 0) (pc))
3914                     (minus (const_int 506)
3915                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
3916            (ior (match_test "!arc_short_comparison_p (operands[1], -64)")
3917                 (lt (minus (match_dup 0) (pc)) (const_int -64))
3918                 (gt (minus (match_dup 0) (pc))
3919                     (minus (const_int 58)
3920                            (symbol_ref "get_attr_delay_slot_length (insn)")))))
3921          (const_int 0))
3922        (const_int 4)]
3923       (const_int 2)))
3925    (set (attr "iscompact")
3926         (cond [(match_test "get_attr_length (insn) == 2") (const_string "true")]
3927               (const_string "false")))])
3929 ;; Unconditional and other jump instructions.
3931 (define_expand "jump"
3932   [(set (pc) (label_ref (match_operand 0 "" "")))]
3933   ""
3934   "")
3936 (define_insn "jump_i"
3937   [(set (pc) (label_ref (match_operand 0 "" "")))]
3938   "!TARGET_LONG_CALLS_SET || !CROSSING_JUMP_P (insn)"
3939   "b%!%* %^%l0%&"
3940   [(set_attr "type" "uncond_branch")
3941    (set (attr "iscompact")
3942         (if_then_else (match_test "get_attr_length (insn) == 2")
3943                       (const_string "true") (const_string "false")))
3944    (set_attr "cond" "canuse")
3945    (set (attr "length")
3946         (cond [
3947           ; In arc_reorg we just guesstimate; might be more or less than 4.
3948           (match_test "arc_branch_size_unknown_p ()")
3949           (const_int 4)
3951           (eq_attr "delay_slot_filled" "yes")
3952           (const_int 4)
3954           (match_test "CROSSING_JUMP_P (insn)")
3955           (const_int 4)
3957           (ior (lt (minus (match_dup 0) (pc)) (const_int -512))
3958                (gt (minus (match_dup 0) (pc))
3959                    (minus (const_int 506)
3960                           (symbol_ref "get_attr_delay_slot_length (insn)"))))
3961           (const_int 4)]
3962          (const_int 2)))])
3964 (define_insn "indirect_jump"
3965   [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))]
3966   ""
3967   "@
3968    j%!%* %0%&
3969    j%!%* %0%&
3970    j%!%* %0%&
3971    j%!%* [%0]%&
3972    j%!%* [%0]%&"
3973   [(set_attr "type" "jump")
3974    (set_attr "iscompact" "false,false,false,maybe,false")
3975    (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")])
3977 ;; Implement a switch statement.
3979 (define_expand "casesi"
3980   [(set (match_dup 5)
3981         (minus:SI (match_operand:SI 0 "register_operand" "")
3982                   (match_operand:SI 1 "nonmemory_operand" "")))
3983    (set (reg:CC CC_REG)
3984         (compare:CC (match_dup 5)
3985                     (match_operand:SI 2 "nonmemory_operand" "")))
3986    (set (pc)
3987         (if_then_else (gtu (reg:CC CC_REG)
3988                            (const_int 0))
3989                       (label_ref (match_operand 4 "" ""))
3990                       (pc)))
3991    (set (match_dup 6)
3992         (unspec:SI [(match_operand 3 "" "")
3993                     (match_dup 5) (match_dup 7)] UNSPEC_ARC_CASESI))
3994    (parallel [(set (pc) (match_dup 6)) (use (match_dup 7))])]
3995   ""
3996   "
3998   rtx x;
4000   operands[5] = gen_reg_rtx (SImode);
4001   operands[6] = gen_reg_rtx (SImode);
4002   operands[7] = operands[3];
4003   emit_insn (gen_subsi3 (operands[5], operands[0], operands[1]));
4004   emit_insn (gen_cmpsi_cc_insn_mixed (operands[5], operands[2]));
4005   x = gen_rtx_GTU (VOIDmode, gen_rtx_REG (CCmode, CC_REG), const0_rtx);
4006   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
4007                             gen_rtx_LABEL_REF (VOIDmode, operands[4]), pc_rtx);
4008   emit_jump_insn (gen_rtx_SET (pc_rtx, x));
4009   if (TARGET_COMPACT_CASESI)
4010     {
4011       emit_jump_insn (gen_casesi_compact_jump (operands[5], operands[7]));
4012     }
4013   else
4014     {
4015       operands[3] = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
4016       if (flag_pic || !cse_not_expected)
4017         operands[3] = force_reg (Pmode, operands[3]);
4018       emit_insn (gen_casesi_load (operands[6],
4019                                   operands[3], operands[5], operands[7]));
4020       if (CASE_VECTOR_PC_RELATIVE || flag_pic)
4021         emit_insn (gen_addsi3 (operands[6], operands[6], operands[3]));
4022       emit_jump_insn (gen_casesi_jump (operands[6], operands[7]));
4023     }
4024   DONE;
4027 (define_insn "casesi_load"
4028   [(set (match_operand:SI 0 "register_operand"             "=Rcq,r,r")
4029         (unspec:SI [(match_operand:SI 1 "nonmemory_operand" "Rcq,c,Cal")
4030                     (match_operand:SI 2 "register_operand"  "Rcq,c,c")
4031                     (label_ref (match_operand 3 "" ""))] UNSPEC_ARC_CASESI))]
4032   ""
4033   "*
4035   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[3])));
4037   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
4038     {
4039       gcc_assert (GET_CODE (diff_vec) == ADDR_VEC);
4040       gcc_assert (GET_MODE (diff_vec) == SImode);
4041       gcc_assert (!CASE_VECTOR_PC_RELATIVE && !flag_pic);
4042     }
4044   switch (GET_MODE (diff_vec))
4045     {
4046     case E_SImode:
4047       return \"ld.as %0,[%1,%2]%&\";
4048     case E_HImode:
4049       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4050         return \"ld%_.as %0,[%1,%2]\";
4051       return \"ld%_.x.as %0,[%1,%2]\";
4052     case E_QImode:
4053       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4054         return \"ldb%? %0,[%1,%2]%&\";
4055       return \"ldb.x %0,[%1,%2]\";
4056     default:
4057       gcc_unreachable ();
4058     }
4060   [(set_attr "type" "load")
4061    (set_attr_alternative "iscompact"
4062      [(cond
4063         [(ne (symbol_ref "GET_MODE (PATTERN (next_nonnote_insn
4064                                                (as_a<rtx_insn *> (operands[3]))))")
4065              (symbol_ref "QImode"))
4066          (const_string "false")
4067          (match_test "!ADDR_DIFF_VEC_FLAGS (PATTERN (next_nonnote_insn
4068                                                        (as_a<rtx_insn *> (operands[3])))).offset_unsigned")
4069          (const_string "false")]
4070         (const_string "true"))
4071       (const_string "false")
4072       (const_string "false")])
4073    (set_attr_alternative "length"
4074      [(cond
4075         [(eq_attr "iscompact" "false") (const_int 4)
4076         ; We have to mention (match_dup 3) to convince genattrtab.c that this
4077         ; is a varying length insn.
4078          (eq (symbol_ref "1+1") (const_int 2)) (const_int 2)
4079          (gt (minus (match_dup 3) (pc)) (const_int 42)) (const_int 4)]
4080         (const_int 2))
4081       (const_int 4)
4082       (const_int 8)])])
4084 ; Unlike the canonical tablejump, this pattern always uses a jump address,
4085 ; even for CASE_VECTOR_PC_RELATIVE.
4086 (define_insn "casesi_jump"
4087   [(set (pc) (match_operand:SI 0 "register_operand" "Cal,Rcqq,c"))
4088    (use (label_ref (match_operand 1 "" "")))]
4089   ""
4090   "j%!%* [%0]%&"
4091   [(set_attr "type" "jump")
4092    (set_attr "iscompact" "false,maybe,false")
4093    (set_attr "cond" "canuse")])
4095 (define_insn "casesi_compact_jump"
4096   [(set (pc)
4097         (unspec:SI [(match_operand:SI 0 "register_operand" "c,q")]
4098                    UNSPEC_ARC_CASESI))
4099    (use (label_ref (match_operand 1 "" "")))
4100    (clobber (match_scratch:SI 2 "=q,0"))]
4101   "TARGET_COMPACT_CASESI"
4102   "*
4104   rtx diff_vec = PATTERN (next_nonnote_insn (as_a<rtx_insn *> (operands[1])));
4105   int unalign = arc_get_unalign ();
4106   rtx xop[3];
4107   const char *s;
4109   xop[0] = operands[0];
4110   xop[2] = operands[2];
4111   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4113   switch (GET_MODE (diff_vec))
4114     {
4115     case E_SImode:
4116       /* Max length can be 12 in this case, but this is OK because
4117          2 of these are for alignment, and are anticipated in the length
4118          of the ADDR_DIFF_VEC.  */
4119       if (unalign && !satisfies_constraint_Rcq (xop[0]))
4120         s = \"add2 %2,pcl,%0\n\tld_s %2,[%2,12]\";
4121       else if (unalign)
4122         s = \"add_s %2,%0,2\n\tld.as %2,[pcl,%2]\";
4123       else
4124         s = \"add %2,%0,2\n\tld.as %2,[pcl,%2]\";
4125       arc_clear_unalign ();
4126       break;
4127     case E_HImode:
4128       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4129         {
4130           if (satisfies_constraint_Rcq (xop[0]))
4131             {
4132               s = \"add_s %2,%0,%1\n\tld%_.as %2,[pcl,%2]\";
4133               xop[1] = GEN_INT ((10 - unalign) / 2U);
4134             }
4135           else
4136             {
4137               s = \"add1 %2,pcl,%0\n\tld%__s %2,[%2,%1]\";
4138               xop[1] = GEN_INT (10 + unalign);
4139             }
4140         }
4141       else
4142         {
4143           if (satisfies_constraint_Rcq (xop[0]))
4144             {
4145               s = \"add_s %2,%0,%1\n\tld%_.x.as %2,[pcl,%2]\";
4146               xop[1] = GEN_INT ((10 - unalign) / 2U);
4147             }
4148           else
4149             {
4150               s = \"add1 %2,pcl,%0\n\tld%__s.x %2,[%2,%1]\";
4151               xop[1] = GEN_INT (10 + unalign);
4152             }
4153         }
4154       arc_toggle_unalign ();
4155       break;
4156     case E_QImode:
4157       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
4158         {
4159           if ((rtx_equal_p (xop[2], xop[0])
4160                || find_reg_note (insn, REG_DEAD, xop[0]))
4161               && satisfies_constraint_Rcq (xop[0]))
4162             {
4163               s = \"add_s %0,%0,pcl\n\tldb_s %2,[%0,%1]\";
4164               xop[1] = GEN_INT (8 + unalign);
4165             }
4166           else
4167             {
4168               s = \"add %2,%0,pcl\n\tldb_s %2,[%2,%1]\";
4169               xop[1] = GEN_INT (10 + unalign);
4170               arc_toggle_unalign ();
4171             }
4172         }
4173       else if ((rtx_equal_p (xop[0], xop[2])
4174                 || find_reg_note (insn, REG_DEAD, xop[0]))
4175                && satisfies_constraint_Rcq (xop[0]))
4176         {
4177           s = \"add_s %0,%0,%1\n\tldb.x %2,[pcl,%0]\";
4178           xop[1] = GEN_INT (10 - unalign);
4179           arc_toggle_unalign ();
4180         }
4181       else
4182         {
4183           /* ??? Length is 12.  */
4184           s = \"add %2,%0,%1\n\tldb.x %2,[pcl,%2]\";
4185           xop[1] = GEN_INT (8 + unalign);
4186         }
4187       break;
4188     default:
4189       gcc_unreachable ();
4190     }
4191   output_asm_insn (s, xop);
4192   return \"add_s %2,%2,pcl\n\tj_s%* [%2]\";
4194   [(set_attr "length" "10")
4195    (set_attr "type" "jump")
4196    (set_attr "iscompact" "true")
4197    (set_attr "cond" "nocond")])
4199 (define_expand "call"
4200   ;; operands[1] is stack_size_rtx
4201   ;; operands[2] is next_arg_register
4202   [(parallel [(call (match_operand:SI 0 "call_operand" "")
4203                     (match_operand 1 "" ""))
4204              (clobber (reg:SI 31))])]
4205   ""
4206   "{
4207     rtx callee;
4209     gcc_assert (MEM_P (operands[0]));
4210     callee  = XEXP (operands[0], 0);
4211     /* This is to decide if we should generate indirect calls by loading the
4212        32 bit address of the callee into a register before performing the
4213        branch and link - this exposes cse opportunities.
4214        Also, in weird cases like compile/20010107-1.c, we may get a PLUS.  */
4215     if (GET_CODE (callee) != REG
4216         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4217       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4218   }
4222 ; Rcq, which is used in alternative 0, checks for conditional execution.
4223 ; At instruction output time, if it doesn't match and we end up with
4224 ; alternative 1 ("q"), that means that we can't use the short form.
4225 (define_insn "*call_i"
4226   [(call (mem:SI (match_operand:SI 0
4227                   "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4228          (match_operand 1 "" ""))
4229    (clobber (reg:SI 31))]
4230   ""
4231   "@
4232    jl%!%* [%0]%&
4233    jl%!%* [%0]%&
4234    jl%!%* [%0]
4235    bl%!%* %P0
4236    bl%!%* %P0
4237    jl%!%* %S0
4238    jl%* %S0
4239    jl%! %S0"
4240   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4241    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4242    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4243    (set_attr "length" "*,*,4,4,4,4,4,8")])
4245 (define_expand "call_value"
4246   ;; operand 2 is stack_size_rtx
4247   ;; operand 3 is next_arg_register
4248   [(parallel [(set (match_operand 0 "dest_reg_operand" "=r")
4249                    (call (match_operand:SI 1 "call_operand" "")
4250                          (match_operand 2 "" "")))
4251              (clobber (reg:SI 31))])]
4252   ""
4253   "
4254   {
4255     rtx callee;
4257     gcc_assert (MEM_P (operands[1]));
4258     callee = XEXP (operands[1], 0);
4259      /* See the comment in define_expand \"call\".  */
4260     if (GET_CODE (callee) != REG
4261         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4262       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4263   }")
4266 ; Rcq, which is used in alternative 0, checks for conditional execution.
4267 ; At instruction output time, if it doesn't match and we end up with
4268 ; alternative 1 ("q"), that means that we can't use the short form.
4269 (define_insn "*call_value_i"
4270   [(set (match_operand 0 "dest_reg_operand"  "=Rcq,q,w,  w,  w,w,w,  w")
4271         (call (mem:SI (match_operand:SI 1
4272                        "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
4273               (match_operand 2 "" "")))
4274    (clobber (reg:SI 31))]
4275   ""
4276   "@
4277    jl%!%* [%1]%&
4278    jl%!%* [%1]%&
4279    jl%!%* [%1]
4280    bl%!%* %P1;1
4281    bl%!%* %P1;1
4282    jl%!%* %S1
4283    jl%* %S1
4284    jl%! %S1"
4285   [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
4286    (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
4287    (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
4288    (set_attr "length" "*,*,4,4,4,4,4,8")])
4290 ; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
4291 ; use it for lack of inter-procedural branch shortening.
4292 ; Link-time relaxation would help...
4294 (define_insn "nop"
4295   [(const_int 0)]
4296   ""
4297   "nop%?"
4298   [(set_attr "type" "misc")
4299    (set_attr "iscompact" "true")
4300    (set_attr "cond" "canuse")
4301    (set_attr "length" "2")])
4303 (define_insn "nopv"
4304   [(unspec_volatile [(const_int 0)] VUNSPEC_ARC_NOP)]
4305   ""
4306   "nop%?"
4307   [(set_attr "type" "misc")
4308    (set_attr "iscompact" "true")
4309    (set_attr "length" "2")])
4311 ;; Special pattern to flush the icache.
4312 ;; ??? Not sure what to do here.  Some ARC's are known to support this.
4314 (define_insn "flush_icache"
4315   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] 0)]
4316   ""
4317   "* return \"\";"
4318   [(set_attr "type" "misc")])
4320 ;; Split up troublesome insns for better scheduling.
4322 ;; Peepholes go at the end.
4323 ;;asl followed by add can be replaced by an add{1,2,3}
4324 ;; Three define_peepholes have been added for this optimization
4325 ;; ??? This used to target non-canonical rtl.  Now we use add_n, which
4326 ;; can be generated by combine.  Check if these peepholes still provide
4327 ;; any benefit.
4329 ;; -------------------------------------------------------------
4330 ;; Pattern 1 : r0 = r1 << {i}
4331 ;;             r3 = r4/INT + r0     ;;and commutative
4332 ;;                 ||
4333 ;;                 \/
4334 ;;             add{i} r3,r4/INT,r1
4335 ;; -------------------------------------------------------------
4336 ;; ??? This should be covered by combine, alas, at times combine gets
4337 ;; too clever for it's own good: when the shifted input is known to be
4338 ;; either 0 or 1, the operation will be made into an if-then-else, and
4339 ;; thus fail to match the add_n pattern.  Example: _mktm_r, line 85 in
4340 ;; newlib/libc/time/mktm_r.c .
4342 (define_peephole2
4343   [(set (match_operand:SI 0 "dest_reg_operand" "")
4344         (ashift:SI (match_operand:SI 1 "register_operand" "")
4345                    (match_operand:SI 2 "const_int_operand" "")))
4346   (set (match_operand:SI 3 "dest_reg_operand" "")
4347        (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
4348                 (match_operand:SI 5 "nonmemory_operand" "")))]
4349   "(INTVAL (operands[2]) == 1
4350     || INTVAL (operands[2]) == 2
4351     || INTVAL (operands[2]) == 3)
4352    && (true_regnum (operands[4]) == true_regnum (operands[0])
4353        || true_regnum (operands[5]) == true_regnum (operands[0]))
4354    && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4355  ;; the preparation statements take care to put proper operand in operands[4]
4356  ;; operands[4] will always contain the correct operand. This is added to satisfy commutativity
4357   [(set (match_dup 3)
4358         (plus:SI (mult:SI (match_dup 1)
4359                           (match_dup 2))
4360                  (match_dup 4)))]
4361   "if (true_regnum (operands[4]) == true_regnum (operands[0]))
4362       operands[4] = operands[5];
4363    operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4366 ;; -------------------------------------------------------------
4367 ;; Pattern 1 : r0 = r1 << {i}
4368 ;;             r3 = r4 - r0
4369 ;;                 ||
4370 ;;                 \/
4371 ;;             sub{i} r3,r4,r1
4372 ;; -------------------------------------------------------------
4373 ;; ??? This should be covered by combine, alas, at times combine gets
4374 ;; too clever for it's own good: when the shifted input is known to be
4375 ;; either 0 or 1, the operation will be made into an if-then-else, and
4376 ;; thus fail to match the sub_n pattern.  Example: __ieee754_yn, line 239 in
4377 ;; newlib/libm/math/e_jn.c .
4379 (define_peephole2
4380   [(set (match_operand:SI 0 "dest_reg_operand" "")
4381         (ashift:SI (match_operand:SI 1 "register_operand" "")
4382                    (match_operand:SI 2 "const_int_operand" "")))
4383    (set (match_operand:SI 3 "dest_reg_operand" "")
4384         (minus:SI (match_operand:SI 4 "nonmemory_operand" "")
4385                   (match_dup 0)))]
4386   "(INTVAL (operands[2]) == 1
4387     || INTVAL (operands[2]) == 2
4388     || INTVAL (operands[2]) == 3)
4389    && (peep2_reg_dead_p (2, operands[0])
4390        || (true_regnum (operands[3]) == true_regnum (operands[0])))"
4391   [(set (match_dup 3)
4392         (minus:SI (match_dup 4)
4393                   (mult:SI (match_dup 1)
4394                            (match_dup 2))))]
4395   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
4400 ; When using the high single bit, the result of a multiply is either
4401 ; the original number or zero.  But MPY costs 4 cycles, which we
4402 ; can replace with the 2 cycles for the pair of TST_S and ADD.NE.
4403 (define_peephole2
4404   [(set (match_operand:SI 0 "dest_reg_operand" "")
4405         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4406                      (const_int 31)))
4407    (set (match_operand:SI 4 "register_operand" "")
4408         (mult:SI (match_operand:SI 2 "register_operand")
4409                  (match_operand:SI 3 "nonmemory_operand" "")))]
4410   "TARGET_ARC700_MPY
4411    && (rtx_equal_p (operands[0], operands[2])
4412        || rtx_equal_p (operands[0], operands[3]))
4413    && peep2_regno_dead_p (0, CC_REG)
4414    && (rtx_equal_p (operands[0], operands[4])
4415        || (peep2_reg_dead_p (2, operands[0])
4416           && peep2_reg_dead_p (1, operands[4])))"
4417   [(parallel [(set (reg:CC_Z CC_REG)
4418                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4419                                  (const_int 0)))
4420               (set (match_dup 4) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4421    (cond_exec
4422      (ne (reg:CC_Z CC_REG) (const_int 0))
4423      (set (match_dup 4) (match_dup 5)))]
4425   if (!rtx_equal_p (operands[0], operands[2]))
4426     operands[5] = operands[2];
4427   else if (!rtx_equal_p (operands[0], operands[3]))
4428     operands[5] = operands[3];
4429   else
4430     operands[5] = operands[4]; /* Actually a no-op... presumably rare.  */
4433 (define_peephole2
4434   [(set (match_operand:SI 0 "dest_reg_operand" "")
4435         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4436                      (const_int 31)))
4437    (set (match_operand:SI 4 "register_operand" "")
4438         (mult:SI (match_operand:SI 2 "register_operand")
4439                  (match_operand:SI 3 "nonmemory_operand" "")))]
4440   "TARGET_ARC700_MPY
4441    && (rtx_equal_p (operands[0], operands[2])
4442        || rtx_equal_p (operands[0], operands[3]))
4443    && peep2_regno_dead_p (2, CC_REG)"
4444   [(parallel [(set (reg:CC_Z CC_REG)
4445                    (compare:CC_Z (lshiftrt:SI (match_dup 1) (const_int 31))
4446                                  (const_int 0)))
4447               (set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
4448    (set (match_dup 4) (match_dup 5))
4449    (cond_exec
4450      (eq (reg:CC_Z CC_REG) (const_int 0))
4451      (set (match_dup 4) (const_int 0)))]
4452  "operands[5] = operands[rtx_equal_p (operands[0], operands[2]) ? 3 : 2];")
4454 ;; Instructions generated through builtins
4456 (define_insn "clrsbsi2"
4457   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4458         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))]
4459   "TARGET_NORM"
4460   "@
4461    norm \t%0, %1
4462    norm \t%0, %S1"
4463   [(set_attr "length" "4,8")
4464    (set_attr "type" "two_cycle_core,two_cycle_core")])
4466 (define_insn "norm_f"
4467   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4468         (clrsb:SI (match_operand:SI 1 "general_operand" "cL,Cal")))
4469    (set (reg:CC_ZN CC_REG)
4470         (compare:CC_ZN (match_dup 1) (const_int 0)))]
4471   "TARGET_NORM"
4472   "@
4473    norm.f\t%0, %1
4474    norm.f\t%0, %S1"
4475   [(set_attr "length" "4,8")
4476    (set_attr "type" "two_cycle_core,two_cycle_core")])
4478 (define_insn_and_split "clrsbhi2"
4479   [(set (match_operand:HI  0 "dest_reg_operand" "=w,w")
4480         (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal")))]
4481   "TARGET_NORM"
4482   "#"
4483   "reload_completed"
4484   [(set (match_dup 0) (zero_extend:SI (clrsb:HI (match_dup 1))))]
4485   "operands[0] = simplify_gen_subreg (SImode, operands[0], HImode, 0);")
4487 (define_insn "normw"
4488   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
4489         (zero_extend:SI
4490           (clrsb:HI (match_operand:HI 1 "general_operand" "cL,Cal"))))]
4491   "TARGET_NORM"
4492   "@
4493    norm%_ \t%0, %1
4494    norm%_ \t%0, %S1"
4495   [(set_attr "length" "4,8")
4496    (set_attr "type" "two_cycle_core,two_cycle_core")])
4498 (define_expand "clzsi2"
4499   [(parallel
4500     [(set (match_operand:SI 0 "register_operand" "")
4501           (clz:SI (match_operand:SI 1 "register_operand" "")))
4502      (clobber (match_dup 2))])]
4503   "TARGET_NORM"
4504   "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);")
4506 (define_insn_and_split "*arc_clzsi2"
4507   [(set (match_operand:SI 0 "register_operand" "=r")
4508         (clz:SI (match_operand:SI 1 "register_operand" "r")))
4509    (clobber (reg:CC_ZN CC_REG))]
4510   "TARGET_NORM"
4511   "#"
4512   "reload_completed"
4513   [(const_int 0)]
4515   emit_insn (gen_norm_f (operands[0], operands[1]));
4516   emit_insn
4517     (gen_rtx_COND_EXEC
4518       (VOIDmode,
4519        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4520        gen_rtx_SET (operands[0], const0_rtx)));
4521   emit_insn
4522     (gen_rtx_COND_EXEC
4523       (VOIDmode,
4524        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4525        gen_rtx_SET (operands[0], plus_constant (SImode, operands[0], 1))));
4526   DONE;
4529 (define_expand "ctzsi2"
4530   [(match_operand:SI 0 "register_operand" "")
4531    (match_operand:SI 1 "register_operand" "")]
4532   "TARGET_NORM"
4533   "
4534   emit_insn (gen_arc_ctzsi2 (operands[0], operands[1]));
4535   DONE;
4538 (define_insn_and_split "arc_ctzsi2"
4539   [(set (match_operand:SI 0 "register_operand" "=r")
4540         (ctz:SI (match_operand:SI 1 "register_operand" "r")))
4541    (clobber (reg:CC_ZN CC_REG))
4542    (clobber (match_scratch:SI 2 "=&r"))]
4543   "TARGET_NORM"
4544   "#"
4545   "reload_completed"
4546   [(const_int 0)]
4548   rtx temp = operands[0];
4550   if (reg_overlap_mentioned_p (temp, operands[1])
4551       || (REGNO (temp) < FIRST_PSEUDO_REGISTER
4552           && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
4553                                  REGNO (temp))))
4554     temp = operands[2];
4555   emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx));
4556   emit_insn (gen_bic_f_zn (temp, temp, operands[1]));
4557   emit_insn (gen_clrsbsi2 (operands[0], temp));
4558   emit_insn
4559     (gen_rtx_COND_EXEC
4560       (VOIDmode,
4561        gen_rtx_LT (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4562        gen_rtx_SET (operands[0], GEN_INT (32))));
4563   emit_insn
4564     (gen_rtx_COND_EXEC
4565       (VOIDmode,
4566        gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx),
4567        gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31),
4568                                                 operands[0]))));
4569   DONE;
4573 (define_insn "swap"
4574   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w,w")
4575         (unspec:SI [(match_operand:SI 1 "general_operand" "L,Cal,c")]
4576                             UNSPEC_ARC_SWAP))]
4577   "TARGET_SWAP"
4578   "@
4579    swap \t%0, %1
4580    swap \t%0, %S1
4581    swap \t%0, %1"
4582   [(set_attr "length" "4,8,4")
4583    (set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
4585 (define_insn "divaw"
4586   [(set (match_operand:SI 0 "dest_reg_operand" "=&w,&w,&w")
4587                           (unspec:SI [(div:SI (match_operand:SI 1 "general_operand" "r,Cal,r")
4588                                            (match_operand:SI 2 "general_operand" "r,r,Cal"))]
4589                                            UNSPEC_ARC_DIVAW))]
4590   "TARGET_ARC700 || TARGET_EA_SET"
4591   "@
4592    divaw \t%0, %1, %2
4593    divaw \t%0, %S1, %2
4594    divaw \t%0, %1, %S2"
4595   [(set_attr "length" "4,8,8")
4596    (set_attr "type" "divaw,divaw,divaw")])
4598 (define_insn "flag"
4599   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
4600                    VUNSPEC_ARC_FLAG)]
4601   ""
4602   "@
4603     flag%? %0
4604     flag %0
4605     flag%? %S0"
4606   [(set_attr "length" "4,4,8")
4607    (set_attr "type" "misc,misc,misc")
4608    (set_attr "predicable" "yes,no,yes")
4609    (set_attr "cond" "clob,clob,clob")])
4611 (define_insn "brk"
4612   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4613                    VUNSPEC_ARC_BRK)]
4614   ""
4615   "brk"
4616   [(set_attr "length" "4")
4617   (set_attr "type" "misc")])
4619 (define_insn "rtie"
4620   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4621                    VUNSPEC_ARC_RTIE)]
4622   ""
4623   "rtie"
4624   [(set_attr "length" "4")
4625   (set_attr "type" "misc")
4626   (set_attr "cond" "clob")])
4628 (define_insn "sync"
4629   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4630                    VUNSPEC_ARC_SYNC)]
4631   ""
4632   "sync"
4633   [(set_attr "length" "4")
4634   (set_attr "type" "misc")])
4636 (define_insn "swi"
4637   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4638                    VUNSPEC_ARC_SWI)]
4639   ""
4640   "*
4642     if(TARGET_ARC700)
4643         return \"trap0\";
4644     else
4645         return \"swi\";
4647   [(set_attr "length" "4")
4648   (set_attr "type" "misc")])
4651 (define_insn "sleep"
4652   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L")]
4653                    VUNSPEC_ARC_SLEEP)]
4654   "check_if_valid_sleep_operand(operands,0)"
4655   "sleep %0"
4656   [(set_attr "length" "4")
4657   (set_attr "type" "misc")])
4659 (define_insn "core_read"
4660   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r")
4661         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "Hn,!r")]
4662                             VUNSPEC_ARC_CORE_READ))]
4663   ""
4664   "*
4665     if (check_if_valid_regno_const (operands, 1))
4666       return \"mov \t%0, r%1\";
4667     return \"mov \t%0, r%1\";
4668   "
4669   [(set_attr "length" "4")
4670    (set_attr "type" "unary")])
4672 (define_insn "core_write"
4673   [(unspec_volatile [(match_operand:SI 0 "general_operand" "r,r")
4674                      (match_operand:SI 1 "general_operand" "Hn,!r")]
4675                    VUNSPEC_ARC_CORE_WRITE)]
4676   ""
4677   "*
4678     if (check_if_valid_regno_const (operands, 1))
4679       return \"mov \tr%1, %0\";
4680     return \"mov \tr%1, %0\";
4681   "
4682   [(set_attr "length" "4")
4683    (set_attr "type" "unary")])
4685 (define_insn "lr"
4686   [(set (match_operand:SI  0 "dest_reg_operand" "=r,r,r,r")
4687         (unspec_volatile:SI [(match_operand:SI 1 "general_operand" "I,HCal,r,D")]
4688                             VUNSPEC_ARC_LR))]
4689   ""
4690   "lr\t%0, [%1]"
4691   [(set_attr "length" "4,8,4,8")
4692    (set_attr "type" "lr,lr,lr,lr")])
4694 (define_insn "sr"
4695   [(unspec_volatile [(match_operand:SI 0 "general_operand" "Cal,r,r,r")
4696                      (match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
4697                    VUNSPEC_ARC_SR)]
4698   ""
4699   "sr\t%S0, [%1]"
4700   [(set_attr "length" "8,4,8,4")
4701    (set_attr "type" "sr,sr,sr,sr")])
4703 (define_insn "trap_s"
4704   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "L,Cal")]
4705                    VUNSPEC_ARC_TRAP_S)]
4706   "!TARGET_ARC600_FAMILY"
4708   if (which_alternative == 0)
4709     {
4710       arc_toggle_unalign ();
4711       return \"trap_s %0\";
4712     }
4714   /* Keep this message in sync with the one in arc.c:arc_expand_builtin,
4715      because *.md files do not get scanned by exgettext.  */
4716   fatal_error (input_location,
4717                \"operand to trap_s should be an unsigned 6-bit value\");
4719   [(set_attr "length" "2")
4720   (set_attr "type" "misc")])
4722 (define_insn "unimp_s"
4723   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
4724                    VUNSPEC_ARC_UNIMP_S)]
4725   "!TARGET_ARC600_FAMILY"
4726   "unimp_s"
4727   [(set_attr "length" "4")
4728   (set_attr "type" "misc")])
4730 ;; End of instructions generated through builtins
4732 ; Since the demise of REG_N_SETS as reliable data readily available to the
4733 ; target, it is no longer possible to find out
4734 ; in the prologue / epilogue expanders how many times blink is set.
4735 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4736 ; any explicit use of blink will cause it to be saved; hence we cannot
4737 ; represent the blink use in return / sibcall instructions themselves, and
4738 ; instead have to show it in EPILOGUE_USES and must explicitly
4739 ; forbid instructions that change blink in the return / sibcall delay slot.
4740 (define_expand "sibcall"
4741   [(parallel [(call (match_operand 0 "memory_operand" "")
4742                     (match_operand 1 "general_operand" ""))
4743               (simple_return)
4744               (use (match_operand 2 "" ""))])]
4745   ""
4746   "
4747   {
4748     rtx callee = XEXP (operands[0], 0);
4750     if (operands[2] == NULL_RTX)
4751       operands[2] = const0_rtx;
4752     if (GET_CODE (callee) != REG
4753         && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee)))
4754       XEXP (operands[0], 0) = force_reg (Pmode, callee);
4755   }"
4758 (define_expand "sibcall_value"
4759   [(parallel [(set (match_operand 0 "dest_reg_operand" "")
4760                    (call (match_operand 1 "memory_operand" "")
4761                          (match_operand 2 "general_operand" "")))
4762               (simple_return)
4763               (use (match_operand 3 "" ""))])]
4764   ""
4765   "
4766   {
4767     rtx callee = XEXP (operands[1], 0);
4769     if (operands[3] == NULL_RTX)
4770       operands[3] = const0_rtx;
4771     if (GET_CODE (callee) != REG && arc_is_longcall_p (callee))
4772       XEXP (operands[1], 0) = force_reg (Pmode, callee);
4773   }"
4776 (define_insn "*sibcall_insn"
4777  [(call (mem:SI (match_operand:SI 0 "call_address_operand"
4778                  "Cbp,Cbr,Rs5,Rsc,Cal"))
4779         (match_operand 1 "" ""))
4780   (simple_return)
4781   (use (match_operand 2 "" ""))]
4782   ""
4783   "@
4784    b%!%* %P0
4785    b%!%* %P0
4786    j%!%* [%0]%&
4787    j%!%* [%0]
4788    j%! %P0"
4789   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4790    (set_attr "predicable" "yes,no,no,yes,yes")
4791    (set_attr "iscompact" "false,false,maybe,false,false")
4792    (set_attr "is_SIBCALL" "yes")]
4795 (define_insn "*sibcall_value_insn"
4796  [(set (match_operand 0 "dest_reg_operand" "")
4797        (call (mem:SI (match_operand:SI 1 "call_address_operand"
4798               "Cbp,Cbr,Rs5,Rsc,Cal"))
4799              (match_operand 2 "" "")))
4800   (simple_return)
4801   (use (match_operand 3 "" ""))]
4802   ""
4803   "@
4804    b%!%* %P1
4805    b%!%* %P1
4806    j%!%* [%1]%&
4807    j%!%* [%1]
4808    j%! %P1"
4809   [(set_attr "type" "call,call,call,call,call_no_delay_slot")
4810    (set_attr "predicable" "yes,no,no,yes,yes")
4811    (set_attr "iscompact" "false,false,maybe,false,false")
4812    (set_attr "is_SIBCALL" "yes")]
4815 (define_expand "prologue"
4816   [(pc)]
4817   ""
4819   arc_expand_prologue ();
4820   DONE;
4823 (define_expand "epilogue"
4824   [(pc)]
4825   ""
4827   arc_expand_epilogue (0);
4828   DONE;
4831 (define_expand "sibcall_epilogue"
4832   [(pc)]
4833   ""
4835   arc_expand_epilogue (1);
4836   DONE;
4839 ; Since the demise of REG_N_SETS, it is no longer possible to find out
4840 ; in the prologue / epilogue expanders how many times blink is set.
4841 ; Using df_regs_ever_live_p to decide if blink needs saving means that
4842 ; any explicit use of blink will cause it to be saved; hence we cannot
4843 ; represent the blink use in return / sibcall instructions themselves, and
4844 ; instead have to show it in EPILOGUE_USES and must explicitly
4845 ; forbid instructions that change blink in the return / sibcall delay slot.
4846 (define_insn "simple_return"
4847   [(simple_return)]
4848   "reload_completed"
4850   rtx reg
4851     = gen_rtx_REG (Pmode,
4852                    arc_return_address_register (arc_compute_function_type
4853                                                 (cfun)));
4855   if (TARGET_V2
4856       && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
4857   {
4858     return \"rtie\";
4859   }
4860   if (TARGET_PAD_RETURN)
4861     arc_pad_return ();
4862   output_asm_insn (\"j%!%* [%0]%&\", &reg);
4863   return \"\";
4865   [(set (attr "type")
4866         (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
4867                     (match_test "TARGET_V2"))
4868                (const_string "brcc_no_delay_slot")]
4869               (const_string "return")))
4870    ; predicable won't help here since the canonical rtl looks different
4871    ; for branches.
4872    (set (attr "cond")
4873         (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
4874                         (symbol_ref "ARC_FUNCTION_ILINK1"))
4875                     (match_test "TARGET_V2"))
4876                (const_string "nocond")]
4877               (const_string "canuse")))
4878   (set (attr "iscompact")
4879         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4880                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4881                (const_string "maybe")]
4882               (const_string "false")))
4883    (set (attr "length")
4884         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4885                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4886                (const_int 4)]
4887               (const_int 2)))])
4889 (define_insn "p_return_i"
4890   [(set (pc)
4891         (if_then_else (match_operator 0 "proper_comparison_operator"
4892                                       [(reg CC_REG) (const_int 0)])
4893                       (simple_return) (pc)))]
4894   "reload_completed
4895    && !(TARGET_V2
4896      && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
4898   rtx xop[2];
4899   xop[0] = operands[0];
4900   xop[1]
4901     = gen_rtx_REG (Pmode,
4902                    arc_return_address_register (arc_compute_function_type
4903                                                 (cfun)));
4905   if (TARGET_PAD_RETURN)
4906     arc_pad_return ();
4907   output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
4908   /* record the condition in case there is a delay insn.  */
4909   arc_ccfsm_record_condition (xop[0], false, insn, 0);
4910   return \"\";
4912   [(set_attr "type" "return")
4913    (set_attr "cond" "use")
4914    (set (attr "iscompact")
4915         (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
4916                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4917                (const_string "maybe")]
4918               (const_string "false")))
4919    (set (attr "length")
4920         (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
4921                    (symbol_ref "ARC_FUNCTION_NORMAL"))
4922                (const_int 4)
4923                (not (match_operand 0 "equality_comparison_operator" ""))
4924                (const_int 4)
4925                (eq_attr "delay_slot_filled" "yes")
4926                (const_int 4)]
4927               (const_int 2)))])
4929 (define_insn_and_split "eh_return"
4930   [(eh_return)
4931    (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc"))
4932    (clobber (match_scratch:SI 1  "=X,r"))
4933    (clobber (match_scratch:SI 2 "=&r,r"))]
4934   ""
4935   "#"
4936   "reload_completed"
4937   [(set (match_dup 2) (match_dup 0))]
4939   int offs = arc_return_slot_offset ();
4941   if (offs < 0)
4942     operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
4943   else
4944     {
4945       if (!register_operand (operands[0], Pmode)
4946           && !satisfies_constraint_C32 (operands[0]))
4947         {
4948           emit_move_insn (operands[1], operands[0]);
4949           operands[0] = operands[1];
4950         }
4951       rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
4952       if (!strict_memory_address_p (Pmode, addr))
4953         {
4954           emit_move_insn (operands[2], addr);
4955           addr = operands[2];
4956         }
4957       operands[2] = gen_frame_mem (Pmode, addr);
4958     }
4960   [(set_attr "length" "12")])
4962 ;; ??? #ifdefs in function.c require the presence of this pattern, with a
4963 ;; non-constant predicate.
4964 (define_expand "return"
4965   [(return)]
4966   "optimize < 0")
4968  ;; Comment in final.c (insn_current_reference_address) says
4969  ;; forward branch addresses are calculated from the next insn after branch
4970  ;; and for backward branches, it is calculated from the branch insn start.
4971  ;; The shortening logic here is tuned to accomodate this behavior
4972 ;; ??? This should be grokked by the ccfsm machinery.
4973 (define_insn "cbranchsi4_scratch"
4974   [(set (pc)
4975         (if_then_else (match_operator 0 "proper_comparison_operator"
4976                         [(match_operand:SI 1 "register_operand" "c,c, c")
4977                          (match_operand:SI 2 "nonmemory_operand" "L,c,?Cal")])
4978                       (label_ref (match_operand 3 "" ""))
4979                       (pc)))
4980    (clobber (match_operand 4 "cc_register" ""))]
4981    "(reload_completed
4982      || (TARGET_EARLY_CBRANCHSI
4983          && brcc_nolimm_operator (operands[0], VOIDmode)))
4984     && !CROSSING_JUMP_P (insn)"
4985    "*
4986      switch (get_attr_length (insn))
4987      {
4988        case 2: return \"br%d0%? %1, %2, %^%l3%&\";
4989        case 4: return \"br%d0%* %1, %B2, %^%l3\";
4990        case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode))
4991                  return \"br%d0%* %1, %B2, %^%l3\";
4992        /* FALLTHRU */
4993        case 6: case 10:
4994        case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\";
4995        default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable ();
4996      }
4997    "
4998   [(set_attr "cond" "clob, clob, clob")
4999    (set (attr "type")
5000         (if_then_else
5001           (match_test "valid_brcc_with_delay_p (operands)")
5002           (const_string "brcc")
5003           (const_string "brcc_no_delay_slot")))
5004    ; For forward branches, we need to account not only for the distance to
5005    ; the target, but also the difference between pcl and pc, the instruction
5006    ; length, and any delay insn, if present.
5007    (set
5008      (attr "length")
5009      (cond ; the outer cond does a test independent of branch shortening.
5010        [(match_operand 0 "brcc_nolimm_operator" "")
5011         (cond
5012           [(and (match_operand:CC_Z 4 "cc_register")
5013                 (eq_attr "delay_slot_filled" "no")
5014                 (ge (minus (match_dup 3) (pc)) (const_int -128))
5015                 (le (minus (match_dup 3) (pc))
5016                     (minus (const_int 122)
5017                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5018            (const_int 2)
5019            (and (ge (minus (match_dup 3) (pc)) (const_int -256))
5020                 (le (minus (match_dup 3) (pc))
5021                     (minus (const_int 244)
5022                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5023            (const_int 4)
5024            (and (match_operand:SI 1 "compact_register_operand" "")
5025                 (match_operand:SI 2 "compact_hreg_operand" ""))
5026            (const_int 6)]
5027           (const_int 8))]
5028          (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256))
5029                      (le (minus (match_dup 3) (pc)) (const_int 244)))
5030                 (const_int 8)
5031                 (and (match_operand:SI 1 "compact_register_operand" "")
5032                      (match_operand:SI 2 "compact_hreg_operand" ""))
5033                 (const_int 10)]
5034                (const_int 12))))
5035    (set (attr "iscompact")
5036         (if_then_else (match_test "get_attr_length (insn) & 2")
5037                       (const_string "true") (const_string "false")))])
5039 ; combiner pattern observed for unwind-dw2-fde.c:linear_search_fdes.
5040 (define_insn "*bbit"
5041   [(set (pc)
5042         (if_then_else
5043           (match_operator 3 "equality_comparison_operator"
5044             [(zero_extract:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
5045                               (const_int 1)
5046                               (match_operand:SI 2 "nonmemory_operand" "L,Lc"))
5047              (const_int 0)])
5048           (label_ref (match_operand 0 "" ""))
5049           (pc)))
5050    (clobber (reg:CC_ZN CC_REG))]
5051   "!CROSSING_JUMP_P (insn)"
5053   switch (get_attr_length (insn))
5054     {
5055       case 4: return (GET_CODE (operands[3]) == EQ
5056                       ? \"bbit0%* %1,%2,%0\" : \"bbit1%* %1,%2,%0\");
5057       case 6:
5058       case 8: return \"btst%? %1,%2\n\tb%d3%* %0; bbit out of range\";
5059       default: gcc_unreachable ();
5060     }
5062   [(set_attr "type" "brcc")
5063    (set_attr "cond" "clob")
5064    (set (attr "length")
5065         (cond [(and (ge (minus (match_dup 0) (pc)) (const_int -254))
5066                     (le (minus (match_dup 0) (pc))
5067                     (minus (const_int 248)
5068                            (symbol_ref "get_attr_delay_slot_length (insn)"))))
5069                (const_int 4)
5070                (eq (symbol_ref "which_alternative") (const_int 0))
5071                (const_int 6)]
5072               (const_int 8)))
5073    (set (attr "iscompact")
5074         (if_then_else (match_test "get_attr_length (insn) == 6")
5075                       (const_string "true") (const_string "false")))])
5077 ; ??? When testing a bit from a DImode register, combine creates a
5078 ; zero_extract in DImode.  This goes via an AND with a DImode constant,
5079 ; so can only be observed on 64 bit hosts.
5080 (define_insn_and_split "*bbit_di"
5081   [(set (pc)
5082         (if_then_else
5083           (match_operator 3 "equality_comparison_operator"
5084             [(zero_extract:DI (match_operand:SI 1 "register_operand" "Rcqq,c")
5085                               (const_int 1)
5086                               (match_operand 2 "immediate_operand" "L,L"))
5087              (const_int 0)])
5088           (label_ref (match_operand 0 "" ""))
5089           (pc)))
5090    (clobber (reg:CC_ZN CC_REG))]
5091   "!CROSSING_JUMP_P (insn)"
5092   "#"
5093   ""
5094   [(parallel
5095      [(set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 0)) (pc)))
5096       (clobber (reg:CC_ZN CC_REG))])]
5098   rtx xtr;
5100   xtr = gen_rtx_ZERO_EXTRACT (SImode, operands[1], const1_rtx, operands[2]);
5101   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
5102                                 xtr, const0_rtx);
5105 ; operand 0 is the loop count pseudo register
5106 ; operand 1 is the loop end pattern
5107 (define_expand "doloop_begin"
5108   [(use (match_operand 0 "register_operand" ""))
5109    (use (match_operand 1 "" ""))]
5110   ""
5112   /* Using the INSN_UID of the loop end pattern to identify it causes
5113      trouble with -fcompare-debug, so allocate a debug-independent
5114      id instead.  We use negative numbers so that we can use the same
5115      slot in doloop_end_i where we later store a CODE_LABEL_NUMBER, and
5116      still be able to tell what kind of number this is.  */
5117   static HOST_WIDE_INT loop_end_id = 0;
5119   rtx id = GEN_INT (--loop_end_id);
5120   XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
5121   emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
5122                                  const0_rtx, const0_rtx));
5123   DONE;
5126 ; ??? can't describe the insn properly as then the optimizers try to
5127 ; hoist the SETs.
5128 ;(define_insn "doloop_begin_i"
5129 ;  [(set (reg:SI LP_START) (pc))
5130 ;   (set (reg:SI LP_END) (unspec:SI [(pc)] UNSPEC_ARC_LP))
5131 ;   (use (match_operand 0 "const_int_operand" "n"))]
5132 ;  ""
5133 ;  "lp .L__GCC__LP%0"
5136 ; The operands of doloop_end_i are also read / written by arc_reorg with
5137 ; XVECEXP (PATTERN (lp, 0, N), so if you want to change the pattern, you
5138 ; might have to adjust arc_reorg.
5139 ; operands 0 / 2 are supplied by the expander, 1, 3 and 4 are filled in
5140 ; by arc_reorg.  arc_reorg might also alter operand 0.
5142 ; N in XVECEXP PATTERN (lp, 0 N)
5143 ;  V              rtl                 purpose
5144 ;  0           unspec UNSPEC_ARC_LP identify pattern
5145 ;  1           clobber LP_START     show LP_START is set
5146 ;  2           clobber LP_END       show LP_END is set
5147 ;  3           use operand0         loop count pseudo register
5148 ;  4           use operand1         before arc_reorg: -id
5149 ;                                   after : CODE_LABEL_NUMBER of loop top label
5150 ;  5           use operand2         INSN_UID of loop end insn
5151 ;  6           use operand3         loop setup not at start (1 above, 2 below)
5152 ;  7           use operand4         LABEL_REF of top label, if not
5153 ;                                   immediately following
5154 ; If operand1 is still zero after arc_reorg, this is an orphaned loop
5155 ; instruction that was not at the start of the loop.
5156 ; There is no point is reloading this insn - then lp_count would still not
5157 ; be available for the loop end.
5158 (define_insn "doloop_begin_i"
5159   [(unspec:SI [(pc)] UNSPEC_ARC_LP)
5160    (clobber (reg:SI LP_START))
5161    (clobber (reg:SI LP_END))
5162    (use (match_operand:SI 0 "register_operand" "l,l,????*X"))
5163    (use (match_operand 1 "const_int_operand" "n,n,C_0"))
5164    (use (match_operand 2 "const_int_operand" "n,n,X"))
5165    (use (match_operand 3 "const_int_operand" "C_0,n,X"))
5166    (use (match_operand 4 "const_int_operand" "C_0,X,X"))]
5167   ""
5169   rtx_insn *scan;
5170   int len, size = 0;
5171   int n_insns = 0;
5172   rtx loop_start = operands[4];
5174   if (CONST_INT_P (loop_start))
5175     loop_start = NULL_RTX;
5176   /* Size implications of the alignment will be taken care of by the
5177      alignment inserted at the loop start.  */
5178   if (LOOP_ALIGN (0) && INTVAL (operands[1]))
5179     {
5180       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5181       arc_clear_unalign ();
5182     }
5183   if (!INTVAL (operands[1]))
5184     return "; LITTLE LOST LOOP";
5185   if (loop_start && flag_pic)
5186     {
5187       /* ??? Can do better for when a scratch register
5188          is known.  But that would require extra testing.  */
5189       return "push_s r0\;add r0,pcl,%4@pcl\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1@pcl\;sr r0,[3]; LP_END\;pop_s r0";
5190     }
5191   /* Check if the loop end is in range to be set by the lp instruction.  */
5192   size = INTVAL (operands[3]) < 2 ? 0 : 2048;
5193   for (scan = insn; scan && size < 2048; scan = NEXT_INSN (scan))
5194     {
5195       if (!INSN_P (scan))
5196         continue;
5197       if (recog_memoized (scan) == CODE_FOR_doloop_end_i
5198           && (XEXP (XVECEXP (PATTERN (scan), 0, 4), 0)
5199               == XEXP (XVECEXP (PATTERN (insn), 0, 4), 0)))
5200         break;
5201       len = get_attr_length (scan);
5202       size += len;
5203     }
5204   /* Try to verify that there are at least three instruction fetches
5205      between the loop setup and the first encounter of the loop end.  */
5206   for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan))
5207     {
5208       if (!INSN_P (scan))
5209         continue;
5210       if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (scan)))
5211         scan = seq->insn (0);
5212       if (JUMP_P (scan))
5213         {
5214           if (recog_memoized (scan) != CODE_FOR_doloop_end_i)
5215             {
5216               n_insns += 2;
5217               if (simplejump_p (scan))
5218                 {
5219                   scan = as_a <rtx_insn *> (XEXP (SET_SRC (PATTERN (scan)), 0));
5220                   continue;
5221                 }
5223               rtx lab = JUMP_LABEL (scan);
5224               if (!lab)
5225                 break;
5227               rtx_insn *next_scan
5228                 = next_active_insn (NEXT_INSN (PREV_INSN (scan)));
5229               if (next_scan
5230                   && recog_memoized (next_scan) != CODE_FOR_doloop_begin_i)
5231                 break;
5233               /* JUMP_LABEL might be simple_return instead if an insn.  */
5234               if (!INSN_P (lab))
5235                 {
5236                   n_insns++;
5237                   break;
5238                 }
5240               rtx_insn *next_lab = next_active_insn (as_a<rtx_insn *> (lab));
5241               if (next_lab
5242                   && recog_memoized (next_lab) != CODE_FOR_doloop_begin_i)
5243                 break;
5245                 n_insns++;
5246             }
5247           break;
5248         }
5249       len = get_attr_length (scan);
5250       /* Size estimation of asms assumes that each line which is nonempty
5251          codes an insn, and that each has a long immediate.  For minimum insn
5252          count, assume merely that a nonempty asm has at least one insn.  */
5253       if (GET_CODE (PATTERN (scan)) == ASM_INPUT
5254           || asm_noperands (PATTERN (scan)) >= 0)
5255         n_insns += (len != 0);
5256       else
5257         n_insns += (len > 4 ? 2 : (len ? 1 : 0));
5258     }
5259   if (LOOP_ALIGN (0))
5260     {
5261       asm_fprintf (asm_out_file, "\t.p2align %d\\n", LOOP_ALIGN (0));
5262       arc_clear_unalign ();
5263     }
5264   gcc_assert (n_insns || GET_CODE (next_nonnote_insn (insn)) == CODE_LABEL);
5265   if (size >= 2048 || (TARGET_ARC600 && n_insns == 1) || loop_start)
5266     {
5267       if (flag_pic)
5268         {
5269           /* ??? Can do better for when a scratch register
5270              is known.  But that would require extra testing.  */
5271           arc_clear_unalign ();
5272           return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1@pcl\;sr r0,[3]; LP_END\;pop_s r0";
5273         }
5274       output_asm_insn ((size < 2048
5275                         ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"),
5276                        operands);
5277       output_asm_insn (loop_start
5278                        ? "sr %4,[2]; LP_START" : "sr 0f,[2]; LP_START",
5279                        operands);
5280       if (TARGET_ARC600 && n_insns < 1)
5281         output_asm_insn ("nop", operands);
5282       return (TARGET_ARC600 && n_insns < 3) ? "nop_s\;nop_s\;0:" : "0:";
5283     }
5284   else if (TARGET_ARC600 && n_insns < 3)
5285     {
5286       /* At least four instructions are needed between the setting of LP_COUNT
5287          and the loop end - but the lp instruction qualifies as one.  */
5288       rtx_insn *prev = prev_nonnote_insn (insn);
5290       if (!INSN_P (prev) || dead_or_set_regno_p (prev, LP_COUNT))
5291         output_asm_insn ("nop", operands);
5292     }
5293   return "lp .L__GCC__LP%1";
5295   [(set_attr "type" "loop_setup")
5296    (set_attr_alternative "length"
5297 ;     FIXME: length is usually 4, but we need branch shortening
5298 ;     to get this right.
5299 ;     [(if_then_else (match_test "TARGET_ARC600") (const_int 16) (const_int 4))
5300      [(if_then_else (match_test "flag_pic") (const_int 24) (const_int 16))
5301       (if_then_else (match_test "flag_pic") (const_int 28) (const_int 16))
5302       (const_int 0)])]
5303   ;; ??? we should really branch shorten this insn, but then we'd
5304   ;; need a proper label first.  N.B. the end label can not only go out
5305   ;; of range when it is far away, but also when it precedes the loop -
5306   ;; which, unfortunately, it sometimes does, when the loop "optimizer"
5307   ;; messes things up.
5310 ; operand 0 is the loop count pseudo register
5311 ; operand 1 is the label to jump to at the top of the loop
5312 ; Use this for the ARC600 and ARC700.
5313 ; ??? ARC600 might want to check if the loop has few iteration and only a
5314 ; single insn - loop setup is expensive then.
5315 (define_expand "doloop_end"
5316   [(use (match_operand 0 "register_operand" ""))
5317    (use (label_ref (match_operand 1 "" "")))]
5318   "!TARGET_ARC601"
5320   /* We could do smaller bivs with biv widening, and wider bivs by having
5321      a high-word counter in an outer loop - but punt on this for now.  */
5322   if (GET_MODE (operands[0]) != SImode)
5323     FAIL;
5324   emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
5325   DONE;
5328 (define_insn_and_split "doloop_end_i"
5329   [(set (pc)
5330         (if_then_else (ne (match_operand:SI 0 "shouldbe_register_operand" "+l,*c,*m")
5331                            (const_int 1))
5332                       (label_ref (match_operand 1 "" ""))
5333                       (pc)))
5334    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5335    (use (reg:SI LP_START))
5336    (use (reg:SI LP_END))
5337    (use (match_operand 2 "const_int_operand" "n,???Cn0,???X"))
5338    (clobber (match_scratch:SI 3 "=X,X,&????r"))]
5339   ""
5340   "*
5342   rtx_insn *prev = prev_nonnote_insn (insn);
5344   /* If there is an immediately preceding label, we must output a nop,
5345      lest a branch to that label will fall out of the loop.
5346      ??? We could try to avoid this by claiming to have a delay slot if there
5347      is a preceding label, and outputting the delay slot insn instead, if
5348      present.
5349      Or we could have some optimization that changes the source edge to update
5350      the loop count and jump to the loop start instead.  */
5351   /* For ARC600, we must also prevent jumps inside the loop and jumps where
5352      the loop counter value is live at the target from being directly at the
5353      loop end.  Being sure that the loop counter is dead at the target is
5354      too much hair - we can't rely on data flow information at this point -
5355      so insert a nop for all branches.
5356      The ARC600 also can't read the loop counter in the last insn of a loop.  */
5357   if (LABEL_P (prev))
5358     output_asm_insn (\"nop%?\", operands);
5359   return \"\\n.L__GCC__LP%2: ; loop end, start is %1\";
5361   "&& memory_operand (operands[0], SImode)"
5362   [(pc)]
5364   emit_move_insn (operands[3], operands[0]);
5365   emit_jump_insn (gen_doloop_fallback_m (operands[3], operands[1], operands[0]));
5366   DONE;
5368   [(set_attr "type" "loop_end")
5369    (set (attr "length")
5370         (if_then_else (match_test "LABEL_P (prev_nonnote_insn (insn))")
5371                       (const_int 4) (const_int 0)))]
5374 ; This pattern is generated by arc_reorg when there is no recognizable
5375 ; loop start.
5376 (define_insn "*doloop_fallback"
5377   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+r,!w")
5378                                 (const_int 1))
5379                            (label_ref (match_operand 1 "" ""))
5380                            (pc)))
5381    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
5382    ; avoid fooling the loop optimizer into assuming this is a special insn.
5383   "reload_completed"
5384   "*return get_attr_length (insn) == 8
5385    ? \"brne.d %0,1,%1\;sub %0,%0,1\"
5386    : \"breq %0,1,0f\;b.d %1\;sub %0,%0,1\\n0:\";"
5387   [(set (attr "length")
5388         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -256))
5389                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5390                       (const_int 8) (const_int 12)))
5391    (set_attr "type" "brcc_no_delay_slot")
5392    (set_attr "cond" "nocond")]
5395 ; reload can't make output reloads for jump insns, so we have to do this by hand.
5396 (define_insn "doloop_fallback_m"
5397   [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "+&r")
5398                                 (const_int 1))
5399                            (label_ref (match_operand 1 "" ""))
5400                            (pc)))
5401    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))
5402    (set (match_operand:SI 2 "memory_operand" "=m")
5403         (plus:SI (match_dup 0) (const_int -1)))]
5404    ; avoid fooling the loop optimizer into assuming this is a special insn.
5405   "reload_completed"
5406   "*return get_attr_length (insn) == 12
5407    ? \"sub %0,%0,1\;brne.d %0,0,%1\;st%U2%V2 %0,%2\"
5408    : \"sub %0,%0,1\;breq %0,0,0f\;b.d %1\\n0:\tst%U2%V2 %0,%2\";"
5409   [(set (attr "length")
5410         (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -252))
5411                            (le (minus (match_dup 1) (pc)) (const_int 244)))
5412                       (const_int 12) (const_int 16)))
5413    (set_attr "type" "brcc_no_delay_slot")
5414    (set_attr "cond" "nocond")]
5417 (define_expand "movmemsi"
5418   [(match_operand:BLK 0 "" "")
5419    (match_operand:BLK 1 "" "")
5420    (match_operand:SI 2 "nonmemory_operand" "")
5421    (match_operand 3 "immediate_operand" "")]
5422   ""
5423   "if (arc_expand_movmem (operands)) DONE; else FAIL;")
5425 ;; Close http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35803 if this works
5426 ;; to the point that we can generate cmove instructions.
5427 (define_expand "cbranch<mode>4"
5428   [(set (reg:CC CC_REG)
5429         (compare:CC (match_operand:SDF 1 "register_operand" "")
5430                     (match_operand:SDF 2 "register_operand" "")))
5431    (set (pc)
5432         (if_then_else
5433          (match_operator 0 "comparison_operator" [(reg CC_REG)
5434                                                       (const_int 0)])
5435          (label_ref (match_operand 3 "" ""))
5436          (pc)))]
5438   "TARGET_FP_SP_BASE || TARGET_OPTFPE"
5440   gcc_assert (XEXP (operands[0], 0) == operands[1]);
5441   gcc_assert (XEXP (operands[0], 1) == operands[2]);
5442   operands[0] = gen_compare_reg (operands[0], VOIDmode);
5443   emit_jump_insn (gen_branch_insn (operands[3], operands[0]));
5444   DONE;
5447 (define_expand "cmp_float"
5448   [(parallel [(set (match_operand 0 "") (match_operand 1 ""))
5449               (clobber (reg:SI RETURN_ADDR_REGNUM))
5450               (clobber (reg:SI R12_REG))])]
5451   ""
5452   "")
5454 (define_mode_iterator OPTFPE_CMP [CC_Z CC_FP_GT CC_FP_GE CC_FP_UNEQ CC_FP_ORD])
5455 (define_mode_attr cmp [(CC_Z "eq") (CC_FP_GT "gt") (CC_FP_GE "ge")
5456                        (CC_FP_UNEQ "uneq") (CC_FP_ORD "ord")])
5458 (define_insn "*cmpsf_<cmp>"
5459   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:SF 0) (reg:SF 1)))
5460    (clobber (reg:SI RETURN_ADDR_REGNUM))
5461    (clobber (reg:SI R12_REG))]
5462   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_SPFP)
5463    && SFUNC_CHECK_PREDICABLE"
5464   "*return arc_output_libcall (\"__<cmp>sf2\");"
5465   [(set_attr "is_sfunc" "yes")
5466    (set_attr "predicable" "yes")])
5468 ;; N.B. for "*cmpdf_ord":
5469 ;; double precision fpx sets bit 31 for NaNs.  We need bit 51 set
5470 ;; for the floating point emulation to recognize the NaN.
5471 (define_insn "*cmpdf_<cmp>"
5472   [(set (reg:OPTFPE_CMP CC_REG) (compare:OPTFPE_CMP (reg:DF 0) (reg:DF 2)))
5473    (clobber (reg:SI RETURN_ADDR_REGNUM))
5474    (clobber (reg:SI R12_REG))]
5475   "TARGET_OPTFPE && (!TARGET_ARGONAUT_SET || !TARGET_DPFP)
5476    && SFUNC_CHECK_PREDICABLE"
5477   "*return arc_output_libcall (\"__<cmp>df2\");"
5478   [(set_attr "is_sfunc" "yes")
5479    (set_attr "predicable" "yes")])
5481 (define_insn "abssf2"
5482   [(set (match_operand:SF 0 "dest_reg_operand"    "=Rcq#q,Rcw,w")
5483         (abs:SF (match_operand:SF 1 "register_operand" "0,  0,c")))]
5484   ""
5485   "bclr%? %0,%1,31%&"
5486   [(set_attr "type" "unary")
5487    (set_attr "iscompact" "maybe,false,false")
5488    (set_attr "length" "2,4,4")
5489    (set_attr "predicable" "no,yes,no")])
5491 (define_insn "negsf2"
5492   [(set (match_operand:SF 0 "dest_reg_operand" "=Rcw,w")
5493         (neg:SF (match_operand:SF 1 "register_operand" "0,c")))]
5494   ""
5495   "bxor%? %0,%1,31"
5496   [(set_attr "type" "unary")
5497    (set_attr "predicable" "yes,no")])
5499 ;; ??? Should this use arc_output_libcall and set is_sfunc?
5500 (define_insn "*millicode_thunk_st"
5501   [(match_parallel 0 "millicode_store_operation"
5502      [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
5503   ""
5505   output_asm_insn ("bl%* __st_r13_to_%0",
5506                    &SET_SRC (XVECEXP (operands[0], 0,
5507                                       XVECLEN (operands[0], 0) - 2)));
5508   return "";
5510   [(set_attr "type" "call")])
5512 (define_insn "*millicode_thunk_ld"
5513   [(match_parallel 0 "millicode_load_clob_operation"
5514      [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5515   ""
5517   output_asm_insn ("bl%* __ld_r13_to_%0",
5518                    &SET_DEST (XVECEXP (operands[0], 0,
5519                                        XVECLEN (operands[0], 0) - 2)));
5520   return "";
5522   [(set_attr "type" "call")])
5524 ; the sibthunk restores blink, so we use the return rtx.
5525 (define_insn "*millicode_sibthunk_ld"
5526   [(match_parallel 0 "millicode_load_operation"
5527      [(return)
5528       (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
5529       (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
5530   ""
5532   output_asm_insn ("b%* __ld_r13_to_%0_ret",
5533                    &SET_DEST (XVECEXP (operands[0], 0,
5534                                        XVECLEN (operands[0], 0) - 1)));
5535   return "";
5537   [(set_attr "type" "call")
5538    (set_attr "is_SIBCALL" "yes")])
5540 (define_insn "tls_load_tp_soft"
5541   [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF))
5542    (clobber (reg:SI RETURN_ADDR_REGNUM))]
5543   ""
5544   "*return arc_output_libcall (\"__read_tp\");"
5545   [(set_attr "is_sfunc" "yes")
5546    (set_attr "predicable" "yes")])
5548 (define_insn "tls_gd_get_addr"
5549   [(set (reg:SI R0_REG)
5550         (call:SI (mem:SI (unspec:SI [(match_operand:SI 0
5551                                       "symbolic_operand" "X,X")]
5552                           UNSPEC_TLS_GD))
5553                  (const_int 0)))
5554    (clobber (reg:SI RETURN_ADDR_REGNUM))]
5555   ""
5556   ".tls_gd_ld %0`bl%* __tls_get_addr@plt"
5557   [(set_attr "type" "call")
5558    ; With TARGET_MEDIUM_CALLS, plt calls are not predicable.
5559    (set_attr "predicable" "no")])
5561 ;; For thread pointer builtins
5562 (define_expand "get_thread_pointersi"
5563   [(set (match_operand:SI 0 "register_operand") (match_dup 1))]
5564  ""
5565  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5567 (define_expand "set_thread_pointersi"
5568   [(set (match_dup 1) (match_operand:SI 0 "register_operand"))]
5569  ""
5570  "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);")
5572 ;; If hardware floating point is available, don't define a negdf pattern;
5573 ;; it would be something like:
5574 ;;(define_insn "negdf2"
5575 ;;  [(set (match_operand:DF 0 "register_operand" "=w,w,D,?r")
5576 ;;      (neg:DF (match_operand:DF 1 "register_operand" "0,c,D,D")))
5577 ;;   (clobber (match_scratch:DF 2 "=X,X,X,X,D1"))]
5578 ;;  ""
5579 ;;  "@
5580 ;;   bxor%? %H0,%H1,31
5581 ;;   bxor %H0,%H1,31 ` mov %L0,%L1
5582 ;;   drsubh%F0%F1 0,0,0
5583 ;;   drsubh%F2%F1 %H0,0,0 ` dexcl%F2 %L0,%H0,%L0"
5584 ;;  [(set_attr "type" "unary,unary,dpfp_addsub,dpfp_addsub")
5585 ;;   (set_attr "iscompact" "false,false,false,false")
5586 ;;   (set_attr "length" "4,4,8,12")
5587 ;;   (set_attr "cond" "canuse,nocond,nocond,nocond")])
5588 ;; and this suffers from always requiring a long immediate when using
5589 ;; the floating point hardware.
5590 ;; We then want the sub[sd]f patterns to be used, so that we can load the
5591 ;; constant zero efficiently into a register when we want to do the
5592 ;; computation using the floating point hardware.  There should be a special
5593 ;; subdf alternative that matches a zero operand 1, which then can allow
5594 ;; to use bxor to flip the high bit of an integer register.
5595 ;; ??? we actually can't use the floating point hardware for neg, because
5596 ;; this would not work right for -0.  OTOH optabs.c has already code
5597 ;; to synthesyze negate by flipping the sign bit.
5599 ;;V2 instructions
5600 (define_insn "bswapsi2"
5601   [(set (match_operand:SI 0 "register_operand"           "= r,r")
5602         (bswap:SI (match_operand:SI 1 "nonmemory_operand" "rL,Cal")))]
5603   "TARGET_V2 && TARGET_SWAP"
5604   "swape %0, %1"
5605   [(set_attr "length" "4,8")
5606    (set_attr "type" "two_cycle_core")])
5608 (define_expand "prefetch"
5609   [(prefetch (match_operand:SI 0 "address_operand" "")
5610              (match_operand:SI 1 "const_int_operand" "")
5611              (match_operand:SI 2 "const_int_operand" ""))]
5612   "TARGET_HS"
5613   "")
5615 (define_insn "prefetch_1"
5616   [(prefetch (match_operand:SI 0 "register_operand" "r")
5617              (match_operand:SI 1 "const_int_operand" "n")
5618              (match_operand:SI 2 "const_int_operand" "n"))]
5619   "TARGET_HS"
5620   {
5621    if (INTVAL (operands[1]))
5622       return "prefetchw [%0]";
5623    else
5624       return "prefetch [%0]";
5625   }
5626   [(set_attr "type" "load")
5627    (set_attr "length" "4")])
5629 (define_insn "prefetch_2"
5630   [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r,r,r")
5631                       (match_operand:SI 1 "nonmemory_operand" "r,Cm2,Cal"))
5632              (match_operand:SI 2 "const_int_operand" "n,n,n")
5633              (match_operand:SI 3 "const_int_operand" "n,n,n"))]
5634   "TARGET_HS"
5635   {
5636    if (INTVAL (operands[2]))
5637       return "prefetchw [%0, %1]";
5638    else
5639       return "prefetch [%0, %1]";
5640   }
5641   [(set_attr "type" "load")
5642    (set_attr "length" "4,4,8")])
5644 (define_insn "prefetch_3"
5645   [(prefetch (match_operand:SI 0 "address_operand" "p")
5646              (match_operand:SI 1 "const_int_operand" "n")
5647              (match_operand:SI 2 "const_int_operand" "n"))]
5648   "TARGET_HS"
5649   {
5650    operands[0] = gen_rtx_MEM (SImode, operands[0]);
5651    if (INTVAL (operands[1]))
5652       return "prefetchw%U0 %0";
5653    else
5654       return "prefetch%U0 %0";
5655    }
5656   [(set_attr "type" "load")
5657    (set_attr "length" "8")])
5659 (define_insn "divsi3"
5660   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5661         (div:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5662                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5663   "TARGET_DIVREM"
5664   "div%? %0, %1, %2"
5665   [(set_attr "length" "4,4,8,4,4,4,8,8")
5666    (set_attr "iscompact" "false")
5667    (set_attr "type" "div_rem")
5668    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5669    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5670    ])
5672 (define_insn "udivsi3"
5673   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5674         (udiv:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5675                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5676   "TARGET_DIVREM"
5677   "divu%? %0, %1, %2"
5678   [(set_attr "length" "4,4,8,4,4,4,8,8")
5679    (set_attr "iscompact" "false")
5680    (set_attr "type" "div_rem")
5681    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5682    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5683    ])
5685 (define_insn "modsi3"
5686   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r,r,r,  r,  r")
5687         (mod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5688                 (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5689   "TARGET_DIVREM"
5690   "rem%? %0, %1, %2"
5691   [(set_attr "length" "4,4,8,4,4,4,8,8")
5692    (set_attr "iscompact" "false")
5693    (set_attr "type" "div_rem")
5694    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5695    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5696    ])
5698 (define_insn "umodsi3"
5699   [(set (match_operand:SI 0 "register_operand"          "=r,r,  r,r,r,r,  r,  r")
5700         (umod:SI (match_operand:SI 1 "nonmemory_operand" "0,r,Cal,0,r,0,  0,  r")
5701                  (match_operand:SI 2 "nonmemory_operand" "r,r,  r,L,L,I,Cal,Cal")))]
5702   "TARGET_DIVREM"
5703   "remu%? %0, %1, %2"
5704   [(set_attr "length" "4,4,8,4,4,4,8,8")
5705    (set_attr "iscompact" "false")
5706    (set_attr "type" "div_rem")
5707    (set_attr "predicable" "yes,no,no,yes,no,no,yes,no")
5708    (set_attr "cond" "canuse,nocond,nocond,canuse,nocond,nocond,canuse,nocond")
5709    ])
5711 ;; SETcc instructions
5712 (define_code_iterator arcCC_cond [eq ne gt lt ge le])
5714 (define_insn "arcset<code>"
5715   [(set (match_operand:SI 0 "register_operand"                "=r,r,r,r,r,r,r")
5716         (arcCC_cond:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,0,r")
5717                        (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,n,n")))]
5718   "TARGET_V2 && TARGET_CODE_DENSITY"
5719   "set<code>%? %0, %1, %2"
5720   [(set_attr "length" "4,4,4,4,4,8,8")
5721    (set_attr "iscompact" "false")
5722    (set_attr "type" "compare")
5723    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5724    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5725    ])
5727 (define_insn "arcsetltu"
5728   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5729         (ltu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5730                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5731   "TARGET_V2 && TARGET_CODE_DENSITY"
5732   "setlo%? %0, %1, %2"
5733   [(set_attr "length" "4,4,4,4,4,8,8")
5734    (set_attr "iscompact" "false")
5735    (set_attr "type" "compare")
5736    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5737    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5738    ])
5740 (define_insn "arcsetgeu"
5741   [(set (match_operand:SI 0 "register_operand"         "=r,r,r,r,r,  r,  r")
5742         (geu:SI (match_operand:SI 1 "register_operand"  "0,r,0,r,0,  0,  r")
5743                 (match_operand:SI 2 "nonmemory_operand" "r,r,L,L,I,  n,  n")))]
5744   "TARGET_V2 && TARGET_CODE_DENSITY"
5745   "seths%? %0, %1, %2"
5746   [(set_attr "length" "4,4,4,4,4,8,8")
5747    (set_attr "iscompact" "false")
5748    (set_attr "type" "compare")
5749    (set_attr "predicable" "yes,no,yes,no,no,yes,no")
5750    (set_attr "cond" "canuse,nocond,canuse,nocond,nocond,canuse,nocond")
5751    ])
5753 ;; Special cases of SETCC
5754 (define_insn_and_split "arcsethi"
5755   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5756         (gtu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5757                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5758   "TARGET_V2 && TARGET_CODE_DENSITY"
5759   "setlo%? %0, %2, %1"
5760   "reload_completed
5761    && CONST_INT_P (operands[2])
5762    && satisfies_constraint_C62 (operands[2])"
5763   [(const_int 0)]
5764   "{
5765     /* sethi a,b,u6 => seths a,b,u6 + 1.  */
5766     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5767     emit_insn (gen_arcsetgeu (operands[0], operands[1], operands[2]));
5768     DONE;
5769  }"
5770  [(set_attr "length" "4,4,4,8")
5771    (set_attr "iscompact" "false")
5772    (set_attr "type" "compare")
5773    (set_attr "predicable" "yes,no,no,no")
5774    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5777 (define_insn_and_split "arcsetls"
5778   [(set (match_operand:SI 0 "register_operand"         "=r,r,  r,r")
5779         (leu:SI (match_operand:SI 1 "register_operand"  "r,r,  r,r")
5780                 (match_operand:SI 2 "nonmemory_operand" "0,r,C62,n")))]
5781   "TARGET_V2 && TARGET_CODE_DENSITY"
5782   "seths%? %0, %2, %1"
5783   "reload_completed
5784    && CONST_INT_P (operands[2])
5785    && satisfies_constraint_C62 (operands[2])"
5786   [(const_int 0)]
5787   "{
5788     /* setls a,b,u6 => setlo a,b,u6 + 1.  */
5789     operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
5790     emit_insn (gen_arcsetltu (operands[0], operands[1], operands[2]));
5791     DONE;
5792  }"
5793  [(set_attr "length" "4,4,4,8")
5794    (set_attr "iscompact" "false")
5795    (set_attr "type" "compare")
5796    (set_attr "predicable" "yes,no,no,no")
5797    (set_attr "cond" "canuse,nocond,nocond,nocond")]
5800 ; Any mode that needs to be solved by secondary reload
5801 (define_mode_iterator SRI [QI HI])
5803 (define_expand "reload_<mode>_load"
5804   [(parallel [(match_operand:SRI 0 "register_operand" "=r")
5805               (match_operand:SRI 1 "memory_operand" "m")
5806               (match_operand:SI 2 "register_operand" "=&r")])]
5807   ""
5809  arc_secondary_reload_conv (operands[0], operands[1], operands[2], false);
5810  DONE;
5813 (define_expand "reload_<mode>_store"
5814   [(parallel [(match_operand:SRI 0 "memory_operand" "=m")
5815               (match_operand:SRI 1 "register_operand" "r")
5816               (match_operand:SI 2 "register_operand" "=&r")])]
5817   ""
5819  arc_secondary_reload_conv (operands[1], operands[0], operands[2], true);
5820  DONE;
5824 (define_insn "extzvsi"
5825   [(set (match_operand:SI 0 "register_operand"                  "=r  , r  , r, r, r")
5826         (zero_extract:SI (match_operand:SI 1 "register_operand"  "0  , r  , 0, 0, r")
5827                          (match_operand:SI 2 "const_int_operand" "C3p, C3p, i, i, i")
5828                          (match_operand:SI 3 "const_int_operand" "i  , i  , i, i, i")))]
5829   "TARGET_HS && TARGET_BARREL_SHIFTER"
5830   {
5831    int assemble_op2 = (((INTVAL (operands[2]) - 1) & 0x1f) << 5) | (INTVAL (operands[3]) & 0x1f);
5832    operands[2] = GEN_INT (assemble_op2);
5833    return "xbfu%? %0,%1,%2";
5834   }
5835   [(set_attr "type"       "shift")
5836    (set_attr "iscompact"  "false")
5837    (set_attr "length"     "4,4,4,8,8")
5838    (set_attr "predicable" "yes,no,no,yes,no")
5839    (set_attr "cond"       "canuse,nocond,nocond,canuse,nocond")])
5841 (define_insn "kflag"
5842   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "rL,I,Cal")]
5843                    VUNSPEC_ARC_KFLAG)]
5844   "TARGET_V2"
5845   "@
5846     kflag%? %0
5847     kflag %0
5848     kflag%? %S0"
5849   [(set_attr "length" "4,4,8")
5850    (set_attr "type" "misc,misc,misc")
5851    (set_attr "predicable" "yes,no,yes")
5852    (set_attr "cond" "clob,clob,clob")])
5854 (define_insn "clri"
5855   [(set (match_operand:SI  0 "dest_reg_operand" "=r")
5856         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "N")]
5857                             VUNSPEC_ARC_CLRI))]
5858   "TARGET_V2"
5859   "clri  %0"
5860   [(set_attr "length" "4")
5861    (set_attr "type" "misc")])
5863 (define_insn "ffs"
5864   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5865         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5866                             UNSPEC_ARC_FFS))]
5867   "TARGET_NORM && TARGET_V2"
5868   "@
5869    ffs \t%0, %1
5870    ffs \t%0, %S1"
5871   [(set_attr "length" "4,8")
5872    (set_attr "type" "two_cycle_core,two_cycle_core")])
5874 (define_insn "ffs_f"
5875   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5876         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5877                             UNSPEC_ARC_FFS))
5878    (set (reg:CC_ZN CC_REG)
5879         (compare:CC_ZN (match_dup 1) (const_int 0)))]
5880   "TARGET_NORM && TARGET_V2"
5881   "@
5882    ffs.f\t%0, %1
5883    ffs.f\t%0, %S1"
5884   [(set_attr "length" "4,8")
5885    (set_attr "type" "two_cycle_core,two_cycle_core")])
5887 (define_expand "ffssi2"
5888   [(parallel [(set (match_dup 2)
5889                    (unspec:SI [(match_operand:SI 1 "register_operand" "")]
5890                               UNSPEC_ARC_FFS))
5891               (set (reg:CC_ZN CC_REG)
5892                    (compare:CC_ZN (match_dup 1) (const_int 0)))])
5893    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
5894    (set (match_operand:SI 0 "dest_reg_operand" "")
5895         (if_then_else:SI (eq:SI (reg:CC_ZN CC_REG) (const_int 0))
5896                          (const_int 0)
5897                          (match_dup 2)))]
5898   "TARGET_NORM && TARGET_V2"
5899   {
5900    operands[2] = gen_reg_rtx (SImode);
5901    })
5903 (define_insn "fls"
5904   [(set (match_operand:SI  0 "dest_reg_operand" "=w,w")
5905         (unspec:SI [(match_operand:SI 1 "general_operand" "cL,Cal")]
5906                             UNSPEC_ARC_FLS))]
5907   "TARGET_NORM && TARGET_V2"
5908   "@
5909    fls \t%0, %1
5910    fls \t%0, %S1"
5911   [(set_attr "length" "4,8")
5912    (set_attr "type" "two_cycle_core,two_cycle_core")])
5914 (define_insn "seti"
5915   [(unspec_volatile:SI [(match_operand:SI 0 "general_operand" "rL")]
5916                        VUNSPEC_ARC_SETI)]
5917   "TARGET_V2"
5918   "seti  %0"
5919   [(set_attr "length" "4")
5920    (set_attr "type" "misc")])
5922 ;; FPU/FPX expands
5924 ;;add
5925 (define_expand "addsf3"
5926   [(set (match_operand:SF 0 "register_operand"           "")
5927         (plus:SF (match_operand:SF 1 "nonmemory_operand" "")
5928                  (match_operand:SF 2 "nonmemory_operand" "")))]
5929   "TARGET_FP_SP_BASE || TARGET_SPFP"
5930   "
5931   if (!register_operand (operands[1], SFmode)
5932       && !register_operand (operands[2], SFmode))
5933     operands[1] = force_reg (SFmode, operands[1]);
5934   ")
5936 ;;sub
5937 (define_expand "subsf3"
5938   [(set (match_operand:SF 0 "register_operand"            "")
5939         (minus:SF (match_operand:SF 1 "nonmemory_operand" "")
5940                   (match_operand:SF 2 "nonmemory_operand" "")))]
5941   "TARGET_FP_SP_BASE || TARGET_SPFP"
5942   "
5943   if (!register_operand (operands[1], SFmode)
5944       && !register_operand (operands[2], SFmode))
5945     operands[1] = force_reg (SFmode, operands[1]);
5946   ")
5948 ;;mul
5949 (define_expand "mulsf3"
5950   [(set (match_operand:SF 0 "register_operand"           "")
5951         (mult:SF (match_operand:SF 1 "nonmemory_operand" "")
5952                  (match_operand:SF 2 "nonmemory_operand" "")))]
5953   "TARGET_FP_SP_BASE || TARGET_SPFP"
5954   "
5955   if (!register_operand (operands[1], SFmode)
5956       && !register_operand (operands[2], SFmode))
5957     operands[1] = force_reg (SFmode, operands[1]);
5958   ")
5960 ;;add
5961 (define_expand "adddf3"
5962   [(set (match_operand:DF 0 "double_register_operand"           "")
5963         (plus:DF (match_operand:DF 1 "double_register_operand"  "")
5964                  (match_operand:DF 2 "nonmemory_operand" "")))]
5965  "TARGET_FP_DP_BASE || TARGET_DPFP"
5967   if (TARGET_DPFP)
5968    {
5969     if (GET_CODE (operands[2]) == CONST_DOUBLE)
5970      {
5971         rtx first, second, tmp;
5972         split_double (operands[2], &first, &second);
5973         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
5974         emit_insn (gen_adddf3_insn (operands[0], operands[1],
5975                                     operands[2], tmp, const0_rtx));
5976      }
5977     else
5978      emit_insn (gen_adddf3_insn (operands[0], operands[1],
5979                                  operands[2], const1_rtx, const1_rtx));
5980    DONE;
5981   }
5982  else if (TARGET_FP_DP_BASE)
5983   {
5984    if (!even_register_operand (operands[2], DFmode))
5985       operands[2] = force_reg (DFmode, operands[2]);
5987    if (!even_register_operand (operands[1], DFmode))
5988       operands[1] = force_reg (DFmode, operands[1]);
5989   }
5990  else
5991   gcc_unreachable ();
5992  ")
5994 ;;sub
5995 (define_expand "subdf3"
5996   [(set (match_operand:DF 0 "double_register_operand"            "")
5997         (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
5998                   (match_operand:DF 2 "nonmemory_operand" "")))]
5999   "TARGET_FP_DP_BASE || TARGET_DPFP"
6000   "
6001    if (TARGET_DPFP)
6002     {
6003      if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE))
6004        operands[1] = force_reg (DFmode, operands[1]);
6005      if ((GET_CODE (operands[1]) == CONST_DOUBLE)
6006           || GET_CODE (operands[2]) == CONST_DOUBLE)
6007       {
6008         rtx first, second, tmp;
6009         int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2);
6010         split_double (operands[const_index], &first, &second);
6011         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
6012         emit_insn (gen_subdf3_insn (operands[0], operands[1],
6013                                     operands[2], tmp, const0_rtx));
6014       }
6015     else
6016      emit_insn (gen_subdf3_insn (operands[0], operands[1],
6017                                  operands[2], const1_rtx, const1_rtx));
6018     DONE;
6019    }
6020   else if (TARGET_FP_DP_BASE)
6021    {
6022     if (!even_register_operand (operands[2], DFmode))
6023        operands[2] = force_reg (DFmode, operands[2]);
6025     if (!even_register_operand (operands[1], DFmode))
6026        operands[1] = force_reg (DFmode, operands[1]);
6027    }
6028   else
6029    gcc_unreachable ();
6030   ")
6032 ;;mul
6033 (define_expand "muldf3"
6034   [(set (match_operand:DF 0 "double_register_operand"           "")
6035         (mult:DF (match_operand:DF 1 "double_register_operand"  "")
6036                  (match_operand:DF 2 "nonmemory_operand" "")))]
6037   "TARGET_FP_DP_BASE || TARGET_DPFP"
6038   "
6039    if (TARGET_DPFP)
6040     {
6041      if (GET_CODE (operands[2]) == CONST_DOUBLE)
6042       {
6043         rtx first, second, tmp;
6044         split_double (operands[2], &first, &second);
6045         tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second);
6046         emit_insn (gen_muldf3_insn (operands[0], operands[1],
6047                                     operands[2], tmp, const0_rtx));
6048       }
6049      else
6050       emit_insn (gen_muldf3_insn (operands[0], operands[1],
6051                                   operands[2], const1_rtx, const1_rtx));
6052     DONE;
6053    }
6054   else if (TARGET_FP_DP_BASE)
6055    {
6056     if (!even_register_operand (operands[2], DFmode))
6057        operands[2] = force_reg (DFmode, operands[2]);
6059     if (!even_register_operand (operands[1], DFmode))
6060        operands[1] = force_reg (DFmode, operands[1]);
6061    }
6062   else
6063    gcc_unreachable ();
6064  ")
6066 ;;div
6067 (define_expand "divsf3"
6068   [(set (match_operand:SF 0 "register_operand"        "")
6069         (div:SF (match_operand:SF 1 "nonmemory_operand" "")
6070                 (match_operand:SF 2 "nonmemory_operand" "")))]
6071   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
6072   "
6073   if (TARGET_FPX_QUARK)
6074    {
6075      operands[1] = force_reg (SFmode, operands[1]);
6076      operands[2] = force_reg (SFmode, operands[2]);
6077    }
6078   else
6079    {
6080      if (!register_operand (operands[1], SFmode)
6081         && !register_operand (operands[2], SFmode))
6082        operands[1] = force_reg (SFmode, operands[1]);
6083    }
6084   ")
6086 ;; Square root
6087 (define_expand "sqrtsf2"
6088   [(set (match_operand:SF 0 "register_operand"           "")
6089         (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))]
6090   "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT"
6091   "
6092   if (TARGET_FPX_QUARK)
6093    {
6094      operands[1] = force_reg (SFmode, operands[1]);
6095    }
6098 ;; SF->SI (using rounding towards zero)
6099 (define_expand "fix_truncsfsi2"
6100   [(set (match_operand:SI 0 "register_operand"                "")
6101         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))]
6102   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
6103   "")
6105 ;; SI->SF
6106 (define_expand "floatsisf2"
6107   [(set (match_operand:SF 0 "register_operand"            "")
6108         (float:SF (match_operand:SI 1 "register_operand" "")))]
6109   "TARGET_FPX_QUARK || TARGET_FP_SP_CONV"
6110   "")
6112 (define_expand "extzv"
6113   [(set (match_operand:SI 0 "register_operand" "")
6114         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
6115                          (match_operand:SI 2 "const_int_operand" "")
6116                          (match_operand:SI 3 "const_int_operand" "")))]
6117   "TARGET_NPS_BITOPS")
6119 ; We need a sanity check in the instuction predicate because combine
6120 ; will throw any old rubbish at us and see what sticks.
6121 (define_insn "*extzv_i"
6122   [(set (match_operand:SI 0 "register_operand" "=Rrq")
6123         (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
6124                          (match_operand:SI 2 "const_int_operand" "n")
6125                          (match_operand:SI 3 "const_int_operand" "n")))]
6126   "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
6127   "movb.cl %0,%1,0,%3,%2"
6128   [(set_attr "type" "shift")
6129    (set_attr "length" "4")])
6131 (define_expand "insv"
6132   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
6133                          (match_operand:SI 1 "const_int_operand" "")
6134                          (match_operand:SI 2 "const_int_operand" ""))
6135         (match_operand:SI 3 "nonmemory_operand" ""))]
6136   "TARGET_NPS_BITOPS"
6138   int size = INTVAL (operands[1]);
6140   if (size != 1 && size != 2 && size != 4 && size != 8)
6141     operands[3] = force_reg (SImode, operands[3]);
6144 (define_insn "*insv_i"
6145   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
6146                          (match_operand:SI 1 "const_int_operand" "C18,n")
6147                          (match_operand:SI 2 "const_int_operand" "n,n"))
6148         (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
6149   "TARGET_NPS_BITOPS
6150    && (register_operand (operands[3], SImode)
6151        || satisfies_constraint_C18 (operands[1]))"
6152   "@
6153    movbi %0,%0,%3,%2,%1
6154    movb %0,%0,%3,%2,0,%1"
6155   [(set_attr "type" "shift")
6156    (set_attr "length" "4")])
6158 (define_insn "*movb"
6159   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6160                          (match_operand:SI 1 "const_int_operand" "n")
6161                          (match_operand:SI 2 "const_int_operand" "n"))
6162         (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6163                          (match_dup 1)
6164                          (match_operand:SI 4 "const_int_operand" "n")))]
6165   "TARGET_NPS_BITOPS"
6166   "movb %0,%0,%3,%2,%4,%1"
6167   [(set_attr "type" "shift")
6168    (set_attr "length" "4")])
6170 (define_insn "*movb_signed"
6171   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6172                          (match_operand:SI 1 "const_int_operand" "n")
6173                          (match_operand:SI 2 "const_int_operand" "n"))
6174         (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
6175                          (match_dup 1)
6176                          (match_operand:SI 4 "const_int_operand" "n")))]
6177   "TARGET_NPS_BITOPS"
6178   "movb %0,%0,%3,%2,%4,%1"
6179   [(set_attr "type" "shift")
6180    (set_attr "length" "4")])
6182 (define_insn "*movb_high"
6183   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6184                          (match_operand:SI 1 "const_int_operand" "n")
6185                          (match_operand:SI 2 "const_int_operand" "n"))
6186         (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6187                      (match_operand:SI 4 "const_int_operand" "n")))]
6188   "TARGET_NPS_BITOPS
6189    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6190   "movb %0,%0,%3,%2,%4,%1"
6191   [(set_attr "type" "shift")
6192    (set_attr "length" "4")])
6194 ; N.B.: when processing signed bitfields that fit in the top half of
6195 ; a word, gcc will use a narrow sign extending load, and in this case
6196 ; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
6197 (define_insn "*movb_high_signed"
6198   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6199                          (match_operand:SI 1 "const_int_operand" "n")
6200                          (match_operand:SI 2 "const_int_operand" "n"))
6201         (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
6202                      (match_operand:SI 4 "const_int_operand" "n")))]
6203   "TARGET_NPS_BITOPS
6204    && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
6205   "movb %0,%0,%3,%2,%4,%1"
6206   [(set_attr "type" "shift")
6207    (set_attr "length" "4")])
6209 (define_split
6210   [(set (match_operand:SI 0 "register_operand" "")
6211         (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
6212                            (match_operand:SI 2 "const_int_operand" ""))
6213                 (subreg:SI (match_operand 3 "") 0)))]
6214   "TARGET_NPS_BITOPS
6215    && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
6216    && !reg_overlap_mentioned_p (operands[0], operands[1])"
6217   [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
6218    (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
6219         (match_dup 1))]
6220   "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
6222 (define_insn "*mrgb"
6223   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
6224                          (match_operand:SI 1 "const_int_operand" "n")
6225                          (match_operand:SI 2 "const_int_operand" "n"))
6226         (zero_extract:SI (match_dup 0) (match_dup 1)
6227                          (match_operand:SI 3 "const_int_operand" "n")))
6228    (set (zero_extract:SI (match_dup 0)
6229                          (match_operand:SI 4 "const_int_operand" "n")
6230                          (match_operand:SI 5 "const_int_operand" "n"))
6231         (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
6232                          (match_dup 4)
6233                          (match_operand:SI 7 "const_int_operand" "n")))]
6234   "TARGET_NPS_BITOPS"
6236   output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
6237   /* The ;%? updates the known unalignment.  */
6238   return arc_short_long (insn, ";%?", "nop_s");
6240   [(set_attr "type" "shift")
6241    (set_attr "length" "6")
6242    (set_attr "iscompact" "true")])
6244 ;; combine fumbles combination of two movb patterns, and then the
6245 ;; combination is rejected by combinable_i3pat.
6246 ;; Thus, we can only use a peephole2 to combine two such insns.
6248 (define_peephole2
6249   [(set (match_operand:SI 0 "register_operand" "")
6250         (match_operand:SI 1 "register_operand" ""))
6251    (set (zero_extract:SI (match_dup 0)
6252                          (match_operand:SI 2 "const_int_operand" "")
6253                          (match_operand:SI 3 "const_int_operand" ""))
6254         (zero_extract:SI (match_dup 1)
6255                          (match_dup 2)
6256                          (match_operand:SI 4 "const_int_operand" "")))
6257    (match_operand 9) ; unrelated insn scheduled here
6258    (set (zero_extract:SI (match_dup 0)
6259                          (match_operand:SI 5 "const_int_operand" "")
6260                          (match_operand:SI 6 "const_int_operand" ""))
6261         (zero_extract:SI (match_operand:SI 7 "register_operand" "")
6262                          (match_dup 5)
6263                          (match_operand:SI 8 "const_int_operand" "")))]
6264   "TARGET_NPS_BITOPS
6265    // Check that the second movb doesn't clobber an input of the extra insn.
6266    && !reg_overlap_mentioned_p (operands[0], operands[9])
6267    // And vice versa.
6268    && !reg_set_p (operands[0], operands[9])
6269    && !reg_set_p (operands[7], operands[9])"
6270   [(set (match_dup 0) (match_dup 1))
6271    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6272                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
6273               (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
6274                    (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
6275    (match_dup 9)])
6277 (define_peephole2
6278   [(set (match_operand:SI 0 "register_operand" "")
6279         (match_operand:SI 1 "register_operand" ""))
6280    (set (zero_extract:SI (match_dup 0)
6281                          (match_operand:SI 2 "const_int_operand" "")
6282                          (match_operand:SI 3 "const_int_operand" ""))
6283         (zero_extract:SI (match_dup 1)
6284                          (match_dup 2)
6285                          (match_operand:SI 4 "const_int_operand" "")))
6286    (set (match_dup 1) (match_operand 8))
6287    (set (zero_extract:SI (match_dup 0)
6288                          (match_operand:SI 5 "const_int_operand" "")
6289                          (match_operand:SI 6 "const_int_operand" ""))
6290         (zero_extract:SI (match_dup 1) (match_dup 5)
6291                          (match_operand:SI 7 "const_int_operand" "")))]
6292   "TARGET_NPS_BITOPS
6293    && !reg_overlap_mentioned_p (operands[0], operands[8])"
6294   [(set (match_dup 0) (match_dup 1))
6295    (set (match_dup 1) (match_dup 8))
6296    (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
6297                    (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
6298               (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
6299                    (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
6300    (match_dup 1)])
6302 (define_insn "*rotrsi3_cnt1"
6303   [(set (match_operand:SI 0 "dest_reg_operand"             "=w")
6304         (rotatert:SI (match_operand:SI 1 "register_operand" "c")
6305                      (const_int 1)))]
6306   ""
6307   "ror %0,%1%&"
6308   [(set_attr "type" "shift")
6309    (set_attr "predicable" "no")
6310    (set_attr "length" "4")])
6312 (define_insn "*ashlsi2_cnt1"
6313   [(set (match_operand:SI 0 "dest_reg_operand"           "=Rcqq,w")
6314         (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6315                    (const_int 1)))]
6316   ""
6317   "asl%? %0,%1%&"
6318   [(set_attr "type" "shift")
6319    (set_attr "iscompact" "maybe,false")
6320    (set_attr "predicable" "no,no")])
6322 (define_insn "*lshrsi3_cnt1"
6323   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcqq,w")
6324         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6325                      (const_int 1)))]
6326   ""
6327   "lsr%? %0,%1%&"
6328   [(set_attr "type" "shift")
6329    (set_attr "iscompact" "maybe,false")
6330    (set_attr "predicable" "no,no")])
6332 (define_insn "*ashrsi3_cnt1"
6333   [(set (match_operand:SI 0 "dest_reg_operand"             "=Rcqq,w")
6334         (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c")
6335                      (const_int 1)))]
6336   ""
6337   "asr%? %0,%1%&"
6338   [(set_attr "type" "shift")
6339    (set_attr "iscompact" "maybe,false")
6340    (set_attr "predicable" "no,no")])
6342 (define_peephole2
6343   [(set (match_operand:SI 0 "register_operand" "")
6344         (zero_extract:SI (match_dup 0)
6345                          (match_operand:SI 1 "const_int_operand" "")
6346                          (match_operand:SI 2 "const_int_operand" "")))
6347    (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
6348                          (match_dup 1)
6349                          (match_dup 2))
6350         (match_dup 0))]
6351   "TARGET_NPS_BITOPS
6352    && !reg_overlap_mentioned_p (operands[0], operands[3])"
6353   [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
6354         (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
6356 ;; Dummy pattern used as a place holder for automatically saved
6357 ;; registers.
6358 (define_insn "stack_irq_dwarf"
6359   [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)]
6360   ""
6361   ""
6362   [(set_attr "length" "0")])
6364 ;; MAC and DMPY instructions
6365 (define_insn_and_split "maddsidi4"
6366   [(set (match_operand:DI 0 "register_operand" "=r")
6367         (plus:DI
6368          (mult:DI
6369           (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6370           (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6371          (match_operand:DI 3 "register_operand" "r")))]
6372   "TARGET_PLUS_DMPY"
6373   "#"
6374   "TARGET_PLUS_DMPY && reload_completed"
6375   [(const_int 0)]
6376   "{
6377    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6378    emit_move_insn (acc_reg, operands[3]);
6379    if (TARGET_PLUS_MACD)
6380      emit_insn (gen_macd (operands[0], operands[1], operands[2]));
6381    else
6382      {
6383       emit_insn (gen_mac (operands[1], operands[2]));
6384       emit_move_insn (operands[0], acc_reg);
6385      }
6386    DONE;
6387    }"
6388   [(set_attr "type" "multi")
6389    (set_attr "length" "36")])
6391 (define_insn "macd"
6392   [(set (match_operand:DI 0 "even_register_operand"            "=Rcr,r,r")
6393         (plus:DI
6394          (mult:DI
6395           (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6396           (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal")))
6397          (reg:DI ARCV2_ACC)))
6398    (set (reg:DI ARCV2_ACC)
6399         (plus:DI
6400          (mult:DI (sign_extend:DI (match_dup 1))
6401                   (sign_extend:DI (match_dup 2)))
6402          (reg:DI ARCV2_ACC)))]
6403  "TARGET_PLUS_MACD"
6404  "macd %0,%1,%2"
6405   [(set_attr "length" "4,4,8")
6406    (set_attr "type" "multi")
6407    (set_attr "predicable" "yes,no,no")
6408    (set_attr "cond" "canuse,nocond,nocond")])
6410 (define_insn "mac"
6411   [(set (reg:DI ARCV2_ACC)
6412         (plus:DI
6413          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6414                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6415          (reg:DI ARCV2_ACC)))]
6416  "TARGET_PLUS_DMPY"
6417  "mac 0,%0,%1"
6418   [(set_attr "length" "4,8")
6419    (set_attr "type" "multi")
6420    (set_attr "predicable" "no")
6421    (set_attr "cond" "nocond")])
6423 (define_peephole2
6424   [(set (reg:DI ARCV2_ACC)
6425         (plus:DI
6426          (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" ""))
6427                   (sign_extend:DI (match_operand:SI 1 "extend_operand" "")))
6428          (reg:DI ARCV2_ACC)))
6429    (set (match_operand:SI 2 "register_operand" "")
6430         (match_operand:SI 3 "accl_operand" ""))]
6431  "TARGET_PLUS_DMPY"
6432  [(const_int 0)]
6434   emit_insn (gen_mac_r (operands[2], operands[0], operands[1]));
6435   DONE;
6436  })
6438 (define_insn "mac_r"
6439   [(set (match_operand:SI 0 "register_operand" "=r,r")
6440         (truncate:SI
6441          (plus:DI
6442           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6443                    (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6444           (reg:DI ARCV2_ACC))))
6445    (clobber (reg:DI ARCV2_ACC))]
6446  "TARGET_PLUS_DMPY"
6447  "mac %0,%1,%2"
6448   [(set_attr "length" "4,8")
6449    (set_attr "type" "multi")
6450    (set_attr "predicable" "no")
6451    (set_attr "cond" "nocond")])
6453 (define_insn_and_split "umaddsidi4"
6454   [(set (match_operand:DI 0 "register_operand" "=r")
6455         (plus:DI
6456          (mult:DI
6457           (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
6458           (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri")))
6459          (match_operand:DI 3 "register_operand" "r")))]
6460   "TARGET_PLUS_DMPY"
6461   "#"
6462   "TARGET_PLUS_DMPY && reload_completed"
6463   [(const_int 0)]
6464   "{
6465    rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
6466    emit_move_insn (acc_reg, operands[3]);
6467    if (TARGET_PLUS_MACD)
6468      emit_insn (gen_macdu (operands[0], operands[1], operands[2]));
6469    else
6470      {
6471       emit_insn (gen_macu (operands[1], operands[2]));
6472       emit_move_insn (operands[0], acc_reg);
6473      }
6474    DONE;
6475    }"
6476   [(set_attr "type" "multi")
6477    (set_attr "length" "36")])
6479 (define_insn "macdu"
6480   [(set (match_operand:DI 0 "even_register_operand"            "=Rcr,r,r")
6481         (plus:DI
6482          (mult:DI
6483           (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c"))
6484           (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i")))
6485          (reg:DI ARCV2_ACC)))
6486    (set (reg:DI ARCV2_ACC)
6487         (plus:DI
6488          (mult:DI (zero_extend:DI (match_dup 1))
6489                   (zero_extend:DI (match_dup 2)))
6490          (reg:DI ARCV2_ACC)))]
6491  "TARGET_PLUS_MACD"
6492  "macdu %0,%1,%2"
6493   [(set_attr "length" "4,4,8")
6494    (set_attr "type" "multi")
6495    (set_attr "predicable" "yes,no,no")
6496    (set_attr "cond" "canuse,nocond,nocond")])
6498 (define_insn "macu"
6499   [(set (reg:DI ARCV2_ACC)
6500         (plus:DI
6501          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r"))
6502                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i")))
6503          (reg:DI ARCV2_ACC)))]
6504  "TARGET_PLUS_DMPY"
6505  "macu 0,%0,%1"
6506   [(set_attr "length" "4,8")
6507    (set_attr "type" "multi")
6508    (set_attr "predicable" "no")
6509    (set_attr "cond" "nocond")])
6511 (define_peephole2
6512   [(set (reg:DI ARCV2_ACC)
6513         (plus:DI
6514          (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" ""))
6515                   (zero_extend:DI (match_operand:SI 1 "extend_operand" "")))
6516          (reg:DI ARCV2_ACC)))
6517    (set (match_operand:SI 2 "register_operand" "")
6518         (match_operand:SI 3 "accl_operand" ""))]
6519  "TARGET_PLUS_DMPY"
6520  [(const_int 0)]
6522   emit_insn (gen_macu_r (operands[2], operands[0], operands[1]));
6523   DONE;
6524  })
6526 (define_insn "macu_r"
6527   [(set (match_operand:SI 0 "register_operand" "=r,r")
6528         (truncate:SI
6529          (plus:DI
6530           (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r"))
6531                    (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i")))
6532           (reg:DI ARCV2_ACC))))
6533    (clobber (reg:DI ARCV2_ACC))]
6534  "TARGET_PLUS_DMPY"
6535  "macu %0,%1,%2"
6536   [(set_attr "length" "4,8")
6537    (set_attr "type" "multi")
6538    (set_attr "predicable" "no")
6539    (set_attr "cond" "nocond")])
6541 (define_insn "mpyd_arcv2hs"
6542   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r")
6543         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "  0, c"))
6544                  (sign_extend:DI (match_operand:SI 2 "register_operand"  "  c, c"))))
6545    (set (reg:DI ARCV2_ACC)
6546         (mult:DI
6547           (sign_extend:DI (match_dup 1))
6548           (sign_extend:DI (match_dup 2))))]
6549   "TARGET_PLUS_MACD"
6550   "mpyd%? %0,%1,%2"
6551   [(set_attr "length" "4,4")
6552   (set_attr "iscompact" "false")
6553   (set_attr "type" "multi")
6554   (set_attr "predicable" "yes,no")
6555   (set_attr "cond" "canuse,nocond")])
6557 (define_insn "mpyd_imm_arcv2hs"
6558   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r,r,Rcr,  r")
6559         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  "  0, c,0,  0,  c"))
6560                  (match_operand 2                   "immediate_operand"  "  L, L,I,Cal,Cal")))
6561    (set (reg:DI ARCV2_ACC)
6562         (mult:DI (sign_extend:DI (match_dup 1))
6563                  (match_dup 2)))]
6564   "TARGET_PLUS_MACD"
6565   "mpyd%? %0,%1,%2"
6566   [(set_attr "length" "4,4,4,8,8")
6567   (set_attr "iscompact" "false")
6568   (set_attr "type" "multi")
6569   (set_attr "predicable" "yes,no,no,yes,no")
6570   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6572 (define_insn "mpydu_arcv2hs"
6573   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r")
6574         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "  0, c"))
6575                  (zero_extend:DI (match_operand:SI 2 "register_operand" "   c, c"))))
6576    (set (reg:DI ARCV2_ACC)
6577         (mult:DI (zero_extend:DI (match_dup 1))
6578                  (zero_extend:DI (match_dup 2))))]
6579   "TARGET_PLUS_MACD"
6580   "mpydu%? %0,%1,%2"
6581   [(set_attr "length" "4,4")
6582   (set_attr "iscompact" "false")
6583   (set_attr "type" "multi")
6584   (set_attr "predicable" "yes,no")
6585   (set_attr "cond" "canuse,nocond")])
6587 (define_insn "mpydu_imm_arcv2hs"
6588   [(set (match_operand:DI 0 "even_register_operand"                     "=Rcr, r,r,Rcr,  r")
6589         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand"  "  0, c,0,  0,  c"))
6590                  (match_operand 2                   "immediate_operand"  "  L, L,I,Cal,Cal")))
6591    (set (reg:DI ARCV2_ACC)
6592         (mult:DI (zero_extend:DI (match_dup 1))
6593                  (match_dup 2)))]
6594   "TARGET_PLUS_MACD"
6595   "mpydu%? %0,%1,%2"
6596   [(set_attr "length" "4,4,4,8,8")
6597   (set_attr "iscompact" "false")
6598   (set_attr "type" "multi")
6599   (set_attr "predicable" "yes,no,no,yes,no")
6600   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
6602 (define_insn "stack_tie"
6603   [(set (mem:BLK (scratch))
6604         (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
6605                      (match_operand:SI 1 "register_operand" "rb")]
6606                     UNSPEC_ARC_STKTIE))]
6607   ""
6608   ""
6609   [(set_attr "length" "0")
6610    (set_attr "iscompact" "false")
6611    (set_attr "type" "block")]
6612   )
6614 ;; include the arc-FPX instructions
6615 (include "fpx.md")
6617 ;; include the arc-FPU instructions
6618 (include "fpu.md")
6620 (include "simdext.md")
6622 ;; include atomic extensions
6623 (include "atomic.md")